summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/ads7846.c13
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c17
-rw-r--r--drivers/input/touchscreen/intel-mid-touch.c2
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c2
-rw-r--r--drivers/input/touchscreen/wm831x-ts.c75
-rw-r--r--drivers/input/touchscreen/wm9705.c2
-rw-r--r--drivers/input/touchscreen/wm9712.c2
-rw-r--r--drivers/input/touchscreen/wm9713.c2
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c4
9 files changed, 91 insertions, 28 deletions
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index c24946f51256..1de1c19dad30 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -281,17 +281,24 @@ struct ser_req {
u8 command;
u8 ref_off;
u16 scratch;
- __be16 sample;
struct spi_message msg;
struct spi_transfer xfer[6];
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 sample ____cacheline_aligned;
};
struct ads7845_ser_req {
u8 command[3];
- u8 pwrdown[3];
- u8 sample[3];
struct spi_message msg;
struct spi_transfer xfer[2];
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ u8 sample[3] ____cacheline_aligned;
};
static int ads7846_read12_ser(struct device *dev, unsigned command)
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index efa06882de00..45f93d0f5592 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -399,31 +399,34 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
err = -EBUSY;
- goto fail2;
+ goto fail1;
}
if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) {
printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
err = -EBUSY;
- goto fail3;
+ goto fail2;
}
serio_set_drvdata(serio, ts);
err = serio_open(serio, drv);
if (err)
- return err;
+ goto fail3;
//h3600_flite_control(1, 25); /* default brightness */
- input_register_device(ts->dev);
+ err = input_register_device(ts->dev);
+ if (err)
+ goto fail4;
return 0;
-fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
+fail4: serio_close(serio);
+fail3: serio_set_drvdata(serio, NULL);
+ free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
-fail1: serio_set_drvdata(serio, NULL);
- input_free_device(input_dev);
+fail1: input_free_device(input_dev);
kfree(ts);
return err;
}
diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c
index c0307b22d86f..66c96bfc5522 100644
--- a/drivers/input/touchscreen/intel-mid-touch.c
+++ b/drivers/input/touchscreen/intel-mid-touch.c
@@ -542,7 +542,7 @@ static int __devinit mrstouch_adc_init(struct mrstouch_dev *tsdev)
* ADC power on, start, enable PENDET and set loop delay
* ADC loop delay is set to 4.5 ms approximately
* Loop delay more than this results in jitter in adc readings
- * Setting loop delay to 0 (continous loop) in MAXIM stops PENDET
+ * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET
* interrupt generation sometimes.
*/
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 028a5363eea1..3b5b5df04dd6 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -6,7 +6,7 @@
* Copyright: MontaVista Software, Inc.
*
* Spliting done by: Marek Vasut <marek.vasut@gmail.com>
- * If something doesnt work and it worked before spliting, e-mail me,
+ * If something doesn't work and it worked before spliting, e-mail me,
* dont bother Nicolas please ;-)
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c
index 6ae054f8e0aa..9175d49d2546 100644
--- a/drivers/input/touchscreen/wm831x-ts.c
+++ b/drivers/input/touchscreen/wm831x-ts.c
@@ -68,8 +68,23 @@ struct wm831x_ts {
unsigned int pd_irq;
bool pressure;
bool pen_down;
+ struct work_struct pd_data_work;
};
+static void wm831x_pd_data_work(struct work_struct *work)
+{
+ struct wm831x_ts *wm831x_ts =
+ container_of(work, struct wm831x_ts, pd_data_work);
+
+ if (wm831x_ts->pen_down) {
+ enable_irq(wm831x_ts->data_irq);
+ dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n");
+ } else {
+ enable_irq(wm831x_ts->pd_irq);
+ dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n");
+ }
+}
+
static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
{
struct wm831x_ts *wm831x_ts = irq_data;
@@ -110,6 +125,9 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
}
if (!wm831x_ts->pen_down) {
+ /* Switch from data to pen down */
+ dev_dbg(wm831x->dev, "IRQ DATA->PD\n");
+
disable_irq_nosync(wm831x_ts->data_irq);
/* Don't need data any more */
@@ -128,6 +146,10 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
ABS_PRESSURE, 0);
input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0);
+
+ schedule_work(&wm831x_ts->pd_data_work);
+ } else {
+ input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
}
input_sync(wm831x_ts->input_dev);
@@ -141,6 +163,11 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
struct wm831x *wm831x = wm831x_ts->wm831x;
int ena = 0;
+ if (wm831x_ts->pen_down)
+ return IRQ_HANDLED;
+
+ disable_irq_nosync(wm831x_ts->pd_irq);
+
/* Start collecting data */
if (wm831x_ts->pressure)
ena |= WM831X_TCH_Z_ENA;
@@ -149,14 +176,14 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA,
WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena);
- input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
- input_sync(wm831x_ts->input_dev);
-
wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
WM831X_TCHPD_EINT, WM831X_TCHPD_EINT);
wm831x_ts->pen_down = true;
- enable_irq(wm831x_ts->data_irq);
+
+ /* Switch from pen down to data */
+ dev_dbg(wm831x->dev, "IRQ PD->DATA\n");
+ schedule_work(&wm831x_ts->pd_data_work);
return IRQ_HANDLED;
}
@@ -182,13 +209,28 @@ static void wm831x_ts_input_close(struct input_dev *idev)
struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
struct wm831x *wm831x = wm831x_ts->wm831x;
+ /* Shut the controller down, disabling all other functionality too */
wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
- WM831X_TCH_ENA | WM831X_TCH_CVT_ENA |
- WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
- WM831X_TCH_Z_ENA, 0);
+ WM831X_TCH_ENA | WM831X_TCH_X_ENA |
+ WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0);
- if (wm831x_ts->pen_down)
+ /* Make sure any pending IRQs are done, the above will prevent
+ * new ones firing.
+ */
+ synchronize_irq(wm831x_ts->data_irq);
+ synchronize_irq(wm831x_ts->pd_irq);
+
+ /* Make sure the IRQ completion work is quiesced */
+ flush_work_sync(&wm831x_ts->pd_data_work);
+
+ /* If we ended up with the pen down then make sure we revert back
+ * to pen detection state for the next time we start up.
+ */
+ if (wm831x_ts->pen_down) {
disable_irq(wm831x_ts->data_irq);
+ enable_irq(wm831x_ts->pd_irq);
+ wm831x_ts->pen_down = false;
+ }
}
static __devinit int wm831x_ts_probe(struct platform_device *pdev)
@@ -198,7 +240,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent);
struct wm831x_touch_pdata *pdata = NULL;
struct input_dev *input_dev;
- int error;
+ int error, irqf;
if (core_pdata)
pdata = core_pdata->touch;
@@ -212,6 +254,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
wm831x_ts->wm831x = wm831x;
wm831x_ts->input_dev = input_dev;
+ INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work);
/*
* If we have a direct IRQ use it, otherwise use the interrupt
@@ -270,9 +313,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
WM831X_TCH_RATE_MASK, 6);
+ if (pdata && pdata->data_irqf)
+ irqf = pdata->data_irqf;
+ else
+ irqf = IRQF_TRIGGER_HIGH;
+
error = request_threaded_irq(wm831x_ts->data_irq,
NULL, wm831x_ts_data_irq,
- IRQF_ONESHOT,
+ irqf | IRQF_ONESHOT,
"Touchscreen data", wm831x_ts);
if (error) {
dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n",
@@ -281,9 +329,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
}
disable_irq(wm831x_ts->data_irq);
+ if (pdata && pdata->pd_irqf)
+ irqf = pdata->pd_irqf;
+ else
+ irqf = IRQF_TRIGGER_HIGH;
+
error = request_threaded_irq(wm831x_ts->pd_irq,
NULL, wm831x_ts_pen_down_irq,
- IRQF_ONESHOT,
+ irqf | IRQF_ONESHOT,
"Touchscreen pen down", wm831x_ts);
if (error) {
dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n",
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
index 6b5be742c27d..98e61175d3f5 100644
--- a/drivers/input/touchscreen/wm9705.c
+++ b/drivers/input/touchscreen/wm9705.c
@@ -306,7 +306,7 @@ static int wm9705_acc_enable(struct wm97xx *wm, int enable)
dig2 = wm->dig[2];
if (enable) {
- /* continous mode */
+ /* continuous mode */
if (wm->mach_ops->acc_startup &&
(ret = wm->mach_ops->acc_startup(wm)) < 0)
return ret;
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
index 7490b05c3566..2bc2fb801009 100644
--- a/drivers/input/touchscreen/wm9712.c
+++ b/drivers/input/touchscreen/wm9712.c
@@ -419,7 +419,7 @@ static int wm9712_acc_enable(struct wm97xx *wm, int enable)
dig2 = wm->dig[2];
if (enable) {
- /* continous mode */
+ /* continuous mode */
if (wm->mach_ops->acc_startup) {
ret = wm->mach_ops->acc_startup(wm);
if (ret < 0)
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
index 238b5132712e..73ec99568f12 100644
--- a/drivers/input/touchscreen/wm9713.c
+++ b/drivers/input/touchscreen/wm9713.c
@@ -431,7 +431,7 @@ static int wm9713_acc_enable(struct wm97xx *wm, int enable)
dig3 = wm->dig[2];
if (enable) {
- /* continous mode */
+ /* continuous mode */
if (wm->mach_ops->acc_startup &&
(ret = wm->mach_ops->acc_startup(wm)) < 0)
return ret;
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index 6b75c9f660ae..5dbe73af2f8f 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -335,7 +335,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work)
*/
if (!wm->mach_ops->acc_enabled || wm->mach_ops->acc_pen_down) {
if (wm->pen_is_down && !pen_was_down) {
- /* Data is not availiable immediately on pen down */
+ /* Data is not available immediately on pen down */
queue_delayed_work(wm->ts_workq, &wm->ts_reader, 1);
}
@@ -354,7 +354,7 @@ static void wm97xx_pen_irq_worker(struct work_struct *work)
* Codec PENDOWN irq handler
*
* We have to disable the codec interrupt in the handler because it
- * can take upto 1ms to clear the interrupt source. We schedule a task
+ * can take up to 1ms to clear the interrupt source. We schedule a task
* in a work queue to do the actual interaction with the chip. The
* interrupt is then enabled again in the slow handler when the source
* has been cleared.