aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:34:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-24 13:34:29 -0400
commit2c01e7bc46f10e9190818437e564f7e0db875ae9 (patch)
tree8b06c85d69754f7df27f7fb42520f6e2ceaea907 /drivers/input/touchscreen
parentab11ca34eea8fda7a1a9302d86f6ef6108ffd68f (diff)
parente644dae645e167d154c0526358940986682a72b0 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input layer updates from Dmitry Torokhov: - a bunch of new drivers (DA9052/53 touchscreenn controller, Synaptics Navpoint, LM8333 keypads, Wacom I2C touhscreen); - updates to existing touchpad drivers (ALPS, Sntelic); - Wacom driver now supports Intuos5; - device-tree bindings in numerous drivers; - other cleanups and fixes. Fix annoying conflict in drivers/input/tablet/wacom_wac.c that I think implies that the input layer device naming is broken, but let's see. I brough it up with Dmitry. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (57 commits) Input: matrix-keymap - fix building keymaps Input: spear-keyboard - document DT bindings Input: spear-keyboard - add device tree bindings Input: matrix-keymap - wire up device tree support Input: matrix-keymap - uninline and prepare for device tree support Input: adp5588 - add support for gpio names Input: omap-keypad - dynamically handle register offsets Input: synaptics - fix compile warning MAINTAINERS: adjust input-related patterns Input: ALPS - switch to using input_mt_report_finger_count Input: ALPS - add semi-MT support for v4 protocol Input: Add Synaptics NavPoint (PXA27x SSP/SPI) driver Input: atmel_mxt_ts - dump each message on just 1 line Input: atmel_mxt_ts - do not read extra (checksum) byte Input: atmel_mxt_ts - verify object size in mxt_write_object Input: atmel_mxt_ts - only allow root to update firmware Input: atmel_mxt_ts - use CONFIG_PM_SLEEP Input: sentelic - report device's production serial number Input: tl6040-vibra - Device Tree support Input: evdev - properly handle read/write with count 0 ...
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r--drivers/input/touchscreen/Kconfig34
-rw-r--r--drivers/input/touchscreen/Makefile2
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c33
-rw-r--r--drivers/input/touchscreen/da9052_tsi.c370
-rw-r--r--drivers/input/touchscreen/dynapro.c17
-rw-r--r--drivers/input/touchscreen/elo.c17
-rw-r--r--drivers/input/touchscreen/fujitsu_ts.c13
-rw-r--r--drivers/input/touchscreen/gunze.c17
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c17
-rw-r--r--drivers/input/touchscreen/hampshire.c17
-rw-r--r--drivers/input/touchscreen/inexio.c17
-rw-r--r--drivers/input/touchscreen/lpc32xx_ts.c10
-rw-r--r--drivers/input/touchscreen/mtouch.c17
-rw-r--r--drivers/input/touchscreen/penmount.c17
-rw-r--r--drivers/input/touchscreen/st1232.c20
-rw-r--r--drivers/input/touchscreen/touchit213.c17
-rw-r--r--drivers/input/touchscreen/touchright.c17
-rw-r--r--drivers/input/touchscreen/touchwin.c17
-rw-r--r--drivers/input/touchscreen/tsc40.c12
-rw-r--r--drivers/input/touchscreen/wacom_i2c.c282
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c13
21 files changed, 734 insertions, 242 deletions
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 75838d7710ce..98d263504eea 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -187,6 +187,23 @@ config TOUCHSCREEN_DA9034
187 Say Y here to enable the support for the touchscreen found 187 Say Y here to enable the support for the touchscreen found
188 on Dialog Semiconductor DA9034 PMIC. 188 on Dialog Semiconductor DA9034 PMIC.
189 189
190 If unsure, say N.
191
192 To compile this driver as a module, choose M here: the
193 module will be called da9034-ts.
194
195config TOUCHSCREEN_DA9052
196 tristate "Dialog DA9052/DA9053 TSI"
197 depends on PMIC_DA9052
198 help
199 Say Y here to support the touchscreen found on Dialog Semiconductor
200 DA9052-BC and DA9053-AA/Bx PMICs.
201
202 If unsure, say N.
203
204 To compile this driver as a module, choose M here: the
205 module will be called da9052_tsi.
206
190config TOUCHSCREEN_DYNAPRO 207config TOUCHSCREEN_DYNAPRO
191 tristate "Dynapro serial touchscreen" 208 tristate "Dynapro serial touchscreen"
192 select SERIO 209 select SERIO
@@ -306,6 +323,18 @@ config TOUCHSCREEN_WACOM_W8001
306 To compile this driver as a module, choose M here: the 323 To compile this driver as a module, choose M here: the
307 module will be called wacom_w8001. 324 module will be called wacom_w8001.
308 325
326config TOUCHSCREEN_WACOM_I2C
327 tristate "Wacom Tablet support (I2C)"
328 depends on I2C
329 help
330 Say Y here if you want to use the I2C version of the Wacom
331 Pen Tablet.
332
333 If unsure, say N.
334
335 To compile this driver as a module, choose M here: the module
336 will be called wacom_i2c.
337
309config TOUCHSCREEN_LPC32XX 338config TOUCHSCREEN_LPC32XX
310 tristate "LPC32XX touchscreen controller" 339 tristate "LPC32XX touchscreen controller"
311 depends on ARCH_LPC32XX 340 depends on ARCH_LPC32XX
@@ -635,6 +664,7 @@ config TOUCHSCREEN_USB_COMPOSITE
635 - Zytronic controllers 664 - Zytronic controllers
636 - Elo TouchSystems 2700 IntelliTouch 665 - Elo TouchSystems 2700 IntelliTouch
637 - EasyTouch USB Touch Controller from Data Modul 666 - EasyTouch USB Touch Controller from Data Modul
667 - e2i (Mimo monitors)
638 668
639 Have a look at <http://linux.chapter7.ch/touchkit/> for 669 Have a look at <http://linux.chapter7.ch/touchkit/> for
640 a usage description and the required user-space stuff. 670 a usage description and the required user-space stuff.
@@ -721,7 +751,7 @@ config TOUCHSCREEN_USB_ELO
721 751
722config TOUCHSCREEN_USB_E2I 752config TOUCHSCREEN_USB_E2I
723 default y 753 default y
724 bool "e2i Touchscreen controller (e.g. from Mimo 740)" 754 bool "e2i Touchscreen controller (e.g. from Mimo 740)" if EXPERT
725 depends on TOUCHSCREEN_USB_COMPOSITE 755 depends on TOUCHSCREEN_USB_COMPOSITE
726 756
727config TOUCHSCREEN_USB_ZYTRONIC 757config TOUCHSCREEN_USB_ZYTRONIC
@@ -744,7 +774,7 @@ config TOUCHSCREEN_USB_EASYTOUCH
744 bool "EasyTouch USB Touch controller device support" if EMBEDDED 774 bool "EasyTouch USB Touch controller device support" if EMBEDDED
745 depends on TOUCHSCREEN_USB_COMPOSITE 775 depends on TOUCHSCREEN_USB_COMPOSITE
746 help 776 help
747 Say Y here if you have a EasyTouch USB Touch controller device support. 777 Say Y here if you have an EasyTouch USB Touch controller.
748 If unsure, say N. 778 If unsure, say N.
749 779
750config TOUCHSCREEN_TOUCHIT213 780config TOUCHSCREEN_TOUCHIT213
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 3d5cf8cbf89c..eb8bfe1c1a46 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o
22obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o 22obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o
23obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o 23obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o
24obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o 24obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
25obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o
25obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o 26obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
26obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o 27obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
27obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o 28obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
@@ -59,6 +60,7 @@ obj-$(CONFIG_TOUCHSCREEN_TSC2005) += tsc2005.o
59obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o 60obj-$(CONFIG_TOUCHSCREEN_TSC2007) += tsc2007.o
60obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o 61obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
61obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o 62obj-$(CONFIG_TOUCHSCREEN_WACOM_W8001) += wacom_w8001.o
63obj-$(CONFIG_TOUCHSCREEN_WACOM_I2C) += wacom_i2c.o
62obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o 64obj-$(CONFIG_TOUCHSCREEN_WM831X) += wm831x-ts.o
63obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o 65obj-$(CONFIG_TOUCHSCREEN_WM97XX) += wm97xx-ts.o
64wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o 66wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 19d4ea65ea01..42e645062c20 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -236,7 +236,6 @@ struct mxt_object {
236struct mxt_message { 236struct mxt_message {
237 u8 reportid; 237 u8 reportid;
238 u8 message[7]; 238 u8 message[7];
239 u8 checksum;
240}; 239};
241 240
242struct mxt_finger { 241struct mxt_finger {
@@ -326,17 +325,12 @@ static bool mxt_object_writable(unsigned int type)
326} 325}
327 326
328static void mxt_dump_message(struct device *dev, 327static void mxt_dump_message(struct device *dev,
329 struct mxt_message *message) 328 struct mxt_message *message)
330{ 329{
331 dev_dbg(dev, "reportid:\t0x%x\n", message->reportid); 330 dev_dbg(dev, "reportid: %u\tmessage: %02x %02x %02x %02x %02x %02x %02x\n",
332 dev_dbg(dev, "message1:\t0x%x\n", message->message[0]); 331 message->reportid, message->message[0], message->message[1],
333 dev_dbg(dev, "message2:\t0x%x\n", message->message[1]); 332 message->message[2], message->message[3], message->message[4],
334 dev_dbg(dev, "message3:\t0x%x\n", message->message[2]); 333 message->message[5], message->message[6]);
335 dev_dbg(dev, "message4:\t0x%x\n", message->message[3]);
336 dev_dbg(dev, "message5:\t0x%x\n", message->message[4]);
337 dev_dbg(dev, "message6:\t0x%x\n", message->message[5]);
338 dev_dbg(dev, "message7:\t0x%x\n", message->message[6]);
339 dev_dbg(dev, "checksum:\t0x%x\n", message->checksum);
340} 334}
341 335
342static int mxt_check_bootloader(struct i2c_client *client, 336static int mxt_check_bootloader(struct i2c_client *client,
@@ -506,7 +500,7 @@ static int mxt_write_object(struct mxt_data *data,
506 u16 reg; 500 u16 reg;
507 501
508 object = mxt_get_object(data, type); 502 object = mxt_get_object(data, type);
509 if (!object) 503 if (!object || offset >= object->size + 1)
510 return -EINVAL; 504 return -EINVAL;
511 505
512 reg = object->start_address; 506 reg = object->start_address;
@@ -1049,8 +1043,8 @@ static ssize_t mxt_update_fw_store(struct device *dev,
1049 return count; 1043 return count;
1050} 1044}
1051 1045
1052static DEVICE_ATTR(object, 0444, mxt_object_show, NULL); 1046static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
1053static DEVICE_ATTR(update_fw, 0664, NULL, mxt_update_fw_store); 1047static DEVICE_ATTR(update_fw, S_IWUSR, NULL, mxt_update_fw_store);
1054 1048
1055static struct attribute *mxt_attrs[] = { 1049static struct attribute *mxt_attrs[] = {
1056 &dev_attr_object.attr, 1050 &dev_attr_object.attr,
@@ -1201,7 +1195,7 @@ static int __devexit mxt_remove(struct i2c_client *client)
1201 return 0; 1195 return 0;
1202} 1196}
1203 1197
1204#ifdef CONFIG_PM 1198#ifdef CONFIG_PM_SLEEP
1205static int mxt_suspend(struct device *dev) 1199static int mxt_suspend(struct device *dev)
1206{ 1200{
1207 struct i2c_client *client = to_i2c_client(dev); 1201 struct i2c_client *client = to_i2c_client(dev);
@@ -1239,13 +1233,10 @@ static int mxt_resume(struct device *dev)
1239 1233
1240 return 0; 1234 return 0;
1241} 1235}
1242
1243static const struct dev_pm_ops mxt_pm_ops = {
1244 .suspend = mxt_suspend,
1245 .resume = mxt_resume,
1246};
1247#endif 1236#endif
1248 1237
1238static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume);
1239
1249static const struct i2c_device_id mxt_id[] = { 1240static const struct i2c_device_id mxt_id[] = {
1250 { "qt602240_ts", 0 }, 1241 { "qt602240_ts", 0 },
1251 { "atmel_mxt_ts", 0 }, 1242 { "atmel_mxt_ts", 0 },
@@ -1258,9 +1249,7 @@ static struct i2c_driver mxt_driver = {
1258 .driver = { 1249 .driver = {
1259 .name = "atmel_mxt_ts", 1250 .name = "atmel_mxt_ts",
1260 .owner = THIS_MODULE, 1251 .owner = THIS_MODULE,
1261#ifdef CONFIG_PM
1262 .pm = &mxt_pm_ops, 1252 .pm = &mxt_pm_ops,
1263#endif
1264 }, 1253 },
1265 .probe = mxt_probe, 1254 .probe = mxt_probe,
1266 .remove = __devexit_p(mxt_remove), 1255 .remove = __devexit_p(mxt_remove),
diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c
new file mode 100644
index 000000000000..e8df341090c0
--- /dev/null
+++ b/drivers/input/touchscreen/da9052_tsi.c
@@ -0,0 +1,370 @@
1/*
2 * TSI driver for Dialog DA9052
3 *
4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14#include <linux/module.h>
15#include <linux/input.h>
16#include <linux/delay.h>
17#include <linux/platform_device.h>
18#include <linux/interrupt.h>
19
20#include <linux/mfd/da9052/reg.h>
21#include <linux/mfd/da9052/da9052.h>
22
23#define TSI_PEN_DOWN_STATUS 0x40
24
25struct da9052_tsi {
26 struct da9052 *da9052;
27 struct input_dev *dev;
28 struct delayed_work ts_pen_work;
29 struct mutex mutex;
30 unsigned int irq_pendwn;
31 unsigned int irq_datardy;
32 bool stopped;
33 bool adc_on;
34};
35
36static void da9052_ts_adc_toggle(struct da9052_tsi *tsi, bool on)
37{
38 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 0, on);
39 tsi->adc_on = on;
40}
41
42static irqreturn_t da9052_ts_pendwn_irq(int irq, void *data)
43{
44 struct da9052_tsi *tsi = data;
45
46 if (!tsi->stopped) {
47 /* Mask PEN_DOWN event and unmask TSI_READY event */
48 disable_irq_nosync(tsi->irq_pendwn);
49 enable_irq(tsi->irq_datardy);
50
51 da9052_ts_adc_toggle(tsi, true);
52
53 schedule_delayed_work(&tsi->ts_pen_work, HZ / 50);
54 }
55
56 return IRQ_HANDLED;
57}
58
59static void da9052_ts_read(struct da9052_tsi *tsi)
60{
61 struct input_dev *input = tsi->dev;
62 int ret;
63 u16 x, y, z;
64 u8 v;
65
66 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_X_MSB_REG);
67 if (ret < 0)
68 return;
69
70 x = (u16) ret;
71
72 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Y_MSB_REG);
73 if (ret < 0)
74 return;
75
76 y = (u16) ret;
77
78 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_Z_MSB_REG);
79 if (ret < 0)
80 return;
81
82 z = (u16) ret;
83
84 ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
85 if (ret < 0)
86 return;
87
88 v = (u8) ret;
89
90 x = ((x << 2) & 0x3fc) | (v & 0x3);
91 y = ((y << 2) & 0x3fc) | ((v & 0xc) >> 2);
92 z = ((z << 2) & 0x3fc) | ((v & 0x30) >> 4);
93
94 input_report_key(input, BTN_TOUCH, 1);
95 input_report_abs(input, ABS_X, x);
96 input_report_abs(input, ABS_Y, y);
97 input_report_abs(input, ABS_PRESSURE, z);
98 input_sync(input);
99}
100
101static irqreturn_t da9052_ts_datardy_irq(int irq, void *data)
102{
103 struct da9052_tsi *tsi = data;
104
105 da9052_ts_read(tsi);
106
107 return IRQ_HANDLED;
108}
109
110static void da9052_ts_pen_work(struct work_struct *work)
111{
112 struct da9052_tsi *tsi = container_of(work, struct da9052_tsi,
113 ts_pen_work.work);
114 if (!tsi->stopped) {
115 int ret = da9052_reg_read(tsi->da9052, DA9052_TSI_LSB_REG);
116 if (ret < 0 || (ret & TSI_PEN_DOWN_STATUS)) {
117 /* Pen is still DOWN (or read error) */
118 schedule_delayed_work(&tsi->ts_pen_work, HZ / 50);
119 } else {
120 struct input_dev *input = tsi->dev;
121
122 /* Pen UP */
123 da9052_ts_adc_toggle(tsi, false);
124
125 /* Report Pen UP */
126 input_report_key(input, BTN_TOUCH, 0);
127 input_report_abs(input, ABS_PRESSURE, 0);
128 input_sync(input);
129
130 /*
131 * FIXME: Fixes the unhandled irq issue when quick
132 * pen down and pen up events occurs
133 */
134 ret = da9052_reg_update(tsi->da9052,
135 DA9052_EVENT_B_REG, 0xC0, 0xC0);
136 if (ret < 0)
137 return;
138
139 /* Mask TSI_READY event and unmask PEN_DOWN event */
140 disable_irq(tsi->irq_datardy);
141 enable_irq(tsi->irq_pendwn);
142 }
143 }
144}
145
146static int __devinit da9052_ts_configure_gpio(struct da9052 *da9052)
147{
148 int error;
149
150 error = da9052_reg_update(da9052, DA9052_GPIO_2_3_REG, 0x30, 0);
151 if (error < 0)
152 return error;
153
154 error = da9052_reg_update(da9052, DA9052_GPIO_4_5_REG, 0x33, 0);
155 if (error < 0)
156 return error;
157
158 error = da9052_reg_update(da9052, DA9052_GPIO_6_7_REG, 0x33, 0);
159 if (error < 0)
160 return error;
161
162 return 0;
163}
164
165static int __devinit da9052_configure_tsi(struct da9052_tsi *tsi)
166{
167 int error;
168
169 error = da9052_ts_configure_gpio(tsi->da9052);
170 if (error)
171 return error;
172
173 /* Measure TSI sample every 1ms */
174 error = da9052_reg_update(tsi->da9052, DA9052_ADC_CONT_REG,
175 1 << 6, 1 << 6);
176 if (error < 0)
177 return error;
178
179 /* TSI_DELAY: 3 slots, TSI_SKIP: 0 slots, TSI_MODE: XYZP */
180 error = da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 0xFC, 0xC0);
181 if (error < 0)
182 return error;
183
184 /* Supply TSIRef through LD09 */
185 error = da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x59);
186 if (error < 0)
187 return error;
188
189 return 0;
190}
191
192static int da9052_ts_input_open(struct input_dev *input_dev)
193{
194 struct da9052_tsi *tsi = input_get_drvdata(input_dev);
195
196 tsi->stopped = false;
197 mb();
198
199 /* Unmask PEN_DOWN event */
200 enable_irq(tsi->irq_pendwn);
201
202 /* Enable Pen Detect Circuit */
203 return da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG,
204 1 << 1, 1 << 1);
205}
206
207static void da9052_ts_input_close(struct input_dev *input_dev)
208{
209 struct da9052_tsi *tsi = input_get_drvdata(input_dev);
210
211 tsi->stopped = true;
212 mb();
213 disable_irq(tsi->irq_pendwn);
214 cancel_delayed_work_sync(&tsi->ts_pen_work);
215
216 if (tsi->adc_on) {
217 disable_irq(tsi->irq_datardy);
218 da9052_ts_adc_toggle(tsi, false);
219
220 /*
221 * If ADC was on that means that pendwn IRQ was disabled
222 * twice and we need to enable it to keep enable/disable
223 * counter balanced. IRQ is still off though.
224 */
225 enable_irq(tsi->irq_pendwn);
226 }
227
228 /* Disable Pen Detect Circuit */
229 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0);
230}
231
232static int __devinit da9052_ts_probe(struct platform_device *pdev)
233{
234 struct da9052 *da9052;
235 struct da9052_tsi *tsi;
236 struct input_dev *input_dev;
237 int irq_pendwn;
238 int irq_datardy;
239 int error;
240
241 da9052 = dev_get_drvdata(pdev->dev.parent);
242 if (!da9052)
243 return -EINVAL;
244
245 irq_pendwn = platform_get_irq_byname(pdev, "PENDWN");
246 irq_datardy = platform_get_irq_byname(pdev, "TSIRDY");
247 if (irq_pendwn < 0 || irq_datardy < 0) {
248 dev_err(da9052->dev, "Unable to determine device interrupts\n");
249 return -ENXIO;
250 }
251
252 tsi = kzalloc(sizeof(struct da9052_tsi), GFP_KERNEL);
253 input_dev = input_allocate_device();
254 if (!tsi || !input_dev) {
255 error = -ENOMEM;
256 goto err_free_mem;
257 }
258
259 tsi->da9052 = da9052;
260 tsi->dev = input_dev;
261 tsi->irq_pendwn = da9052->irq_base + irq_pendwn;
262 tsi->irq_datardy = da9052->irq_base + irq_datardy;
263 tsi->stopped = true;
264 INIT_DELAYED_WORK(&tsi->ts_pen_work, da9052_ts_pen_work);
265
266 input_dev->id.version = 0x0101;
267 input_dev->id.vendor = 0x15B6;
268 input_dev->id.product = 0x9052;
269 input_dev->name = "Dialog DA9052 TouchScreen Driver";
270 input_dev->dev.parent = &pdev->dev;
271 input_dev->open = da9052_ts_input_open;
272 input_dev->close = da9052_ts_input_close;
273
274 __set_bit(EV_ABS, input_dev->evbit);
275 __set_bit(EV_KEY, input_dev->evbit);
276 __set_bit(BTN_TOUCH, input_dev->keybit);
277
278 input_set_abs_params(input_dev, ABS_X, 0, 1023, 0, 0);
279 input_set_abs_params(input_dev, ABS_Y, 0, 1023, 0, 0);
280 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1023, 0, 0);
281
282 input_set_drvdata(input_dev, tsi);
283
284 /* Disable Pen Detect Circuit */
285 da9052_reg_update(tsi->da9052, DA9052_TSI_CONT_A_REG, 1 << 1, 0);
286
287 /* Disable ADC */
288 da9052_ts_adc_toggle(tsi, false);
289
290 error = request_threaded_irq(tsi->irq_pendwn,
291 NULL, da9052_ts_pendwn_irq,
292 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
293 "PENDWN", tsi);
294 if (error) {
295 dev_err(tsi->da9052->dev,
296 "Failed to register PENDWN IRQ %d, error = %d\n",
297 tsi->irq_pendwn, error);
298 goto err_free_mem;
299 }
300
301 error = request_threaded_irq(tsi->irq_datardy,
302 NULL, da9052_ts_datardy_irq,
303 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
304 "TSIRDY", tsi);
305 if (error) {
306 dev_err(tsi->da9052->dev,
307 "Failed to register TSIRDY IRQ %d, error = %d\n",
308 tsi->irq_datardy, error);
309 goto err_free_pendwn_irq;
310 }
311
312 /* Mask PEN_DOWN and TSI_READY events */
313 disable_irq(tsi->irq_pendwn);
314 disable_irq(tsi->irq_datardy);
315
316 error = da9052_configure_tsi(tsi);
317 if (error)
318 goto err_free_datardy_irq;
319
320 error = input_register_device(tsi->dev);
321 if (error)
322 goto err_free_datardy_irq;
323
324 platform_set_drvdata(pdev, tsi);
325
326 return 0;
327
328err_free_datardy_irq:
329 free_irq(tsi->irq_datardy, tsi);
330err_free_pendwn_irq:
331 free_irq(tsi->irq_pendwn, tsi);
332err_free_mem:
333 kfree(tsi);
334 input_free_device(input_dev);
335
336 return error;
337}
338
339static int __devexit da9052_ts_remove(struct platform_device *pdev)
340{
341 struct da9052_tsi *tsi = platform_get_drvdata(pdev);
342
343 da9052_reg_write(tsi->da9052, DA9052_LDO9_REG, 0x19);
344
345 free_irq(tsi->irq_pendwn, tsi);
346 free_irq(tsi->irq_datardy, tsi);
347
348 input_unregister_device(tsi->dev);
349 kfree(tsi);
350
351 platform_set_drvdata(pdev, NULL);
352
353 return 0;
354}
355
356static struct platform_driver da9052_tsi_driver = {
357 .probe = da9052_ts_probe,
358 .remove = __devexit_p(da9052_ts_remove),
359 .driver = {
360 .name = "da9052-tsi",
361 .owner = THIS_MODULE,
362 },
363};
364
365module_platform_driver(da9052_tsi_driver);
366
367MODULE_DESCRIPTION("Touchscreen driver for Dialog Semiconductor DA9052");
368MODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>");
369MODULE_LICENSE("GPL");
370MODULE_ALIAS("platform:da9052-tsi");
diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c
index 455353908bdf..1809677a6513 100644
--- a/drivers/input/touchscreen/dynapro.c
+++ b/drivers/input/touchscreen/dynapro.c
@@ -188,19 +188,4 @@ static struct serio_driver dynapro_drv = {
188 .disconnect = dynapro_disconnect, 188 .disconnect = dynapro_disconnect,
189}; 189};
190 190
191/* 191module_serio_driver(dynapro_drv);
192 * The functions for inserting/removing us as a module.
193 */
194
195static int __init dynapro_init(void)
196{
197 return serio_register_driver(&dynapro_drv);
198}
199
200static void __exit dynapro_exit(void)
201{
202 serio_unregister_driver(&dynapro_drv);
203}
204
205module_init(dynapro_init);
206module_exit(dynapro_exit);
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 486d31ba9c09..957423d1471d 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -405,19 +405,4 @@ static struct serio_driver elo_drv = {
405 .disconnect = elo_disconnect, 405 .disconnect = elo_disconnect,
406}; 406};
407 407
408/* 408module_serio_driver(elo_drv);
409 * The functions for inserting/removing us as a module.
410 */
411
412static int __init elo_init(void)
413{
414 return serio_register_driver(&elo_drv);
415}
416
417static void __exit elo_exit(void)
418{
419 serio_unregister_driver(&elo_drv);
420}
421
422module_init(elo_init);
423module_exit(elo_exit);
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c
index 80b21800355f..10794ddbdf58 100644
--- a/drivers/input/touchscreen/fujitsu_ts.c
+++ b/drivers/input/touchscreen/fujitsu_ts.c
@@ -175,15 +175,4 @@ static struct serio_driver fujitsu_drv = {
175 .disconnect = fujitsu_disconnect, 175 .disconnect = fujitsu_disconnect,
176}; 176};
177 177
178static int __init fujitsu_init(void) 178module_serio_driver(fujitsu_drv);
179{
180 return serio_register_driver(&fujitsu_drv);
181}
182
183static void __exit fujitsu_exit(void)
184{
185 serio_unregister_driver(&fujitsu_drv);
186}
187
188module_init(fujitsu_init);
189module_exit(fujitsu_exit);
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index a54f90e02ab6..41c71766bf18 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -186,19 +186,4 @@ static struct serio_driver gunze_drv = {
186 .disconnect = gunze_disconnect, 186 .disconnect = gunze_disconnect,
187}; 187};
188 188
189/* 189module_serio_driver(gunze_drv);
190 * The functions for inserting/removing us as a module.
191 */
192
193static int __init gunze_init(void)
194{
195 return serio_register_driver(&gunze_drv);
196}
197
198static void __exit gunze_exit(void)
199{
200 serio_unregister_driver(&gunze_drv);
201}
202
203module_init(gunze_init);
204module_exit(gunze_exit);
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index 6107e563e681..b9e8686a6f1c 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -476,19 +476,4 @@ static struct serio_driver h3600ts_drv = {
476 .disconnect = h3600ts_disconnect, 476 .disconnect = h3600ts_disconnect,
477}; 477};
478 478
479/* 479module_serio_driver(h3600ts_drv);
480 * The functions for inserting/removing us as a module.
481 */
482
483static int __init h3600ts_init(void)
484{
485 return serio_register_driver(&h3600ts_drv);
486}
487
488static void __exit h3600ts_exit(void)
489{
490 serio_unregister_driver(&h3600ts_drv);
491}
492
493module_init(h3600ts_init);
494module_exit(h3600ts_exit);
diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c
index 2da6cc31bb21..0cc47ea98acf 100644
--- a/drivers/input/touchscreen/hampshire.c
+++ b/drivers/input/touchscreen/hampshire.c
@@ -187,19 +187,4 @@ static struct serio_driver hampshire_drv = {
187 .disconnect = hampshire_disconnect, 187 .disconnect = hampshire_disconnect,
188}; 188};
189 189
190/* 190module_serio_driver(hampshire_drv);
191 * The functions for inserting/removing us as a module.
192 */
193
194static int __init hampshire_init(void)
195{
196 return serio_register_driver(&hampshire_drv);
197}
198
199static void __exit hampshire_exit(void)
200{
201 serio_unregister_driver(&hampshire_drv);
202}
203
204module_init(hampshire_init);
205module_exit(hampshire_exit);
diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c
index 192ade0a0fb9..a29c99c32245 100644
--- a/drivers/input/touchscreen/inexio.c
+++ b/drivers/input/touchscreen/inexio.c
@@ -189,19 +189,4 @@ static struct serio_driver inexio_drv = {
189 .disconnect = inexio_disconnect, 189 .disconnect = inexio_disconnect,
190}; 190};
191 191
192/* 192module_serio_driver(inexio_drv);
193 * The functions for inserting/removing us as a module.
194 */
195
196static int __init inexio_init(void)
197{
198 return serio_register_driver(&inexio_drv);
199}
200
201static void __exit inexio_exit(void)
202{
203 serio_unregister_driver(&inexio_drv);
204}
205
206module_init(inexio_init);
207module_exit(inexio_exit);
diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c
index afcd0691ec67..4c2b8ed3bf16 100644
--- a/drivers/input/touchscreen/lpc32xx_ts.c
+++ b/drivers/input/touchscreen/lpc32xx_ts.c
@@ -22,6 +22,7 @@
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/of.h>
25 26
26/* 27/*
27 * Touchscreen controller register offsets 28 * Touchscreen controller register offsets
@@ -383,6 +384,14 @@ static const struct dev_pm_ops lpc32xx_ts_pm_ops = {
383#define LPC32XX_TS_PM_OPS NULL 384#define LPC32XX_TS_PM_OPS NULL
384#endif 385#endif
385 386
387#ifdef CONFIG_OF
388static struct of_device_id lpc32xx_tsc_of_match[] = {
389 { .compatible = "nxp,lpc3220-tsc", },
390 { },
391};
392MODULE_DEVICE_TABLE(of, lpc32xx_tsc_of_match);
393#endif
394
386static struct platform_driver lpc32xx_ts_driver = { 395static struct platform_driver lpc32xx_ts_driver = {
387 .probe = lpc32xx_ts_probe, 396 .probe = lpc32xx_ts_probe,
388 .remove = __devexit_p(lpc32xx_ts_remove), 397 .remove = __devexit_p(lpc32xx_ts_remove),
@@ -390,6 +399,7 @@ static struct platform_driver lpc32xx_ts_driver = {
390 .name = MOD_NAME, 399 .name = MOD_NAME,
391 .owner = THIS_MODULE, 400 .owner = THIS_MODULE,
392 .pm = LPC32XX_TS_PM_OPS, 401 .pm = LPC32XX_TS_PM_OPS,
402 .of_match_table = of_match_ptr(lpc32xx_tsc_of_match),
393 }, 403 },
394}; 404};
395module_platform_driver(lpc32xx_ts_driver); 405module_platform_driver(lpc32xx_ts_driver);
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index 9077228418b7..eb66b7c37c2f 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -202,19 +202,4 @@ static struct serio_driver mtouch_drv = {
202 .disconnect = mtouch_disconnect, 202 .disconnect = mtouch_disconnect,
203}; 203};
204 204
205/* 205module_serio_driver(mtouch_drv);
206 * The functions for inserting/removing us as a module.
207 */
208
209static int __init mtouch_init(void)
210{
211 return serio_register_driver(&mtouch_drv);
212}
213
214static void __exit mtouch_exit(void)
215{
216 serio_unregister_driver(&mtouch_drv);
217}
218
219module_init(mtouch_init);
220module_exit(mtouch_exit);
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 4c012fb2b01e..4ccde45b9da2 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -317,19 +317,4 @@ static struct serio_driver pm_drv = {
317 .disconnect = pm_disconnect, 317 .disconnect = pm_disconnect,
318}; 318};
319 319
320/* 320module_serio_driver(pm_drv);
321 * The functions for inserting/removing us as a module.
322 */
323
324static int __init pm_init(void)
325{
326 return serio_register_driver(&pm_drv);
327}
328
329static void __exit pm_exit(void)
330{
331 serio_unregister_driver(&pm_drv);
332}
333
334module_init(pm_init);
335module_exit(pm_exit);
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c
index cbbf71b22696..6cb68a1981bf 100644
--- a/drivers/input/touchscreen/st1232.c
+++ b/drivers/input/touchscreen/st1232.c
@@ -218,7 +218,7 @@ static int __devexit st1232_ts_remove(struct i2c_client *client)
218 return 0; 218 return 0;
219} 219}
220 220
221#ifdef CONFIG_PM 221#ifdef CONFIG_PM_SLEEP
222static int st1232_ts_suspend(struct device *dev) 222static int st1232_ts_suspend(struct device *dev)
223{ 223{
224 struct i2c_client *client = to_i2c_client(dev); 224 struct i2c_client *client = to_i2c_client(dev);
@@ -243,18 +243,25 @@ static int st1232_ts_resume(struct device *dev)
243 return 0; 243 return 0;
244} 244}
245 245
246static const struct dev_pm_ops st1232_ts_pm_ops = {
247 .suspend = st1232_ts_suspend,
248 .resume = st1232_ts_resume,
249};
250#endif 246#endif
251 247
248static SIMPLE_DEV_PM_OPS(st1232_ts_pm_ops,
249 st1232_ts_suspend, st1232_ts_resume);
250
252static const struct i2c_device_id st1232_ts_id[] = { 251static const struct i2c_device_id st1232_ts_id[] = {
253 { ST1232_TS_NAME, 0 }, 252 { ST1232_TS_NAME, 0 },
254 { } 253 { }
255}; 254};
256MODULE_DEVICE_TABLE(i2c, st1232_ts_id); 255MODULE_DEVICE_TABLE(i2c, st1232_ts_id);
257 256
257#ifdef CONFIG_OF
258static const struct of_device_id st1232_ts_dt_ids[] __devinitconst = {
259 { .compatible = "sitronix,st1232", },
260 { }
261};
262MODULE_DEVICE_TABLE(of, st1232_ts_dt_ids);
263#endif
264
258static struct i2c_driver st1232_ts_driver = { 265static struct i2c_driver st1232_ts_driver = {
259 .probe = st1232_ts_probe, 266 .probe = st1232_ts_probe,
260 .remove = __devexit_p(st1232_ts_remove), 267 .remove = __devexit_p(st1232_ts_remove),
@@ -262,9 +269,8 @@ static struct i2c_driver st1232_ts_driver = {
262 .driver = { 269 .driver = {
263 .name = ST1232_TS_NAME, 270 .name = ST1232_TS_NAME,
264 .owner = THIS_MODULE, 271 .owner = THIS_MODULE,
265#ifdef CONFIG_PM 272 .of_match_table = of_match_ptr(st1232_ts_dt_ids),
266 .pm = &st1232_ts_pm_ops, 273 .pm = &st1232_ts_pm_ops,
267#endif
268 }, 274 },
269}; 275};
270 276
diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c
index d1297ba19daf..5f29e5b8e1c1 100644
--- a/drivers/input/touchscreen/touchit213.c
+++ b/drivers/input/touchscreen/touchit213.c
@@ -216,19 +216,4 @@ static struct serio_driver touchit213_drv = {
216 .disconnect = touchit213_disconnect, 216 .disconnect = touchit213_disconnect,
217}; 217};
218 218
219/* 219module_serio_driver(touchit213_drv);
220 * The functions for inserting/removing us as a module.
221 */
222
223static int __init touchit213_init(void)
224{
225 return serio_register_driver(&touchit213_drv);
226}
227
228static void __exit touchit213_exit(void)
229{
230 serio_unregister_driver(&touchit213_drv);
231}
232
233module_init(touchit213_init);
234module_exit(touchit213_exit);
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
index 3a5c142c2a78..8a2887daf194 100644
--- a/drivers/input/touchscreen/touchright.c
+++ b/drivers/input/touchscreen/touchright.c
@@ -176,19 +176,4 @@ static struct serio_driver tr_drv = {
176 .disconnect = tr_disconnect, 176 .disconnect = tr_disconnect,
177}; 177};
178 178
179/* 179module_serio_driver(tr_drv);
180 * The functions for inserting/removing us as a module.
181 */
182
183static int __init tr_init(void)
184{
185 return serio_register_driver(&tr_drv);
186}
187
188static void __exit tr_exit(void)
189{
190 serio_unregister_driver(&tr_drv);
191}
192
193module_init(tr_init);
194module_exit(tr_exit);
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
index 763a656a59f8..588cdcb839dd 100644
--- a/drivers/input/touchscreen/touchwin.c
+++ b/drivers/input/touchscreen/touchwin.c
@@ -183,19 +183,4 @@ static struct serio_driver tw_drv = {
183 .disconnect = tw_disconnect, 183 .disconnect = tw_disconnect,
184}; 184};
185 185
186/* 186module_serio_driver(tw_drv);
187 * The functions for inserting/removing us as a module.
188 */
189
190static int __init tw_init(void)
191{
192 return serio_register_driver(&tw_drv);
193}
194
195static void __exit tw_exit(void)
196{
197 serio_unregister_driver(&tw_drv);
198}
199
200module_init(tw_init);
201module_exit(tw_exit);
diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c
index 29d5ed4dd31c..63209aaa55f0 100644
--- a/drivers/input/touchscreen/tsc40.c
+++ b/drivers/input/touchscreen/tsc40.c
@@ -167,17 +167,7 @@ static struct serio_driver tsc_drv = {
167 .disconnect = tsc_disconnect, 167 .disconnect = tsc_disconnect,
168}; 168};
169 169
170static int __init tsc_ser_init(void) 170module_serio_driver(tsc_drv);
171{
172 return serio_register_driver(&tsc_drv);
173}
174module_init(tsc_ser_init);
175
176static void __exit tsc_exit(void)
177{
178 serio_unregister_driver(&tsc_drv);
179}
180module_exit(tsc_exit);
181 171
182MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>"); 172MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
183MODULE_DESCRIPTION(DRIVER_DESC); 173MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/input/touchscreen/wacom_i2c.c b/drivers/input/touchscreen/wacom_i2c.c
new file mode 100644
index 000000000000..35572575d34a
--- /dev/null
+++ b/drivers/input/touchscreen/wacom_i2c.c
@@ -0,0 +1,282 @@
1/*
2 * Wacom Penabled Driver for I2C
3 *
4 * Copyright (c) 2011 Tatsunosuke Tobita, Wacom.
5 * <tobita.tatsunosuke@wacom.co.jp>
6 *
7 * This program is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU General
9 * Public License as published by the Free Software
10 * Foundation; either version of 2 of the License,
11 * or (at your option) any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/input.h>
16#include <linux/i2c.h>
17#include <linux/slab.h>
18#include <linux/irq.h>
19#include <linux/interrupt.h>
20#include <linux/gpio.h>
21#include <asm/unaligned.h>
22
23#define WACOM_CMD_QUERY0 0x04
24#define WACOM_CMD_QUERY1 0x00
25#define WACOM_CMD_QUERY2 0x33
26#define WACOM_CMD_QUERY3 0x02
27#define WACOM_CMD_THROW0 0x05
28#define WACOM_CMD_THROW1 0x00
29#define WACOM_QUERY_SIZE 19
30#define WACOM_RETRY_CNT 100
31
32struct wacom_features {
33 int x_max;
34 int y_max;
35 int pressure_max;
36 char fw_version;
37};
38
39struct wacom_i2c {
40 struct i2c_client *client;
41 struct input_dev *input;
42 u8 data[WACOM_QUERY_SIZE];
43};
44
45static int wacom_query_device(struct i2c_client *client,
46 struct wacom_features *features)
47{
48 int ret;
49 u8 cmd1[] = { WACOM_CMD_QUERY0, WACOM_CMD_QUERY1,
50 WACOM_CMD_QUERY2, WACOM_CMD_QUERY3 };
51 u8 cmd2[] = { WACOM_CMD_THROW0, WACOM_CMD_THROW1 };
52 u8 data[WACOM_QUERY_SIZE];
53 struct i2c_msg msgs[] = {
54 {
55 .addr = client->addr,
56 .flags = 0,
57 .len = sizeof(cmd1),
58 .buf = cmd1,
59 },
60 {
61 .addr = client->addr,
62 .flags = 0,
63 .len = sizeof(cmd2),
64 .buf = cmd2,
65 },
66 {
67 .addr = client->addr,
68 .flags = I2C_M_RD,
69 .len = sizeof(data),
70 .buf = data,
71 },
72 };
73
74 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
75 if (ret < 0)
76 return ret;
77 if (ret != ARRAY_SIZE(msgs))
78 return -EIO;
79
80 features->x_max = get_unaligned_le16(&data[3]);
81 features->y_max = get_unaligned_le16(&data[5]);
82 features->pressure_max = get_unaligned_le16(&data[11]);
83 features->fw_version = get_unaligned_le16(&data[13]);
84
85 dev_dbg(&client->dev,
86 "x_max:%d, y_max:%d, pressure:%d, fw:%d\n",
87 features->x_max, features->y_max,
88 features->pressure_max, features->fw_version);
89
90 return 0;
91}
92
93static irqreturn_t wacom_i2c_irq(int irq, void *dev_id)
94{
95 struct wacom_i2c *wac_i2c = dev_id;
96 struct input_dev *input = wac_i2c->input;
97 u8 *data = wac_i2c->data;
98 unsigned int x, y, pressure;
99 unsigned char tsw, f1, f2, ers;
100 int error;
101
102 error = i2c_master_recv(wac_i2c->client,
103 wac_i2c->data, sizeof(wac_i2c->data));
104 if (error < 0)
105 goto out;
106
107 tsw = data[3] & 0x01;
108 ers = data[3] & 0x04;
109 f1 = data[3] & 0x02;
110 f2 = data[3] & 0x10;
111 x = le16_to_cpup((__le16 *)&data[4]);
112 y = le16_to_cpup((__le16 *)&data[6]);
113 pressure = le16_to_cpup((__le16 *)&data[8]);
114
115 input_report_key(input, BTN_TOUCH, tsw || ers);
116 input_report_key(input, BTN_TOOL_PEN, tsw);
117 input_report_key(input, BTN_TOOL_RUBBER, ers);
118 input_report_key(input, BTN_STYLUS, f1);
119 input_report_key(input, BTN_STYLUS2, f2);
120 input_report_abs(input, ABS_X, x);
121 input_report_abs(input, ABS_Y, y);
122 input_report_abs(input, ABS_PRESSURE, pressure);
123 input_sync(input);
124
125out:
126 return IRQ_HANDLED;
127}
128
129static int wacom_i2c_open(struct input_dev *dev)
130{
131 struct wacom_i2c *wac_i2c = input_get_drvdata(dev);
132 struct i2c_client *client = wac_i2c->client;
133
134 enable_irq(client->irq);
135
136 return 0;
137}
138
139static void wacom_i2c_close(struct input_dev *dev)
140{
141 struct wacom_i2c *wac_i2c = input_get_drvdata(dev);
142 struct i2c_client *client = wac_i2c->client;
143
144 disable_irq(client->irq);
145}
146
147static int __devinit wacom_i2c_probe(struct i2c_client *client,
148 const struct i2c_device_id *id)
149{
150 struct wacom_i2c *wac_i2c;
151 struct input_dev *input;
152 struct wacom_features features;
153 int error;
154
155 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
156 dev_err(&client->dev, "i2c_check_functionality error\n");
157 return -EIO;
158 }
159
160 error = wacom_query_device(client, &features);
161 if (error)
162 return error;
163
164 wac_i2c = kzalloc(sizeof(*wac_i2c), GFP_KERNEL);
165 input = input_allocate_device();
166 if (!wac_i2c || !input) {
167 error = -ENOMEM;
168 goto err_free_mem;
169 }
170
171 wac_i2c->client = client;
172 wac_i2c->input = input;
173
174 input->name = "Wacom I2C Digitizer";
175 input->id.bustype = BUS_I2C;
176 input->id.vendor = 0x56a;
177 input->id.version = features.fw_version;
178 input->dev.parent = &client->dev;
179 input->open = wacom_i2c_open;
180 input->close = wacom_i2c_close;
181
182 input->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
183
184 __set_bit(BTN_TOOL_PEN, input->keybit);
185 __set_bit(BTN_TOOL_RUBBER, input->keybit);
186 __set_bit(BTN_STYLUS, input->keybit);
187 __set_bit(BTN_STYLUS2, input->keybit);
188 __set_bit(BTN_TOUCH, input->keybit);
189
190 input_set_abs_params(input, ABS_X, 0, features.x_max, 0, 0);
191 input_set_abs_params(input, ABS_Y, 0, features.y_max, 0, 0);
192 input_set_abs_params(input, ABS_PRESSURE,
193 0, features.pressure_max, 0, 0);
194
195 input_set_drvdata(input, wac_i2c);
196
197 error = request_threaded_irq(client->irq, NULL, wacom_i2c_irq,
198 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
199 "wacom_i2c", wac_i2c);
200 if (error) {
201 dev_err(&client->dev,
202 "Failed to enable IRQ, error: %d\n", error);
203 goto err_free_mem;
204 }
205
206 /* Disable the IRQ, we'll enable it in wac_i2c_open() */
207 disable_irq(client->irq);
208
209 error = input_register_device(wac_i2c->input);
210 if (error) {
211 dev_err(&client->dev,
212 "Failed to register input device, error: %d\n", error);
213 goto err_free_irq;
214 }
215
216 i2c_set_clientdata(client, wac_i2c);
217 return 0;
218
219err_free_irq:
220 free_irq(client->irq, wac_i2c);
221err_free_mem:
222 input_free_device(input);
223 kfree(wac_i2c);
224
225 return error;
226}
227
228static int __devexit wacom_i2c_remove(struct i2c_client *client)
229{
230 struct wacom_i2c *wac_i2c = i2c_get_clientdata(client);
231
232 free_irq(client->irq, wac_i2c);
233 input_unregister_device(wac_i2c->input);
234 kfree(wac_i2c);
235
236 return 0;
237}
238
239#ifdef CONFIG_PM_SLEEP
240static int wacom_i2c_suspend(struct device *dev)
241{
242 struct i2c_client *client = to_i2c_client(dev);
243
244 disable_irq(client->irq);
245
246 return 0;
247}
248
249static int wacom_i2c_resume(struct device *dev)
250{
251 struct i2c_client *client = to_i2c_client(dev);
252
253 enable_irq(client->irq);
254
255 return 0;
256}
257#endif
258
259static SIMPLE_DEV_PM_OPS(wacom_i2c_pm, wacom_i2c_suspend, wacom_i2c_resume);
260
261static const struct i2c_device_id wacom_i2c_id[] = {
262 { "WAC_I2C_EMR", 0 },
263 { },
264};
265MODULE_DEVICE_TABLE(i2c, wacom_i2c_id);
266
267static struct i2c_driver wacom_i2c_driver = {
268 .driver = {
269 .name = "wacom_i2c",
270 .owner = THIS_MODULE,
271 .pm = &wacom_i2c_pm,
272 },
273
274 .probe = wacom_i2c_probe,
275 .remove = __devexit_p(wacom_i2c_remove),
276 .id_table = wacom_i2c_id,
277};
278module_i2c_driver(wacom_i2c_driver);
279
280MODULE_AUTHOR("Tatsunosuke Tobita <tobita.tatsunosuke@wacom.co.jp>");
281MODULE_DESCRIPTION("WACOM EMR I2C Driver");
282MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 1569a3934ab2..8f9ad2f893b8 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -594,15 +594,4 @@ static struct serio_driver w8001_drv = {
594 .disconnect = w8001_disconnect, 594 .disconnect = w8001_disconnect,
595}; 595};
596 596
597static int __init w8001_init(void) 597module_serio_driver(w8001_drv);
598{
599 return serio_register_driver(&w8001_drv);
600}
601
602static void __exit w8001_exit(void)
603{
604 serio_unregister_driver(&w8001_drv);
605}
606
607module_init(w8001_init);
608module_exit(w8001_exit);