diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/input.c | 10 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 11 | ||||
-rw-r--r-- | drivers/input/serio/altera_ps2.c | 7 | ||||
-rw-r--r-- | drivers/input/serio/ambakmi.c | 9 | ||||
-rw-r--r-- | drivers/input/serio/at32psif.c | 3 | ||||
-rw-r--r-- | drivers/input/serio/gscps2.c | 6 | ||||
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 8 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 8 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 88 | ||||
-rw-r--r-- | drivers/input/serio/sa1111ps2.c | 10 | ||||
-rw-r--r-- | drivers/input/tablet/wacom.h | 11 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_sys.c | 231 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.c | 368 | ||||
-rw-r--r-- | drivers/input/tablet/wacom_wac.h | 29 |
14 files changed, 558 insertions, 241 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 5c16001959cc..ab060710688f 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -296,9 +296,15 @@ static void input_handle_event(struct input_dev *dev, | |||
296 | * @value: value of the event | 296 | * @value: value of the event |
297 | * | 297 | * |
298 | * This function should be used by drivers implementing various input | 298 | * This function should be used by drivers implementing various input |
299 | * devices. See also input_inject_event(). | 299 | * devices to report input events. See also input_inject_event(). |
300 | * | ||
301 | * NOTE: input_event() may be safely used right after input device was | ||
302 | * allocated with input_allocate_device(), even before it is registered | ||
303 | * with input_register_device(), but the event will not reach any of the | ||
304 | * input handlers. Such early invocation of input_event() may be used | ||
305 | * to 'seed' initial state of a switch or initial position of absolute | ||
306 | * axis, etc. | ||
300 | */ | 307 | */ |
301 | |||
302 | void input_event(struct input_dev *dev, | 308 | void input_event(struct input_dev *dev, |
303 | unsigned int type, unsigned int code, int value) | 309 | unsigned int type, unsigned int code, int value) |
304 | { | 310 | { |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index a3f492a50850..b03e7e0b4099 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -487,6 +487,17 @@ int alps_init(struct psmouse *psmouse) | |||
487 | if (alps_hw_init(psmouse)) | 487 | if (alps_hw_init(psmouse)) |
488 | goto init_fail; | 488 | goto init_fail; |
489 | 489 | ||
490 | /* | ||
491 | * Undo part of setup done for us by psmouse core since touchpad | ||
492 | * is not a relative device. | ||
493 | */ | ||
494 | __clear_bit(EV_REL, dev1->evbit); | ||
495 | __clear_bit(REL_X, dev1->relbit); | ||
496 | __clear_bit(REL_Y, dev1->relbit); | ||
497 | |||
498 | /* | ||
499 | * Now set up our capabilities. | ||
500 | */ | ||
490 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); | 501 | dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); |
491 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); | 502 | dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); |
492 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); | 503 | dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); |
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index f479ea50919f..457da76d4c83 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -79,7 +79,7 @@ static void altera_ps2_close(struct serio *io) | |||
79 | /* | 79 | /* |
80 | * Add one device to this driver. | 80 | * Add one device to this driver. |
81 | */ | 81 | */ |
82 | static int altera_ps2_probe(struct platform_device *pdev) | 82 | static int __devinit altera_ps2_probe(struct platform_device *pdev) |
83 | { | 83 | { |
84 | struct ps2if *ps2if; | 84 | struct ps2if *ps2if; |
85 | struct serio *serio; | 85 | struct serio *serio; |
@@ -155,7 +155,7 @@ static int altera_ps2_probe(struct platform_device *pdev) | |||
155 | /* | 155 | /* |
156 | * Remove one device from this driver. | 156 | * Remove one device from this driver. |
157 | */ | 157 | */ |
158 | static int altera_ps2_remove(struct platform_device *pdev) | 158 | static int __devexit altera_ps2_remove(struct platform_device *pdev) |
159 | { | 159 | { |
160 | struct ps2if *ps2if = platform_get_drvdata(pdev); | 160 | struct ps2if *ps2if = platform_get_drvdata(pdev); |
161 | 161 | ||
@@ -175,9 +175,10 @@ static int altera_ps2_remove(struct platform_device *pdev) | |||
175 | */ | 175 | */ |
176 | static struct platform_driver altera_ps2_driver = { | 176 | static struct platform_driver altera_ps2_driver = { |
177 | .probe = altera_ps2_probe, | 177 | .probe = altera_ps2_probe, |
178 | .remove = altera_ps2_remove, | 178 | .remove = __devexit_p(altera_ps2_remove), |
179 | .driver = { | 179 | .driver = { |
180 | .name = DRV_NAME, | 180 | .name = DRV_NAME, |
181 | .owner = THIS_MODULE, | ||
181 | }, | 182 | }, |
182 | }; | 183 | }; |
183 | 184 | ||
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index 89b394183a75..92563a681d65 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c | |||
@@ -107,7 +107,7 @@ static void amba_kmi_close(struct serio *io) | |||
107 | clk_disable(kmi->clk); | 107 | clk_disable(kmi->clk); |
108 | } | 108 | } |
109 | 109 | ||
110 | static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | 110 | static int __devinit amba_kmi_probe(struct amba_device *dev, struct amba_id *id) |
111 | { | 111 | { |
112 | struct amba_kmi_port *kmi; | 112 | struct amba_kmi_port *kmi; |
113 | struct serio *io; | 113 | struct serio *io; |
@@ -134,7 +134,7 @@ static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | |||
134 | io->port_data = kmi; | 134 | io->port_data = kmi; |
135 | io->dev.parent = &dev->dev; | 135 | io->dev.parent = &dev->dev; |
136 | 136 | ||
137 | kmi->io = io; | 137 | kmi->io = io; |
138 | kmi->base = ioremap(dev->res.start, resource_size(&dev->res)); | 138 | kmi->base = ioremap(dev->res.start, resource_size(&dev->res)); |
139 | if (!kmi->base) { | 139 | if (!kmi->base) { |
140 | ret = -ENOMEM; | 140 | ret = -ENOMEM; |
@@ -162,7 +162,7 @@ static int amba_kmi_probe(struct amba_device *dev, struct amba_id *id) | |||
162 | return ret; | 162 | return ret; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int amba_kmi_remove(struct amba_device *dev) | 165 | static int __devexit amba_kmi_remove(struct amba_device *dev) |
166 | { | 166 | { |
167 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); | 167 | struct amba_kmi_port *kmi = amba_get_drvdata(dev); |
168 | 168 | ||
@@ -197,10 +197,11 @@ static struct amba_id amba_kmi_idtable[] = { | |||
197 | static struct amba_driver ambakmi_driver = { | 197 | static struct amba_driver ambakmi_driver = { |
198 | .drv = { | 198 | .drv = { |
199 | .name = "kmi-pl050", | 199 | .name = "kmi-pl050", |
200 | .owner = THIS_MODULE, | ||
200 | }, | 201 | }, |
201 | .id_table = amba_kmi_idtable, | 202 | .id_table = amba_kmi_idtable, |
202 | .probe = amba_kmi_probe, | 203 | .probe = amba_kmi_probe, |
203 | .remove = amba_kmi_remove, | 204 | .remove = __devexit_p(amba_kmi_remove), |
204 | .resume = amba_kmi_resume, | 205 | .resume = amba_kmi_resume, |
205 | }; | 206 | }; |
206 | 207 | ||
diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index a6fb7a3dcc46..b54452a8c771 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c | |||
@@ -137,7 +137,7 @@ static int psif_write(struct serio *io, unsigned char val) | |||
137 | spin_lock_irqsave(&psif->lock, flags); | 137 | spin_lock_irqsave(&psif->lock, flags); |
138 | 138 | ||
139 | while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) | 139 | while (!(psif_readl(psif, SR) & PSIF_BIT(TXEMPTY)) && timeout--) |
140 | msleep(10); | 140 | udelay(50); |
141 | 141 | ||
142 | if (timeout >= 0) { | 142 | if (timeout >= 0) { |
143 | psif_writel(psif, THR, val); | 143 | psif_writel(psif, THR, val); |
@@ -352,6 +352,7 @@ static struct platform_driver psif_driver = { | |||
352 | .remove = __exit_p(psif_remove), | 352 | .remove = __exit_p(psif_remove), |
353 | .driver = { | 353 | .driver = { |
354 | .name = "atmel_psif", | 354 | .name = "atmel_psif", |
355 | .owner = THIS_MODULE, | ||
355 | }, | 356 | }, |
356 | .suspend = psif_suspend, | 357 | .suspend = psif_suspend, |
357 | .resume = psif_resume, | 358 | .resume = psif_resume, |
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index bd0f92d9f40f..06addfa7cc47 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> | 6 | * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org> |
7 | * | 7 | * |
8 | * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c | 8 | * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c |
9 | * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca> | 9 | * Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca> |
10 | * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org> | 10 | * Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org> |
11 | * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr> | 11 | * Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr> |
12 | * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr> | 12 | * Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr> |
@@ -326,7 +326,7 @@ static void gscps2_close(struct serio *port) | |||
326 | * @return: success/error report | 326 | * @return: success/error report |
327 | */ | 327 | */ |
328 | 328 | ||
329 | static int __init gscps2_probe(struct parisc_device *dev) | 329 | static int __devinit gscps2_probe(struct parisc_device *dev) |
330 | { | 330 | { |
331 | struct gscps2port *ps2port; | 331 | struct gscps2port *ps2port; |
332 | struct serio *serio; | 332 | struct serio *serio; |
@@ -443,7 +443,7 @@ static struct parisc_driver parisc_ps2_driver = { | |||
443 | .name = "gsc_ps2", | 443 | .name = "gsc_ps2", |
444 | .id_table = gscps2_device_tbl, | 444 | .id_table = gscps2_device_tbl, |
445 | .probe = gscps2_probe, | 445 | .probe = gscps2_probe, |
446 | .remove = gscps2_remove, | 446 | .remove = __devexit_p(gscps2_remove), |
447 | }; | 447 | }; |
448 | 448 | ||
449 | static int __init gscps2_init(void) | 449 | static int __init gscps2_init(void) |
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 7ba9f2b2c041..6cd03ebaf5fb 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c | |||
@@ -993,10 +993,8 @@ int hil_mlc_unregister(hil_mlc *mlc) | |||
993 | 993 | ||
994 | static int __init hil_mlc_init(void) | 994 | static int __init hil_mlc_init(void) |
995 | { | 995 | { |
996 | init_timer(&hil_mlcs_kicker); | 996 | setup_timer(&hil_mlcs_kicker, &hil_mlcs_timer, 0); |
997 | hil_mlcs_kicker.expires = jiffies + HZ; | 997 | mod_timer(&hil_mlcs_kicker, jiffies + HZ); |
998 | hil_mlcs_kicker.function = &hil_mlcs_timer; | ||
999 | add_timer(&hil_mlcs_kicker); | ||
1000 | 998 | ||
1001 | tasklet_enable(&hil_mlcs_tasklet); | 999 | tasklet_enable(&hil_mlcs_tasklet); |
1002 | 1000 | ||
@@ -1005,7 +1003,7 @@ static int __init hil_mlc_init(void) | |||
1005 | 1003 | ||
1006 | static void __exit hil_mlc_exit(void) | 1004 | static void __exit hil_mlc_exit(void) |
1007 | { | 1005 | { |
1008 | del_timer(&hil_mlcs_kicker); | 1006 | del_timer_sync(&hil_mlcs_kicker); |
1009 | 1007 | ||
1010 | tasklet_disable(&hil_mlcs_tasklet); | 1008 | tasklet_disable(&hil_mlcs_tasklet); |
1011 | tasklet_kill(&hil_mlcs_tasklet); | 1009 | tasklet_kill(&hil_mlcs_tasklet); |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 7fbffe431bc5..64b688daf48a 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -158,6 +158,14 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
158 | }, | 158 | }, |
159 | }, | 159 | }, |
160 | { | 160 | { |
161 | /* Gigabyte M1022M netbook */ | ||
162 | .matches = { | ||
163 | DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co.,Ltd."), | ||
164 | DMI_MATCH(DMI_BOARD_NAME, "M1022E"), | ||
165 | DMI_MATCH(DMI_BOARD_VERSION, "1.02"), | ||
166 | }, | ||
167 | }, | ||
168 | { | ||
161 | .matches = { | 169 | .matches = { |
162 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 170 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
163 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), | 171 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv9700"), |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 1df02d25aca5..d84a36e545f6 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -126,6 +126,8 @@ static unsigned char i8042_suppress_kbd_ack; | |||
126 | static struct platform_device *i8042_platform_device; | 126 | static struct platform_device *i8042_platform_device; |
127 | 127 | ||
128 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 128 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
129 | static bool (*i8042_platform_filter)(unsigned char data, unsigned char str, | ||
130 | struct serio *serio); | ||
129 | 131 | ||
130 | void i8042_lock_chip(void) | 132 | void i8042_lock_chip(void) |
131 | { | 133 | { |
@@ -139,6 +141,48 @@ void i8042_unlock_chip(void) | |||
139 | } | 141 | } |
140 | EXPORT_SYMBOL(i8042_unlock_chip); | 142 | EXPORT_SYMBOL(i8042_unlock_chip); |
141 | 143 | ||
144 | int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str, | ||
145 | struct serio *serio)) | ||
146 | { | ||
147 | unsigned long flags; | ||
148 | int ret = 0; | ||
149 | |||
150 | spin_lock_irqsave(&i8042_lock, flags); | ||
151 | |||
152 | if (i8042_platform_filter) { | ||
153 | ret = -EBUSY; | ||
154 | goto out; | ||
155 | } | ||
156 | |||
157 | i8042_platform_filter = filter; | ||
158 | |||
159 | out: | ||
160 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
161 | return ret; | ||
162 | } | ||
163 | EXPORT_SYMBOL(i8042_install_filter); | ||
164 | |||
165 | int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str, | ||
166 | struct serio *port)) | ||
167 | { | ||
168 | unsigned long flags; | ||
169 | int ret = 0; | ||
170 | |||
171 | spin_lock_irqsave(&i8042_lock, flags); | ||
172 | |||
173 | if (i8042_platform_filter != filter) { | ||
174 | ret = -EINVAL; | ||
175 | goto out; | ||
176 | } | ||
177 | |||
178 | i8042_platform_filter = NULL; | ||
179 | |||
180 | out: | ||
181 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
182 | return ret; | ||
183 | } | ||
184 | EXPORT_SYMBOL(i8042_remove_filter); | ||
185 | |||
142 | /* | 186 | /* |
143 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to | 187 | * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to |
144 | * be ready for reading values from it / writing values to it. | 188 | * be ready for reading values from it / writing values to it. |
@@ -369,6 +413,31 @@ static void i8042_stop(struct serio *serio) | |||
369 | } | 413 | } |
370 | 414 | ||
371 | /* | 415 | /* |
416 | * i8042_filter() filters out unwanted bytes from the input data stream. | ||
417 | * It is called from i8042_interrupt and thus is running with interrupts | ||
418 | * off and i8042_lock held. | ||
419 | */ | ||
420 | static bool i8042_filter(unsigned char data, unsigned char str, | ||
421 | struct serio *serio) | ||
422 | { | ||
423 | if (unlikely(i8042_suppress_kbd_ack)) { | ||
424 | if ((~str & I8042_STR_AUXDATA) && | ||
425 | (data == 0xfa || data == 0xfe)) { | ||
426 | i8042_suppress_kbd_ack--; | ||
427 | dbg("Extra keyboard ACK - filtered out\n"); | ||
428 | return true; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | if (i8042_platform_filter && i8042_platform_filter(data, str, serio)) { | ||
433 | dbg("Filtered out by platfrom filter\n"); | ||
434 | return true; | ||
435 | } | ||
436 | |||
437 | return false; | ||
438 | } | ||
439 | |||
440 | /* | ||
372 | * i8042_interrupt() is the most important function in this driver - | 441 | * i8042_interrupt() is the most important function in this driver - |
373 | * it handles the interrupts from the i8042, and sends incoming bytes | 442 | * it handles the interrupts from the i8042, and sends incoming bytes |
374 | * to the upper layers. | 443 | * to the upper layers. |
@@ -377,13 +446,16 @@ static void i8042_stop(struct serio *serio) | |||
377 | static irqreturn_t i8042_interrupt(int irq, void *dev_id) | 446 | static irqreturn_t i8042_interrupt(int irq, void *dev_id) |
378 | { | 447 | { |
379 | struct i8042_port *port; | 448 | struct i8042_port *port; |
449 | struct serio *serio; | ||
380 | unsigned long flags; | 450 | unsigned long flags; |
381 | unsigned char str, data; | 451 | unsigned char str, data; |
382 | unsigned int dfl; | 452 | unsigned int dfl; |
383 | unsigned int port_no; | 453 | unsigned int port_no; |
454 | bool filtered; | ||
384 | int ret = 1; | 455 | int ret = 1; |
385 | 456 | ||
386 | spin_lock_irqsave(&i8042_lock, flags); | 457 | spin_lock_irqsave(&i8042_lock, flags); |
458 | |||
387 | str = i8042_read_status(); | 459 | str = i8042_read_status(); |
388 | if (unlikely(~str & I8042_STR_OBF)) { | 460 | if (unlikely(~str & I8042_STR_OBF)) { |
389 | spin_unlock_irqrestore(&i8042_lock, flags); | 461 | spin_unlock_irqrestore(&i8042_lock, flags); |
@@ -391,8 +463,8 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
391 | ret = 0; | 463 | ret = 0; |
392 | goto out; | 464 | goto out; |
393 | } | 465 | } |
466 | |||
394 | data = i8042_read_data(); | 467 | data = i8042_read_data(); |
395 | spin_unlock_irqrestore(&i8042_lock, flags); | ||
396 | 468 | ||
397 | if (i8042_mux_present && (str & I8042_STR_AUXDATA)) { | 469 | if (i8042_mux_present && (str & I8042_STR_AUXDATA)) { |
398 | static unsigned long last_transmit; | 470 | static unsigned long last_transmit; |
@@ -441,21 +513,19 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
441 | } | 513 | } |
442 | 514 | ||
443 | port = &i8042_ports[port_no]; | 515 | port = &i8042_ports[port_no]; |
516 | serio = port->exists ? port->serio : NULL; | ||
444 | 517 | ||
445 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", | 518 | dbg("%02x <- i8042 (interrupt, %d, %d%s%s)", |
446 | data, port_no, irq, | 519 | data, port_no, irq, |
447 | dfl & SERIO_PARITY ? ", bad parity" : "", | 520 | dfl & SERIO_PARITY ? ", bad parity" : "", |
448 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 521 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
449 | 522 | ||
450 | if (unlikely(i8042_suppress_kbd_ack)) | 523 | filtered = i8042_filter(data, str, serio); |
451 | if (port_no == I8042_KBD_PORT_NO && | 524 | |
452 | (data == 0xfa || data == 0xfe)) { | 525 | spin_unlock_irqrestore(&i8042_lock, flags); |
453 | i8042_suppress_kbd_ack--; | ||
454 | goto out; | ||
455 | } | ||
456 | 526 | ||
457 | if (likely(port->exists)) | 527 | if (likely(port->exists && !filtered)) |
458 | serio_interrupt(port->serio, data, dfl); | 528 | serio_interrupt(serio, data, dfl); |
459 | 529 | ||
460 | out: | 530 | out: |
461 | return IRQ_RETVAL(ret); | 531 | return IRQ_RETVAL(ret); |
diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index f412c69478a8..d55874e5d1c2 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c | |||
@@ -180,8 +180,8 @@ static void __devinit ps2_clear_input(struct ps2if *ps2if) | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | static inline unsigned int | 183 | static unsigned int __devinit ps2_test_one(struct ps2if *ps2if, |
184 | ps2_test_one(struct ps2if *ps2if, unsigned int mask) | 184 | unsigned int mask) |
185 | { | 185 | { |
186 | unsigned int val; | 186 | unsigned int val; |
187 | 187 | ||
@@ -197,7 +197,7 @@ ps2_test_one(struct ps2if *ps2if, unsigned int mask) | |||
197 | * Test the keyboard interface. We basically check to make sure that | 197 | * Test the keyboard interface. We basically check to make sure that |
198 | * we can drive each line to the keyboard independently of each other. | 198 | * we can drive each line to the keyboard independently of each other. |
199 | */ | 199 | */ |
200 | static int __init ps2_test(struct ps2if *ps2if) | 200 | static int __devinit ps2_test(struct ps2if *ps2if) |
201 | { | 201 | { |
202 | unsigned int stat; | 202 | unsigned int stat; |
203 | int ret = 0; | 203 | int ret = 0; |
@@ -312,7 +312,7 @@ static int __devinit ps2_probe(struct sa1111_dev *dev) | |||
312 | /* | 312 | /* |
313 | * Remove one device from this driver. | 313 | * Remove one device from this driver. |
314 | */ | 314 | */ |
315 | static int ps2_remove(struct sa1111_dev *dev) | 315 | static int __devexit ps2_remove(struct sa1111_dev *dev) |
316 | { | 316 | { |
317 | struct ps2if *ps2if = sa1111_get_drvdata(dev); | 317 | struct ps2if *ps2if = sa1111_get_drvdata(dev); |
318 | 318 | ||
@@ -335,7 +335,7 @@ static struct sa1111_driver ps2_driver = { | |||
335 | }, | 335 | }, |
336 | .devid = SA1111_DEVID_PS2, | 336 | .devid = SA1111_DEVID_PS2, |
337 | .probe = ps2_probe, | 337 | .probe = ps2_probe, |
338 | .remove = ps2_remove, | 338 | .remove = __devexit_p(ps2_remove), |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static int __init ps2_init(void) | 341 | static int __init ps2_init(void) |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 9114ae1c7488..16310f368dab 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom.h | 2 | * drivers/input/tablet/wacom.h |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support | 4 | * USB Wacom tablet support |
5 | * | 5 | * |
6 | * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> | 6 | * Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz> |
7 | * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> | 7 | * Copyright (c) 2000 Andreas Bach Aaen <abach@stofanet.dk> |
@@ -69,6 +69,9 @@ | |||
69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) | 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) |
70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 | 70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 |
71 | * v1.51 (pc) - Added support for Intuos4 | 71 | * v1.51 (pc) - Added support for Intuos4 |
72 | * v1.52 (pc) - Query Wacom data upon system resume | ||
73 | * - add defines for features->type | ||
74 | * - add new devices (0x9F, 0xE2, and 0XE3) | ||
72 | */ | 75 | */ |
73 | 76 | ||
74 | /* | 77 | /* |
@@ -89,9 +92,9 @@ | |||
89 | /* | 92 | /* |
90 | * Version Information | 93 | * Version Information |
91 | */ | 94 | */ |
92 | #define DRIVER_VERSION "v1.51" | 95 | #define DRIVER_VERSION "v1.52" |
93 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 96 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
94 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 97 | #define DRIVER_DESC "USB Wacom tablet driver" |
95 | #define DRIVER_LICENSE "GPL" | 98 | #define DRIVER_LICENSE "GPL" |
96 | 99 | ||
97 | MODULE_AUTHOR(DRIVER_AUTHOR); | 100 | MODULE_AUTHOR(DRIVER_AUTHOR); |
@@ -133,6 +136,8 @@ extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
133 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 136 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
134 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 137 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
135 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 138 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
139 | extern void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
140 | extern void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
136 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 141 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
137 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 142 | extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
138 | extern __u16 wacom_le16_to_cpu(unsigned char *data); | 143 | extern __u16 wacom_le16_to_cpu(unsigned char *data); |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index ea30c983a33e..072f33b3b2b0 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom_sys.c | 2 | * drivers/input/tablet/wacom_sys.c |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support - system specific code | 4 | * USB Wacom tablet support - system specific code |
5 | */ | 5 | */ |
6 | 6 | ||
7 | /* | 7 | /* |
@@ -209,6 +209,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | | 209 | input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) | |
210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); | 210 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); |
211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 211 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
212 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
212 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); | 213 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); |
213 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); | 214 | input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); |
214 | } | 215 | } |
@@ -256,6 +257,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
256 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | | 257 | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | |
257 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); | 258 | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); |
258 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | | 259 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | |
260 | BIT_MASK(BTN_TOOL_PEN) | BIT_MASK(BTN_STYLUS) | | ||
259 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | | 261 | BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | |
260 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | | 262 | BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | |
261 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); | 263 | BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); |
@@ -269,7 +271,8 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
269 | 271 | ||
270 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 272 | void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
271 | { | 273 | { |
272 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2); | 274 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | |
275 | BIT_MASK(BTN_STYLUS) | BIT_MASK(BTN_STYLUS2); | ||
273 | } | 276 | } |
274 | 277 | ||
275 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 278 | void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
@@ -277,12 +280,32 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
277 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); | 280 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); |
278 | } | 281 | } |
279 | 282 | ||
283 | void input_dev_tpc(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
284 | { | ||
285 | if (wacom_wac->features->device_type == BTN_TOOL_DOUBLETAP || | ||
286 | wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
287 | input_set_abs_params(input_dev, ABS_RX, 0, wacom_wac->features->x_phy, 0, 0); | ||
288 | input_set_abs_params(input_dev, ABS_RY, 0, wacom_wac->features->y_phy, 0, 0); | ||
289 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
290 | } | ||
291 | } | ||
292 | |||
293 | void input_dev_tpc2fg(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
294 | { | ||
295 | if (wacom_wac->features->device_type == BTN_TOOL_TRIPLETAP) { | ||
296 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_TRIPLETAP); | ||
297 | input_dev->evbit[0] |= BIT_MASK(EV_MSC); | ||
298 | input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); | ||
299 | } | ||
300 | } | ||
301 | |||
280 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, | 302 | static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc, |
281 | struct wacom_wac *wacom_wac) | 303 | struct wacom_features *features) |
282 | { | 304 | { |
283 | struct usb_device *dev = interface_to_usbdev(intf); | 305 | struct usb_device *dev = interface_to_usbdev(intf); |
284 | struct wacom_features *features = wacom_wac->features; | 306 | char limit = 0; |
285 | char limit = 0, result = 0; | 307 | /* result has to be defined as int for some devices */ |
308 | int result = 0; | ||
286 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; | 309 | int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; |
287 | unsigned char *report; | 310 | unsigned char *report; |
288 | 311 | ||
@@ -328,13 +351,24 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
328 | case HID_USAGE_X: | 351 | case HID_USAGE_X: |
329 | if (usage == WCM_DESKTOP) { | 352 | if (usage == WCM_DESKTOP) { |
330 | if (finger) { | 353 | if (finger) { |
331 | features->touch_x_max = | 354 | features->device_type = BTN_TOOL_DOUBLETAP; |
332 | features->touch_y_max = | 355 | if (features->type == TABLETPC2FG) { |
333 | wacom_le16_to_cpu(&report[i + 3]); | 356 | /* need to reset back */ |
357 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
358 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
359 | } | ||
334 | features->x_max = | 360 | features->x_max = |
361 | wacom_le16_to_cpu(&report[i + 3]); | ||
362 | features->x_phy = | ||
335 | wacom_le16_to_cpu(&report[i + 6]); | 363 | wacom_le16_to_cpu(&report[i + 6]); |
336 | i += 7; | 364 | features->unit = report[i + 9]; |
365 | features->unitExpo = report[i + 11]; | ||
366 | i += 12; | ||
337 | } else if (pen) { | 367 | } else if (pen) { |
368 | /* penabled only accepts exact bytes of data */ | ||
369 | if (features->type == TABLETPC2FG) | ||
370 | features->pktlen = WACOM_PKGLEN_PENABLED; | ||
371 | features->device_type = BTN_TOOL_PEN; | ||
338 | features->x_max = | 372 | features->x_max = |
339 | wacom_le16_to_cpu(&report[i + 3]); | 373 | wacom_le16_to_cpu(&report[i + 3]); |
340 | i += 4; | 374 | i += 4; |
@@ -350,10 +384,35 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
350 | break; | 384 | break; |
351 | 385 | ||
352 | case HID_USAGE_Y: | 386 | case HID_USAGE_Y: |
353 | if (usage == WCM_DESKTOP) | 387 | if (usage == WCM_DESKTOP) { |
354 | features->y_max = | 388 | if (finger) { |
355 | wacom_le16_to_cpu(&report[i + 3]); | 389 | features->device_type = BTN_TOOL_DOUBLETAP; |
356 | i += 4; | 390 | if (features->type == TABLETPC2FG) { |
391 | /* need to reset back */ | ||
392 | features->pktlen = WACOM_PKGLEN_TPC2FG; | ||
393 | features->device_type = BTN_TOOL_TRIPLETAP; | ||
394 | features->y_max = | ||
395 | wacom_le16_to_cpu(&report[i + 3]); | ||
396 | features->y_phy = | ||
397 | wacom_le16_to_cpu(&report[i + 6]); | ||
398 | i += 7; | ||
399 | } else { | ||
400 | features->y_max = | ||
401 | features->x_max; | ||
402 | features->y_phy = | ||
403 | wacom_le16_to_cpu(&report[i + 3]); | ||
404 | i += 4; | ||
405 | } | ||
406 | } else if (pen) { | ||
407 | /* penabled only accepts exact bytes of data */ | ||
408 | if (features->type == TABLETPC2FG) | ||
409 | features->pktlen = WACOM_PKGLEN_PENABLED; | ||
410 | features->device_type = BTN_TOOL_PEN; | ||
411 | features->y_max = | ||
412 | wacom_le16_to_cpu(&report[i + 3]); | ||
413 | i += 4; | ||
414 | } | ||
415 | } | ||
357 | break; | 416 | break; |
358 | 417 | ||
359 | case HID_USAGE_FINGER: | 418 | case HID_USAGE_FINGER: |
@@ -376,7 +435,7 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
376 | break; | 435 | break; |
377 | 436 | ||
378 | case HID_COLLECTION: | 437 | case HID_COLLECTION: |
379 | /* reset UsagePage ans Finger */ | 438 | /* reset UsagePage and Finger */ |
380 | finger = usage = 0; | 439 | finger = usage = 0; |
381 | break; | 440 | break; |
382 | } | 441 | } |
@@ -388,43 +447,92 @@ static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hi | |||
388 | return result; | 447 | return result; |
389 | } | 448 | } |
390 | 449 | ||
391 | static int wacom_query_tablet_data(struct usb_interface *intf) | 450 | static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_features *features) |
392 | { | 451 | { |
393 | unsigned char *rep_data; | 452 | unsigned char *rep_data; |
394 | int limit = 0; | 453 | int limit = 0, report_id = 2; |
395 | int error; | 454 | int error = -ENOMEM; |
396 | 455 | ||
397 | rep_data = kmalloc(2, GFP_KERNEL); | 456 | rep_data = kmalloc(2, GFP_KERNEL); |
398 | if (!rep_data) | 457 | if (!rep_data) |
399 | return -ENOMEM; | 458 | return error; |
400 | 459 | ||
401 | do { | 460 | /* ask to report tablet data if it is 2FGT or not a Tablet PC */ |
402 | rep_data[0] = 2; | 461 | if (features->device_type == BTN_TOOL_TRIPLETAP) { |
403 | rep_data[1] = 2; | 462 | do { |
404 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | 463 | rep_data[0] = 3; |
405 | 2, rep_data, 2); | 464 | rep_data[1] = 4; |
406 | if (error >= 0) | 465 | report_id = 3; |
407 | error = usb_get_report(intf, | 466 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, |
408 | WAC_HID_FEATURE_REPORT, 2, | 467 | report_id, rep_data, 2); |
409 | rep_data, 2); | 468 | if (error >= 0) |
410 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | 469 | error = usb_get_report(intf, |
470 | WAC_HID_FEATURE_REPORT, report_id, | ||
471 | rep_data, 3); | ||
472 | } while ((error < 0 || rep_data[1] != 4) && limit++ < 5); | ||
473 | } else if (features->type != TABLETPC && features->type != TABLETPC2FG) { | ||
474 | do { | ||
475 | rep_data[0] = 2; | ||
476 | rep_data[1] = 2; | ||
477 | error = usb_set_report(intf, WAC_HID_FEATURE_REPORT, | ||
478 | report_id, rep_data, 2); | ||
479 | if (error >= 0) | ||
480 | error = usb_get_report(intf, | ||
481 | WAC_HID_FEATURE_REPORT, report_id, | ||
482 | rep_data, 2); | ||
483 | } while ((error < 0 || rep_data[1] != 2) && limit++ < 5); | ||
484 | } | ||
411 | 485 | ||
412 | kfree(rep_data); | 486 | kfree(rep_data); |
413 | 487 | ||
414 | return error < 0 ? error : 0; | 488 | return error < 0 ? error : 0; |
415 | } | 489 | } |
416 | 490 | ||
491 | static int wacom_retrieve_hid_descriptor(struct usb_interface *intf, | ||
492 | struct wacom_features *features) | ||
493 | { | ||
494 | int error = 0; | ||
495 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
496 | struct hid_descriptor *hid_desc; | ||
497 | |||
498 | /* default device to penabled */ | ||
499 | features->device_type = BTN_TOOL_PEN; | ||
500 | |||
501 | /* only Tablet PCs need to retrieve the info */ | ||
502 | if ((features->type != TABLETPC) && (features->type != TABLETPC2FG)) | ||
503 | goto out; | ||
504 | |||
505 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
506 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
507 | HID_DEVICET_REPORT, &hid_desc)) { | ||
508 | printk("wacom: can not retrieve extra class descriptor\n"); | ||
509 | error = 1; | ||
510 | goto out; | ||
511 | } | ||
512 | } | ||
513 | error = wacom_parse_hid(intf, hid_desc, features); | ||
514 | if (error) | ||
515 | goto out; | ||
516 | |||
517 | /* touch device found but size is not defined. use default */ | ||
518 | if (features->device_type == BTN_TOOL_DOUBLETAP && !features->x_max) { | ||
519 | features->x_max = 1023; | ||
520 | features->y_max = 1023; | ||
521 | } | ||
522 | |||
523 | out: | ||
524 | return error; | ||
525 | } | ||
526 | |||
417 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) | 527 | static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) |
418 | { | 528 | { |
419 | struct usb_device *dev = interface_to_usbdev(intf); | 529 | struct usb_device *dev = interface_to_usbdev(intf); |
420 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
421 | struct usb_endpoint_descriptor *endpoint; | 530 | struct usb_endpoint_descriptor *endpoint; |
422 | struct wacom *wacom; | 531 | struct wacom *wacom; |
423 | struct wacom_wac *wacom_wac; | 532 | struct wacom_wac *wacom_wac; |
424 | struct wacom_features *features; | 533 | struct wacom_features *features; |
425 | struct input_dev *input_dev; | 534 | struct input_dev *input_dev; |
426 | int error = -ENOMEM; | 535 | int error = -ENOMEM; |
427 | struct hid_descriptor *hid_desc; | ||
428 | 536 | ||
429 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); | 537 | wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL); |
430 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); | 538 | wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL); |
@@ -432,7 +540,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
432 | if (!wacom || !input_dev || !wacom_wac) | 540 | if (!wacom || !input_dev || !wacom_wac) |
433 | goto fail1; | 541 | goto fail1; |
434 | 542 | ||
435 | wacom_wac->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma); | 543 | wacom_wac->data = usb_buffer_alloc(dev, WACOM_PKGLEN_MAX, GFP_KERNEL, &wacom->data_dma); |
436 | if (!wacom_wac->data) | 544 | if (!wacom_wac->data) |
437 | goto fail1; | 545 | goto fail1; |
438 | 546 | ||
@@ -448,7 +556,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
448 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); | 556 | strlcat(wacom->phys, "/input0", sizeof(wacom->phys)); |
449 | 557 | ||
450 | wacom_wac->features = features = get_wacom_feature(id); | 558 | wacom_wac->features = features = get_wacom_feature(id); |
451 | BUG_ON(features->pktlen > 10); | 559 | BUG_ON(features->pktlen > WACOM_PKGLEN_MAX); |
452 | 560 | ||
453 | input_dev->name = wacom_wac->features->name; | 561 | input_dev->name = wacom_wac->features->name; |
454 | wacom->wacom_wac = wacom_wac; | 562 | wacom->wacom_wac = wacom_wac; |
@@ -463,47 +571,24 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
463 | 571 | ||
464 | endpoint = &intf->cur_altsetting->endpoint[0].desc; | 572 | endpoint = &intf->cur_altsetting->endpoint[0].desc; |
465 | 573 | ||
466 | /* Initialize touch_x_max and touch_y_max in case it is not defined */ | 574 | /* Retrieve the physical and logical size for OEM devices */ |
467 | if (wacom_wac->features->type == TABLETPC) { | 575 | error = wacom_retrieve_hid_descriptor(intf, features); |
468 | features->touch_x_max = 1023; | 576 | if (error) |
469 | features->touch_y_max = 1023; | 577 | goto fail2; |
470 | } else { | ||
471 | features->touch_x_max = 0; | ||
472 | features->touch_y_max = 0; | ||
473 | } | ||
474 | |||
475 | /* TabletPC need to retrieve the physical and logical maximum from report descriptor */ | ||
476 | if (wacom_wac->features->type == TABLETPC) { | ||
477 | if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) { | ||
478 | if (usb_get_extra_descriptor(&interface->endpoint[0], | ||
479 | HID_DEVICET_REPORT, &hid_desc)) { | ||
480 | printk("wacom: can not retrive extra class descriptor\n"); | ||
481 | goto fail2; | ||
482 | } | ||
483 | } | ||
484 | error = wacom_parse_hid(intf, hid_desc, wacom_wac); | ||
485 | if (error) | ||
486 | goto fail2; | ||
487 | } | ||
488 | 578 | ||
489 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | 579 | input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); |
490 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | | 580 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOUCH); |
491 | BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); | 581 | |
492 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); | 582 | input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0); |
493 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); | 583 | input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0); |
494 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); | 584 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0); |
495 | if (features->type == TABLETPC) { | ||
496 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP); | ||
497 | input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0); | ||
498 | input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0); | ||
499 | } | ||
500 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); | 585 | input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); |
501 | 586 | ||
502 | wacom_init_input_dev(input_dev, wacom_wac); | 587 | wacom_init_input_dev(input_dev, wacom_wac); |
503 | 588 | ||
504 | usb_fill_int_urb(wacom->irq, dev, | 589 | usb_fill_int_urb(wacom->irq, dev, |
505 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | 590 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), |
506 | wacom_wac->data, wacom_wac->features->pktlen, | 591 | wacom_wac->data, features->pktlen, |
507 | wacom_sys_irq, wacom, endpoint->bInterval); | 592 | wacom_sys_irq, wacom, endpoint->bInterval); |
508 | wacom->irq->transfer_dma = wacom->data_dma; | 593 | wacom->irq->transfer_dma = wacom->data_dma; |
509 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 594 | wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
@@ -512,18 +597,14 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
512 | if (error) | 597 | if (error) |
513 | goto fail3; | 598 | goto fail3; |
514 | 599 | ||
515 | /* | 600 | /* Note that if query fails it is not a hard failure */ |
516 | * Ask the tablet to report tablet data if it is not a Tablet PC. | 601 | wacom_query_tablet_data(intf, features); |
517 | * Note that if query fails it is not a hard failure. | ||
518 | */ | ||
519 | if (wacom_wac->features->type != TABLETPC) | ||
520 | wacom_query_tablet_data(intf); | ||
521 | 602 | ||
522 | usb_set_intfdata(intf, wacom); | 603 | usb_set_intfdata(intf, wacom); |
523 | return 0; | 604 | return 0; |
524 | 605 | ||
525 | fail3: usb_free_urb(wacom->irq); | 606 | fail3: usb_free_urb(wacom->irq); |
526 | fail2: usb_buffer_free(dev, 10, wacom_wac->data, wacom->data_dma); | 607 | fail2: usb_buffer_free(dev, WACOM_PKGLEN_MAX, wacom_wac->data, wacom->data_dma); |
527 | fail1: input_free_device(input_dev); | 608 | fail1: input_free_device(input_dev); |
528 | kfree(wacom); | 609 | kfree(wacom); |
529 | kfree(wacom_wac); | 610 | kfree(wacom_wac); |
@@ -539,7 +620,7 @@ static void wacom_disconnect(struct usb_interface *intf) | |||
539 | usb_kill_urb(wacom->irq); | 620 | usb_kill_urb(wacom->irq); |
540 | input_unregister_device(wacom->dev); | 621 | input_unregister_device(wacom->dev); |
541 | usb_free_urb(wacom->irq); | 622 | usb_free_urb(wacom->irq); |
542 | usb_buffer_free(interface_to_usbdev(intf), 10, | 623 | usb_buffer_free(interface_to_usbdev(intf), WACOM_PKGLEN_MAX, |
543 | wacom->wacom_wac->data, wacom->data_dma); | 624 | wacom->wacom_wac->data, wacom->data_dma); |
544 | kfree(wacom->wacom_wac); | 625 | kfree(wacom->wacom_wac); |
545 | kfree(wacom); | 626 | kfree(wacom); |
@@ -559,12 +640,16 @@ static int wacom_suspend(struct usb_interface *intf, pm_message_t message) | |||
559 | static int wacom_resume(struct usb_interface *intf) | 640 | static int wacom_resume(struct usb_interface *intf) |
560 | { | 641 | { |
561 | struct wacom *wacom = usb_get_intfdata(intf); | 642 | struct wacom *wacom = usb_get_intfdata(intf); |
643 | struct wacom_features *features = wacom->wacom_wac->features; | ||
562 | int rv; | 644 | int rv; |
563 | 645 | ||
564 | mutex_lock(&wacom->lock); | 646 | mutex_lock(&wacom->lock); |
565 | if (wacom->open) | 647 | if (wacom->open) { |
566 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); | 648 | rv = usb_submit_urb(wacom->irq, GFP_NOIO); |
567 | else | 649 | /* switch to wacom mode if needed */ |
650 | if (!wacom_retrieve_hid_descriptor(intf, features)) | ||
651 | wacom_query_tablet_data(intf, features); | ||
652 | } else | ||
568 | rv = 0; | 653 | rv = 0; |
569 | mutex_unlock(&wacom->lock); | 654 | mutex_unlock(&wacom->lock); |
570 | 655 | ||
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c896d6a21b7e..1056f149fe31 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/input/tablet/wacom_wac.c | 2 | * drivers/input/tablet/wacom_wac.c |
3 | * | 3 | * |
4 | * USB Wacom Graphire and Wacom Intuos tablet support - Wacom specific code | 4 | * USB Wacom tablet support - Wacom specific code |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | 7 | ||
@@ -58,16 +58,15 @@ static int wacom_pl_irq(struct wacom_wac *wacom, void *wcombo) | |||
58 | unsigned char *data = wacom->data; | 58 | unsigned char *data = wacom->data; |
59 | int prox, pressure; | 59 | int prox, pressure; |
60 | 60 | ||
61 | if (data[0] != 2) { | 61 | if (data[0] != WACOM_REPORT_PENABLED) { |
62 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); | 62 | dbg("wacom_pl_irq: received unknown report #%d", data[0]); |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
65 | 65 | ||
66 | prox = data[1] & 0x40; | 66 | prox = data[1] & 0x40; |
67 | 67 | ||
68 | wacom->id[0] = ERASER_DEVICE_ID; | ||
69 | if (prox) { | 68 | if (prox) { |
70 | 69 | wacom->id[0] = ERASER_DEVICE_ID; | |
71 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); | 70 | pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1)); |
72 | if (wacom->features->pressure_max > 255) | 71 | if (wacom->features->pressure_max > 255) |
73 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); | 72 | pressure = (pressure << 1) | ((data[4] >> 6) & 1); |
@@ -128,7 +127,7 @@ static int wacom_ptu_irq(struct wacom_wac *wacom, void *wcombo) | |||
128 | { | 127 | { |
129 | unsigned char *data = wacom->data; | 128 | unsigned char *data = wacom->data; |
130 | 129 | ||
131 | if (data[0] != 2) { | 130 | if (data[0] != WACOM_REPORT_PENABLED) { |
132 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); | 131 | printk(KERN_INFO "wacom_ptu_irq: received unknown report #%d\n", data[0]); |
133 | return 0; | 132 | return 0; |
134 | } | 133 | } |
@@ -155,14 +154,16 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
155 | { | 154 | { |
156 | unsigned char *data = wacom->data; | 155 | unsigned char *data = wacom->data; |
157 | int x, y, rw; | 156 | int x, y, rw; |
157 | static int penData = 0; | ||
158 | 158 | ||
159 | if (data[0] != 2) { | 159 | if (data[0] != WACOM_REPORT_PENABLED) { |
160 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); | 160 | dbg("wacom_graphire_irq: received unknown report #%d", data[0]); |
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (data[1] & 0x80) { | 164 | if (data[1] & 0x80) { |
165 | /* in prox and not a pad data */ | 165 | /* in prox and not a pad data */ |
166 | penData = 1; | ||
166 | 167 | ||
167 | switch ((data[1] >> 5) & 3) { | 168 | switch ((data[1] >> 5) & 3) { |
168 | 169 | ||
@@ -232,7 +233,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
232 | switch (wacom->features->type) { | 233 | switch (wacom->features->type) { |
233 | case WACOM_G4: | 234 | case WACOM_G4: |
234 | if (data[7] & 0xf8) { | 235 | if (data[7] & 0xf8) { |
235 | wacom_input_sync(wcombo); /* sync last event */ | 236 | if (penData) { |
237 | wacom_input_sync(wcombo); /* sync last event */ | ||
238 | if (!wacom->id[0]) | ||
239 | penData = 0; | ||
240 | } | ||
236 | wacom->id[1] = PAD_DEVICE_ID; | 241 | wacom->id[1] = PAD_DEVICE_ID; |
237 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 242 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
238 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 243 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
@@ -242,10 +247,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
242 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 247 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
243 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 248 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
244 | } else if (wacom->id[1]) { | 249 | } else if (wacom->id[1]) { |
245 | wacom_input_sync(wcombo); /* sync last event */ | 250 | if (penData) { |
251 | wacom_input_sync(wcombo); /* sync last event */ | ||
252 | if (!wacom->id[0]) | ||
253 | penData = 0; | ||
254 | } | ||
246 | wacom->id[1] = 0; | 255 | wacom->id[1] = 0; |
247 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); | 256 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x40)); |
248 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); | 257 | wacom_report_key(wcombo, BTN_4, (data[7] & 0x80)); |
258 | wacom_report_rel(wcombo, REL_WHEEL, 0); | ||
249 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); | 259 | wacom_report_key(wcombo, BTN_TOOL_FINGER, 0); |
250 | wacom_report_abs(wcombo, ABS_MISC, 0); | 260 | wacom_report_abs(wcombo, ABS_MISC, 0); |
251 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 261 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
@@ -253,7 +263,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
253 | break; | 263 | break; |
254 | case WACOM_MO: | 264 | case WACOM_MO: |
255 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { | 265 | if ((data[7] & 0xf8) || (data[8] & 0xff)) { |
256 | wacom_input_sync(wcombo); /* sync last event */ | 266 | if (penData) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | ||
268 | if (!wacom->id[0]) | ||
269 | penData = 0; | ||
270 | } | ||
257 | wacom->id[1] = PAD_DEVICE_ID; | 271 | wacom->id[1] = PAD_DEVICE_ID; |
258 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 272 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
259 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 273 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -264,7 +278,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
264 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); | 278 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[1]); |
265 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | 279 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); |
266 | } else if (wacom->id[1]) { | 280 | } else if (wacom->id[1]) { |
267 | wacom_input_sync(wcombo); /* sync last event */ | 281 | if (penData) { |
282 | wacom_input_sync(wcombo); /* sync last event */ | ||
283 | if (!wacom->id[0]) | ||
284 | penData = 0; | ||
285 | } | ||
268 | wacom->id[1] = 0; | 286 | wacom->id[1] = 0; |
269 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); | 287 | wacom_report_key(wcombo, BTN_0, (data[7] & 0x08)); |
270 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); | 288 | wacom_report_key(wcombo, BTN_1, (data[7] & 0x20)); |
@@ -432,7 +450,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
432 | unsigned int t; | 450 | unsigned int t; |
433 | int idx = 0, result; | 451 | int idx = 0, result; |
434 | 452 | ||
435 | if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { | 453 | if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_INTUOSREAD |
454 | && data[0] != WACOM_REPORT_INTUOSWRITE && data[0] != WACOM_REPORT_INTUOSPAD) { | ||
436 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); | 455 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); |
437 | return 0; | 456 | return 0; |
438 | } | 457 | } |
@@ -442,7 +461,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
442 | idx = data[1] & 0x01; | 461 | idx = data[1] & 0x01; |
443 | 462 | ||
444 | /* pad packets. Works as a second tool and is always in prox */ | 463 | /* pad packets. Works as a second tool and is always in prox */ |
445 | if (data[0] == 12) { | 464 | if (data[0] == WACOM_REPORT_INTUOSPAD) { |
446 | /* initiate the pad as a device */ | 465 | /* initiate the pad as a device */ |
447 | if (wacom->tool[1] != BTN_TOOL_FINGER) | 466 | if (wacom->tool[1] != BTN_TOOL_FINGER) |
448 | wacom->tool[1] = BTN_TOOL_FINGER; | 467 | wacom->tool[1] = BTN_TOOL_FINGER; |
@@ -608,95 +627,163 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
608 | return 1; | 627 | return 1; |
609 | } | 628 | } |
610 | 629 | ||
630 | |||
631 | static void wacom_tpc_finger_in(struct wacom_wac *wacom, void *wcombo, char *data, int idx) | ||
632 | { | ||
633 | wacom_report_abs(wcombo, ABS_X, | ||
634 | (data[2 + idx * 2] & 0xff) | ((data[3 + idx * 2] & 0x7f) << 8)); | ||
635 | wacom_report_abs(wcombo, ABS_Y, | ||
636 | (data[6 + idx * 2] & 0xff) | ((data[7 + idx * 2] & 0x7f) << 8)); | ||
637 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
638 | wacom_report_key(wcombo, wacom->tool[idx], 1); | ||
639 | if (idx) | ||
640 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
641 | else | ||
642 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
643 | } | ||
644 | |||
645 | static void wacom_tpc_touch_out(struct wacom_wac *wacom, void *wcombo, int idx) | ||
646 | { | ||
647 | wacom_report_abs(wcombo, ABS_X, 0); | ||
648 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
649 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
650 | wacom_report_key(wcombo, wacom->tool[idx], 0); | ||
651 | if (idx) | ||
652 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xf0); | ||
653 | else | ||
654 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
655 | return; | ||
656 | } | ||
657 | |||
658 | static void wacom_tpc_touch_in(struct wacom_wac *wacom, void *wcombo) | ||
659 | { | ||
660 | char *data = wacom->data; | ||
661 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | ||
662 | static int firstFinger = 0; | ||
663 | static int secondFinger = 0; | ||
664 | |||
665 | wacom->tool[0] = BTN_TOOL_DOUBLETAP; | ||
666 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
667 | wacom->tool[1] = BTN_TOOL_TRIPLETAP; | ||
668 | |||
669 | if (urb->actual_length != WACOM_PKGLEN_TPC1FG) { | ||
670 | switch (data[0]) { | ||
671 | case WACOM_REPORT_TPC1FG: | ||
672 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
673 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
674 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
675 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
676 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
677 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
678 | break; | ||
679 | case WACOM_REPORT_TPC2FG: | ||
680 | /* keep this byte to send proper out-prox event */ | ||
681 | wacom->id[1] = data[1] & 0x03; | ||
682 | |||
683 | if (data[1] & 0x01) { | ||
684 | wacom_tpc_finger_in(wacom, wcombo, data, 0); | ||
685 | firstFinger = 1; | ||
686 | } else if (firstFinger) { | ||
687 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
688 | } | ||
689 | |||
690 | if (data[1] & 0x02) { | ||
691 | /* sync first finger data */ | ||
692 | if (firstFinger) | ||
693 | wacom_input_sync(wcombo); | ||
694 | |||
695 | wacom_tpc_finger_in(wacom, wcombo, data, 1); | ||
696 | secondFinger = 1; | ||
697 | } else if (secondFinger) { | ||
698 | /* sync first finger data */ | ||
699 | if (firstFinger) | ||
700 | wacom_input_sync(wcombo); | ||
701 | |||
702 | wacom_tpc_touch_out(wacom, wcombo, 1); | ||
703 | secondFinger = 0; | ||
704 | } | ||
705 | if (!(data[1] & 0x01)) | ||
706 | firstFinger = 0; | ||
707 | break; | ||
708 | } | ||
709 | } else { | ||
710 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
711 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
712 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
713 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
714 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
715 | } | ||
716 | return; | ||
717 | } | ||
718 | |||
611 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | 719 | static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) |
612 | { | 720 | { |
613 | char *data = wacom->data; | 721 | char *data = wacom->data; |
614 | int prox = 0, pressure; | 722 | int prox = 0, pressure, idx = -1; |
615 | static int stylusInProx, touchInProx = 1, touchOut; | 723 | static int stylusInProx, touchInProx = 1, touchOut; |
616 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; | 724 | struct urb *urb = ((struct wacom_combo *)wcombo)->urb; |
617 | 725 | ||
618 | dbg("wacom_tpc_irq: received report #%d", data[0]); | 726 | dbg("wacom_tpc_irq: received report #%d", data[0]); |
619 | 727 | ||
620 | if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */ | 728 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG || /* single touch */ |
621 | if (urb->actual_length == 5) { /* with touch */ | 729 | data[0] == WACOM_REPORT_TPC1FG || /* single touch */ |
622 | prox = data[0] & 0x03; | 730 | data[0] == WACOM_REPORT_TPC2FG) { /* 2FG touch */ |
731 | if (urb->actual_length == WACOM_PKGLEN_TPC1FG) { /* with touch */ | ||
732 | prox = data[0] & 0x01; | ||
623 | } else { /* with capacity */ | 733 | } else { /* with capacity */ |
624 | prox = data[1] & 0x03; | 734 | if (data[0] == WACOM_REPORT_TPC1FG) |
735 | /* single touch */ | ||
736 | prox = data[1] & 0x01; | ||
737 | else | ||
738 | /* 2FG touch data */ | ||
739 | prox = data[1] & 0x03; | ||
625 | } | 740 | } |
626 | 741 | ||
627 | if (!stylusInProx) { /* stylus not in prox */ | 742 | if (!stylusInProx) { /* stylus not in prox */ |
628 | if (prox) { | 743 | if (prox) { |
629 | if (touchInProx) { | 744 | if (touchInProx) { |
630 | wacom->tool[1] = BTN_TOOL_DOUBLETAP; | 745 | wacom_tpc_touch_in(wacom, wcombo); |
631 | wacom->id[0] = TOUCH_DEVICE_ID; | ||
632 | if (urb->actual_length != 5) { | ||
633 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2])); | ||
634 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4])); | ||
635 | wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6])); | ||
636 | wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6])); | ||
637 | } else { | ||
638 | wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1])); | ||
639 | wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3])); | ||
640 | wacom_report_key(wcombo, BTN_TOUCH, 1); | ||
641 | } | ||
642 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
643 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | ||
644 | touchOut = 1; | 746 | touchOut = 1; |
645 | return 1; | 747 | return 1; |
646 | } | 748 | } |
647 | } else { | 749 | } else { |
648 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 750 | /* 2FGT out-prox */ |
649 | wacom_report_key(wcombo, wacom->tool[1], prox & 0x01); | 751 | if (data[0] == WACOM_REPORT_TPC2FG) { |
650 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 752 | idx = (wacom->id[1] & 0x01) - 1; |
753 | if (idx == 0) { | ||
754 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
755 | /* sync first finger event */ | ||
756 | if (wacom->id[1] & 0x02) | ||
757 | wacom_input_sync(wcombo); | ||
758 | } | ||
759 | idx = (wacom->id[1] & 0x02) - 1; | ||
760 | if (idx == 1) | ||
761 | wacom_tpc_touch_out(wacom, wcombo, idx); | ||
762 | } else /* one finger touch */ | ||
763 | wacom_tpc_touch_out(wacom, wcombo, 0); | ||
651 | touchOut = 0; | 764 | touchOut = 0; |
652 | touchInProx = 1; | 765 | touchInProx = 1; |
653 | return 1; | 766 | return 1; |
654 | } | 767 | } |
655 | } else if (touchOut || !prox) { /* force touch out-prox */ | 768 | } else if (touchOut || !prox) { /* force touch out-prox */ |
656 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); | 769 | wacom_tpc_touch_out(wacom, wcombo, 0); |
657 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
658 | wacom_report_key(wcombo, BTN_TOUCH, 0); | ||
659 | touchOut = 0; | 770 | touchOut = 0; |
660 | touchInProx = 1; | 771 | touchInProx = 1; |
661 | return 1; | 772 | return 1; |
662 | } | 773 | } |
663 | } else if (data[0] == 2) { /* Penabled */ | 774 | } else if (data[0] == WACOM_REPORT_PENABLED) { /* Penabled */ |
664 | prox = data[1] & 0x20; | 775 | prox = data[1] & 0x20; |
665 | 776 | ||
666 | touchInProx = 0; | 777 | touchInProx = 0; |
667 | 778 | ||
668 | wacom->id[0] = ERASER_DEVICE_ID; | ||
669 | |||
670 | /* | ||
671 | * if going from out of proximity into proximity select between the eraser | ||
672 | * and the pen based on the state of the stylus2 button, choose eraser if | ||
673 | * pressed else choose pen. if not a proximity change from out to in, send | ||
674 | * an out of proximity for previous tool then a in for new tool. | ||
675 | */ | ||
676 | if (prox) { /* in prox */ | 779 | if (prox) { /* in prox */ |
677 | if (!wacom->tool[0]) { | 780 | if (!wacom->id[0]) { |
678 | /* Going into proximity select tool */ | 781 | /* Going into proximity select tool */ |
679 | wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; | 782 | wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN; |
680 | if (wacom->tool[1] == BTN_TOOL_PEN) | 783 | if (wacom->tool[0] == BTN_TOOL_PEN) |
681 | wacom->id[0] = STYLUS_DEVICE_ID; | 784 | wacom->id[0] = STYLUS_DEVICE_ID; |
682 | } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) { | 785 | else |
683 | /* | 786 | wacom->id[0] = ERASER_DEVICE_ID; |
684 | * was entered with stylus2 pressed | ||
685 | * report out proximity for previous tool | ||
686 | */ | ||
687 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | ||
688 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
689 | wacom_input_sync(wcombo); | ||
690 | |||
691 | /* set new tool */ | ||
692 | wacom->tool[1] = BTN_TOOL_PEN; | ||
693 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
694 | return 0; | ||
695 | } | ||
696 | if (wacom->tool[1] != BTN_TOOL_RUBBER) { | ||
697 | /* Unknown tool selected default to pen tool */ | ||
698 | wacom->tool[1] = BTN_TOOL_PEN; | ||
699 | wacom->id[0] = STYLUS_DEVICE_ID; | ||
700 | } | 787 | } |
701 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 788 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
702 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); | 789 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10); |
@@ -706,17 +793,21 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
706 | if (pressure < 0) | 793 | if (pressure < 0) |
707 | pressure = wacom->features->pressure_max + pressure + 1; | 794 | pressure = wacom->features->pressure_max + pressure + 1; |
708 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); | 795 | wacom_report_abs(wcombo, ABS_PRESSURE, pressure); |
709 | wacom_report_key(wcombo, BTN_TOUCH, pressure); | 796 | wacom_report_key(wcombo, BTN_TOUCH, data[1] & 0x05); |
710 | } else { | 797 | } else { |
798 | wacom_report_abs(wcombo, ABS_X, 0); | ||
799 | wacom_report_abs(wcombo, ABS_Y, 0); | ||
711 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 800 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); |
712 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 801 | wacom_report_key(wcombo, BTN_STYLUS, 0); |
713 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 802 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
714 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 803 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
804 | wacom->id[0] = 0; | ||
805 | /* pen is out so touch can be enabled now */ | ||
806 | touchInProx = 1; | ||
715 | } | 807 | } |
716 | wacom_report_key(wcombo, wacom->tool[1], prox); | 808 | wacom_report_key(wcombo, wacom->tool[0], prox); |
717 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); | 809 | wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]); |
718 | stylusInProx = prox; | 810 | stylusInProx = prox; |
719 | wacom->tool[0] = prox; | ||
720 | return 1; | 811 | return 1; |
721 | } | 812 | } |
722 | return 0; | 813 | return 0; |
@@ -751,6 +842,7 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
751 | return wacom_intuos_irq(wacom_wac, wcombo); | 842 | return wacom_intuos_irq(wacom_wac, wcombo); |
752 | 843 | ||
753 | case TABLETPC: | 844 | case TABLETPC: |
845 | case TABLETPC2FG: | ||
754 | return wacom_tpc_irq(wacom_wac, wcombo); | 846 | return wacom_tpc_irq(wacom_wac, wcombo); |
755 | 847 | ||
756 | default: | 848 | default: |
@@ -791,9 +883,17 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
791 | input_dev_i4s(input_dev, wacom_wac); | 883 | input_dev_i4s(input_dev, wacom_wac); |
792 | input_dev_i(input_dev, wacom_wac); | 884 | input_dev_i(input_dev, wacom_wac); |
793 | break; | 885 | break; |
886 | case TABLETPC2FG: | ||
887 | input_dev_tpc2fg(input_dev, wacom_wac); | ||
888 | /* fall through */ | ||
889 | case TABLETPC: | ||
890 | input_dev_tpc(input_dev, wacom_wac); | ||
891 | if (wacom_wac->features->device_type != BTN_TOOL_PEN) | ||
892 | break; /* no need to process stylus stuff */ | ||
893 | |||
894 | /* fall through */ | ||
794 | case PL: | 895 | case PL: |
795 | case PTU: | 896 | case PTU: |
796 | case TABLETPC: | ||
797 | input_dev_pl(input_dev, wacom_wac); | 897 | input_dev_pl(input_dev, wacom_wac); |
798 | /* fall through */ | 898 | /* fall through */ |
799 | case PENPARTNER: | 899 | case PENPARTNER: |
@@ -804,66 +904,69 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
804 | } | 904 | } |
805 | 905 | ||
806 | static struct wacom_features wacom_features[] = { | 906 | static struct wacom_features wacom_features[] = { |
807 | { "Wacom Penpartner", 7, 5040, 3780, 255, 0, PENPARTNER }, | 907 | { "Wacom Penpartner", WACOM_PKGLEN_PENPRTN, 5040, 3780, 255, 0, PENPARTNER }, |
808 | { "Wacom Graphire", 8, 10206, 7422, 511, 63, GRAPHIRE }, | 908 | { "Wacom Graphire", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, |
809 | { "Wacom Graphire2 4x5", 8, 10206, 7422, 511, 63, GRAPHIRE }, | 909 | { "Wacom Graphire2 4x5", WACOM_PKGLEN_GRAPHIRE, 10206, 7422, 511, 63, GRAPHIRE }, |
810 | { "Wacom Graphire2 5x7", 8, 13918, 10206, 511, 63, GRAPHIRE }, | 910 | { "Wacom Graphire2 5x7", WACOM_PKGLEN_GRAPHIRE, 13918, 10206, 511, 63, GRAPHIRE }, |
811 | { "Wacom Graphire3", 8, 10208, 7424, 511, 63, GRAPHIRE }, | 911 | { "Wacom Graphire3", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, GRAPHIRE }, |
812 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, | 912 | { "Wacom Graphire3 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, |
813 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, | 913 | { "Wacom Graphire4 4x5", WACOM_PKGLEN_GRAPHIRE, 10208, 7424, 511, 63, WACOM_G4 }, |
814 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 914 | { "Wacom Graphire4 6x8", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, WACOM_G4 }, |
815 | { "Wacom BambooFun 4x5", 9, 14760, 9225, 511, 63, WACOM_MO }, | 915 | { "Wacom BambooFun 4x5", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, |
816 | { "Wacom BambooFun 6x8", 9, 21648, 13530, 511, 63, WACOM_MO }, | 916 | { "Wacom BambooFun 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 511, 63, WACOM_MO }, |
817 | { "Wacom Bamboo1 Medium",8, 16704, 12064, 511, 63, GRAPHIRE }, | 917 | { "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE, 16704, 12064, 511, 63, GRAPHIRE }, |
818 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 918 | { "Wacom Volito", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, |
819 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, | 919 | { "Wacom PenStation2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 255, 63, GRAPHIRE }, |
820 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 920 | { "Wacom Volito2 4x5", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, |
821 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, | 921 | { "Wacom Volito2 2x3", WACOM_PKGLEN_GRAPHIRE, 3248, 2320, 511, 63, GRAPHIRE }, |
822 | { "Wacom PenPartner2", 8, 3250, 2320, 511, 63, GRAPHIRE }, | 922 | { "Wacom PenPartner2", WACOM_PKGLEN_GRAPHIRE, 3250, 2320, 511, 63, GRAPHIRE }, |
823 | { "Wacom Bamboo", 9, 14760, 9225, 511, 63, WACOM_MO }, | 923 | { "Wacom Bamboo", WACOM_PKGLEN_BBFUN, 14760, 9225, 511, 63, WACOM_MO }, |
824 | { "Wacom Bamboo1", 8, 5104, 3712, 511, 63, GRAPHIRE }, | 924 | { "Wacom Bamboo1", WACOM_PKGLEN_GRAPHIRE, 5104, 3712, 511, 63, GRAPHIRE }, |
825 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 925 | { "Wacom Intuos 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, |
826 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 926 | { "Wacom Intuos 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, |
827 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, | 927 | { "Wacom Intuos 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, |
828 | { "Wacom Intuos 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, | 928 | { "Wacom Intuos 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, |
829 | { "Wacom Intuos 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, | 929 | { "Wacom Intuos 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, |
830 | { "Wacom PL400", 8, 5408, 4056, 255, 0, PL }, | 930 | { "Wacom PL400", WACOM_PKGLEN_GRAPHIRE, 5408, 4056, 255, 0, PL }, |
831 | { "Wacom PL500", 8, 6144, 4608, 255, 0, PL }, | 931 | { "Wacom PL500", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 255, 0, PL }, |
832 | { "Wacom PL600", 8, 6126, 4604, 255, 0, PL }, | 932 | { "Wacom PL600", WACOM_PKGLEN_GRAPHIRE, 6126, 4604, 255, 0, PL }, |
833 | { "Wacom PL600SX", 8, 6260, 5016, 255, 0, PL }, | 933 | { "Wacom PL600SX", WACOM_PKGLEN_GRAPHIRE, 6260, 5016, 255, 0, PL }, |
834 | { "Wacom PL550", 8, 6144, 4608, 511, 0, PL }, | 934 | { "Wacom PL550", WACOM_PKGLEN_GRAPHIRE, 6144, 4608, 511, 0, PL }, |
835 | { "Wacom PL800", 8, 7220, 5780, 511, 0, PL }, | 935 | { "Wacom PL800", WACOM_PKGLEN_GRAPHIRE, 7220, 5780, 511, 0, PL }, |
836 | { "Wacom PL700", 8, 6758, 5406, 511, 0, PL }, | 936 | { "Wacom PL700", WACOM_PKGLEN_GRAPHIRE, 6758, 5406, 511, 0, PL }, |
837 | { "Wacom PL510", 8, 6282, 4762, 511, 0, PL }, | 937 | { "Wacom PL510", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, |
838 | { "Wacom DTU710", 8, 34080, 27660, 511, 0, PL }, | 938 | { "Wacom DTU710", WACOM_PKGLEN_GRAPHIRE, 34080, 27660, 511, 0, PL }, |
839 | { "Wacom DTF521", 8, 6282, 4762, 511, 0, PL }, | 939 | { "Wacom DTF521", WACOM_PKGLEN_GRAPHIRE, 6282, 4762, 511, 0, PL }, |
840 | { "Wacom DTF720", 8, 6858, 5506, 511, 0, PL }, | 940 | { "Wacom DTF720", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, |
841 | { "Wacom DTF720a", 8, 6858, 5506, 511, 0, PL }, | 941 | { "Wacom DTF720a", WACOM_PKGLEN_GRAPHIRE, 6858, 5506, 511, 0, PL }, |
842 | { "Wacom Cintiq Partner",8, 20480, 15360, 511, 0, PTU }, | 942 | { "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE, 20480, 15360, 511, 0, PTU }, |
843 | { "Wacom Intuos2 4x5", 10, 12700, 10600, 1023, 31, INTUOS }, | 943 | { "Wacom Intuos2 4x5", WACOM_PKGLEN_INTUOS, 12700, 10600, 1023, 31, INTUOS }, |
844 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 944 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, |
845 | { "Wacom Intuos2 9x12", 10, 30480, 24060, 1023, 31, INTUOS }, | 945 | { "Wacom Intuos2 9x12", WACOM_PKGLEN_INTUOS, 30480, 24060, 1023, 31, INTUOS }, |
846 | { "Wacom Intuos2 12x12", 10, 30480, 31680, 1023, 31, INTUOS }, | 946 | { "Wacom Intuos2 12x12", WACOM_PKGLEN_INTUOS, 30480, 31680, 1023, 31, INTUOS }, |
847 | { "Wacom Intuos2 12x18", 10, 45720, 31680, 1023, 31, INTUOS }, | 947 | { "Wacom Intuos2 12x18", WACOM_PKGLEN_INTUOS, 45720, 31680, 1023, 31, INTUOS }, |
848 | { "Wacom Intuos3 4x5", 10, 25400, 20320, 1023, 63, INTUOS3S }, | 948 | { "Wacom Intuos3 4x5", WACOM_PKGLEN_INTUOS, 25400, 20320, 1023, 63, INTUOS3S }, |
849 | { "Wacom Intuos3 6x8", 10, 40640, 30480, 1023, 63, INTUOS3 }, | 949 | { "Wacom Intuos3 6x8", WACOM_PKGLEN_INTUOS, 40640, 30480, 1023, 63, INTUOS3 }, |
850 | { "Wacom Intuos3 9x12", 10, 60960, 45720, 1023, 63, INTUOS3 }, | 950 | { "Wacom Intuos3 9x12", WACOM_PKGLEN_INTUOS, 60960, 45720, 1023, 63, INTUOS3 }, |
851 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, | 951 | { "Wacom Intuos3 12x12", WACOM_PKGLEN_INTUOS, 60960, 60960, 1023, 63, INTUOS3L }, |
852 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, | 952 | { "Wacom Intuos3 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 1023, 63, INTUOS3L }, |
853 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 953 | { "Wacom Intuos3 6x11", WACOM_PKGLEN_INTUOS, 54204, 31750, 1023, 63, INTUOS3 }, |
854 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, | 954 | { "Wacom Intuos3 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 1023, 63, INTUOS3S }, |
855 | { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, | 955 | { "Wacom Intuos4 4x6", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, 63, INTUOS4S }, |
856 | { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, | 956 | { "Wacom Intuos4 6x9", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, 63, INTUOS4 }, |
857 | { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, | 957 | { "Wacom Intuos4 8x13", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, 63, INTUOS4L }, |
858 | { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, | 958 | { "Wacom Intuos4 12x19", WACOM_PKGLEN_INTUOS, 97536, 60960, 2047, 63, INTUOS4L }, |
859 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 959 | { "Wacom Cintiq 21UX", WACOM_PKGLEN_INTUOS, 87200, 65600, 1023, 63, CINTIQ }, |
860 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, | 960 | { "Wacom Cintiq 20WSX", WACOM_PKGLEN_INTUOS, 86680, 54180, 1023, 63, WACOM_BEE }, |
861 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, | 961 | { "Wacom Cintiq 12WX", WACOM_PKGLEN_INTUOS, 53020, 33440, 1023, 63, WACOM_BEE }, |
862 | { "Wacom DTU1931", 8, 37832, 30305, 511, 0, PL }, | 962 | { "Wacom DTU1931", WACOM_PKGLEN_GRAPHIRE, 37832, 30305, 511, 0, PL }, |
863 | { "Wacom ISDv4 90", 8, 26202, 16325, 255, 0, TABLETPC }, | 963 | { "Wacom ISDv4 90", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
864 | { "Wacom ISDv4 93", 8, 26202, 16325, 255, 0, TABLETPC }, | 964 | { "Wacom ISDv4 93", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
865 | { "Wacom ISDv4 9A", 8, 26202, 16325, 255, 0, TABLETPC }, | 965 | { "Wacom ISDv4 9A", WACOM_PKGLEN_GRAPHIRE, 26202, 16325, 255, 0, TABLETPC }, |
866 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 31, INTUOS }, | 966 | { "Wacom ISDv4 9F", WACOM_PKGLEN_PENABLED, 26202, 16325, 255, 0, TABLETPC }, |
967 | { "Wacom ISDv4 E2", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
968 | { "Wacom ISDv4 E3", WACOM_PKGLEN_TPC2FG, 26202, 16325, 255, 0, TABLETPC2FG }, | ||
969 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, 31, INTUOS }, | ||
867 | { } | 970 | { } |
868 | }; | 971 | }; |
869 | 972 | ||
@@ -927,6 +1030,9 @@ static struct usb_device_id wacom_ids[] = { | |||
927 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, | 1030 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) }, |
928 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, | 1031 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) }, |
929 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, | 1032 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) }, |
1033 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9F) }, | ||
1034 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE2) }, | ||
1035 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xE3) }, | ||
930 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, | 1036 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) }, |
931 | { } | 1037 | { } |
932 | }; | 1038 | }; |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index c10235aba7e5..ee01e1902785 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -9,12 +9,33 @@ | |||
9 | #ifndef WACOM_WAC_H | 9 | #ifndef WACOM_WAC_H |
10 | #define WACOM_WAC_H | 10 | #define WACOM_WAC_H |
11 | 11 | ||
12 | /* maximum packet length for USB devices */ | ||
13 | #define WACOM_PKGLEN_MAX 32 | ||
14 | |||
15 | /* packet length for individual models */ | ||
16 | #define WACOM_PKGLEN_PENPRTN 7 | ||
17 | #define WACOM_PKGLEN_GRAPHIRE 8 | ||
18 | #define WACOM_PKGLEN_BBFUN 9 | ||
19 | #define WACOM_PKGLEN_INTUOS 10 | ||
20 | #define WACOM_PKGLEN_PENABLED 8 | ||
21 | #define WACOM_PKGLEN_TPC1FG 5 | ||
22 | #define WACOM_PKGLEN_TPC2FG 14 | ||
23 | |||
24 | /* device IDs */ | ||
12 | #define STYLUS_DEVICE_ID 0x02 | 25 | #define STYLUS_DEVICE_ID 0x02 |
13 | #define TOUCH_DEVICE_ID 0x03 | 26 | #define TOUCH_DEVICE_ID 0x03 |
14 | #define CURSOR_DEVICE_ID 0x06 | 27 | #define CURSOR_DEVICE_ID 0x06 |
15 | #define ERASER_DEVICE_ID 0x0A | 28 | #define ERASER_DEVICE_ID 0x0A |
16 | #define PAD_DEVICE_ID 0x0F | 29 | #define PAD_DEVICE_ID 0x0F |
17 | 30 | ||
31 | /* wacom data packet report IDs */ | ||
32 | #define WACOM_REPORT_PENABLED 2 | ||
33 | #define WACOM_REPORT_INTUOSREAD 5 | ||
34 | #define WACOM_REPORT_INTUOSWRITE 6 | ||
35 | #define WACOM_REPORT_INTUOSPAD 12 | ||
36 | #define WACOM_REPORT_TPC1FG 6 | ||
37 | #define WACOM_REPORT_TPC2FG 13 | ||
38 | |||
18 | enum { | 39 | enum { |
19 | PENPARTNER = 0, | 40 | PENPARTNER = 0, |
20 | GRAPHIRE, | 41 | GRAPHIRE, |
@@ -32,6 +53,7 @@ enum { | |||
32 | WACOM_BEE, | 53 | WACOM_BEE, |
33 | WACOM_MO, | 54 | WACOM_MO, |
34 | TABLETPC, | 55 | TABLETPC, |
56 | TABLETPC2FG, | ||
35 | MAX_TYPE | 57 | MAX_TYPE |
36 | }; | 58 | }; |
37 | 59 | ||
@@ -43,8 +65,11 @@ struct wacom_features { | |||
43 | int pressure_max; | 65 | int pressure_max; |
44 | int distance_max; | 66 | int distance_max; |
45 | int type; | 67 | int type; |
46 | int touch_x_max; | 68 | int device_type; |
47 | int touch_y_max; | 69 | int x_phy; |
70 | int y_phy; | ||
71 | unsigned char unit; | ||
72 | unsigned char unitExpo; | ||
48 | }; | 73 | }; |
49 | 74 | ||
50 | struct wacom_wac { | 75 | struct wacom_wac { |