aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/input/ff.txt4
-rw-r--r--Documentation/kernel-parameters.txt1
-rw-r--r--drivers/input/joystick/Kconfig10
-rw-r--r--drivers/input/joystick/Makefile1
-rw-r--r--drivers/input/joystick/as5011.c367
-rw-r--r--drivers/input/keyboard/Kconfig12
-rw-r--r--drivers/input/keyboard/Makefile1
-rw-r--r--drivers/input/keyboard/aaed2000_kbd.c186
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h21
-rw-r--r--drivers/input/serio/i8042.c6
-rw-r--r--drivers/input/touchscreen/ad7879-i2c.c17
-rw-r--r--drivers/input/touchscreen/cy8ctmg110_ts.c15
-rw-r--r--drivers/input/touchscreen/eeti_ts.c16
-rw-r--r--drivers/input/touchscreen/mcs5000_ts.c17
-rw-r--r--drivers/input/touchscreen/migor_ts.c12
-rw-r--r--drivers/input/touchscreen/wacom_w8001.c182
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/input/as5011.h20
18 files changed, 624 insertions, 265 deletions
diff --git a/Documentation/input/ff.txt b/Documentation/input/ff.txt
index ded4d5f53109..b3867bf49f8f 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -49,7 +49,9 @@ This information is subject to change.
49#include <linux/input.h> 49#include <linux/input.h>
50#include <sys/ioctl.h> 50#include <sys/ioctl.h>
51 51
52unsigned long features[1 + FF_MAX/sizeof(unsigned long)]; 52#define BITS_TO_LONGS(x) \
53 (((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
54unsigned long features[BITS_TO_LONGS(FF_CNT)];
53int ioctl(int file_descriptor, int request, unsigned long *features); 55int ioctl(int file_descriptor, int request, unsigned long *features);
54 56
55"request" must be EVIOCGBIT(EV_FF, size of features array in bytes ) 57"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ed3708f8d0db..5e4d9a65d550 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -888,6 +888,7 @@ and is between 256 and 4096 characters. It is defined in the file
888 controller 888 controller
889 i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX 889 i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
890 controllers 890 controllers
891 i8042.notimeout [HW] Ignore timeout condition signalled by conroller
891 i8042.reset [HW] Reset the controller during init and cleanup 892 i8042.reset [HW] Reset the controller during init and cleanup
892 i8042.unlock [HW] Unlock (ignore) the keylock 893 i8042.unlock [HW] Unlock (ignore) the keylock
893 894
diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig
index 5b596165b571..56eb471b5576 100644
--- a/drivers/input/joystick/Kconfig
+++ b/drivers/input/joystick/Kconfig
@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA
255 To compile this driver as a module, choose M here: the 255 To compile this driver as a module, choose M here: the
256 module will be called amijoy. 256 module will be called amijoy.
257 257
258config JOYSTICK_AS5011
259 tristate "Austria Microsystem AS5011 joystick"
260 depends on I2C
261 help
262 Say Y here if you have an AS5011 digital joystick connected to your
263 system.
264
265 To compile this driver as a module, choose M here: the
266 module will be called as5011.
267
258config JOYSTICK_JOYDUMP 268config JOYSTICK_JOYDUMP
259 tristate "Gameport data dumper" 269 tristate "Gameport data dumper"
260 select GAMEPORT 270 select GAMEPORT
diff --git a/drivers/input/joystick/Makefile b/drivers/input/joystick/Makefile
index f3a8cbe2abb6..92dc0de9dfed 100644
--- a/drivers/input/joystick/Makefile
+++ b/drivers/input/joystick/Makefile
@@ -7,6 +7,7 @@
7obj-$(CONFIG_JOYSTICK_A3D) += a3d.o 7obj-$(CONFIG_JOYSTICK_A3D) += a3d.o
8obj-$(CONFIG_JOYSTICK_ADI) += adi.o 8obj-$(CONFIG_JOYSTICK_ADI) += adi.o
9obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o 9obj-$(CONFIG_JOYSTICK_AMIGA) += amijoy.o
10obj-$(CONFIG_JOYSTICK_AS5011) += as5011.o
10obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o 11obj-$(CONFIG_JOYSTICK_ANALOG) += analog.o
11obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o 12obj-$(CONFIG_JOYSTICK_COBRA) += cobra.o
12obj-$(CONFIG_JOYSTICK_DB9) += db9.o 13obj-$(CONFIG_JOYSTICK_DB9) += db9.o
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c
new file mode 100644
index 000000000000..f6732b57ca07
--- /dev/null
+++ b/drivers/input/joystick/as5011.c
@@ -0,0 +1,367 @@
1/*
2 * Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
3 * Sponsored by ARMadeus Systems
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * Driver for Austria Microsystems joysticks AS5011
20 *
21 * TODO:
22 * - Power on the chip when open() and power down when close()
23 * - Manage power mode
24 */
25
26#include <linux/i2c.h>
27#include <linux/interrupt.h>
28#include <linux/input.h>
29#include <linux/gpio.h>
30#include <linux/delay.h>
31#include <linux/input/as5011.h>
32#include <linux/slab.h>
33
34#define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
35#define MODULE_DEVICE_ALIAS "as5011"
36
37MODULE_AUTHOR("Fabien Marteau <fabien.marteau@armadeus.com>");
38MODULE_DESCRIPTION(DRIVER_DESC);
39MODULE_LICENSE("GPL");
40
41/* registers */
42#define AS5011_CTRL1 0x76
43#define AS5011_CTRL2 0x75
44#define AS5011_XP 0x43
45#define AS5011_XN 0x44
46#define AS5011_YP 0x53
47#define AS5011_YN 0x54
48#define AS5011_X_REG 0x41
49#define AS5011_Y_REG 0x42
50#define AS5011_X_RES_INT 0x51
51#define AS5011_Y_RES_INT 0x52
52
53/* CTRL1 bits */
54#define AS5011_CTRL1_LP_PULSED 0x80
55#define AS5011_CTRL1_LP_ACTIVE 0x40
56#define AS5011_CTRL1_LP_CONTINUE 0x20
57#define AS5011_CTRL1_INT_WUP_EN 0x10
58#define AS5011_CTRL1_INT_ACT_EN 0x08
59#define AS5011_CTRL1_EXT_CLK_EN 0x04
60#define AS5011_CTRL1_SOFT_RST 0x02
61#define AS5011_CTRL1_DATA_VALID 0x01
62
63/* CTRL2 bits */
64#define AS5011_CTRL2_EXT_SAMPLE_EN 0x08
65#define AS5011_CTRL2_RC_BIAS_ON 0x04
66#define AS5011_CTRL2_INV_SPINNING 0x02
67
68#define AS5011_MAX_AXIS 80
69#define AS5011_MIN_AXIS (-80)
70#define AS5011_FUZZ 8
71#define AS5011_FLAT 40
72
73struct as5011_device {
74 struct input_dev *input_dev;
75 struct i2c_client *i2c_client;
76 unsigned int button_gpio;
77 unsigned int button_irq;
78 unsigned int axis_irq;
79};
80
81static int as5011_i2c_write(struct i2c_client *client,
82 uint8_t aregaddr,
83 uint8_t avalue)
84{
85 uint8_t data[2] = { aregaddr, avalue };
86 struct i2c_msg msg = {
87 client->addr, I2C_M_IGNORE_NAK, 2, (uint8_t *)data
88 };
89 int error;
90
91 error = i2c_transfer(client->adapter, &msg, 1);
92 return error < 0 ? error : 0;
93}
94
95static int as5011_i2c_read(struct i2c_client *client,
96 uint8_t aregaddr, signed char *value)
97{
98 uint8_t data[2] = { aregaddr };
99 struct i2c_msg msg_set[2] = {
100 { client->addr, I2C_M_REV_DIR_ADDR, 1, (uint8_t *)data },
101 { client->addr, I2C_M_RD | I2C_M_NOSTART, 1, (uint8_t *)data }
102 };
103 int error;
104
105 error = i2c_transfer(client->adapter, msg_set, 2);
106 if (error < 0)
107 return error;
108
109 *value = data[0] & 0x80 ? -1 * (1 + ~data[0]) : data[0];
110 return 0;
111}
112
113static irqreturn_t as5011_button_interrupt(int irq, void *dev_id)
114{
115 struct as5011_device *as5011 = dev_id;
116 int val = gpio_get_value_cansleep(as5011->button_gpio);
117
118 input_report_key(as5011->input_dev, BTN_JOYSTICK, !val);
119 input_sync(as5011->input_dev);
120
121 return IRQ_HANDLED;
122}
123
124static irqreturn_t as5011_axis_interrupt(int irq, void *dev_id)
125{
126 struct as5011_device *as5011 = dev_id;
127 int error;
128 signed char x, y;
129
130 error = as5011_i2c_read(as5011->i2c_client, AS5011_X_RES_INT, &x);
131 if (error < 0)
132 goto out;
133
134 error = as5011_i2c_read(as5011->i2c_client, AS5011_Y_RES_INT, &y);
135 if (error < 0)
136 goto out;
137
138 input_report_abs(as5011->input_dev, ABS_X, x);
139 input_report_abs(as5011->input_dev, ABS_Y, y);
140 input_sync(as5011->input_dev);
141
142out:
143 return IRQ_HANDLED;
144}
145
146static int __devinit as5011_configure_chip(struct as5011_device *as5011,
147 const struct as5011_platform_data *plat_dat)
148{
149 struct i2c_client *client = as5011->i2c_client;
150 int error;
151 signed char value;
152
153 /* chip soft reset */
154 error = as5011_i2c_write(client, AS5011_CTRL1,
155 AS5011_CTRL1_SOFT_RST);
156 if (error < 0) {
157 dev_err(&client->dev, "Soft reset failed\n");
158 return error;
159 }
160
161 mdelay(10);
162
163 error = as5011_i2c_write(client, AS5011_CTRL1,
164 AS5011_CTRL1_LP_PULSED |
165 AS5011_CTRL1_LP_ACTIVE |
166 AS5011_CTRL1_INT_ACT_EN);
167 if (error < 0) {
168 dev_err(&client->dev, "Power config failed\n");
169 return error;
170 }
171
172 error = as5011_i2c_write(client, AS5011_CTRL2,
173 AS5011_CTRL2_INV_SPINNING);
174 if (error < 0) {
175 dev_err(&client->dev, "Can't invert spinning\n");
176 return error;
177 }
178
179 /* write threshold */
180 error = as5011_i2c_write(client, AS5011_XP, plat_dat->xp);
181 if (error < 0) {
182 dev_err(&client->dev, "Can't write threshold\n");
183 return error;
184 }
185
186 error = as5011_i2c_write(client, AS5011_XN, plat_dat->xn);
187 if (error < 0) {
188 dev_err(&client->dev, "Can't write threshold\n");
189 return error;
190 }
191
192 error = as5011_i2c_write(client, AS5011_YP, plat_dat->yp);
193 if (error < 0) {
194 dev_err(&client->dev, "Can't write threshold\n");
195 return error;
196 }
197
198 error = as5011_i2c_write(client, AS5011_YN, plat_dat->yn);
199 if (error < 0) {
200 dev_err(&client->dev, "Can't write threshold\n");
201 return error;
202 }
203
204 /* to free irq gpio in chip */
205 error = as5011_i2c_read(client, AS5011_X_RES_INT, &value);
206 if (error < 0) {
207 dev_err(&client->dev, "Can't read i2c X resolution value\n");
208 return error;
209 }
210
211 return 0;
212}
213
214static int __devinit as5011_probe(struct i2c_client *client,
215 const struct i2c_device_id *id)
216{
217 const struct as5011_platform_data *plat_data;
218 struct as5011_device *as5011;
219 struct input_dev *input_dev;
220 int irq;
221 int error;
222
223 plat_data = client->dev.platform_data;
224 if (!plat_data)
225 return -EINVAL;
226
227 if (!plat_data->axis_irq) {
228 dev_err(&client->dev, "No axis IRQ?\n");
229 return -EINVAL;
230 }
231
232 if (!i2c_check_functionality(client->adapter,
233 I2C_FUNC_PROTOCOL_MANGLING)) {
234 dev_err(&client->dev,
235 "need i2c bus that supports protocol mangling\n");
236 return -ENODEV;
237 }
238
239 as5011 = kmalloc(sizeof(struct as5011_device), GFP_KERNEL);
240 input_dev = input_allocate_device();
241 if (!as5011 || !input_dev) {
242 dev_err(&client->dev,
243 "Can't allocate memory for device structure\n");
244 error = -ENOMEM;
245 goto err_free_mem;
246 }
247
248 as5011->i2c_client = client;
249 as5011->input_dev = input_dev;
250 as5011->button_gpio = plat_data->button_gpio;
251 as5011->axis_irq = plat_data->axis_irq;
252
253 input_dev->name = "Austria Microsystem as5011 joystick";
254 input_dev->id.bustype = BUS_I2C;
255 input_dev->dev.parent = &client->dev;
256
257 __set_bit(EV_KEY, input_dev->evbit);
258 __set_bit(EV_ABS, input_dev->evbit);
259 __set_bit(BTN_JOYSTICK, input_dev->keybit);
260
261 input_set_abs_params(input_dev, ABS_X,
262 AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
263 input_set_abs_params(as5011->input_dev, ABS_Y,
264 AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT);
265
266 error = gpio_request(as5011->button_gpio, "AS5011 button");
267 if (error < 0) {
268 dev_err(&client->dev, "Failed to request button gpio\n");
269 goto err_free_mem;
270 }
271
272 irq = gpio_to_irq(as5011->button_gpio);
273 if (irq < 0) {
274 dev_err(&client->dev,
275 "Failed to get irq number for button gpio\n");
276 goto err_free_button_gpio;
277 }
278
279 as5011->button_irq = irq;
280
281 error = request_threaded_irq(as5011->button_irq,
282 NULL, as5011_button_interrupt,
283 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
284 "as5011_button", as5011);
285 if (error < 0) {
286 dev_err(&client->dev,
287 "Can't allocate button irq %d\n", as5011->button_irq);
288 goto err_free_button_gpio;
289 }
290
291 error = as5011_configure_chip(as5011, plat_data);
292 if (error)
293 goto err_free_button_irq;
294
295 error = request_threaded_irq(as5011->axis_irq, NULL,
296 as5011_axis_interrupt,
297 plat_data->axis_irqflags,
298 "as5011_joystick", as5011);
299 if (error) {
300 dev_err(&client->dev,
301 "Can't allocate axis irq %d\n", plat_data->axis_irq);
302 goto err_free_button_irq;
303 }
304
305 error = input_register_device(as5011->input_dev);
306 if (error) {
307 dev_err(&client->dev, "Failed to register input device\n");
308 goto err_free_axis_irq;
309 }
310
311 i2c_set_clientdata(client, as5011);
312
313 return 0;
314
315err_free_axis_irq:
316 free_irq(as5011->axis_irq, as5011);
317err_free_button_irq:
318 free_irq(as5011->button_irq, as5011);
319err_free_button_gpio:
320 gpio_free(as5011->button_gpio);
321err_free_mem:
322 input_free_device(input_dev);
323 kfree(as5011);
324
325 return error;
326}
327
328static int __devexit as5011_remove(struct i2c_client *client)
329{
330 struct as5011_device *as5011 = i2c_get_clientdata(client);
331
332 free_irq(as5011->axis_irq, as5011);
333 free_irq(as5011->button_irq, as5011);
334 gpio_free(as5011->button_gpio);
335
336 input_unregister_device(as5011->input_dev);
337 kfree(as5011);
338
339 return 0;
340}
341
342static const struct i2c_device_id as5011_id[] = {
343 { MODULE_DEVICE_ALIAS, 0 },
344 { }
345};
346MODULE_DEVICE_TABLE(i2c, as5011_id);
347
348static struct i2c_driver as5011_driver = {
349 .driver = {
350 .name = "as5011",
351 },
352 .probe = as5011_probe,
353 .remove = __devexit_p(as5011_remove),
354 .id_table = as5011_id,
355};
356
357static int __init as5011_init(void)
358{
359 return i2c_add_driver(&as5011_driver);
360}
361module_init(as5011_init);
362
363static void __exit as5011_exit(void)
364{
365 i2c_del_driver(&as5011_driver);
366}
367module_exit(as5011_exit);
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index f829998fabe6..7b3c0b8fa432 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD
12 12
13if INPUT_KEYBOARD 13if INPUT_KEYBOARD
14 14
15config KEYBOARD_AAED2000
16 tristate "AAED-2000 keyboard"
17 depends on MACH_AAED2000
18 select INPUT_POLLDEV
19 default y
20 help
21 Say Y here to enable the keyboard on the Agilent AAED-2000
22 development board.
23
24 To compile this driver as a module, choose M here: the
25 module will be called aaed2000_kbd.
26
27config KEYBOARD_ADP5520 15config KEYBOARD_ADP5520
28 tristate "Keypad Support for ADP5520 PMIC" 16 tristate "Keypad Support for ADP5520 PMIC"
29 depends on PMIC_ADP5520 17 depends on PMIC_ADP5520
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index 8933e9ca938d..4e5571b72cda 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -4,7 +4,6 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_KEYBOARD_AAED2000) += aaed2000_kbd.o
8obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o 7obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
9obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o 8obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
10obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o 9obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
deleted file mode 100644
index 18222a689a03..000000000000
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/*
2 * Keyboard driver for the AAED-2000 dev board
3 *
4 * Copyright (c) 2006 Nicolas Bellido Y Ortega
5 *
6 * Based on corgikbd.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/delay.h>
15#include <linux/platform_device.h>
16#include <linux/init.h>
17#include <linux/input-polldev.h>
18#include <linux/interrupt.h>
19#include <linux/jiffies.h>
20#include <linux/module.h>
21#include <linux/slab.h>
22
23#include <mach/hardware.h>
24#include <mach/aaed2000.h>
25
26#define KB_ROWS 12
27#define KB_COLS 8
28#define KB_ROWMASK(r) (1 << (r))
29#define SCANCODE(r,c) (((c) * KB_ROWS) + (r))
30#define NR_SCANCODES (KB_COLS * KB_ROWS)
31
32#define SCAN_INTERVAL (50) /* ms */
33#define KB_ACTIVATE_DELAY (20) /* us */
34
35static unsigned char aaedkbd_keycode[NR_SCANCODES] = {
36 KEY_9, KEY_0, KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, 0, KEY_SPACE, KEY_KP6, 0, KEY_KPDOT, 0, 0,
37 KEY_K, KEY_M, KEY_O, KEY_DOT, KEY_SLASH, 0, KEY_F, 0, 0, 0, KEY_LEFTSHIFT, 0,
38 KEY_I, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_BACKSLASH, 0, 0, 0, 0, 0, KEY_RIGHTSHIFT, 0,
39 KEY_8, KEY_L, KEY_SEMICOLON, KEY_APOSTROPHE, KEY_ENTER, 0, 0, 0, 0, 0, 0, 0,
40 KEY_J, KEY_H, KEY_B, KEY_KP8, KEY_KP4, 0, KEY_C, KEY_D, KEY_S, KEY_A, 0, KEY_CAPSLOCK,
41 KEY_Y, KEY_U, KEY_N, KEY_T, 0, 0, KEY_R, KEY_E, KEY_W, KEY_Q, 0, KEY_TAB,
42 KEY_7, KEY_6, KEY_G, 0, KEY_5, 0, KEY_4, KEY_3, KEY_2, KEY_1, 0, KEY_GRAVE,
43 0, 0, KEY_COMMA, 0, KEY_KP2, 0, KEY_V, KEY_LEFTALT, KEY_X, KEY_Z, 0, KEY_LEFTCTRL
44};
45
46struct aaedkbd {
47 unsigned char keycode[ARRAY_SIZE(aaedkbd_keycode)];
48 struct input_polled_dev *poll_dev;
49 int kbdscan_state[KB_COLS];
50 int kbdscan_count[KB_COLS];
51};
52
53#define KBDSCAN_STABLE_COUNT 2
54
55static void aaedkbd_report_col(struct aaedkbd *aaedkbd,
56 unsigned int col, unsigned int rowd)
57{
58 unsigned int scancode, pressed;
59 unsigned int row;
60
61 for (row = 0; row < KB_ROWS; row++) {
62 scancode = SCANCODE(row, col);
63 pressed = rowd & KB_ROWMASK(row);
64
65 input_report_key(aaedkbd->poll_dev->input,
66 aaedkbd->keycode[scancode], pressed);
67 }
68}
69
70/* Scan the hardware keyboard and push any changes up through the input layer */
71static void aaedkbd_poll(struct input_polled_dev *dev)
72{
73 struct aaedkbd *aaedkbd = dev->private;
74 unsigned int col, rowd;
75
76 col = 0;
77 do {
78 AAEC_GPIO_KSCAN = col + 8;
79 udelay(KB_ACTIVATE_DELAY);
80 rowd = AAED_EXT_GPIO & AAED_EGPIO_KBD_SCAN;
81
82 if (rowd != aaedkbd->kbdscan_state[col]) {
83 aaedkbd->kbdscan_count[col] = 0;
84 aaedkbd->kbdscan_state[col] = rowd;
85 } else if (++aaedkbd->kbdscan_count[col] >= KBDSCAN_STABLE_COUNT) {
86 aaedkbd_report_col(aaedkbd, col, rowd);
87 col++;
88 }
89 } while (col < KB_COLS);
90
91 AAEC_GPIO_KSCAN = 0x07;
92 input_sync(dev->input);
93}
94
95static int __devinit aaedkbd_probe(struct platform_device *pdev)
96{
97 struct aaedkbd *aaedkbd;
98 struct input_polled_dev *poll_dev;
99 struct input_dev *input_dev;
100 int i;
101 int error;
102
103 aaedkbd = kzalloc(sizeof(struct aaedkbd), GFP_KERNEL);
104 poll_dev = input_allocate_polled_device();
105 if (!aaedkbd || !poll_dev) {
106 error = -ENOMEM;
107 goto fail;
108 }
109
110 platform_set_drvdata(pdev, aaedkbd);
111
112 aaedkbd->poll_dev = poll_dev;
113 memcpy(aaedkbd->keycode, aaedkbd_keycode, sizeof(aaedkbd->keycode));
114
115 poll_dev->private = aaedkbd;
116 poll_dev->poll = aaedkbd_poll;
117 poll_dev->poll_interval = SCAN_INTERVAL;
118
119 input_dev = poll_dev->input;
120 input_dev->name = "AAED-2000 Keyboard";
121 input_dev->phys = "aaedkbd/input0";
122 input_dev->id.bustype = BUS_HOST;
123 input_dev->id.vendor = 0x0001;
124 input_dev->id.product = 0x0001;
125 input_dev->id.version = 0x0100;
126 input_dev->dev.parent = &pdev->dev;
127
128 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
129 input_dev->keycode = aaedkbd->keycode;
130 input_dev->keycodesize = sizeof(unsigned char);
131 input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode);
132
133 for (i = 0; i < ARRAY_SIZE(aaedkbd_keycode); i++)
134 set_bit(aaedkbd->keycode[i], input_dev->keybit);
135 clear_bit(0, input_dev->keybit);
136
137 error = input_register_polled_device(aaedkbd->poll_dev);
138 if (error)
139 goto fail;
140
141 return 0;
142
143 fail: kfree(aaedkbd);
144 input_free_polled_device(poll_dev);
145 return error;
146}
147
148static int __devexit aaedkbd_remove(struct platform_device *pdev)
149{
150 struct aaedkbd *aaedkbd = platform_get_drvdata(pdev);
151
152 input_unregister_polled_device(aaedkbd->poll_dev);
153 input_free_polled_device(aaedkbd->poll_dev);
154 kfree(aaedkbd);
155
156 return 0;
157}
158
159/* work with hotplug and coldplug */
160MODULE_ALIAS("platform:aaed2000-keyboard");
161
162static struct platform_driver aaedkbd_driver = {
163 .probe = aaedkbd_probe,
164 .remove = __devexit_p(aaedkbd_remove),
165 .driver = {
166 .name = "aaed2000-keyboard",
167 .owner = THIS_MODULE,
168 },
169};
170
171static int __init aaedkbd_init(void)
172{
173 return platform_driver_register(&aaedkbd_driver);
174}
175
176static void __exit aaedkbd_exit(void)
177{
178 platform_driver_unregister(&aaedkbd_driver);
179}
180
181module_init(aaedkbd_init);
182module_exit(aaedkbd_exit);
183
184MODULE_AUTHOR("Nicolas Bellido Y Ortega");
185MODULE_DESCRIPTION("AAED-2000 Keyboard Driver");
186MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 5ae0fc4578fe..bb9f5d31f0d0 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
424 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), 424 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
425 }, 425 },
426 }, 426 },
427 {
428 /* Dell Vostro V13 */
429 .matches = {
430 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
431 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
432 },
433 },
427 { } 434 { }
428}; 435};
429 436
@@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
545}; 552};
546#endif 553#endif
547 554
555static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
556 {
557 /* Dell Vostro V13 */
558 .matches = {
559 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
560 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"),
561 },
562 },
563 { }
564};
565
548/* 566/*
549 * Some Wistron based laptops need us to explicitly enable the 'Dritek 567 * Some Wistron based laptops need us to explicitly enable the 'Dritek
550 * keyboard extension' to make their extra keys start generating scancodes. 568 * keyboard extension' to make their extra keys start generating scancodes.
@@ -896,6 +914,9 @@ static int __init i8042_platform_init(void)
896 if (dmi_check_system(i8042_dmi_nomux_table)) 914 if (dmi_check_system(i8042_dmi_nomux_table))
897 i8042_nomux = true; 915 i8042_nomux = true;
898 916
917 if (dmi_check_system(i8042_dmi_notimeout_table))
918 i8042_notimeout = true;
919
899 if (dmi_check_system(i8042_dmi_dritek_table)) 920 if (dmi_check_system(i8042_dmi_dritek_table))
900 i8042_dritek = true; 921 i8042_dritek = true;
901#endif /* CONFIG_X86 */ 922#endif /* CONFIG_X86 */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c04ff00a3663..ac4c93689ab9 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -63,6 +63,10 @@ static bool i8042_noloop;
63module_param_named(noloop, i8042_noloop, bool, 0); 63module_param_named(noloop, i8042_noloop, bool, 0);
64MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port"); 64MODULE_PARM_DESC(noloop, "Disable the AUX Loopback command while probing for the AUX port");
65 65
66static bool i8042_notimeout;
67module_param_named(notimeout, i8042_notimeout, bool, 0);
68MODULE_PARM_DESC(notimeout, "Ignore timeouts signalled by i8042");
69
66#ifdef CONFIG_X86 70#ifdef CONFIG_X86
67static bool i8042_dritek; 71static bool i8042_dritek;
68module_param_named(dritek, i8042_dritek, bool, 0); 72module_param_named(dritek, i8042_dritek, bool, 0);
@@ -504,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
504 } else { 508 } else {
505 509
506 dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) | 510 dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
507 ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0); 511 ((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0);
508 512
509 port_no = (str & I8042_STR_AUXDATA) ? 513 port_no = (str & I8042_STR_AUXDATA) ?
510 I8042_AUX_PORT_NO : I8042_KBD_PORT_NO; 514 I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
diff --git a/drivers/input/touchscreen/ad7879-i2c.c b/drivers/input/touchscreen/ad7879-i2c.c
index d82a38ee9a3e..4e4e58cec6c8 100644
--- a/drivers/input/touchscreen/ad7879-i2c.c
+++ b/drivers/input/touchscreen/ad7879-i2c.c
@@ -10,14 +10,16 @@
10#include <linux/i2c.h> 10#include <linux/i2c.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/pm.h>
13 14
14#include "ad7879.h" 15#include "ad7879.h"
15 16
16#define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ 17#define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */
17 18
18#ifdef CONFIG_PM 19#ifdef CONFIG_PM
19static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message) 20static int ad7879_i2c_suspend(struct device *dev)
20{ 21{
22 struct i2c_client *client = to_i2c_client(dev);
21 struct ad7879 *ts = i2c_get_clientdata(client); 23 struct ad7879 *ts = i2c_get_clientdata(client);
22 24
23 ad7879_suspend(ts); 25 ad7879_suspend(ts);
@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message)
25 return 0; 27 return 0;
26} 28}
27 29
28static int ad7879_i2c_resume(struct i2c_client *client) 30static int ad7879_i2c_resume(struct device *dev)
29{ 31{
32 struct i2c_client *client = to_i2c_client(dev);
30 struct ad7879 *ts = i2c_get_clientdata(client); 33 struct ad7879 *ts = i2c_get_clientdata(client);
31 34
32 ad7879_resume(ts); 35 ad7879_resume(ts);
33 36
34 return 0; 37 return 0;
35} 38}
36#else 39
37# define ad7879_i2c_suspend NULL 40static SIMPLE_DEV_PM_OPS(ad7879_i2c_pm, ad7879_i2c_suspend, ad7879_i2c_resume);
38# define ad7879_i2c_resume NULL
39#endif 41#endif
40 42
41/* All registers are word-sized. 43/* All registers are word-sized.
@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = {
117 .driver = { 119 .driver = {
118 .name = "ad7879", 120 .name = "ad7879",
119 .owner = THIS_MODULE, 121 .owner = THIS_MODULE,
122#ifdef CONFIG_PM
123 .pm = &ad7879_i2c_pm,
124#endif
120 }, 125 },
121 .probe = ad7879_i2c_probe, 126 .probe = ad7879_i2c_probe,
122 .remove = __devexit_p(ad7879_i2c_remove), 127 .remove = __devexit_p(ad7879_i2c_remove),
123 .suspend = ad7879_i2c_suspend,
124 .resume = ad7879_i2c_resume,
125 .id_table = ad7879_id, 128 .id_table = ad7879_id,
126}; 129};
127 130
diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c
index d0c3a7229adf..a93c5c26ab3f 100644
--- a/drivers/input/touchscreen/cy8ctmg110_ts.c
+++ b/drivers/input/touchscreen/cy8ctmg110_ts.c
@@ -280,8 +280,9 @@ err_free_mem:
280} 280}
281 281
282#ifdef CONFIG_PM 282#ifdef CONFIG_PM
283static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg) 283static int cy8ctmg110_suspend(struct device *dev)
284{ 284{
285 struct i2c_client *client = to_i2c_client(dev);
285 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 286 struct cy8ctmg110 *ts = i2c_get_clientdata(client);
286 287
287 if (device_may_wakeup(&client->dev)) 288 if (device_may_wakeup(&client->dev))
@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg)
293 return 0; 294 return 0;
294} 295}
295 296
296static int cy8ctmg110_resume(struct i2c_client *client) 297static int cy8ctmg110_resume(struct device *dev)
297{ 298{
299 struct i2c_client *client = to_i2c_client(dev);
298 struct cy8ctmg110 *ts = i2c_get_clientdata(client); 300 struct cy8ctmg110 *ts = i2c_get_clientdata(client);
299 301
300 if (device_may_wakeup(&client->dev)) 302 if (device_may_wakeup(&client->dev))
@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client)
305 } 307 }
306 return 0; 308 return 0;
307} 309}
310
311static SIMPLE_DEV_PM_OPS(cy8ctmg110_pm, cy8ctmg110_suspend, cy8ctmg110_resume);
308#endif 312#endif
309 313
310static int __devexit cy8ctmg110_remove(struct i2c_client *client) 314static int __devexit cy8ctmg110_remove(struct i2c_client *client)
@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = {
335 .driver = { 339 .driver = {
336 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
337 .name = CY8CTMG110_DRIVER_NAME, 341 .name = CY8CTMG110_DRIVER_NAME,
342#ifdef CONFIG_PM
343 .pm = &cy8ctmg110_pm,
344#endif
338 }, 345 },
339 .id_table = cy8ctmg110_idtable, 346 .id_table = cy8ctmg110_idtable,
340 .probe = cy8ctmg110_probe, 347 .probe = cy8ctmg110_probe,
341 .remove = __devexit_p(cy8ctmg110_remove), 348 .remove = __devexit_p(cy8ctmg110_remove),
342#ifdef CONFIG_PM
343 .suspend = cy8ctmg110_suspend,
344 .resume = cy8ctmg110_resume,
345#endif
346}; 349};
347 350
348static int __init cy8ctmg110_init(void) 351static int __init cy8ctmg110_init(void)
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 7a3a916f84a8..7f8f538a9806 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
261} 261}
262 262
263#ifdef CONFIG_PM 263#ifdef CONFIG_PM
264static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) 264static int eeti_ts_suspend(struct device *dev)
265{ 265{
266 struct i2c_client *client = to_i2c_client(dev);
266 struct eeti_ts_priv *priv = i2c_get_clientdata(client); 267 struct eeti_ts_priv *priv = i2c_get_clientdata(client);
267 struct input_dev *input_dev = priv->input; 268 struct input_dev *input_dev = priv->input;
268 269
@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
279 return 0; 280 return 0;
280} 281}
281 282
282static int eeti_ts_resume(struct i2c_client *client) 283static int eeti_ts_resume(struct device *dev)
283{ 284{
285 struct i2c_client *client = to_i2c_client(dev);
284 struct eeti_ts_priv *priv = i2c_get_clientdata(client); 286 struct eeti_ts_priv *priv = i2c_get_clientdata(client);
285 struct input_dev *input_dev = priv->input; 287 struct input_dev *input_dev = priv->input;
286 288
@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client)
296 298
297 return 0; 299 return 0;
298} 300}
299#else 301
300#define eeti_ts_suspend NULL 302static SIMPLE_DEV_PM_OPS(eeti_ts_pm, eeti_ts_suspend, eeti_ts_resume);
301#define eeti_ts_resume NULL
302#endif 303#endif
303 304
304static const struct i2c_device_id eeti_ts_id[] = { 305static const struct i2c_device_id eeti_ts_id[] = {
@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id);
310static struct i2c_driver eeti_ts_driver = { 311static struct i2c_driver eeti_ts_driver = {
311 .driver = { 312 .driver = {
312 .name = "eeti_ts", 313 .name = "eeti_ts",
314#ifdef CONFIG_PM
315 .pm = &eeti_ts_pm,
316#endif
313 }, 317 },
314 .probe = eeti_ts_probe, 318 .probe = eeti_ts_probe,
315 .remove = __devexit_p(eeti_ts_remove), 319 .remove = __devexit_p(eeti_ts_remove),
316 .suspend = eeti_ts_suspend,
317 .resume = eeti_ts_resume,
318 .id_table = eeti_ts_id, 320 .id_table = eeti_ts_id,
319}; 321};
320 322
diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c
index 6ee9940aaf5b..2d84c80ceb66 100644
--- a/drivers/input/touchscreen/mcs5000_ts.c
+++ b/drivers/input/touchscreen/mcs5000_ts.c
@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client)
261} 261}
262 262
263#ifdef CONFIG_PM 263#ifdef CONFIG_PM
264static int mcs5000_ts_suspend(struct i2c_client *client, pm_message_t mesg) 264static int mcs5000_ts_suspend(struct device *dev)
265{ 265{
266 struct i2c_client *client = to_i2c_client(dev);
267
266 /* Touch sleep mode */ 268 /* Touch sleep mode */
267 i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); 269 i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP);
268 270
269 return 0; 271 return 0;
270} 272}
271 273
272static int mcs5000_ts_resume(struct i2c_client *client) 274static int mcs5000_ts_resume(struct device *dev)
273{ 275{
276 struct i2c_client *client = to_i2c_client(dev);
274 struct mcs5000_ts_data *data = i2c_get_clientdata(client); 277 struct mcs5000_ts_data *data = i2c_get_clientdata(client);
275 278
276 mcs5000_ts_phys_init(data); 279 mcs5000_ts_phys_init(data);
277 280
278 return 0; 281 return 0;
279} 282}
280#else 283
281#define mcs5000_ts_suspend NULL 284static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume);
282#define mcs5000_ts_resume NULL
283#endif 285#endif
284 286
285static const struct i2c_device_id mcs5000_ts_id[] = { 287static const struct i2c_device_id mcs5000_ts_id[] = {
@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id);
291static struct i2c_driver mcs5000_ts_driver = { 293static struct i2c_driver mcs5000_ts_driver = {
292 .probe = mcs5000_ts_probe, 294 .probe = mcs5000_ts_probe,
293 .remove = __devexit_p(mcs5000_ts_remove), 295 .remove = __devexit_p(mcs5000_ts_remove),
294 .suspend = mcs5000_ts_suspend,
295 .resume = mcs5000_ts_resume,
296 .driver = { 296 .driver = {
297 .name = "mcs5000_ts", 297 .name = "mcs5000_ts",
298#ifdef CONFIG_PM
299 .pm = &mcs5000_ts_pm,
300#endif
298 }, 301 },
299 .id_table = mcs5000_ts_id, 302 .id_table = mcs5000_ts_id,
300}; 303};
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index defe5dd3627c..5803bd0c1cca 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -23,6 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/input.h> 24#include <linux/input.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/pm.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <asm/io.h> 28#include <asm/io.h>
28#include <linux/i2c.h> 29#include <linux/i2c.h>
@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client)
226 return 0; 227 return 0;
227} 228}
228 229
229static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg) 230static int migor_ts_suspend(struct device *dev)
230{ 231{
232 struct i2c_client *client = to_i2c_client(dev);
231 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); 233 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
232 234
233 if (device_may_wakeup(&client->dev)) 235 if (device_may_wakeup(&client->dev))
@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
236 return 0; 238 return 0;
237} 239}
238 240
239static int migor_ts_resume(struct i2c_client *client) 241static int migor_ts_resume(struct device *dev)
240{ 242{
243 struct i2c_client *client = to_i2c_client(dev);
241 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev); 244 struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
242 245
243 if (device_may_wakeup(&client->dev)) 246 if (device_may_wakeup(&client->dev))
@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client)
246 return 0; 249 return 0;
247} 250}
248 251
252static SIMPLE_DEV_PM_OPS(migor_ts_pm, migor_ts_suspend, migor_ts_resume);
253
249static const struct i2c_device_id migor_ts_id[] = { 254static const struct i2c_device_id migor_ts_id[] = {
250 { "migor_ts", 0 }, 255 { "migor_ts", 0 },
251 { } 256 { }
@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts);
255static struct i2c_driver migor_ts_driver = { 260static struct i2c_driver migor_ts_driver = {
256 .driver = { 261 .driver = {
257 .name = "migor_ts", 262 .name = "migor_ts",
263 .pm = &migor_ts_pm,
258 }, 264 },
259 .probe = migor_ts_probe, 265 .probe = migor_ts_probe,
260 .remove = migor_ts_remove, 266 .remove = migor_ts_remove,
261 .suspend = migor_ts_suspend,
262 .resume = migor_ts_resume,
263 .id_table = migor_ts_id, 267 .id_table = migor_ts_id,
264}; 268};
265 269
diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
index 8ed53aded2d3..5cb8449c909d 100644
--- a/drivers/input/touchscreen/wacom_w8001.c
+++ b/drivers/input/touchscreen/wacom_w8001.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2008 Jaya Kumar 4 * Copyright (c) 2008 Jaya Kumar
5 * Copyright (c) 2010 Red Hat, Inc. 5 * Copyright (c) 2010 Red Hat, Inc.
6 * Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com>
6 * 7 *
7 * This file is subject to the terms and conditions of the GNU General Public 8 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for 9 * License. See the file COPYING in the main directory of this archive for
@@ -64,11 +65,11 @@ struct w8001_coord {
64 65
65/* touch query reply packet */ 66/* touch query reply packet */
66struct w8001_touch_query { 67struct w8001_touch_query {
68 u16 x;
69 u16 y;
67 u8 panel_res; 70 u8 panel_res;
68 u8 capacity_res; 71 u8 capacity_res;
69 u8 sensor_id; 72 u8 sensor_id;
70 u16 x;
71 u16 y;
72}; 73};
73 74
74/* 75/*
@@ -87,9 +88,14 @@ struct w8001 {
87 char phys[32]; 88 char phys[32];
88 int type; 89 int type;
89 unsigned int pktlen; 90 unsigned int pktlen;
91 u16 max_touch_x;
92 u16 max_touch_y;
93 u16 max_pen_x;
94 u16 max_pen_y;
95 char name[64];
90}; 96};
91 97
92static void parse_data(u8 *data, struct w8001_coord *coord) 98static void parse_pen_data(u8 *data, struct w8001_coord *coord)
93{ 99{
94 memset(coord, 0, sizeof(*coord)); 100 memset(coord, 0, sizeof(*coord));
95 101
@@ -113,11 +119,30 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
113 coord->tilt_y = data[8] & 0x7F; 119 coord->tilt_y = data[8] & 0x7F;
114} 120}
115 121
116static void parse_touch(struct w8001 *w8001) 122static void parse_single_touch(u8 *data, struct w8001_coord *coord)
123{
124 coord->x = (data[1] << 7) | data[2];
125 coord->y = (data[3] << 7) | data[4];
126 coord->tsw = data[0] & 0x01;
127}
128
129static void scale_touch_coordinates(struct w8001 *w8001,
130 unsigned int *x, unsigned int *y)
131{
132 if (w8001->max_pen_x && w8001->max_touch_x)
133 *x = *x * w8001->max_pen_x / w8001->max_touch_x;
134
135 if (w8001->max_pen_y && w8001->max_touch_y)
136 *y = *y * w8001->max_pen_y / w8001->max_touch_y;
137}
138
139static void parse_multi_touch(struct w8001 *w8001)
117{ 140{
118 struct input_dev *dev = w8001->dev; 141 struct input_dev *dev = w8001->dev;
119 unsigned char *data = w8001->data; 142 unsigned char *data = w8001->data;
143 unsigned int x, y;
120 int i; 144 int i;
145 int count = 0;
121 146
122 for (i = 0; i < 2; i++) { 147 for (i = 0; i < 2; i++) {
123 bool touch = data[0] & (1 << i); 148 bool touch = data[0] & (1 << i);
@@ -125,15 +150,29 @@ static void parse_touch(struct w8001 *w8001)
125 input_mt_slot(dev, i); 150 input_mt_slot(dev, i);
126 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch); 151 input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
127 if (touch) { 152 if (touch) {
128 int x = (data[6 * i + 1] << 7) | (data[6 * i + 2]); 153 x = (data[6 * i + 1] << 7) | data[6 * i + 2];
129 int y = (data[6 * i + 3] << 7) | (data[6 * i + 4]); 154 y = (data[6 * i + 3] << 7) | data[6 * i + 4];
130 /* data[5,6] and [11,12] is finger capacity */ 155 /* data[5,6] and [11,12] is finger capacity */
131 156
157 /* scale to pen maximum */
158 scale_touch_coordinates(w8001, &x, &y);
159
132 input_report_abs(dev, ABS_MT_POSITION_X, x); 160 input_report_abs(dev, ABS_MT_POSITION_X, x);
133 input_report_abs(dev, ABS_MT_POSITION_Y, y); 161 input_report_abs(dev, ABS_MT_POSITION_Y, y);
162 count++;
134 } 163 }
135 } 164 }
136 165
166 /* emulate single touch events when stylus is out of proximity.
167 * This is to make single touch backward support consistent
168 * across all Wacom single touch devices.
169 */
170 if (w8001->type != BTN_TOOL_PEN &&
171 w8001->type != BTN_TOOL_RUBBER) {
172 w8001->type = count == 1 ? BTN_TOOL_FINGER : KEY_RESERVED;
173 input_mt_report_pointer_emulation(dev, true);
174 }
175
137 input_sync(dev); 176 input_sync(dev);
138} 177}
139 178
@@ -152,6 +191,15 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
152 query->y = data[5] << 9; 191 query->y = data[5] << 9;
153 query->y |= data[6] << 2; 192 query->y |= data[6] << 2;
154 query->y |= (data[2] >> 3) & 0x3; 193 query->y |= (data[2] >> 3) & 0x3;
194
195 /* Early days' single-finger touch models need the following defaults */
196 if (!query->x && !query->y) {
197 query->x = 1024;
198 query->y = 1024;
199 if (query->panel_res)
200 query->x = query->y = (1 << query->panel_res);
201 query->panel_res = 10;
202 }
155} 203}
156 204
157static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord) 205static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
@@ -161,16 +209,15 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
161 /* 209 /*
162 * We have 1 bit for proximity (rdy) and 3 bits for tip, side, 210 * We have 1 bit for proximity (rdy) and 3 bits for tip, side,
163 * side2/eraser. If rdy && f2 are set, this can be either pen + side2, 211 * side2/eraser. If rdy && f2 are set, this can be either pen + side2,
164 * or eraser. assume 212 * or eraser. Assume:
165 * - if dev is already in proximity and f2 is toggled → pen + side2 213 * - if dev is already in proximity and f2 is toggled → pen + side2
166 * - if dev comes into proximity with f2 set → eraser 214 * - if dev comes into proximity with f2 set → eraser
167 * If f2 disappears after assuming eraser, fake proximity out for 215 * If f2 disappears after assuming eraser, fake proximity out for
168 * eraser and in for pen. 216 * eraser and in for pen.
169 */ 217 */
170 218
171 if (!w8001->type) { 219 switch (w8001->type) {
172 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; 220 case BTN_TOOL_RUBBER:
173 } else if (w8001->type == BTN_TOOL_RUBBER) {
174 if (!coord->f2) { 221 if (!coord->f2) {
175 input_report_abs(dev, ABS_PRESSURE, 0); 222 input_report_abs(dev, ABS_PRESSURE, 0);
176 input_report_key(dev, BTN_TOUCH, 0); 223 input_report_key(dev, BTN_TOUCH, 0);
@@ -180,8 +227,21 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
180 input_sync(dev); 227 input_sync(dev);
181 w8001->type = BTN_TOOL_PEN; 228 w8001->type = BTN_TOOL_PEN;
182 } 229 }
183 } else { 230 break;
231
232 case BTN_TOOL_FINGER:
233 input_report_key(dev, BTN_TOUCH, 0);
234 input_report_key(dev, BTN_TOOL_FINGER, 0);
235 input_sync(dev);
236 /* fall through */
237
238 case KEY_RESERVED:
239 w8001->type = coord->f2 ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
240 break;
241
242 default:
184 input_report_key(dev, BTN_STYLUS2, coord->f2); 243 input_report_key(dev, BTN_STYLUS2, coord->f2);
244 break;
185 } 245 }
186 246
187 input_report_abs(dev, ABS_X, coord->x); 247 input_report_abs(dev, ABS_X, coord->x);
@@ -193,7 +253,26 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
193 input_sync(dev); 253 input_sync(dev);
194 254
195 if (!coord->rdy) 255 if (!coord->rdy)
196 w8001->type = 0; 256 w8001->type = KEY_RESERVED;
257}
258
259static void report_single_touch(struct w8001 *w8001, struct w8001_coord *coord)
260{
261 struct input_dev *dev = w8001->dev;
262 unsigned int x = coord->x;
263 unsigned int y = coord->y;
264
265 /* scale to pen maximum */
266 scale_touch_coordinates(w8001, &x, &y);
267
268 input_report_abs(dev, ABS_X, x);
269 input_report_abs(dev, ABS_Y, y);
270 input_report_key(dev, BTN_TOUCH, coord->tsw);
271 input_report_key(dev, BTN_TOOL_FINGER, coord->tsw);
272
273 input_sync(dev);
274
275 w8001->type = coord->tsw ? BTN_TOOL_FINGER : KEY_RESERVED;
197} 276}
198 277
199static irqreturn_t w8001_interrupt(struct serio *serio, 278static irqreturn_t w8001_interrupt(struct serio *serio,
@@ -214,9 +293,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
214 293
215 case W8001_PKTLEN_TOUCH93 - 1: 294 case W8001_PKTLEN_TOUCH93 - 1:
216 case W8001_PKTLEN_TOUCH9A - 1: 295 case W8001_PKTLEN_TOUCH9A - 1:
217 /* ignore one-finger touch packet. */ 296 tmp = w8001->data[0] & W8001_TOUCH_BYTE;
218 if (w8001->pktlen == w8001->idx) 297 if (tmp != W8001_TOUCH_BYTE)
298 break;
299
300 if (w8001->pktlen == w8001->idx) {
219 w8001->idx = 0; 301 w8001->idx = 0;
302 if (w8001->type != BTN_TOOL_PEN &&
303 w8001->type != BTN_TOOL_RUBBER) {
304 parse_single_touch(w8001->data, &coord);
305 report_single_touch(w8001, &coord);
306 }
307 }
220 break; 308 break;
221 309
222 /* Pen coordinates packet */ 310 /* Pen coordinates packet */
@@ -225,18 +313,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
225 if (unlikely(tmp == W8001_TAB_BYTE)) 313 if (unlikely(tmp == W8001_TAB_BYTE))
226 break; 314 break;
227 315
228 tmp = (w8001->data[0] & W8001_TOUCH_BYTE); 316 tmp = w8001->data[0] & W8001_TOUCH_BYTE;
229 if (tmp == W8001_TOUCH_BYTE) 317 if (tmp == W8001_TOUCH_BYTE)
230 break; 318 break;
231 319
232 w8001->idx = 0; 320 w8001->idx = 0;
233 parse_data(w8001->data, &coord); 321 parse_pen_data(w8001->data, &coord);
234 report_pen_events(w8001, &coord); 322 report_pen_events(w8001, &coord);
235 break; 323 break;
236 324
237 /* control packet */ 325 /* control packet */
238 case W8001_PKTLEN_TPCCTL - 1: 326 case W8001_PKTLEN_TPCCTL - 1:
239 tmp = (w8001->data[0] & W8001_TOUCH_MASK); 327 tmp = w8001->data[0] & W8001_TOUCH_MASK;
240 if (tmp == W8001_TOUCH_BYTE) 328 if (tmp == W8001_TOUCH_BYTE)
241 break; 329 break;
242 330
@@ -249,7 +337,7 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
249 /* 2 finger touch packet */ 337 /* 2 finger touch packet */
250 case W8001_PKTLEN_TOUCH2FG - 1: 338 case W8001_PKTLEN_TOUCH2FG - 1:
251 w8001->idx = 0; 339 w8001->idx = 0;
252 parse_touch(w8001); 340 parse_multi_touch(w8001);
253 break; 341 break;
254 } 342 }
255 343
@@ -279,6 +367,7 @@ static int w8001_setup(struct w8001 *w8001)
279{ 367{
280 struct input_dev *dev = w8001->dev; 368 struct input_dev *dev = w8001->dev;
281 struct w8001_coord coord; 369 struct w8001_coord coord;
370 struct w8001_touch_query touch;
282 int error; 371 int error;
283 372
284 error = w8001_command(w8001, W8001_CMD_STOP, false); 373 error = w8001_command(w8001, W8001_CMD_STOP, false);
@@ -287,14 +376,21 @@ static int w8001_setup(struct w8001 *w8001)
287 376
288 msleep(250); /* wait 250ms before querying the device */ 377 msleep(250); /* wait 250ms before querying the device */
289 378
379 dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
380 strlcat(w8001->name, "Wacom Serial", sizeof(w8001->name));
381
290 /* penabled? */ 382 /* penabled? */
291 error = w8001_command(w8001, W8001_CMD_QUERY, true); 383 error = w8001_command(w8001, W8001_CMD_QUERY, true);
292 if (!error) { 384 if (!error) {
385 __set_bit(BTN_TOUCH, dev->keybit);
293 __set_bit(BTN_TOOL_PEN, dev->keybit); 386 __set_bit(BTN_TOOL_PEN, dev->keybit);
294 __set_bit(BTN_TOOL_RUBBER, dev->keybit); 387 __set_bit(BTN_TOOL_RUBBER, dev->keybit);
295 __set_bit(BTN_STYLUS, dev->keybit); 388 __set_bit(BTN_STYLUS, dev->keybit);
296 __set_bit(BTN_STYLUS2, dev->keybit); 389 __set_bit(BTN_STYLUS2, dev->keybit);
297 parse_data(w8001->response, &coord); 390
391 parse_pen_data(w8001->response, &coord);
392 w8001->max_pen_x = coord.x;
393 w8001->max_pen_y = coord.y;
298 394
299 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0); 395 input_set_abs_params(dev, ABS_X, 0, coord.x, 0, 0);
300 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0); 396 input_set_abs_params(dev, ABS_Y, 0, coord.y, 0, 0);
@@ -303,6 +399,8 @@ static int w8001_setup(struct w8001 *w8001)
303 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0); 399 input_set_abs_params(dev, ABS_TILT_X, 0, coord.tilt_x, 0, 0);
304 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0); 400 input_set_abs_params(dev, ABS_TILT_Y, 0, coord.tilt_y, 0, 0);
305 } 401 }
402 w8001->id = 0x90;
403 strlcat(w8001->name, " Penabled", sizeof(w8001->name));
306 } 404 }
307 405
308 /* Touch enabled? */ 406 /* Touch enabled? */
@@ -313,24 +411,38 @@ static int w8001_setup(struct w8001 *w8001)
313 * second byte is empty, which indicates touch is not supported. 411 * second byte is empty, which indicates touch is not supported.
314 */ 412 */
315 if (!error && w8001->response[1]) { 413 if (!error && w8001->response[1]) {
316 struct w8001_touch_query touch; 414 __set_bit(BTN_TOUCH, dev->keybit);
415 __set_bit(BTN_TOOL_FINGER, dev->keybit);
317 416
318 parse_touchquery(w8001->response, &touch); 417 parse_touchquery(w8001->response, &touch);
418 w8001->max_touch_x = touch.x;
419 w8001->max_touch_y = touch.y;
420
421 /* scale to pen maximum */
422 if (w8001->max_pen_x && w8001->max_pen_y) {
423 touch.x = w8001->max_pen_x;
424 touch.y = w8001->max_pen_y;
425 }
319 426
320 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0); 427 input_set_abs_params(dev, ABS_X, 0, touch.x, 0, 0);
321 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0); 428 input_set_abs_params(dev, ABS_Y, 0, touch.y, 0, 0);
322 __set_bit(BTN_TOOL_FINGER, dev->keybit);
323 429
324 switch (touch.sensor_id) { 430 switch (touch.sensor_id) {
325 case 0: 431 case 0:
326 case 2: 432 case 2:
327 w8001->pktlen = W8001_PKTLEN_TOUCH93; 433 w8001->pktlen = W8001_PKTLEN_TOUCH93;
434 w8001->id = 0x93;
435 strlcat(w8001->name, " 1FG", sizeof(w8001->name));
328 break; 436 break;
437
329 case 1: 438 case 1:
330 case 3: 439 case 3:
331 case 4: 440 case 4:
332 w8001->pktlen = W8001_PKTLEN_TOUCH9A; 441 w8001->pktlen = W8001_PKTLEN_TOUCH9A;
442 strlcat(w8001->name, " 1FG", sizeof(w8001->name));
443 w8001->id = 0x9a;
333 break; 444 break;
445
334 case 5: 446 case 5:
335 w8001->pktlen = W8001_PKTLEN_TOUCH2FG; 447 w8001->pktlen = W8001_PKTLEN_TOUCH2FG;
336 448
@@ -341,10 +453,18 @@ static int w8001_setup(struct w8001 *w8001)
341 0, touch.y, 0, 0); 453 0, touch.y, 0, 0);
342 input_set_abs_params(dev, ABS_MT_TOOL_TYPE, 454 input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
343 0, MT_TOOL_MAX, 0, 0); 455 0, MT_TOOL_MAX, 0, 0);
456
457 strlcat(w8001->name, " 2FG", sizeof(w8001->name));
458 if (w8001->max_pen_x && w8001->max_pen_y)
459 w8001->id = 0xE3;
460 else
461 w8001->id = 0xE2;
344 break; 462 break;
345 } 463 }
346 } 464 }
347 465
466 strlcat(w8001->name, " Touchscreen", sizeof(w8001->name));
467
348 return w8001_command(w8001, W8001_CMD_START, false); 468 return w8001_command(w8001, W8001_CMD_START, false);
349} 469}
350 470
@@ -384,22 +504,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
384 } 504 }
385 505
386 w8001->serio = serio; 506 w8001->serio = serio;
387 w8001->id = serio->id.id;
388 w8001->dev = input_dev; 507 w8001->dev = input_dev;
389 init_completion(&w8001->cmd_done); 508 init_completion(&w8001->cmd_done);
390 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys); 509 snprintf(w8001->phys, sizeof(w8001->phys), "%s/input0", serio->phys);
391 510
392 input_dev->name = "Wacom W8001 Penabled Serial TouchScreen";
393 input_dev->phys = w8001->phys;
394 input_dev->id.bustype = BUS_RS232;
395 input_dev->id.vendor = SERIO_W8001;
396 input_dev->id.product = w8001->id;
397 input_dev->id.version = 0x0100;
398 input_dev->dev.parent = &serio->dev;
399
400 input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
401 __set_bit(BTN_TOUCH, input_dev->keybit);
402
403 serio_set_drvdata(serio, w8001); 511 serio_set_drvdata(serio, w8001);
404 err = serio_open(serio, drv); 512 err = serio_open(serio, drv);
405 if (err) 513 if (err)
@@ -409,6 +517,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
409 if (err) 517 if (err)
410 goto fail3; 518 goto fail3;
411 519
520 input_dev->name = w8001->name;
521 input_dev->phys = w8001->phys;
522 input_dev->id.product = w8001->id;
523 input_dev->id.bustype = BUS_RS232;
524 input_dev->id.vendor = 0x056a;
525 input_dev->id.version = 0x0100;
526 input_dev->dev.parent = &serio->dev;
527
412 err = input_register_device(w8001->dev); 528 err = input_register_device(w8001->dev);
413 if (err) 529 if (err)
414 goto fail3; 530 goto fail3;
diff --git a/include/linux/input.h b/include/linux/input.h
index c4e9d91ec979..e428382ca28a 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -802,6 +802,7 @@ struct input_keymap_entry {
802#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */ 802#define SW_CAMERA_LENS_COVER 0x09 /* set = lens covered */
803#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ 803#define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */
804#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ 804#define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */
805#define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */
805#define SW_MAX 0x0f 806#define SW_MAX 0x0f
806#define SW_CNT (SW_MAX+1) 807#define SW_CNT (SW_MAX+1)
807 808
diff --git a/include/linux/input/as5011.h b/include/linux/input/as5011.h
new file mode 100644
index 000000000000..1affd0ddfa9d
--- /dev/null
+++ b/include/linux/input/as5011.h
@@ -0,0 +1,20 @@
1#ifndef _AS5011_H
2#define _AS5011_H
3
4/*
5 * Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12struct as5011_platform_data {
13 unsigned int button_gpio;
14 unsigned int axis_irq; /* irq number */
15 unsigned long axis_irqflags;
16 char xp, xn; /* threshold for x axis */
17 char yp, yn; /* threshold for y axis */
18};
19
20#endif /* _AS5011_H */