#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/input.h>
-#include <linux/device.h>
#include <linux/interrupt.h>
-#include <linux/suspend.h>
-#include <linux/slab.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/io.h>
-
#include <sound/driver.h>
-#include <sound/core.h>
-#include <sound/ac97_codec.h>
-
-#include <linux/gameport.h> //bonus XXX
-
+#include <asm/io.h>
#include <linux/platform_device.h>
-
-/*
- * originaly from
- * linux/drivers/misc/mx1ts.h
- *
- * Copyright (C) 2003 Blue Mug, Inc. for Motorola, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
/* Interrupt numbers */
#define ASP_COMPARE_IRQ 5
#define ASP_PENDATA_IRQ 33
/* Analog signal processor (ASP) control registers */
#define ASP_BASE_ADDR 0x00215000
+#define ASP_BASE_ADDR_LEN 0x38
#define ASP_ACNTLCR (0x10) /* Control register */
#define ASP_PSMPLRG (0x14) /* Pen A/D sampe rate control */
struct mx1ts {
struct input_dev *ts_idev;
- struct resource pamet;
- int irq;
+ /*struct resource pamet;*/
+ unsigned int irq_touch;
+ unsigned int irq_pen_data;
wait_queue_head_t ts_wait;
struct task_struct *ts_task;
- unsigned int irq_pending;
- unsigned int ts_restart:1;
- unsigned int adcsync:1;
- void __iomem* mx1ts_mem;
-
+ void __iomem* mx1ts_mem; /* remaped memmory */
+ unsigned int baseaddr;
+ unsigned int baseaddr_len;
u16 x_res;
u16 y_res;
u16 x_akt;
u16 cal_auto_zero;
u16 cal_range_x;
u16 cal_range_y;
- unsigned int stav;
+ /*unsigned int stav; */
u8 auto_calibration;
u8 is_open;
};
-static int MX1TS_presed = 0;
-static int MX1TS_lastx = 0;
-static int MX1TS_lasty = 0;
static inline void mx1ts_reg_set_mask(struct mx1ts *mts , unsigned int reg, u32 mask)
{
u32 val;
- val = __raw_readl(mts->mx1ts_mem+reg);
+ val = __raw_readl(mts->mx1ts_mem+reg); /* TODO zvazit pouziti ioread32 */
val |= mask;
__raw_writel(val, mts->mx1ts_mem+reg );
}
static inline void mx1ts_reg_write(struct mx1ts *mts, unsigned int reg, unsigned int val)
{
__raw_writel(val, mts->mx1ts_mem+reg);
- printk(KERN_ERR "mx1_touchscreen: zapisuji do : %p hodnotu %x\n",mts->mx1ts_mem+reg, val);
+ /*printk(KERN_DEBUG "mx1_touchscreen: writing into : %p value %x\n",mts->mx1ts_mem+reg, val);*/
}
static inline unsigned int mx1ts_reg_read(struct mx1ts *mts, unsigned int reg)
{
unsigned int out;
-
out = __raw_readl( mts->mx1ts_mem + reg );
- /*printk(KERN_ERR "mx1_touchscreen: ctu z %p : %d \n",mts->mx1ts_mem + reg, out);*/
+ /*printk(KERN_DEBUG "mx1_touchscreen: reading from %p : %d \n",mts->mx1ts_mem + reg, out);*/
return out;
}
static void mx1ts_enable_auto_sample(struct mx1ts *mts)
{
unsigned int value;
-
mx1ts_flush_fifo(mts);
value = mx1ts_reg_read(mts, ASP_ACNTLCR);
value |= ASP_EDGE | /*ASP_POL |*/ ASP_PIRQE;
mx1ts_reg_write(mts, ASP_ICNTLR, value);
- printk(KERN_ERR "mx1_touchscreen pen_touch: aktivuji pen down interrupt \n");
+ printk(KERN_DEBUG "mx1_touchscreen: pen_touch: activating pen_down interrupt \n");
}
static void mx1ts_disable_pen_touch_interrupt(struct mx1ts *mts)
/* Enable pen touch interrupt. */
value = mx1ts_reg_read(mts, ASP_ICNTLR);
value &= ~ASP_PIRQE;
- value = 0; /* TODO tohle se musi smazat*/
mx1ts_reg_write(mts, ASP_ICNTLR, value);
- printk(KERN_ERR "mx1_touchscreen pen_touch: deaktivuji pen down interrupt \n");
+ printk(KERN_DEBUG "mx1_touchscreen: pen_touch: deaktivating pen_down interrupt \n");
}
static void mx1ts_enable_pen_up_interrupt(struct mx1ts *mts)
value = mx1ts_reg_read(mts, ASP_ICNTLR);
value |= ASP_PUIE;
mx1ts_reg_write(mts, ASP_ICNTLR, value);
- printk(KERN_ERR "mx1_touchscreen pen_up: aktivuji pen up interrupt \n");
+ printk(KERN_DEBUG "mx1_touchscreen: pen_up: activating pen_up interrupt \n");
}
static void mx1ts_disable_pen_up_interrupt(struct mx1ts *mts)
value = mx1ts_reg_read(mts, ASP_ICNTLR);
value &= ~ASP_PUIE;
mx1ts_reg_write(mts, ASP_ICNTLR, value);
- printk(KERN_ERR "mx1_touchscreen pen_up: deaktivuji pen up interrupt \n");
+ printk(KERN_DEBUG "mx1_touchscreen: pen_up: deaktivating pen_up interrupt \n");
}
static void mx1ts_start_auto_calibration(struct mx1ts *mts)
{
unsigned int value;
- printk(KERN_ERR "mx1_touchscreen start_auto_calibration \n");
+ printk(KERN_DEBUG "mx1_touchscreen: start_auto_calibration \n");
mts->auto_calibration = 1;
static void mx1ts_evt_add_touch(struct input_dev *idev, u8 p , u16 x, u16 y)
{
+ struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
+ mts->x_akt = x;
+ mts->y_akt = y;
+
input_report_key(idev, BTN_TOUCH, 1);
input_report_abs(idev, ABS_X, x);
input_report_abs(idev, ABS_Y, y);
input_sync(idev);
}
-static void mx1ts_evt_add_up(struct input_dev *idev, u16 x, u16 y)
+static void mx1ts_evt_add_up(struct input_dev *idev)
{
- input_report_abs(idev, ABS_X, x);
- input_report_abs(idev, ABS_Y, y);
+ struct mx1ts *mts = dev_get_drvdata(idev->dev.parent);
+
+ input_report_abs(idev, ABS_X, mts->x_akt);
+ input_report_abs(idev, ABS_Y, mts->y_akt);
input_report_abs(idev, ABS_PRESSURE, 0);
/*input_report_key(idev, BTN_TOUCH, 0);*/
input_sync(idev);
}
-static void mx1ts_evt_add(struct input_dev *idev, u8 p , u16 x, u16 y)
-{
- if((x < 7900 || x > 8900) && (y < 7751 || y > 10900)) {
- MX1TS_presed = 1;
- MX1TS_lastx = x;
- MX1TS_lasty = y;
- mx1ts_evt_add_touch(idev,p, x, y); /* TODO opravit pen_up pen_down zrejme chyba HW ??? TODO */
-
-
- } else {
- if(MX1TS_presed == 1) {
- MX1TS_presed = 0;
- mx1ts_evt_add_up(idev, MX1TS_lastx, MX1TS_lasty);
- }
- }
-}
-
/*
* Handle the pen data ready interrupt, generated when pen data is
* in the FIFO.
mx1_cal_range_x = 1;
mx1_cal_range_y = 1;
- /*printk(KERN_ERR "mx1_touchscreen mx1ts_pendata_irq \n");*/
-/* printk(KERN_ERR "mx1_touchscreen: mx1_pendata_irq interrupt recived from struct %p\n", mts);*/
+ /*printk(KERN_DEBUG "mx1_touchscreen: mx1_pendata_irq interrupt recived from struct %p\n", mts);*/
- if (mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PUIS) { /*pen up interupt pending*/
- mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PUIS); /*clearing pen up interupt*/
+ if (mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PUIS) { /*pen up interupt pending*/
+ mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PUIS); /*clearing pen up interupt*/
mx1ts_disable_auto_sample(mts);
mx1ts_disable_pen_up_interrupt(mts);
mx1ts_enable_pen_touch_interrupt(mts);
if(mts->is_open) /*report last known touch*/
- mx1ts_evt_add_up(mts->ts_idev, 100, 100);
- printk(KERN_ERR "Pen up interrupt.\n");
+ mx1ts_evt_add_up(mts->ts_idev);
+ printk(KERN_DEBUG "Pen up interrupt.\n");
mx1ts_flush_fifo(mts);
return IRQ_HANDLED;
mts->cal_range_x = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
mts->cal_range_y = mx1ts_reg_read(mts, ASP_PADFIFO) & 0xFFFF;
- printk(KERN_ERR "Kalibrace cal_auto_zero %i.\n",mts->cal_auto_zero);
- printk(KERN_ERR "Kalibrace cal_range_x %i.\n",mts->cal_range_x);
- printk(KERN_ERR "Kalibrace cal_range_y %i.\n",mts->cal_range_y);
-
if ((mts->cal_auto_zero >= mts->cal_range_x) ||
(mts->cal_auto_zero >= mts->cal_range_y)) {
// Invalid data.
- printk(KERN_ERR "Invalid data.\n");
+ printk(KERN_INFO "Invalid calibration data. Recalibrating. \n");
mx1ts_flush_fifo(mts); /*if there are some older data*/
mx1ts_start_auto_calibration(mts);
- return IRQ_NONE; /* return IRQ_HANDLED; */
+ return IRQ_HANDLED; /*return IRQ_NONE;*/
}
+ printk(KERN_DEBUG "mx1 touchscreen: calibration cal_auto_zero %i.\n",mts->cal_auto_zero);
+ printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_x %i.\n",mts->cal_range_x);
+ printk(KERN_DEBUG "mx1 touchscreen: calibration cal_range_y %i.\n",mts->cal_range_y);
mts->cal_range_x -= mts->cal_auto_zero;
mts->cal_range_y -= mts->cal_auto_zero;
// generated as long as there is data in the FIFO.
if ((mx1ts_reg_read(mts, ASP_ISTATR) & ASP_PDR) != ASP_PDR) {
- return IRQ_NONE; /* TODO je to tak? */
+ return IRQ_NONE;
}
auto_zero = mx1ts_reg_read(mts, ASP_PADFIFO);
pen_y = mx1ts_reg_read(mts, ASP_PADFIFO);
pen_u = mx1ts_reg_read(mts, ASP_PADFIFO);
- pen_x = (u32)(((pen_x - auto_zero) << 16) /
+ pen_x = mts->x_res - (u32)(((pen_x - auto_zero) << 16) /
mts->cal_range_x);
- pen_y = (u32)(((pen_y - auto_zero) << 16) /
+ pen_y = mts->y_res - (u32)(((pen_y - auto_zero) << 16) /
mts->cal_range_y);
if(mts->is_open)
- mx1ts_evt_add(mts->ts_idev, 200 , pen_x, pen_y);
+ mx1ts_evt_add_touch(mts->ts_idev, 200 , pen_x, pen_y);
}
return IRQ_HANDLED;
}
{
struct mx1ts *mts = (struct mx1ts *) dev_id;
- printk(KERN_ERR "Prijat touch down irq \n");
+ printk(KERN_DEBUG "mx1 touchscreen: Touch down interrupt \n");
/* Clear the interrupt. */
mx1ts_reg_set_mask(mts, ASP_ISTATR, ASP_PEN);
static inline int mx1ts_enable_irqs(struct mx1ts *mts) //zaregistruje preruseni
{
int result;
- result = request_irq(ASP_PENDATA_IRQ,
+
+ result = request_irq(mts->irq_pen_data,
mx1ts_pendata_irq,
- /*IRQF_*/ 0,
+ 0,
DEV_IRQ_ID,
mts);
if (result) {
- printk(KERN_ERR "Couldn't request pen data IRQ.\n");
+ printk(KERN_ERR "mx1 touchscreen: Couldn't request pen data IRQ.\n");
return result;
}
-
- result = request_irq(ASP_TOUCH_IRQ,
+
+ result = request_irq(mts->irq_touch,
mx1ts_touch_irq,
/*IRQF_*/ 0,
DEV_IRQ_ID,
mts);
if (result) {
- printk(KERN_ERR "Couldn't request pen touch IRQ.\n");
- free_irq(ASP_PENDATA_IRQ, mts);
+ printk(KERN_ERR "mx1 touchscreen: Couldn't request pen touch IRQ.\n");
+ free_irq(mts->irq_pen_data, mts);
return result;
}
return result;
{
int ret = 0;
- if(!request_mem_region(ASP_BASE_ADDR, 0x38 , "mx1ts")) {
- printk(KERN_ERR "mx1ts: request_mem_region \tFAILED\n");
- return -1;
+ if(!request_mem_region(mts->baseaddr, mts->baseaddr_len , "mx1ts")) {
+ printk(KERN_ERR "mx1 touchscreen: request_mem_region \tFAILED\n");
+ return -ENOMEM;
}
- printk(KERN_ERR "mx1ts: request_mem_region \tOK\n");
+ printk(KERN_DEBUG "mx1 touchscreen: request_mem_region \tOK\n");
- mts->mx1ts_mem = ioremap ( ASP_BASE_ADDR, 0x38);
+ mts->mx1ts_mem = ioremap ( mts->baseaddr, mts->baseaddr_len);
- printk(KERN_ERR "mx1ts: memory remaped on %p \n", mts->mx1ts_mem);
+ if(!mts->mx1ts_mem) {
+ release_mem_region(mts->baseaddr, mts->baseaddr_len);
+ printk(KERN_ERR "mx1 touchscreen: ioremap \tFAILED\n");
+ return -1;
+ }
+
+ printk(KERN_DEBUG "mx1 touchscreen: memory remaped on %p \n", mts->mx1ts_mem);
- printk(KERN_ERR "mx1ts: enabling irqs\n");
+ /*printk(KERN_DEBUG "mx1 touchscreen: enabling irqs\n");*/
if ((ret = mx1ts_enable_irqs(mts)))
return ret;
- printk(KERN_ERR "mx1ts: irqs enabled \tOK\n");
+ printk(KERN_DEBUG "mx1 touchscreen: irqs enabled \tOK\n");
mx1ts_reset_asp(mts);
- printk(KERN_ERR "mx1ts: reset\tOK\n");
+ printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
return 0;
}
mts->is_open = 0;
mx1ts_flush_fifo(mts);
mx1ts_reset_asp(mts);
- printk(KERN_ERR "mx1ts: reset\tOK\n");
+ printk(KERN_DEBUG "mx1 touchscreen: reset\tOK\n");
mx1ts_disable_pen_touch_interrupt(mts);
mx1ts_disable_pen_up_interrupt(mts);
mts->is_open = 1;
mx1ts_flush_fifo(mts); /*if there are some older data*/
mx1ts_enable_pen_touch_interrupt(mts);
- printk(KERN_ERR "mx1ts: zapnuti touch interrupt\n");
+ printk(KERN_DEBUG "mx1 touchscreen: touch_down interupt enabled\n");
return 0;
}
{
struct mx1ts *mts;
struct input_dev *idev;
- int error, x_res, y_res;
+ int error;
/* TODO jak poznat ze zarizeni je pritomne ? */
- mts = kzalloc(sizeof(struct mx1ts), GFP_KERNEL); /* alokuje pamet */
+ mts = kzalloc(sizeof(struct mx1ts), GFP_KERNEL);
idev = input_allocate_device();
if (!mts || !idev) {
error = -ENOMEM;
- printk(KERN_ERR "mx1ts: failed allocate memory for struct mx1ts or idev\n");
+ printk(KERN_ERR "mx1 touchscreen: failed allocate memory for struct mx1ts or idev\n");
goto err_free_devs;
return error;
}
-
- mx1ts_on(mts); /* remaping registers, reseting device */
-
- mts->ts_idev = idev;
- //ucb->adcsync = adcsync;
- //ucb->ac97 = to_ac97_t(dev);
- init_waitqueue_head(&mts->ts_wait);
-
-/* id = mx1ts_reg_read(ucb, UCB_ID);
- if (id != UCB_ID_1400) {
- error = -ENODEV;
- goto err_free_devs;
- }
-
- error = mx1ts_detect_irq(ucb);
- if (error) {
- printk(KERN_ERR "UCB1400: IRQ probe failed\n");
+ mts->baseaddr = dev->resource[0].start;
+ mts->baseaddr_len = dev->resource[0].end - dev->resource[0].start;
+ printk(KERN_ERR "mx1 touchscreen: memorry base addr %d \n", mts->baseaddr);
+ printk(KERN_ERR "mx1 touchscreen: memorry base addr_len %d \n", mts->baseaddr_len);
+ mts->irq_pen_data = dev->resource[1].start;
+ mts->irq_touch = dev->resource[2].start;
+
+ error = mx1ts_on(mts);
+ if(error<0) { /* remaping registers, reseting device */
+ printk(KERN_ERR "mx1 touchscreen: failed mx1ts_on - remaping registers, reseting device\n");
goto err_free_devs;
+ return error;
}
- error = request_irq(ucb->irq, mx1ts_hard_irq, IRQF_TRIGGER_RISING,
- "UCB1400", ucb);
- if (error) {
- printk(KERN_ERR "mx1ts: unable to grab irq%d: %d\n",
- ucb->irq, error);
- goto err_free_devs;
- }
- printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);*/
+ mts->ts_idev = idev;
+ init_waitqueue_head(&mts->ts_wait);
//input_set_drvdata(idev, mts); /*moznost ulozit ukazatel na trukturu do input_driver*/
platform_set_drvdata(dev, mts);
-
+
idev->dev.parent = &dev->dev;
idev->name = "MX1 touchscreen interface";
+ idev->phys = "mx1ts/input0";
idev->id.vendor = (unsigned int) 345; /*mx1ts_reg_read(mx1_ts, AC97_VENDOR_ID1);*/
- idev->id.product = (unsigned int) 354; /*id;*/
+ idev->id.product = (unsigned int) 354;
+ idev->id.version = 0x0100;
+ idev->id.bustype = BUS_HOST;
idev->open = mx1ts_open;
idev->close = mx1ts_close;
idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- printk(KERN_ERR "mx1ts: setting idev struct \tOK\n");
+ printk(KERN_DEBUG "mx1ts: setting idev struct \tOK\n");
- x_res = 60000;
- y_res = 60000;
- printk(KERN_DEBUG "mx1ts: x/y = %d/%d\n", x_res, y_res);
+ mts->x_res = 60000; /*TODO neni mozne zmerit ? */
+ mts->y_res = 60000;
+ printk(KERN_DEBUG "mx1ts: x/y = %d/%d\n", mts->x_res, mts->y_res);
- input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
- input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
- input_set_abs_params(idev, ABS_PRESSURE, 0, 20000, 0, 0);
+ input_set_abs_params(idev, ABS_X, 0, mts->x_res, 0, 0);
+ input_set_abs_params(idev, ABS_Y, 0, mts->y_res, 0, 0);
+ input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);
error = input_register_device(idev);
if (error) {
- printk(KERN_ERR "mx1ts: error while register input device\n");
+ printk(KERN_ERR "mx1 touchscreen: error while register input device\n");
goto err_free_devs;
}
- printk(KERN_ERR "mx1ts: input device registered \tOK\n");
+ printk(KERN_DEBUG "mx1ts: input device registered \tOK\n");
return 0;
err_free_devs:
- printk(KERN_ERR "mx1ts: error in device probe \n");
- /*input_free_device(idev);*/
+ printk(KERN_ERR "mx1 touchscreen: error in device probe \n");
+ input_free_device(idev);
kfree(mts);
return error;
{
struct mx1ts *mts = platform_get_drvdata(dev);
- BUG_ON(mts == NULL);
+ //BUG_ON(mts == NULL);
- free_irq(ASP_PENDATA_IRQ, mts);
- free_irq(ASP_TOUCH_IRQ, mts);
+ free_irq(mts->irq_pen_data, mts);
+ free_irq(mts->irq_touch, mts);
/*input_free_device(mts->ts_idev);
- printk(KERN_ERR "Free device \tOK\n");*/
+ printk(KERN_DEBUG "Free device \tOK\n");*/
input_unregister_device(mts->ts_idev);
- printk(KERN_ERR "Unregister device \tOK\n");
+ printk(KERN_INFO "mx1 touchscreen: Unregister device \tOK\n");
iounmap(mts->mx1ts_mem);
- release_mem_region(ASP_BASE_ADDR, 0x38);
+ release_mem_region(mts->baseaddr, mts->baseaddr_len);
kfree(mts);
- printk(KERN_ERR "Removing driver \tOK\n");
+ printk(KERN_INFO "mx1 touchscreen: Removing driver \tOK\n");
return 0;
}
return 0;
}
-/* inicializace ovladace a driveru (insmod, rmmmod ) */
-
static struct platform_driver mx1ts_driver = {
.probe = mx1ts_probe,
.remove = mx1ts_remove,
static struct resource mx1ts_resources[] = {
[0] = {
.start = ASP_BASE_ADDR + 0,
- .end = ASP_BASE_ADDR + 0x37,
+ .end = ASP_BASE_ADDR + ASP_BASE_ADDR_LEN,
.flags = IORESOURCE_MEM,
},
[1] = {
},
};
+void mx1ts_device_release(struct device *dev) {
+ /*struct platform_device *pdev = to_platform_device(dev);
+ release_resource(&dev->res);
+ kfree(pdev);
+ }*/
+}
+
static struct platform_device mx1ts_device = {
.name = "mx1ts",
.id = 0,
.num_resources = ARRAY_SIZE(mx1ts_resources),
.resource = mx1ts_resources,
+ .dev = {
+ .release = mx1ts_device_release,
+ },
};
int error;
error = platform_device_register(&mx1ts_device);
if(error) {
- printk(KERN_ERR "PiMX1_touchsceen: device registration failed\n");
+ printk(KERN_ERR "mx1 touchscreen: device registration failed\n");
return error;
}
return;
}
-//module_param(adcsync, bool, 0444);
+//module_param(adcsync, bool, 0444); /* priklad parametru modulu*/
//MODULE_PARM_DESC(adcsync, "Synchronize touch readings with ADCSYNC pin.");
-//module_param(ts_delay, int, 0444);
-//MODULE_PARM_DESC(ts_delay, "Delay between panel setup and position read. Default = 55us.");
-
-//module_param(ts_delay_pressure, int, 0444);
-//MODULE_PARM_DESC(ts_delay_pressure,
-// "delay between panel setup and pressure read. Default = 0us.");
-
module_init(mx1ts_init);
module_exit(mx1ts_exit);