diff options
Diffstat (limited to 'drivers/input')
48 files changed, 1799 insertions, 259 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 38b523a1ece0..a11ff74a5127 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig | |||
@@ -80,7 +80,7 @@ config INPUT_MATRIXKMAP | |||
80 | comment "Userland interfaces" | 80 | comment "Userland interfaces" |
81 | 81 | ||
82 | config INPUT_MOUSEDEV | 82 | config INPUT_MOUSEDEV |
83 | tristate "Mouse interface" if EXPERT | 83 | tristate "Mouse interface" |
84 | default y | 84 | default y |
85 | help | 85 | help |
86 | Say Y here if you want your mouse to be accessible as char devices | 86 | Say Y here if you want your mouse to be accessible as char devices |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index b6ded17b3be3..a06e12552886 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/poll.h> | 18 | #include <linux/poll.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/vmalloc.h> | ||
22 | #include <linux/mm.h> | ||
21 | #include <linux/module.h> | 23 | #include <linux/module.h> |
22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
23 | #include <linux/input/mt.h> | 25 | #include <linux/input/mt.h> |
@@ -369,7 +371,11 @@ static int evdev_release(struct inode *inode, struct file *file) | |||
369 | mutex_unlock(&evdev->mutex); | 371 | mutex_unlock(&evdev->mutex); |
370 | 372 | ||
371 | evdev_detach_client(evdev, client); | 373 | evdev_detach_client(evdev, client); |
372 | kfree(client); | 374 | |
375 | if (is_vmalloc_addr(client)) | ||
376 | vfree(client); | ||
377 | else | ||
378 | kfree(client); | ||
373 | 379 | ||
374 | evdev_close_device(evdev); | 380 | evdev_close_device(evdev); |
375 | 381 | ||
@@ -389,12 +395,14 @@ static int evdev_open(struct inode *inode, struct file *file) | |||
389 | { | 395 | { |
390 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); | 396 | struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev); |
391 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); | 397 | unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev); |
398 | unsigned int size = sizeof(struct evdev_client) + | ||
399 | bufsize * sizeof(struct input_event); | ||
392 | struct evdev_client *client; | 400 | struct evdev_client *client; |
393 | int error; | 401 | int error; |
394 | 402 | ||
395 | client = kzalloc(sizeof(struct evdev_client) + | 403 | client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN); |
396 | bufsize * sizeof(struct input_event), | 404 | if (!client) |
397 | GFP_KERNEL); | 405 | client = vzalloc(size); |
398 | if (!client) | 406 | if (!client) |
399 | return -ENOMEM; | 407 | return -ENOMEM; |
400 | 408 | ||
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index da739d9d1905..922a7fea2ce6 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -639,16 +639,18 @@ EXPORT_SYMBOL(gameport_unregister_port); | |||
639 | * Gameport driver operations | 639 | * Gameport driver operations |
640 | */ | 640 | */ |
641 | 641 | ||
642 | static ssize_t gameport_driver_show_description(struct device_driver *drv, char *buf) | 642 | static ssize_t description_show(struct device_driver *drv, char *buf) |
643 | { | 643 | { |
644 | struct gameport_driver *driver = to_gameport_driver(drv); | 644 | struct gameport_driver *driver = to_gameport_driver(drv); |
645 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); | 645 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); |
646 | } | 646 | } |
647 | static DRIVER_ATTR_RO(description); | ||
647 | 648 | ||
648 | static struct driver_attribute gameport_driver_attrs[] = { | 649 | static struct attribute *gameport_driver_attrs[] = { |
649 | __ATTR(description, S_IRUGO, gameport_driver_show_description, NULL), | 650 | &driver_attr_description.attr, |
650 | __ATTR_NULL | 651 | NULL |
651 | }; | 652 | }; |
653 | ATTRIBUTE_GROUPS(gameport_driver); | ||
652 | 654 | ||
653 | static int gameport_driver_probe(struct device *dev) | 655 | static int gameport_driver_probe(struct device *dev) |
654 | { | 656 | { |
@@ -749,7 +751,7 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv) | |||
749 | static struct bus_type gameport_bus = { | 751 | static struct bus_type gameport_bus = { |
750 | .name = "gameport", | 752 | .name = "gameport", |
751 | .dev_attrs = gameport_device_attrs, | 753 | .dev_attrs = gameport_device_attrs, |
752 | .drv_attrs = gameport_driver_attrs, | 754 | .drv_groups = gameport_driver_groups, |
753 | .match = gameport_bus_match, | 755 | .match = gameport_bus_match, |
754 | .probe = gameport_driver_probe, | 756 | .probe = gameport_driver_probe, |
755 | .remove = gameport_driver_remove, | 757 | .remove = gameport_driver_remove, |
diff --git a/drivers/input/input.c b/drivers/input/input.c index e75d015024a1..846ccdd905b1 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -2052,7 +2052,7 @@ int input_register_device(struct input_dev *dev) | |||
2052 | if (dev->hint_events_per_packet < packet_size) | 2052 | if (dev->hint_events_per_packet < packet_size) |
2053 | dev->hint_events_per_packet = packet_size; | 2053 | dev->hint_events_per_packet = packet_size; |
2054 | 2054 | ||
2055 | dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2; | 2055 | dev->max_vals = dev->hint_events_per_packet + 2; |
2056 | dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); | 2056 | dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); |
2057 | if (!dev->vals) { | 2057 | if (!dev->vals) { |
2058 | error = -ENOMEM; | 2058 | error = -ENOMEM; |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 269d4c3658cb..bb174c1a9886 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # Input core configuration | 2 | # Input core configuration |
3 | # | 3 | # |
4 | menuconfig INPUT_KEYBOARD | 4 | menuconfig INPUT_KEYBOARD |
5 | bool "Keyboards" if EXPERT || !X86 | 5 | bool "Keyboards" |
6 | default y | 6 | default y |
7 | help | 7 | help |
8 | Say Y here, and a list of supported keyboards will be displayed. | 8 | Say Y here, and a list of supported keyboards will be displayed. |
@@ -67,7 +67,7 @@ config KEYBOARD_ATARI | |||
67 | module will be called atakbd. | 67 | module will be called atakbd. |
68 | 68 | ||
69 | config KEYBOARD_ATKBD | 69 | config KEYBOARD_ATKBD |
70 | tristate "AT keyboard" if EXPERT || !X86 | 70 | tristate "AT keyboard" |
71 | default y | 71 | default y |
72 | select SERIO | 72 | select SERIO |
73 | select SERIO_LIBPS2 | 73 | select SERIO_LIBPS2 |
@@ -224,7 +224,7 @@ config KEYBOARD_TCA6416 | |||
224 | 224 | ||
225 | config KEYBOARD_TCA8418 | 225 | config KEYBOARD_TCA8418 |
226 | tristate "TCA8418 Keypad Support" | 226 | tristate "TCA8418 Keypad Support" |
227 | depends on I2C && GENERIC_HARDIRQS | 227 | depends on I2C |
228 | select INPUT_MATRIXKMAP | 228 | select INPUT_MATRIXKMAP |
229 | help | 229 | help |
230 | This driver implements basic keypad functionality | 230 | This driver implements basic keypad functionality |
@@ -303,7 +303,7 @@ config KEYBOARD_HP7XX | |||
303 | 303 | ||
304 | config KEYBOARD_LM8323 | 304 | config KEYBOARD_LM8323 |
305 | tristate "LM8323 keypad chip" | 305 | tristate "LM8323 keypad chip" |
306 | depends on I2C && GENERIC_HARDIRQS | 306 | depends on I2C |
307 | depends on LEDS_CLASS | 307 | depends on LEDS_CLASS |
308 | help | 308 | help |
309 | If you say yes here you get support for the National Semiconductor | 309 | If you say yes here you get support for the National Semiconductor |
@@ -525,7 +525,7 @@ config KEYBOARD_SUNKBD | |||
525 | 525 | ||
526 | config KEYBOARD_SH_KEYSC | 526 | config KEYBOARD_SH_KEYSC |
527 | tristate "SuperH KEYSC keypad support" | 527 | tristate "SuperH KEYSC keypad support" |
528 | depends on SUPERH || ARCH_SHMOBILE | 528 | depends on SUPERH || ARM || COMPILE_TEST |
529 | help | 529 | help |
530 | Say Y here if you want to use a keypad attached to the KEYSC block | 530 | Say Y here if you want to use a keypad attached to the KEYSC block |
531 | on SuperH processors such as sh7722 and sh7343. | 531 | on SuperH processors such as sh7722 and sh7343. |
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 49557f27bfa6..7e8b0a52af25 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c | |||
@@ -206,33 +206,6 @@ static int cros_ec_keyb_work(struct notifier_block *nb, | |||
206 | return NOTIFY_DONE; | 206 | return NOTIFY_DONE; |
207 | } | 207 | } |
208 | 208 | ||
209 | /* Clear any keys in the buffer */ | ||
210 | static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) | ||
211 | { | ||
212 | uint8_t old_state[ckdev->cols]; | ||
213 | uint8_t new_state[ckdev->cols]; | ||
214 | unsigned long duration; | ||
215 | int i, ret; | ||
216 | |||
217 | /* | ||
218 | * Keep reading until we see that the scan state does not change. | ||
219 | * That indicates that we are done. | ||
220 | * | ||
221 | * Assume that the EC keyscan buffer is at most 32 deep. | ||
222 | */ | ||
223 | duration = jiffies; | ||
224 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
225 | for (i = 1; !ret && i < 32; i++) { | ||
226 | memcpy(old_state, new_state, sizeof(old_state)); | ||
227 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
228 | if (0 == memcmp(old_state, new_state, sizeof(old_state))) | ||
229 | break; | ||
230 | } | ||
231 | duration = jiffies - duration; | ||
232 | dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, | ||
233 | jiffies_to_usecs(duration)); | ||
234 | } | ||
235 | |||
236 | static int cros_ec_keyb_probe(struct platform_device *pdev) | 209 | static int cros_ec_keyb_probe(struct platform_device *pdev) |
237 | { | 210 | { |
238 | struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); | 211 | struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); |
@@ -299,6 +272,33 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) | |||
299 | } | 272 | } |
300 | 273 | ||
301 | #ifdef CONFIG_PM_SLEEP | 274 | #ifdef CONFIG_PM_SLEEP |
275 | /* Clear any keys in the buffer */ | ||
276 | static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) | ||
277 | { | ||
278 | uint8_t old_state[ckdev->cols]; | ||
279 | uint8_t new_state[ckdev->cols]; | ||
280 | unsigned long duration; | ||
281 | int i, ret; | ||
282 | |||
283 | /* | ||
284 | * Keep reading until we see that the scan state does not change. | ||
285 | * That indicates that we are done. | ||
286 | * | ||
287 | * Assume that the EC keyscan buffer is at most 32 deep. | ||
288 | */ | ||
289 | duration = jiffies; | ||
290 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
291 | for (i = 1; !ret && i < 32; i++) { | ||
292 | memcpy(old_state, new_state, sizeof(old_state)); | ||
293 | ret = cros_ec_keyb_get_state(ckdev, new_state); | ||
294 | if (0 == memcmp(old_state, new_state, sizeof(old_state))) | ||
295 | break; | ||
296 | } | ||
297 | duration = jiffies - duration; | ||
298 | dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, | ||
299 | jiffies_to_usecs(duration)); | ||
300 | } | ||
301 | |||
302 | static int cros_ec_keyb_resume(struct device *dev) | 302 | static int cros_ec_keyb_resume(struct device *dev) |
303 | { | 303 | { |
304 | struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); | 304 | struct cros_ec_keyb *ckdev = dev_get_drvdata(dev); |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 440ce32462ba..2db13246eb8e 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/gpio_keys.h> | 26 | #include <linux/gpio_keys.h> |
27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | #include <linux/of.h> | ||
29 | #include <linux/of_platform.h> | 30 | #include <linux/of_platform.h> |
30 | #include <linux/of_gpio.h> | 31 | #include <linux/of_gpio.h> |
31 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index cd5ed9e22168..4e428199e580 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
27 | #include <linux/gpio_keys.h> | 27 | #include <linux/gpio_keys.h> |
28 | #include <linux/of.h> | ||
28 | #include <linux/of_platform.h> | 29 | #include <linux/of_platform.h> |
29 | #include <linux/of_gpio.h> | 30 | #include <linux/of_gpio.h> |
30 | 31 | ||
diff --git a/drivers/input/keyboard/lpc32xx-keys.c b/drivers/input/keyboard/lpc32xx-keys.c index 42181435fe67..8b1b01361ec6 100644 --- a/drivers/input/keyboard/lpc32xx-keys.c +++ b/drivers/input/keyboard/lpc32xx-keys.c | |||
@@ -383,7 +383,7 @@ static struct platform_driver lpc32xx_kscan_driver = { | |||
383 | .name = DRV_NAME, | 383 | .name = DRV_NAME, |
384 | .owner = THIS_MODULE, | 384 | .owner = THIS_MODULE, |
385 | .pm = &lpc32xx_kscan_pm_ops, | 385 | .pm = &lpc32xx_kscan_pm_ops, |
386 | .of_match_table = of_match_ptr(lpc32xx_kscan_match), | 386 | .of_match_table = lpc32xx_kscan_match, |
387 | } | 387 | } |
388 | }; | 388 | }; |
389 | 389 | ||
diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index b3e3edab6d9f..b31064981e96 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c | |||
@@ -143,8 +143,10 @@ static int nspire_keypad_open(struct input_dev *input) | |||
143 | return error; | 143 | return error; |
144 | 144 | ||
145 | error = nspire_keypad_chip_init(keypad); | 145 | error = nspire_keypad_chip_init(keypad); |
146 | if (error) | 146 | if (error) { |
147 | clk_disable_unprepare(keypad->clk); | ||
147 | return error; | 148 | return error; |
149 | } | ||
148 | 150 | ||
149 | return 0; | 151 | return 0; |
150 | } | 152 | } |
@@ -267,7 +269,7 @@ static struct platform_driver nspire_keypad_driver = { | |||
267 | .driver = { | 269 | .driver = { |
268 | .name = "nspire-keypad", | 270 | .name = "nspire-keypad", |
269 | .owner = THIS_MODULE, | 271 | .owner = THIS_MODULE, |
270 | .of_match_table = of_match_ptr(nspire_keypad_dt_match), | 272 | .of_match_table = nspire_keypad_dt_match, |
271 | }, | 273 | }, |
272 | .probe = nspire_keypad_probe, | 274 | .probe = nspire_keypad_probe, |
273 | }; | 275 | }; |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index a2e758d27584..186138c720c7 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/input/matrix_keypad.h> | 28 | #include <linux/input/matrix_keypad.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/of.h> | ||
30 | 31 | ||
31 | #include <asm/mach/arch.h> | 32 | #include <asm/mach/arch.h> |
32 | #include <asm/mach/map.h> | 33 | #include <asm/mach/map.h> |
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index 9cd20e6905a0..8508879f6faf 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c | |||
@@ -614,7 +614,7 @@ static int tegra_kbc_probe(struct platform_device *pdev) | |||
614 | unsigned int keymap_rows; | 614 | unsigned int keymap_rows; |
615 | const struct of_device_id *match; | 615 | const struct of_device_id *match; |
616 | 616 | ||
617 | match = of_match_device(of_match_ptr(tegra_kbc_of_match), &pdev->dev); | 617 | match = of_match_device(tegra_kbc_of_match, &pdev->dev); |
618 | 618 | ||
619 | kbc = devm_kzalloc(&pdev->dev, sizeof(*kbc), GFP_KERNEL); | 619 | kbc = devm_kzalloc(&pdev->dev, sizeof(*kbc), GFP_KERNEL); |
620 | if (!kbc) { | 620 | if (!kbc) { |
diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index 5f7b427dd7ed..8bd24d52bf1b 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c | |||
@@ -60,8 +60,8 @@ struct keypad_data { | |||
60 | struct clk *clk; | 60 | struct clk *clk; |
61 | struct device *dev; | 61 | struct device *dev; |
62 | spinlock_t lock; | 62 | spinlock_t lock; |
63 | u32 irq_press; | 63 | int irq_press; |
64 | u32 irq_release; | 64 | int irq_release; |
65 | int rows, cols, row_shift; | 65 | int rows, cols, row_shift; |
66 | int debounce_ms, active_low; | 66 | int debounce_ms, active_low; |
67 | u32 prev_keys[3]; | 67 | u32 prev_keys[3]; |
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index aa51baaa9b1e..5f4967d01bc3 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -156,7 +156,7 @@ config INPUT_MAX8925_ONKEY | |||
156 | 156 | ||
157 | config INPUT_MAX8997_HAPTIC | 157 | config INPUT_MAX8997_HAPTIC |
158 | tristate "MAXIM MAX8997 haptic controller support" | 158 | tristate "MAXIM MAX8997 haptic controller support" |
159 | depends on HAVE_PWM && MFD_MAX8997 | 159 | depends on PWM && HAVE_PWM && MFD_MAX8997 |
160 | select INPUT_FF_MEMLESS | 160 | select INPUT_FF_MEMLESS |
161 | help | 161 | help |
162 | This option enables device driver support for the haptic controller | 162 | This option enables device driver support for the haptic controller |
@@ -461,7 +461,7 @@ config INPUT_PCF8574 | |||
461 | 461 | ||
462 | config INPUT_PWM_BEEPER | 462 | config INPUT_PWM_BEEPER |
463 | tristate "PWM beeper support" | 463 | tristate "PWM beeper support" |
464 | depends on HAVE_PWM || PWM | 464 | depends on PWM && HAVE_PWM |
465 | help | 465 | help |
466 | Say Y here to get support for PWM based beeper devices. | 466 | Say Y here to get support for PWM based beeper devices. |
467 | 467 | ||
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c index 61891486067c..3a90b710e309 100644 --- a/drivers/input/misc/ad714x-spi.c +++ b/drivers/input/misc/ad714x-spi.c | |||
@@ -108,7 +108,6 @@ static int ad714x_spi_remove(struct spi_device *spi) | |||
108 | struct ad714x_chip *chip = spi_get_drvdata(spi); | 108 | struct ad714x_chip *chip = spi_get_drvdata(spi); |
109 | 109 | ||
110 | ad714x_remove(chip); | 110 | ad714x_remove(chip); |
111 | spi_set_drvdata(spi, NULL); | ||
112 | 111 | ||
113 | return 0; | 112 | return 0; |
114 | } | 113 | } |
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c index 4f77f87847e8..b5d71d245854 100644 --- a/drivers/input/misc/cobalt_btns.c +++ b/drivers/input/misc/cobalt_btns.c | |||
@@ -131,7 +131,6 @@ static int cobalt_buttons_probe(struct platform_device *pdev) | |||
131 | err_free_mem: | 131 | err_free_mem: |
132 | input_free_polled_device(poll_dev); | 132 | input_free_polled_device(poll_dev); |
133 | kfree(bdev); | 133 | kfree(bdev); |
134 | dev_set_drvdata(&pdev->dev, NULL); | ||
135 | return error; | 134 | return error; |
136 | } | 135 | } |
137 | 136 | ||
@@ -144,7 +143,6 @@ static int cobalt_buttons_remove(struct platform_device *pdev) | |||
144 | input_free_polled_device(bdev->poll_dev); | 143 | input_free_polled_device(bdev->poll_dev); |
145 | iounmap(bdev->reg); | 144 | iounmap(bdev->reg); |
146 | kfree(bdev); | 145 | kfree(bdev); |
147 | dev_set_drvdata(dev, NULL); | ||
148 | 146 | ||
149 | return 0; | 147 | return 0; |
150 | } | 148 | } |
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c index ee6ae3a00174..a0af8b2506ce 100644 --- a/drivers/input/misc/da9055_onkey.c +++ b/drivers/input/misc/da9055_onkey.c | |||
@@ -36,7 +36,7 @@ static void da9055_onkey_query(struct da9055_onkey *onkey) | |||
36 | } else { | 36 | } else { |
37 | key_stat &= DA9055_NOKEY_STS; | 37 | key_stat &= DA9055_NOKEY_STS; |
38 | /* | 38 | /* |
39 | * Onkey status bit is cleared when onkey button is relased. | 39 | * Onkey status bit is cleared when onkey button is released. |
40 | */ | 40 | */ |
41 | if (!key_stat) { | 41 | if (!key_stat) { |
42 | input_report_key(onkey->input, KEY_POWER, 0); | 42 | input_report_key(onkey->input, KEY_POWER, 0); |
diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c index f3309696d053..59d4dcddf6de 100644 --- a/drivers/input/misc/mma8450.c +++ b/drivers/input/misc/mma8450.c | |||
@@ -168,7 +168,7 @@ static void mma8450_close(struct input_polled_dev *dev) | |||
168 | * I2C init/probing/exit functions | 168 | * I2C init/probing/exit functions |
169 | */ | 169 | */ |
170 | static int mma8450_probe(struct i2c_client *c, | 170 | static int mma8450_probe(struct i2c_client *c, |
171 | const struct i2c_device_id *id) | 171 | const struct i2c_device_id *id) |
172 | { | 172 | { |
173 | struct input_polled_dev *idev; | 173 | struct input_polled_dev *idev; |
174 | struct mma8450 *m; | 174 | struct mma8450 *m; |
@@ -204,6 +204,8 @@ static int mma8450_probe(struct i2c_client *c, | |||
204 | goto err_free_mem; | 204 | goto err_free_mem; |
205 | } | 205 | } |
206 | 206 | ||
207 | i2c_set_clientdata(c, m); | ||
208 | |||
207 | return 0; | 209 | return 0; |
208 | 210 | ||
209 | err_free_mem: | 211 | err_free_mem: |
diff --git a/drivers/input/misc/mpu3050.c b/drivers/input/misc/mpu3050.c index dce0d95943c5..6983ffbbfb94 100644 --- a/drivers/input/misc/mpu3050.c +++ b/drivers/input/misc/mpu3050.c | |||
@@ -383,6 +383,7 @@ static int mpu3050_probe(struct i2c_client *client, | |||
383 | 383 | ||
384 | pm_runtime_enable(&client->dev); | 384 | pm_runtime_enable(&client->dev); |
385 | pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY); | 385 | pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY); |
386 | i2c_set_clientdata(client, sensor); | ||
386 | 387 | ||
387 | return 0; | 388 | return 0; |
388 | 389 | ||
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 2ff4d1c78ab8..940566e7be13 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/input.h> | 16 | #include <linux/input.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/of.h> | ||
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
20 | #include <linux/pwm.h> | 21 | #include <linux/pwm.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
diff --git a/drivers/input/misc/rb532_button.c b/drivers/input/misc/rb532_button.c index fb4f8ac3343b..83fff38b86b3 100644 --- a/drivers/input/misc/rb532_button.c +++ b/drivers/input/misc/rb532_button.c | |||
@@ -87,7 +87,6 @@ static int rb532_button_remove(struct platform_device *pdev) | |||
87 | 87 | ||
88 | input_unregister_polled_device(poll_dev); | 88 | input_unregister_polled_device(poll_dev); |
89 | input_free_polled_device(poll_dev); | 89 | input_free_polled_device(poll_dev); |
90 | dev_set_drvdata(&pdev->dev, NULL); | ||
91 | 90 | ||
92 | return 0; | 91 | return 0; |
93 | } | 92 | } |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 5b1aff825138..f920ba7ab51f 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
25 | #include <linux/rotary_encoder.h> | 25 | #include <linux/rotary_encoder.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/of.h> | ||
27 | #include <linux/of_platform.h> | 28 | #include <linux/of_platform.h> |
28 | #include <linux/of_gpio.h> | 29 | #include <linux/of_gpio.h> |
29 | 30 | ||
diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index 0621c367049a..7b8b03e0d0be 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c | |||
@@ -153,7 +153,7 @@ static struct platform_driver sirfsoc_pwrc_driver = { | |||
153 | .name = "sirfsoc-pwrc", | 153 | .name = "sirfsoc-pwrc", |
154 | .owner = THIS_MODULE, | 154 | .owner = THIS_MODULE, |
155 | .pm = &sirfsoc_pwrc_pm_ops, | 155 | .pm = &sirfsoc_pwrc_pm_ops, |
156 | .of_match_table = of_match_ptr(sirfsoc_pwrc_of_match), | 156 | .of_match_table = sirfsoc_pwrc_of_match, |
157 | } | 157 | } |
158 | }; | 158 | }; |
159 | 159 | ||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index a0a4bbaef02c..772835938a52 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -430,20 +430,30 @@ static int uinput_setup_device(struct uinput_device *udev, | |||
430 | return retval; | 430 | return retval; |
431 | } | 431 | } |
432 | 432 | ||
433 | static ssize_t uinput_inject_event(struct uinput_device *udev, | 433 | static ssize_t uinput_inject_events(struct uinput_device *udev, |
434 | const char __user *buffer, size_t count) | 434 | const char __user *buffer, size_t count) |
435 | { | 435 | { |
436 | struct input_event ev; | 436 | struct input_event ev; |
437 | size_t bytes = 0; | ||
437 | 438 | ||
438 | if (count < input_event_size()) | 439 | if (count != 0 && count < input_event_size()) |
439 | return -EINVAL; | 440 | return -EINVAL; |
440 | 441 | ||
441 | if (input_event_from_user(buffer, &ev)) | 442 | while (bytes + input_event_size() <= count) { |
442 | return -EFAULT; | 443 | /* |
444 | * Note that even if some events were fetched successfully | ||
445 | * we are still going to return EFAULT instead of partial | ||
446 | * count to let userspace know that it got it's buffers | ||
447 | * all wrong. | ||
448 | */ | ||
449 | if (input_event_from_user(buffer + bytes, &ev)) | ||
450 | return -EFAULT; | ||
443 | 451 | ||
444 | input_event(udev->dev, ev.type, ev.code, ev.value); | 452 | input_event(udev->dev, ev.type, ev.code, ev.value); |
453 | bytes += input_event_size(); | ||
454 | } | ||
445 | 455 | ||
446 | return input_event_size(); | 456 | return bytes; |
447 | } | 457 | } |
448 | 458 | ||
449 | static ssize_t uinput_write(struct file *file, const char __user *buffer, | 459 | static ssize_t uinput_write(struct file *file, const char __user *buffer, |
@@ -460,7 +470,7 @@ static ssize_t uinput_write(struct file *file, const char __user *buffer, | |||
460 | return retval; | 470 | return retval; |
461 | 471 | ||
462 | retval = udev->state == UIST_CREATED ? | 472 | retval = udev->state == UIST_CREATED ? |
463 | uinput_inject_event(udev, buffer, count) : | 473 | uinput_inject_events(udev, buffer, count) : |
464 | uinput_setup_device(udev, buffer, count); | 474 | uinput_setup_device(udev, buffer, count); |
465 | 475 | ||
466 | mutex_unlock(&udev->mutex); | 476 | mutex_unlock(&udev->mutex); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7c5d72a6a26a..ca7a26f1dce8 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -1792,7 +1792,7 @@ int alps_init(struct psmouse *psmouse) | |||
1792 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); | 1792 | snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); |
1793 | dev2->phys = priv->phys; | 1793 | dev2->phys = priv->phys; |
1794 | dev2->name = (priv->flags & ALPS_DUALPOINT) ? | 1794 | dev2->name = (priv->flags & ALPS_DUALPOINT) ? |
1795 | "DualPoint Stick" : "PS/2 Mouse"; | 1795 | "DualPoint Stick" : "ALPS PS/2 Device"; |
1796 | dev2->id.bustype = BUS_I8042; | 1796 | dev2->id.bustype = BUS_I8042; |
1797 | dev2->id.vendor = 0x0002; | 1797 | dev2->id.vendor = 0x0002; |
1798 | dev2->id.product = PSMOUSE_ALPS; | 1798 | dev2->id.product = PSMOUSE_ALPS; |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 4ef4d5e198ae..a73f9618b0ad 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -89,9 +89,9 @@ | |||
89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a | 89 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a |
90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b | 90 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b |
91 | /* MacbookAir6,2 (unibody, June 2013) */ | 91 | /* MacbookAir6,2 (unibody, June 2013) */ |
92 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291 | 92 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 |
93 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292 | 93 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 |
94 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293 | 94 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 |
95 | 95 | ||
96 | #define BCM5974_DEVICE(prod) { \ | 96 | #define BCM5974_DEVICE(prod) { \ |
97 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | 97 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ |
diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index f51765fff054..a5869a856ea5 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c | |||
@@ -439,7 +439,7 @@ static int cypress_get_finger_count(unsigned char header_byte) | |||
439 | case 2: return 5; | 439 | case 2: return 5; |
440 | default: | 440 | default: |
441 | /* Invalid contact (e.g. palm). Ignore it. */ | 441 | /* Invalid contact (e.g. palm). Ignore it. */ |
442 | return -1; | 442 | return 0; |
443 | } | 443 | } |
444 | } | 444 | } |
445 | 445 | ||
@@ -452,17 +452,10 @@ static int cypress_parse_packet(struct psmouse *psmouse, | |||
452 | { | 452 | { |
453 | unsigned char *packet = psmouse->packet; | 453 | unsigned char *packet = psmouse->packet; |
454 | unsigned char header_byte = packet[0]; | 454 | unsigned char header_byte = packet[0]; |
455 | int contact_cnt; | ||
456 | 455 | ||
457 | memset(report_data, 0, sizeof(struct cytp_report_data)); | 456 | memset(report_data, 0, sizeof(struct cytp_report_data)); |
458 | 457 | ||
459 | contact_cnt = cypress_get_finger_count(header_byte); | 458 | report_data->contact_cnt = cypress_get_finger_count(header_byte); |
460 | |||
461 | if (contact_cnt < 0) /* e.g. palm detect */ | ||
462 | return -EINVAL; | ||
463 | |||
464 | report_data->contact_cnt = contact_cnt; | ||
465 | |||
466 | report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0; | 459 | report_data->tap = (header_byte & ABS_MULTIFINGER_TAP) ? 1 : 0; |
467 | 460 | ||
468 | if (report_data->contact_cnt == 1) { | 461 | if (report_data->contact_cnt == 1) { |
@@ -535,11 +528,9 @@ static void cypress_process_packet(struct psmouse *psmouse, bool zero_pkt) | |||
535 | int slots[CYTP_MAX_MT_SLOTS]; | 528 | int slots[CYTP_MAX_MT_SLOTS]; |
536 | int n; | 529 | int n; |
537 | 530 | ||
538 | if (cypress_parse_packet(psmouse, cytp, &report_data)) | 531 | cypress_parse_packet(psmouse, cytp, &report_data); |
539 | return; | ||
540 | 532 | ||
541 | n = report_data.contact_cnt; | 533 | n = report_data.contact_cnt; |
542 | |||
543 | if (n > CYTP_MAX_MT_SLOTS) | 534 | if (n > CYTP_MAX_MT_SLOTS) |
544 | n = CYTP_MAX_MT_SLOTS; | 535 | n = CYTP_MAX_MT_SLOTS; |
545 | 536 | ||
@@ -605,10 +596,6 @@ static psmouse_ret_t cypress_validate_byte(struct psmouse *psmouse) | |||
605 | return PSMOUSE_BAD_DATA; | 596 | return PSMOUSE_BAD_DATA; |
606 | 597 | ||
607 | contact_cnt = cypress_get_finger_count(packet[0]); | 598 | contact_cnt = cypress_get_finger_count(packet[0]); |
608 | |||
609 | if (contact_cnt < 0) | ||
610 | return PSMOUSE_BAD_DATA; | ||
611 | |||
612 | if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE) | 599 | if (cytp->mode & CYTP_BIT_ABS_NO_PRESSURE) |
613 | cypress_set_packet_size(psmouse, contact_cnt == 2 ? 7 : 4); | 600 | cypress_set_packet_size(psmouse, contact_cnt == 2 ? 7 : 4); |
614 | else | 601 | else |
@@ -679,15 +666,15 @@ int cypress_init(struct psmouse *psmouse) | |||
679 | { | 666 | { |
680 | struct cytp_data *cytp; | 667 | struct cytp_data *cytp; |
681 | 668 | ||
682 | cytp = (struct cytp_data *)kzalloc(sizeof(struct cytp_data), GFP_KERNEL); | 669 | cytp = kzalloc(sizeof(struct cytp_data), GFP_KERNEL); |
683 | psmouse->private = (void *)cytp; | 670 | if (!cytp) |
684 | if (cytp == NULL) | ||
685 | return -ENOMEM; | 671 | return -ENOMEM; |
686 | 672 | ||
687 | cypress_reset(psmouse); | 673 | psmouse->private = cytp; |
688 | |||
689 | psmouse->pktsize = 8; | 674 | psmouse->pktsize = 8; |
690 | 675 | ||
676 | cypress_reset(psmouse); | ||
677 | |||
691 | if (cypress_query_hardware(psmouse)) { | 678 | if (cypress_query_hardware(psmouse)) { |
692 | psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); | 679 | psmouse_err(psmouse, "Unable to query Trackpad hardware.\n"); |
693 | goto err_exit; | 680 | goto err_exit; |
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 1e691a3a79cb..5a96acb667ea 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig | |||
@@ -2,7 +2,7 @@ | |||
2 | # Input core configuration | 2 | # Input core configuration |
3 | # | 3 | # |
4 | config SERIO | 4 | config SERIO |
5 | tristate "Serial I/O support" if EXPERT || !X86 | 5 | tristate "Serial I/O support" |
6 | default y | 6 | default y |
7 | help | 7 | help |
8 | Say Yes here if you have any input device that uses serial I/O to | 8 | Say Yes here if you have any input device that uses serial I/O to |
@@ -19,7 +19,7 @@ config SERIO | |||
19 | if SERIO | 19 | if SERIO |
20 | 20 | ||
21 | config SERIO_I8042 | 21 | config SERIO_I8042 |
22 | tristate "i8042 PC Keyboard controller" if EXPERT || !X86 | 22 | tristate "i8042 PC Keyboard controller" |
23 | default y | 23 | default y |
24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ | 24 | depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ |
25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ | 25 | (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !S390 && \ |
@@ -170,7 +170,7 @@ config SERIO_MACEPS2 | |||
170 | module will be called maceps2. | 170 | module will be called maceps2. |
171 | 171 | ||
172 | config SERIO_LIBPS2 | 172 | config SERIO_LIBPS2 |
173 | tristate "PS/2 driver library" if EXPERT | 173 | tristate "PS/2 driver library" |
174 | depends on SERIO_I8042 || SERIO_I8042=n | 174 | depends on SERIO_I8042 || SERIO_I8042=n |
175 | help | 175 | help |
176 | Say Y here if you are using a driver for device connected | 176 | Say Y here if you are using a driver for device connected |
@@ -239,7 +239,6 @@ config SERIO_PS2MULT | |||
239 | 239 | ||
240 | config SERIO_ARC_PS2 | 240 | config SERIO_ARC_PS2 |
241 | tristate "ARC PS/2 support" | 241 | tristate "ARC PS/2 support" |
242 | depends on GENERIC_HARDIRQS | ||
243 | help | 242 | help |
244 | Say Y here if you have an ARC FPGA platform with a PS/2 | 243 | Say Y here if you have an ARC FPGA platform with a PS/2 |
245 | controller in it. | 244 | controller in it. |
@@ -267,4 +266,14 @@ config SERIO_OLPC_APSP | |||
267 | To compile this driver as a module, choose M here: the module will | 266 | To compile this driver as a module, choose M here: the module will |
268 | be called olpc_apsp. | 267 | be called olpc_apsp. |
269 | 268 | ||
269 | config HYPERV_KEYBOARD | ||
270 | tristate "Microsoft Synthetic Keyboard driver" | ||
271 | depends on HYPERV | ||
272 | default HYPERV | ||
273 | help | ||
274 | Select this option to enable the Hyper-V Keyboard driver. | ||
275 | |||
276 | To compile this driver as a module, choose M here: the module will | ||
277 | be called hyperv_keyboard. | ||
278 | |||
270 | endif | 279 | endif |
diff --git a/drivers/input/serio/Makefile b/drivers/input/serio/Makefile index 12298b1c0e71..815d874fe724 100644 --- a/drivers/input/serio/Makefile +++ b/drivers/input/serio/Makefile | |||
@@ -28,3 +28,4 @@ obj-$(CONFIG_SERIO_ALTERA_PS2) += altera_ps2.o | |||
28 | obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o | 28 | obj-$(CONFIG_SERIO_ARC_PS2) += arc_ps2.o |
29 | obj-$(CONFIG_SERIO_APBPS2) += apbps2.o | 29 | obj-$(CONFIG_SERIO_APBPS2) += apbps2.o |
30 | obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o | 30 | obj-$(CONFIG_SERIO_OLPC_APSP) += olpc_apsp.o |
31 | obj-$(CONFIG_HYPERV_KEYBOARD) += hyperv-keyboard.o | ||
diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index a0a2657e31ff..4777a73cd390 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c | |||
@@ -176,6 +176,7 @@ static int altera_ps2_remove(struct platform_device *pdev) | |||
176 | #ifdef CONFIG_OF | 176 | #ifdef CONFIG_OF |
177 | static const struct of_device_id altera_ps2_match[] = { | 177 | static const struct of_device_id altera_ps2_match[] = { |
178 | { .compatible = "ALTR,ps2-1.0", }, | 178 | { .compatible = "ALTR,ps2-1.0", }, |
179 | { .compatible = "altr,ps2-1.0", }, | ||
179 | {}, | 180 | {}, |
180 | }; | 181 | }; |
181 | MODULE_DEVICE_TABLE(of, altera_ps2_match); | 182 | MODULE_DEVICE_TABLE(of, altera_ps2_match); |
diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c new file mode 100644 index 000000000000..3a83c3c14b23 --- /dev/null +++ b/drivers/input/serio/hyperv-keyboard.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2013, Microsoft Corporation. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/init.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/completion.h> | ||
18 | #include <linux/hyperv.h> | ||
19 | #include <linux/serio.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | /* | ||
23 | * Current version 1.0 | ||
24 | * | ||
25 | */ | ||
26 | #define SYNTH_KBD_VERSION_MAJOR 1 | ||
27 | #define SYNTH_KBD_VERSION_MINOR 0 | ||
28 | #define SYNTH_KBD_VERSION (SYNTH_KBD_VERSION_MINOR | \ | ||
29 | (SYNTH_KBD_VERSION_MAJOR << 16)) | ||
30 | |||
31 | |||
32 | /* | ||
33 | * Message types in the synthetic input protocol | ||
34 | */ | ||
35 | enum synth_kbd_msg_type { | ||
36 | SYNTH_KBD_PROTOCOL_REQUEST = 1, | ||
37 | SYNTH_KBD_PROTOCOL_RESPONSE = 2, | ||
38 | SYNTH_KBD_EVENT = 3, | ||
39 | SYNTH_KBD_LED_INDICATORS = 4, | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * Basic message structures. | ||
44 | */ | ||
45 | struct synth_kbd_msg_hdr { | ||
46 | __le32 type; | ||
47 | }; | ||
48 | |||
49 | struct synth_kbd_msg { | ||
50 | struct synth_kbd_msg_hdr header; | ||
51 | char data[]; /* Enclosed message */ | ||
52 | }; | ||
53 | |||
54 | union synth_kbd_version { | ||
55 | __le32 version; | ||
56 | }; | ||
57 | |||
58 | /* | ||
59 | * Protocol messages | ||
60 | */ | ||
61 | struct synth_kbd_protocol_request { | ||
62 | struct synth_kbd_msg_hdr header; | ||
63 | union synth_kbd_version version_requested; | ||
64 | }; | ||
65 | |||
66 | #define PROTOCOL_ACCEPTED BIT(0) | ||
67 | struct synth_kbd_protocol_response { | ||
68 | struct synth_kbd_msg_hdr header; | ||
69 | __le32 proto_status; | ||
70 | }; | ||
71 | |||
72 | #define IS_UNICODE BIT(0) | ||
73 | #define IS_BREAK BIT(1) | ||
74 | #define IS_E0 BIT(2) | ||
75 | #define IS_E1 BIT(3) | ||
76 | struct synth_kbd_keystroke { | ||
77 | struct synth_kbd_msg_hdr header; | ||
78 | __le16 make_code; | ||
79 | __le16 reserved0; | ||
80 | __le32 info; /* Additional information */ | ||
81 | }; | ||
82 | |||
83 | |||
84 | #define HK_MAXIMUM_MESSAGE_SIZE 256 | ||
85 | |||
86 | #define KBD_VSC_SEND_RING_BUFFER_SIZE (10 * PAGE_SIZE) | ||
87 | #define KBD_VSC_RECV_RING_BUFFER_SIZE (10 * PAGE_SIZE) | ||
88 | |||
89 | #define XTKBD_EMUL0 0xe0 | ||
90 | #define XTKBD_EMUL1 0xe1 | ||
91 | #define XTKBD_RELEASE 0x80 | ||
92 | |||
93 | |||
94 | /* | ||
95 | * Represents a keyboard device | ||
96 | */ | ||
97 | struct hv_kbd_dev { | ||
98 | struct hv_device *hv_dev; | ||
99 | struct serio *hv_serio; | ||
100 | struct synth_kbd_protocol_request protocol_req; | ||
101 | struct synth_kbd_protocol_response protocol_resp; | ||
102 | /* Synchronize the request/response if needed */ | ||
103 | struct completion wait_event; | ||
104 | spinlock_t lock; /* protects 'started' field */ | ||
105 | bool started; | ||
106 | }; | ||
107 | |||
108 | static void hv_kbd_on_receive(struct hv_device *hv_dev, | ||
109 | struct synth_kbd_msg *msg, u32 msg_length) | ||
110 | { | ||
111 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
112 | struct synth_kbd_keystroke *ks_msg; | ||
113 | unsigned long flags; | ||
114 | u32 msg_type = __le32_to_cpu(msg->header.type); | ||
115 | u32 info; | ||
116 | u16 scan_code; | ||
117 | |||
118 | switch (msg_type) { | ||
119 | case SYNTH_KBD_PROTOCOL_RESPONSE: | ||
120 | /* | ||
121 | * Validate the information provided by the host. | ||
122 | * If the host is giving us a bogus packet, | ||
123 | * drop the packet (hoping the problem | ||
124 | * goes away). | ||
125 | */ | ||
126 | if (msg_length < sizeof(struct synth_kbd_protocol_response)) { | ||
127 | dev_err(&hv_dev->device, | ||
128 | "Illegal protocol response packet (len: %d)\n", | ||
129 | msg_length); | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | memcpy(&kbd_dev->protocol_resp, msg, | ||
134 | sizeof(struct synth_kbd_protocol_response)); | ||
135 | complete(&kbd_dev->wait_event); | ||
136 | break; | ||
137 | |||
138 | case SYNTH_KBD_EVENT: | ||
139 | /* | ||
140 | * Validate the information provided by the host. | ||
141 | * If the host is giving us a bogus packet, | ||
142 | * drop the packet (hoping the problem | ||
143 | * goes away). | ||
144 | */ | ||
145 | if (msg_length < sizeof(struct synth_kbd_keystroke)) { | ||
146 | dev_err(&hv_dev->device, | ||
147 | "Illegal keyboard event packet (len: %d)\n", | ||
148 | msg_length); | ||
149 | break; | ||
150 | } | ||
151 | |||
152 | ks_msg = (struct synth_kbd_keystroke *)msg; | ||
153 | info = __le32_to_cpu(ks_msg->info); | ||
154 | |||
155 | /* | ||
156 | * Inject the information through the serio interrupt. | ||
157 | */ | ||
158 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
159 | if (kbd_dev->started) { | ||
160 | if (info & IS_E0) | ||
161 | serio_interrupt(kbd_dev->hv_serio, | ||
162 | XTKBD_EMUL0, 0); | ||
163 | |||
164 | scan_code = __le16_to_cpu(ks_msg->make_code); | ||
165 | if (info & IS_BREAK) | ||
166 | scan_code |= XTKBD_RELEASE; | ||
167 | |||
168 | serio_interrupt(kbd_dev->hv_serio, scan_code, 0); | ||
169 | } | ||
170 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
171 | break; | ||
172 | |||
173 | default: | ||
174 | dev_err(&hv_dev->device, | ||
175 | "unhandled message type %d\n", msg_type); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | static void hv_kbd_handle_received_packet(struct hv_device *hv_dev, | ||
180 | struct vmpacket_descriptor *desc, | ||
181 | u32 bytes_recvd, | ||
182 | u64 req_id) | ||
183 | { | ||
184 | struct synth_kbd_msg *msg; | ||
185 | u32 msg_sz; | ||
186 | |||
187 | switch (desc->type) { | ||
188 | case VM_PKT_COMP: | ||
189 | break; | ||
190 | |||
191 | case VM_PKT_DATA_INBAND: | ||
192 | /* | ||
193 | * We have a packet that has "inband" data. The API used | ||
194 | * for retrieving the packet guarantees that the complete | ||
195 | * packet is read. So, minimally, we should be able to | ||
196 | * parse the payload header safely (assuming that the host | ||
197 | * can be trusted. Trusting the host seems to be a | ||
198 | * reasonable assumption because in a virtualized | ||
199 | * environment there is not whole lot you can do if you | ||
200 | * don't trust the host. | ||
201 | * | ||
202 | * Nonetheless, let us validate if the host can be trusted | ||
203 | * (in a trivial way). The interesting aspect of this | ||
204 | * validation is how do you recover if we discover that the | ||
205 | * host is not to be trusted? Simply dropping the packet, I | ||
206 | * don't think is an appropriate recovery. In the interest | ||
207 | * of failing fast, it may be better to crash the guest. | ||
208 | * For now, I will just drop the packet! | ||
209 | */ | ||
210 | |||
211 | msg_sz = bytes_recvd - (desc->offset8 << 3); | ||
212 | if (msg_sz <= sizeof(struct synth_kbd_msg_hdr)) { | ||
213 | /* | ||
214 | * Drop the packet and hope | ||
215 | * the problem magically goes away. | ||
216 | */ | ||
217 | dev_err(&hv_dev->device, | ||
218 | "Illegal packet (type: %d, tid: %llx, size: %d)\n", | ||
219 | desc->type, req_id, msg_sz); | ||
220 | break; | ||
221 | } | ||
222 | |||
223 | msg = (void *)desc + (desc->offset8 << 3); | ||
224 | hv_kbd_on_receive(hv_dev, msg, msg_sz); | ||
225 | break; | ||
226 | |||
227 | default: | ||
228 | dev_err(&hv_dev->device, | ||
229 | "unhandled packet type %d, tid %llx len %d\n", | ||
230 | desc->type, req_id, bytes_recvd); | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | |||
235 | static void hv_kbd_on_channel_callback(void *context) | ||
236 | { | ||
237 | struct hv_device *hv_dev = context; | ||
238 | void *buffer; | ||
239 | int bufferlen = 0x100; /* Start with sensible size */ | ||
240 | u32 bytes_recvd; | ||
241 | u64 req_id; | ||
242 | int error; | ||
243 | |||
244 | buffer = kmalloc(bufferlen, GFP_ATOMIC); | ||
245 | if (!buffer) | ||
246 | return; | ||
247 | |||
248 | while (1) { | ||
249 | error = vmbus_recvpacket_raw(hv_dev->channel, buffer, bufferlen, | ||
250 | &bytes_recvd, &req_id); | ||
251 | switch (error) { | ||
252 | case 0: | ||
253 | if (bytes_recvd == 0) { | ||
254 | kfree(buffer); | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | hv_kbd_handle_received_packet(hv_dev, buffer, | ||
259 | bytes_recvd, req_id); | ||
260 | break; | ||
261 | |||
262 | case -ENOBUFS: | ||
263 | kfree(buffer); | ||
264 | /* Handle large packet */ | ||
265 | bufferlen = bytes_recvd; | ||
266 | buffer = kmalloc(bytes_recvd, GFP_ATOMIC); | ||
267 | if (!buffer) | ||
268 | return; | ||
269 | break; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev) | ||
275 | { | ||
276 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
277 | struct synth_kbd_protocol_request *request; | ||
278 | struct synth_kbd_protocol_response *response; | ||
279 | u32 proto_status; | ||
280 | int error; | ||
281 | |||
282 | request = &kbd_dev->protocol_req; | ||
283 | memset(request, 0, sizeof(struct synth_kbd_protocol_request)); | ||
284 | request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST); | ||
285 | request->version_requested.version = __cpu_to_le32(SYNTH_KBD_VERSION); | ||
286 | |||
287 | error = vmbus_sendpacket(hv_dev->channel, request, | ||
288 | sizeof(struct synth_kbd_protocol_request), | ||
289 | (unsigned long)request, | ||
290 | VM_PKT_DATA_INBAND, | ||
291 | VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); | ||
292 | if (error) | ||
293 | return error; | ||
294 | |||
295 | if (!wait_for_completion_timeout(&kbd_dev->wait_event, 10 * HZ)) | ||
296 | return -ETIMEDOUT; | ||
297 | |||
298 | response = &kbd_dev->protocol_resp; | ||
299 | proto_status = __le32_to_cpu(response->proto_status); | ||
300 | if (!(proto_status & PROTOCOL_ACCEPTED)) { | ||
301 | dev_err(&hv_dev->device, | ||
302 | "synth_kbd protocol request failed (version %d)\n", | ||
303 | SYNTH_KBD_VERSION); | ||
304 | return -ENODEV; | ||
305 | } | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int hv_kbd_start(struct serio *serio) | ||
311 | { | ||
312 | struct hv_kbd_dev *kbd_dev = serio->port_data; | ||
313 | unsigned long flags; | ||
314 | |||
315 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
316 | kbd_dev->started = true; | ||
317 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static void hv_kbd_stop(struct serio *serio) | ||
323 | { | ||
324 | struct hv_kbd_dev *kbd_dev = serio->port_data; | ||
325 | unsigned long flags; | ||
326 | |||
327 | spin_lock_irqsave(&kbd_dev->lock, flags); | ||
328 | kbd_dev->started = false; | ||
329 | spin_unlock_irqrestore(&kbd_dev->lock, flags); | ||
330 | } | ||
331 | |||
332 | static int hv_kbd_probe(struct hv_device *hv_dev, | ||
333 | const struct hv_vmbus_device_id *dev_id) | ||
334 | { | ||
335 | struct hv_kbd_dev *kbd_dev; | ||
336 | struct serio *hv_serio; | ||
337 | int error; | ||
338 | |||
339 | kbd_dev = kzalloc(sizeof(struct hv_kbd_dev), GFP_KERNEL); | ||
340 | hv_serio = kzalloc(sizeof(struct serio), GFP_KERNEL); | ||
341 | if (!kbd_dev || !hv_serio) { | ||
342 | error = -ENOMEM; | ||
343 | goto err_free_mem; | ||
344 | } | ||
345 | |||
346 | kbd_dev->hv_dev = hv_dev; | ||
347 | kbd_dev->hv_serio = hv_serio; | ||
348 | spin_lock_init(&kbd_dev->lock); | ||
349 | init_completion(&kbd_dev->wait_event); | ||
350 | hv_set_drvdata(hv_dev, kbd_dev); | ||
351 | |||
352 | hv_serio->dev.parent = &hv_dev->device; | ||
353 | hv_serio->id.type = SERIO_8042_XL; | ||
354 | hv_serio->port_data = kbd_dev; | ||
355 | strlcpy(hv_serio->name, dev_name(&hv_dev->device), | ||
356 | sizeof(hv_serio->name)); | ||
357 | strlcpy(hv_serio->phys, dev_name(&hv_dev->device), | ||
358 | sizeof(hv_serio->phys)); | ||
359 | |||
360 | hv_serio->start = hv_kbd_start; | ||
361 | hv_serio->stop = hv_kbd_stop; | ||
362 | |||
363 | error = vmbus_open(hv_dev->channel, | ||
364 | KBD_VSC_SEND_RING_BUFFER_SIZE, | ||
365 | KBD_VSC_RECV_RING_BUFFER_SIZE, | ||
366 | NULL, 0, | ||
367 | hv_kbd_on_channel_callback, | ||
368 | hv_dev); | ||
369 | if (error) | ||
370 | goto err_free_mem; | ||
371 | |||
372 | error = hv_kbd_connect_to_vsp(hv_dev); | ||
373 | if (error) | ||
374 | goto err_close_vmbus; | ||
375 | |||
376 | serio_register_port(kbd_dev->hv_serio); | ||
377 | return 0; | ||
378 | |||
379 | err_close_vmbus: | ||
380 | vmbus_close(hv_dev->channel); | ||
381 | err_free_mem: | ||
382 | kfree(hv_serio); | ||
383 | kfree(kbd_dev); | ||
384 | return error; | ||
385 | } | ||
386 | |||
387 | static int hv_kbd_remove(struct hv_device *hv_dev) | ||
388 | { | ||
389 | struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); | ||
390 | |||
391 | serio_unregister_port(kbd_dev->hv_serio); | ||
392 | vmbus_close(hv_dev->channel); | ||
393 | kfree(kbd_dev); | ||
394 | |||
395 | hv_set_drvdata(hv_dev, NULL); | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * Keyboard GUID | ||
402 | * {f912ad6d-2b17-48ea-bd65-f927a61c7684} | ||
403 | */ | ||
404 | #define HV_KBD_GUID \ | ||
405 | .guid = { \ | ||
406 | 0x6d, 0xad, 0x12, 0xf9, 0x17, 0x2b, 0xea, 0x48, \ | ||
407 | 0xbd, 0x65, 0xf9, 0x27, 0xa6, 0x1c, 0x76, 0x84 \ | ||
408 | } | ||
409 | |||
410 | static const struct hv_vmbus_device_id id_table[] = { | ||
411 | /* Keyboard guid */ | ||
412 | { HV_KBD_GUID, }, | ||
413 | { }, | ||
414 | }; | ||
415 | |||
416 | MODULE_DEVICE_TABLE(vmbus, id_table); | ||
417 | |||
418 | static struct hv_driver hv_kbd_drv = { | ||
419 | .name = KBUILD_MODNAME, | ||
420 | .id_table = id_table, | ||
421 | .probe = hv_kbd_probe, | ||
422 | .remove = hv_kbd_remove, | ||
423 | }; | ||
424 | |||
425 | static int __init hv_kbd_init(void) | ||
426 | { | ||
427 | return vmbus_driver_register(&hv_kbd_drv); | ||
428 | } | ||
429 | |||
430 | static void __exit hv_kbd_exit(void) | ||
431 | { | ||
432 | vmbus_driver_unregister(&hv_kbd_drv); | ||
433 | } | ||
434 | |||
435 | MODULE_LICENSE("GPL"); | ||
436 | module_init(hv_kbd_init); | ||
437 | module_exit(hv_kbd_exit); | ||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 5f306f79da0c..0ec9abbe31fe 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -765,6 +765,7 @@ static struct pnp_device_id pnp_kbd_devids[] = { | |||
765 | { .id = "CPQA0D7", .driver_data = 0 }, | 765 | { .id = "CPQA0D7", .driver_data = 0 }, |
766 | { .id = "", }, | 766 | { .id = "", }, |
767 | }; | 767 | }; |
768 | MODULE_DEVICE_TABLE(pnp, pnp_kbd_devids); | ||
768 | 769 | ||
769 | static struct pnp_driver i8042_pnp_kbd_driver = { | 770 | static struct pnp_driver i8042_pnp_kbd_driver = { |
770 | .name = "i8042 kbd", | 771 | .name = "i8042 kbd", |
@@ -786,6 +787,7 @@ static struct pnp_device_id pnp_aux_devids[] = { | |||
786 | { .id = "SYN0801", .driver_data = 0 }, | 787 | { .id = "SYN0801", .driver_data = 0 }, |
787 | { .id = "", }, | 788 | { .id = "", }, |
788 | }; | 789 | }; |
790 | MODULE_DEVICE_TABLE(pnp, pnp_aux_devids); | ||
789 | 791 | ||
790 | static struct pnp_driver i8042_pnp_aux_driver = { | 792 | static struct pnp_driver i8042_pnp_aux_driver = { |
791 | .name = "i8042 aux", | 793 | .name = "i8042 aux", |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 25fc5971f426..2b56855c2c77 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -732,19 +732,20 @@ EXPORT_SYMBOL(serio_unregister_child_port); | |||
732 | * Serio driver operations | 732 | * Serio driver operations |
733 | */ | 733 | */ |
734 | 734 | ||
735 | static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf) | 735 | static ssize_t description_show(struct device_driver *drv, char *buf) |
736 | { | 736 | { |
737 | struct serio_driver *driver = to_serio_driver(drv); | 737 | struct serio_driver *driver = to_serio_driver(drv); |
738 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); | 738 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); |
739 | } | 739 | } |
740 | static DRIVER_ATTR_RO(description); | ||
740 | 741 | ||
741 | static ssize_t serio_driver_show_bind_mode(struct device_driver *drv, char *buf) | 742 | static ssize_t bind_mode_show(struct device_driver *drv, char *buf) |
742 | { | 743 | { |
743 | struct serio_driver *serio_drv = to_serio_driver(drv); | 744 | struct serio_driver *serio_drv = to_serio_driver(drv); |
744 | return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto"); | 745 | return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto"); |
745 | } | 746 | } |
746 | 747 | ||
747 | static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char *buf, size_t count) | 748 | static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count) |
748 | { | 749 | { |
749 | struct serio_driver *serio_drv = to_serio_driver(drv); | 750 | struct serio_driver *serio_drv = to_serio_driver(drv); |
750 | int retval; | 751 | int retval; |
@@ -760,14 +761,14 @@ static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char | |||
760 | 761 | ||
761 | return retval; | 762 | return retval; |
762 | } | 763 | } |
764 | static DRIVER_ATTR_RW(bind_mode); | ||
763 | 765 | ||
764 | 766 | static struct attribute *serio_driver_attrs[] = { | |
765 | static struct driver_attribute serio_driver_attrs[] = { | 767 | &driver_attr_description.attr, |
766 | __ATTR(description, S_IRUGO, serio_driver_show_description, NULL), | 768 | &driver_attr_bind_mode.attr, |
767 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, | 769 | NULL, |
768 | serio_driver_show_bind_mode, serio_driver_set_bind_mode), | ||
769 | __ATTR_NULL | ||
770 | }; | 770 | }; |
771 | ATTRIBUTE_GROUPS(serio_driver); | ||
771 | 772 | ||
772 | static int serio_driver_probe(struct device *dev) | 773 | static int serio_driver_probe(struct device *dev) |
773 | { | 774 | { |
@@ -996,7 +997,7 @@ EXPORT_SYMBOL(serio_interrupt); | |||
996 | static struct bus_type serio_bus = { | 997 | static struct bus_type serio_bus = { |
997 | .name = "serio", | 998 | .name = "serio", |
998 | .dev_attrs = serio_device_attrs, | 999 | .dev_attrs = serio_device_attrs, |
999 | .drv_attrs = serio_driver_attrs, | 1000 | .drv_groups = serio_driver_groups, |
1000 | .match = serio_bus_match, | 1001 | .match = serio_bus_match, |
1001 | .uevent = serio_uevent, | 1002 | .uevent = serio_uevent, |
1002 | .probe = serio_driver_probe, | 1003 | .probe = serio_driver_probe, |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index e53416a4d7f3..867e7c33ac55 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
@@ -524,9 +524,6 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int | |||
524 | 524 | ||
525 | error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, | 525 | error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, |
526 | report_id, rep_data, length, 1); | 526 | report_id, rep_data, length, 1); |
527 | if (error >= 0) | ||
528 | error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, | ||
529 | report_id, rep_data, length, 1); | ||
530 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); | 527 | } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); |
531 | 528 | ||
532 | kfree(rep_data); | 529 | kfree(rep_data); |
@@ -548,7 +545,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat | |||
548 | /* MT Tablet PC touch */ | 545 | /* MT Tablet PC touch */ |
549 | return wacom_set_device_mode(intf, 3, 4, 4); | 546 | return wacom_set_device_mode(intf, 3, 4, 4); |
550 | } | 547 | } |
551 | else if (features->type == WACOM_24HDT) { | 548 | else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { |
552 | return wacom_set_device_mode(intf, 18, 3, 2); | 549 | return wacom_set_device_mode(intf, 18, 3, 2); |
553 | } | 550 | } |
554 | } else if (features->device_type == BTN_TOOL_PEN) { | 551 | } else if (features->device_type == BTN_TOOL_PEN) { |
@@ -719,7 +716,7 @@ static int wacom_led_control(struct wacom *wacom) | |||
719 | return -ENOMEM; | 716 | return -ENOMEM; |
720 | 717 | ||
721 | if (wacom->wacom_wac.features.type >= INTUOS5S && | 718 | if (wacom->wacom_wac.features.type >= INTUOS5S && |
722 | wacom->wacom_wac.features.type <= INTUOS5L) { | 719 | wacom->wacom_wac.features.type <= INTUOSPL) { |
723 | /* | 720 | /* |
724 | * Touch Ring and crop mark LED luminance may take on | 721 | * Touch Ring and crop mark LED luminance may take on |
725 | * one of four values: | 722 | * one of four values: |
@@ -981,14 +978,20 @@ static int wacom_initialize_leds(struct wacom *wacom) | |||
981 | case INTUOS5S: | 978 | case INTUOS5S: |
982 | case INTUOS5: | 979 | case INTUOS5: |
983 | case INTUOS5L: | 980 | case INTUOS5L: |
984 | wacom->led.select[0] = 0; | 981 | case INTUOSPS: |
985 | wacom->led.select[1] = 0; | 982 | case INTUOSPM: |
986 | wacom->led.llv = 32; | 983 | case INTUOSPL: |
987 | wacom->led.hlv = 0; | 984 | if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN) { |
988 | wacom->led.img_lum = 0; | 985 | wacom->led.select[0] = 0; |
989 | 986 | wacom->led.select[1] = 0; | |
990 | error = sysfs_create_group(&wacom->intf->dev.kobj, | 987 | wacom->led.llv = 32; |
991 | &intuos5_led_attr_group); | 988 | wacom->led.hlv = 0; |
989 | wacom->led.img_lum = 0; | ||
990 | |||
991 | error = sysfs_create_group(&wacom->intf->dev.kobj, | ||
992 | &intuos5_led_attr_group); | ||
993 | } else | ||
994 | return 0; | ||
992 | break; | 995 | break; |
993 | 996 | ||
994 | default: | 997 | default: |
@@ -1024,8 +1027,12 @@ static void wacom_destroy_leds(struct wacom *wacom) | |||
1024 | case INTUOS5S: | 1027 | case INTUOS5S: |
1025 | case INTUOS5: | 1028 | case INTUOS5: |
1026 | case INTUOS5L: | 1029 | case INTUOS5L: |
1027 | sysfs_remove_group(&wacom->intf->dev.kobj, | 1030 | case INTUOSPS: |
1028 | &intuos5_led_attr_group); | 1031 | case INTUOSPM: |
1032 | case INTUOSPL: | ||
1033 | if (wacom->wacom_wac.features.device_type == BTN_TOOL_PEN) | ||
1034 | sysfs_remove_group(&wacom->intf->dev.kobj, | ||
1035 | &intuos5_led_attr_group); | ||
1029 | break; | 1036 | break; |
1030 | } | 1037 | } |
1031 | } | 1038 | } |
@@ -1185,34 +1192,47 @@ static void wacom_wireless_work(struct work_struct *work) | |||
1185 | wacom_wac1->features = | 1192 | wacom_wac1->features = |
1186 | *((struct wacom_features *)id->driver_info); | 1193 | *((struct wacom_features *)id->driver_info); |
1187 | wacom_wac1->features.device_type = BTN_TOOL_PEN; | 1194 | wacom_wac1->features.device_type = BTN_TOOL_PEN; |
1195 | snprintf(wacom_wac1->name, WACOM_NAME_MAX, "%s (WL) Pen", | ||
1196 | wacom_wac1->features.name); | ||
1188 | error = wacom_register_input(wacom1); | 1197 | error = wacom_register_input(wacom1); |
1189 | if (error) | 1198 | if (error) |
1190 | goto fail1; | 1199 | goto fail; |
1191 | 1200 | ||
1192 | /* Touch interface */ | 1201 | /* Touch interface */ |
1193 | wacom_wac2->features = | 1202 | if (wacom_wac1->features.touch_max) { |
1194 | *((struct wacom_features *)id->driver_info); | 1203 | wacom_wac2->features = |
1195 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; | 1204 | *((struct wacom_features *)id->driver_info); |
1196 | wacom_wac2->features.device_type = BTN_TOOL_FINGER; | 1205 | wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; |
1197 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; | 1206 | wacom_wac2->features.device_type = BTN_TOOL_FINGER; |
1198 | error = wacom_register_input(wacom2); | 1207 | wacom_wac2->features.x_max = wacom_wac2->features.y_max = 4096; |
1199 | if (error) | 1208 | if (wacom_wac2->features.touch_max) |
1200 | goto fail2; | 1209 | snprintf(wacom_wac2->name, WACOM_NAME_MAX, |
1210 | "%s (WL) Finger",wacom_wac2->features.name); | ||
1211 | else | ||
1212 | snprintf(wacom_wac2->name, WACOM_NAME_MAX, | ||
1213 | "%s (WL) Pad",wacom_wac2->features.name); | ||
1214 | error = wacom_register_input(wacom2); | ||
1215 | if (error) | ||
1216 | goto fail; | ||
1217 | } | ||
1201 | 1218 | ||
1202 | error = wacom_initialize_battery(wacom); | 1219 | error = wacom_initialize_battery(wacom); |
1203 | if (error) | 1220 | if (error) |
1204 | goto fail3; | 1221 | goto fail; |
1205 | } | 1222 | } |
1206 | 1223 | ||
1207 | return; | 1224 | return; |
1208 | 1225 | ||
1209 | fail3: | 1226 | fail: |
1210 | input_unregister_device(wacom_wac2->input); | 1227 | if (wacom_wac2->input) { |
1211 | wacom_wac2->input = NULL; | 1228 | input_unregister_device(wacom_wac2->input); |
1212 | fail2: | 1229 | wacom_wac2->input = NULL; |
1213 | input_unregister_device(wacom_wac1->input); | 1230 | } |
1214 | wacom_wac1->input = NULL; | 1231 | |
1215 | fail1: | 1232 | if (wacom_wac1->input) { |
1233 | input_unregister_device(wacom_wac1->input); | ||
1234 | wacom_wac1->input = NULL; | ||
1235 | } | ||
1216 | return; | 1236 | return; |
1217 | } | 1237 | } |
1218 | 1238 | ||
@@ -1302,7 +1322,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1302 | * HID descriptor. If this is the touch interface (wMaxPacketSize | 1322 | * HID descriptor. If this is the touch interface (wMaxPacketSize |
1303 | * of WACOM_PKGLEN_BBTOUCH3), override the table values. | 1323 | * of WACOM_PKGLEN_BBTOUCH3), override the table values. |
1304 | */ | 1324 | */ |
1305 | if (features->type >= INTUOS5S && features->type <= INTUOS5L) { | 1325 | if (features->type >= INTUOS5S && features->type <= INTUOSPL) { |
1306 | if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) { | 1326 | if (endpoint->wMaxPacketSize == WACOM_PKGLEN_BBTOUCH3) { |
1307 | features->device_type = BTN_TOOL_FINGER; | 1327 | features->device_type = BTN_TOOL_FINGER; |
1308 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; | 1328 | features->pktlen = WACOM_PKGLEN_BBTOUCH3; |
@@ -1329,10 +1349,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1329 | struct usb_device *other_dev; | 1349 | struct usb_device *other_dev; |
1330 | 1350 | ||
1331 | /* Append the device type to the name */ | 1351 | /* Append the device type to the name */ |
1332 | strlcat(wacom_wac->name, | 1352 | if (features->device_type != BTN_TOOL_FINGER) |
1333 | features->device_type == BTN_TOOL_PEN ? | 1353 | strlcat(wacom_wac->name, " Pen", WACOM_NAME_MAX); |
1334 | " Pen" : " Finger", | 1354 | else if (features->touch_max) |
1335 | sizeof(wacom_wac->name)); | 1355 | strlcat(wacom_wac->name, " Finger", WACOM_NAME_MAX); |
1356 | else | ||
1357 | strlcat(wacom_wac->name, " Pad", WACOM_NAME_MAX); | ||
1336 | 1358 | ||
1337 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); | 1359 | other_dev = wacom_get_sibling(dev, features->oVid, features->oPid); |
1338 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) | 1360 | if (other_dev == NULL || wacom_get_usbdev_data(other_dev) == NULL) |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index c59b797eeafa..782c2535f1d8 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -427,6 +427,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) | |||
427 | (features->type == WACOM_21UX2)) | 427 | (features->type == WACOM_21UX2)) |
428 | return 1; | 428 | return 1; |
429 | 429 | ||
430 | /* Range Report */ | ||
431 | if ((data[1] & 0xfe) == 0x20) { | ||
432 | input_report_key(input, BTN_TOUCH, 0); | ||
433 | input_report_abs(input, ABS_PRESSURE, 0); | ||
434 | input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max); | ||
435 | } | ||
436 | |||
430 | /* Exit report */ | 437 | /* Exit report */ |
431 | if ((data[1] & 0xfe) == 0x80) { | 438 | if ((data[1] & 0xfe) == 0x80) { |
432 | if (features->quirks == WACOM_QUIRK_MULTI_INPUT) | 439 | if (features->quirks == WACOM_QUIRK_MULTI_INPUT) |
@@ -477,7 +484,7 @@ static void wacom_intuos_general(struct wacom_wac *wacom) | |||
477 | /* general pen packet */ | 484 | /* general pen packet */ |
478 | if ((data[1] & 0xb8) == 0xa0) { | 485 | if ((data[1] & 0xb8) == 0xa0) { |
479 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 486 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
480 | if (features->type >= INTUOS4S && features->type <= WACOM_24HD) { | 487 | if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { |
481 | t = (t << 1) | (data[1] & 1); | 488 | t = (t << 1) | (data[1] & 1); |
482 | } | 489 | } |
483 | input_report_abs(input, ABS_PRESSURE, t); | 490 | input_report_abs(input, ABS_PRESSURE, t); |
@@ -621,14 +628,30 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
621 | } else { | 628 | } else { |
622 | input_report_abs(input, ABS_MISC, 0); | 629 | input_report_abs(input, ABS_MISC, 0); |
623 | } | 630 | } |
624 | } else if (features->type >= INTUOS5S && features->type <= INTUOS5L) { | 631 | } else if (features->type == CINTIQ_HYBRID) { |
632 | /* | ||
633 | * Do not send hardware buttons under Android. They | ||
634 | * are already sent to the system through GPIO (and | ||
635 | * have different meaning). | ||
636 | */ | ||
637 | input_report_key(input, BTN_1, (data[4] & 0x01)); | ||
638 | input_report_key(input, BTN_2, (data[4] & 0x02)); | ||
639 | input_report_key(input, BTN_3, (data[4] & 0x04)); | ||
640 | input_report_key(input, BTN_4, (data[4] & 0x08)); | ||
641 | |||
642 | input_report_key(input, BTN_5, (data[4] & 0x10)); /* Right */ | ||
643 | input_report_key(input, BTN_6, (data[4] & 0x20)); /* Up */ | ||
644 | input_report_key(input, BTN_7, (data[4] & 0x40)); /* Left */ | ||
645 | input_report_key(input, BTN_8, (data[4] & 0x80)); /* Down */ | ||
646 | input_report_key(input, BTN_0, (data[3] & 0x01)); /* Center */ | ||
647 | } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { | ||
625 | int i; | 648 | int i; |
626 | 649 | ||
627 | /* Touch ring mode switch has no capacitive sensor */ | 650 | /* Touch ring mode switch has no capacitive sensor */ |
628 | input_report_key(input, BTN_0, (data[3] & 0x01)); | 651 | input_report_key(input, BTN_0, (data[3] & 0x01)); |
629 | 652 | ||
630 | /* | 653 | /* |
631 | * ExpressKeys on Intuos5 have a capacitive sensor in | 654 | * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in |
632 | * addition to the mechanical switch. Switch data is | 655 | * addition to the mechanical switch. Switch data is |
633 | * stored in data[4], capacitive data in data[5]. | 656 | * stored in data[4], capacitive data in data[5]. |
634 | */ | 657 | */ |
@@ -716,7 +739,9 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
716 | features->type == INTUOS4 || | 739 | features->type == INTUOS4 || |
717 | features->type == INTUOS4S || | 740 | features->type == INTUOS4S || |
718 | features->type == INTUOS5 || | 741 | features->type == INTUOS5 || |
719 | features->type == INTUOS5S)) { | 742 | features->type == INTUOS5S || |
743 | features->type == INTUOSPM || | ||
744 | features->type == INTUOSPS)) { | ||
720 | 745 | ||
721 | return 0; | 746 | return 0; |
722 | } | 747 | } |
@@ -769,8 +794,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
769 | 794 | ||
770 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | 795 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { |
771 | /* I4 mouse */ | 796 | /* I4 mouse */ |
772 | if ((features->type >= INTUOS4S && features->type <= INTUOS4L) || | 797 | if (features->type >= INTUOS4S && features->type <= INTUOSPL) { |
773 | (features->type >= INTUOS5S && features->type <= INTUOS5L)) { | ||
774 | input_report_key(input, BTN_LEFT, data[6] & 0x01); | 798 | input_report_key(input, BTN_LEFT, data[6] & 0x01); |
775 | input_report_key(input, BTN_MIDDLE, data[6] & 0x02); | 799 | input_report_key(input, BTN_MIDDLE, data[6] & 0x02); |
776 | input_report_key(input, BTN_RIGHT, data[6] & 0x04); | 800 | input_report_key(input, BTN_RIGHT, data[6] & 0x04); |
@@ -797,7 +821,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) | |||
797 | } | 821 | } |
798 | } | 822 | } |
799 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || | 823 | } else if ((features->type < INTUOS3S || features->type == INTUOS3L || |
800 | features->type == INTUOS4L || features->type == INTUOS5L) && | 824 | features->type == INTUOS4L || features->type == INTUOS5L || |
825 | features->type == INTUOSPL) && | ||
801 | wacom->tool[idx] == BTN_TOOL_LENS) { | 826 | wacom->tool[idx] == BTN_TOOL_LENS) { |
802 | /* Lens cursor packets */ | 827 | /* Lens cursor packets */ |
803 | input_report_key(input, BTN_LEFT, data[8] & 0x01); | 828 | input_report_key(input, BTN_LEFT, data[8] & 0x01); |
@@ -1107,6 +1132,7 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) | |||
1107 | 1132 | ||
1108 | static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | 1133 | static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) |
1109 | { | 1134 | { |
1135 | struct wacom_features *features = &wacom->features; | ||
1110 | struct input_dev *input = wacom->input; | 1136 | struct input_dev *input = wacom->input; |
1111 | bool touch = data[1] & 0x80; | 1137 | bool touch = data[1] & 0x80; |
1112 | int slot = input_mt_get_slot_by_key(input, data[0]); | 1138 | int slot = input_mt_get_slot_by_key(input, data[0]); |
@@ -1122,14 +1148,23 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) | |||
1122 | if (touch) { | 1148 | if (touch) { |
1123 | int x = (data[2] << 4) | (data[4] >> 4); | 1149 | int x = (data[2] << 4) | (data[4] >> 4); |
1124 | int y = (data[3] << 4) | (data[4] & 0x0f); | 1150 | int y = (data[3] << 4) | (data[4] & 0x0f); |
1125 | int a = data[5]; | 1151 | int width, height; |
1126 | 1152 | ||
1127 | // "a" is a scaled-down area which we assume is roughly | 1153 | if (features->type >= INTUOSPS && features->type <= INTUOSPL) { |
1128 | // circular and which can be described as: a=(pi*r^2)/C. | 1154 | width = data[5]; |
1129 | int x_res = input_abs_get_res(input, ABS_X); | 1155 | height = data[6]; |
1130 | int y_res = input_abs_get_res(input, ABS_Y); | 1156 | } else { |
1131 | int width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE); | 1157 | /* |
1132 | int height = width * y_res / x_res; | 1158 | * "a" is a scaled-down area which we assume is |
1159 | * roughly circular and which can be described as: | ||
1160 | * a=(pi*r^2)/C. | ||
1161 | */ | ||
1162 | int a = data[5]; | ||
1163 | int x_res = input_abs_get_res(input, ABS_X); | ||
1164 | int y_res = input_abs_get_res(input, ABS_Y); | ||
1165 | width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE); | ||
1166 | height = width * y_res / x_res; | ||
1167 | } | ||
1133 | 1168 | ||
1134 | input_report_abs(input, ABS_MT_POSITION_X, x); | 1169 | input_report_abs(input, ABS_MT_POSITION_X, x); |
1135 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 1170 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
@@ -1327,6 +1362,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1327 | case WACOM_22HD: | 1362 | case WACOM_22HD: |
1328 | case WACOM_24HD: | 1363 | case WACOM_24HD: |
1329 | case DTK: | 1364 | case DTK: |
1365 | case CINTIQ_HYBRID: | ||
1330 | sync = wacom_intuos_irq(wacom_wac); | 1366 | sync = wacom_intuos_irq(wacom_wac); |
1331 | break; | 1367 | break; |
1332 | 1368 | ||
@@ -1337,6 +1373,9 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
1337 | case INTUOS5S: | 1373 | case INTUOS5S: |
1338 | case INTUOS5: | 1374 | case INTUOS5: |
1339 | case INTUOS5L: | 1375 | case INTUOS5L: |
1376 | case INTUOSPS: | ||
1377 | case INTUOSPM: | ||
1378 | case INTUOSPL: | ||
1340 | if (len == WACOM_PKGLEN_BBTOUCH3) | 1379 | if (len == WACOM_PKGLEN_BBTOUCH3) |
1341 | sync = wacom_bpt3_touch(wacom_wac); | 1380 | sync = wacom_bpt3_touch(wacom_wac); |
1342 | else | 1381 | else |
@@ -1420,7 +1459,7 @@ void wacom_setup_device_quirks(struct wacom_features *features) | |||
1420 | 1459 | ||
1421 | /* these device have multiple inputs */ | 1460 | /* these device have multiple inputs */ |
1422 | if (features->type >= WIRELESS || | 1461 | if (features->type >= WIRELESS || |
1423 | (features->type >= INTUOS5S && features->type <= INTUOS5L) || | 1462 | (features->type >= INTUOS5S && features->type <= INTUOSPL) || |
1424 | (features->oVid && features->oPid)) | 1463 | (features->oVid && features->oPid)) |
1425 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; | 1464 | features->quirks |= WACOM_QUIRK_MULTI_INPUT; |
1426 | 1465 | ||
@@ -1627,6 +1666,8 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1627 | 1666 | ||
1628 | case INTUOS5: | 1667 | case INTUOS5: |
1629 | case INTUOS5L: | 1668 | case INTUOS5L: |
1669 | case INTUOSPM: | ||
1670 | case INTUOSPL: | ||
1630 | if (features->device_type == BTN_TOOL_PEN) { | 1671 | if (features->device_type == BTN_TOOL_PEN) { |
1631 | __set_bit(BTN_7, input_dev->keybit); | 1672 | __set_bit(BTN_7, input_dev->keybit); |
1632 | __set_bit(BTN_8, input_dev->keybit); | 1673 | __set_bit(BTN_8, input_dev->keybit); |
@@ -1634,6 +1675,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1634 | /* fall through */ | 1675 | /* fall through */ |
1635 | 1676 | ||
1636 | case INTUOS5S: | 1677 | case INTUOS5S: |
1678 | case INTUOSPS: | ||
1637 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | 1679 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); |
1638 | 1680 | ||
1639 | if (features->device_type == BTN_TOOL_PEN) { | 1681 | if (features->device_type == BTN_TOOL_PEN) { |
@@ -1765,6 +1807,24 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, | |||
1765 | 0, 0); | 1807 | 0, 0); |
1766 | } | 1808 | } |
1767 | break; | 1809 | break; |
1810 | |||
1811 | case CINTIQ_HYBRID: | ||
1812 | __set_bit(BTN_1, input_dev->keybit); | ||
1813 | __set_bit(BTN_2, input_dev->keybit); | ||
1814 | __set_bit(BTN_3, input_dev->keybit); | ||
1815 | __set_bit(BTN_4, input_dev->keybit); | ||
1816 | |||
1817 | __set_bit(BTN_5, input_dev->keybit); | ||
1818 | __set_bit(BTN_6, input_dev->keybit); | ||
1819 | __set_bit(BTN_7, input_dev->keybit); | ||
1820 | __set_bit(BTN_8, input_dev->keybit); | ||
1821 | __set_bit(BTN_0, input_dev->keybit); | ||
1822 | |||
1823 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
1824 | __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); | ||
1825 | |||
1826 | wacom_setup_cintiq(wacom_wac); | ||
1827 | break; | ||
1768 | } | 1828 | } |
1769 | return 0; | 1829 | return 0; |
1770 | } | 1830 | } |
@@ -1952,6 +2012,18 @@ static const struct wacom_features wacom_features_0x29 = | |||
1952 | static const struct wacom_features wacom_features_0x2A = | 2012 | static const struct wacom_features wacom_features_0x2A = |
1953 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | 2013 | { "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, |
1954 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2014 | 63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
2015 | static const struct wacom_features wacom_features_0x314 = | ||
2016 | { "Wacom Intuos Pro S", WACOM_PKGLEN_INTUOS, 31496, 19685, 2047, | ||
2017 | 63, INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
2018 | .touch_max = 16 }; | ||
2019 | static const struct wacom_features wacom_features_0x315 = | ||
2020 | { "Wacom Intuos Pro M", WACOM_PKGLEN_INTUOS, 44704, 27940, 2047, | ||
2021 | 63, INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
2022 | .touch_max = 16 }; | ||
2023 | static const struct wacom_features wacom_features_0x317 = | ||
2024 | { "Wacom Intuos Pro L", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047, | ||
2025 | 63, INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
2026 | .touch_max = 16 }; | ||
1955 | static const struct wacom_features wacom_features_0xF4 = | 2027 | static const struct wacom_features wacom_features_0xF4 = |
1956 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, | 2028 | { "Wacom Cintiq 24HD", WACOM_PKGLEN_INTUOS, 104480, 65600, 2047, |
1957 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; | 2029 | 63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES }; |
@@ -2131,6 +2203,13 @@ static const struct wacom_features wacom_features_0x301 = | |||
2131 | static const struct wacom_features wacom_features_0x6004 = | 2203 | static const struct wacom_features wacom_features_0x6004 = |
2132 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, | 2204 | { "ISD-V4", WACOM_PKGLEN_GRAPHIRE, 12800, 8000, 255, |
2133 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 2205 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
2206 | static const struct wacom_features wacom_features_0x0307 = | ||
2207 | { "Wacom ISDv5 307", WACOM_PKGLEN_INTUOS, 59552, 33848, 2047, | ||
2208 | 63, CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, | ||
2209 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 }; | ||
2210 | static const struct wacom_features wacom_features_0x0309 = | ||
2211 | { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */ | ||
2212 | .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10 }; | ||
2134 | 2213 | ||
2135 | #define USB_DEVICE_WACOM(prod) \ | 2214 | #define USB_DEVICE_WACOM(prod) \ |
2136 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 2215 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
@@ -2259,12 +2338,17 @@ const struct usb_device_id wacom_ids[] = { | |||
2259 | { USB_DEVICE_WACOM(0x300) }, | 2338 | { USB_DEVICE_WACOM(0x300) }, |
2260 | { USB_DEVICE_WACOM(0x301) }, | 2339 | { USB_DEVICE_WACOM(0x301) }, |
2261 | { USB_DEVICE_WACOM(0x304) }, | 2340 | { USB_DEVICE_WACOM(0x304) }, |
2341 | { USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) }, | ||
2342 | { USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) }, | ||
2343 | { USB_DEVICE_DETAILED(0x317, USB_CLASS_HID, 0, 0) }, | ||
2262 | { USB_DEVICE_WACOM(0x4001) }, | 2344 | { USB_DEVICE_WACOM(0x4001) }, |
2263 | { USB_DEVICE_WACOM(0x47) }, | 2345 | { USB_DEVICE_WACOM(0x47) }, |
2264 | { USB_DEVICE_WACOM(0xF4) }, | 2346 | { USB_DEVICE_WACOM(0xF4) }, |
2265 | { USB_DEVICE_WACOM(0xF8) }, | 2347 | { USB_DEVICE_WACOM(0xF8) }, |
2266 | { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) }, | 2348 | { USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) }, |
2267 | { USB_DEVICE_WACOM(0xFA) }, | 2349 | { USB_DEVICE_WACOM(0xFA) }, |
2350 | { USB_DEVICE_WACOM(0x0307) }, | ||
2351 | { USB_DEVICE_DETAILED(0x0309, USB_CLASS_HID, 0, 0) }, | ||
2268 | { USB_DEVICE_LENOVO(0x6004) }, | 2352 | { USB_DEVICE_LENOVO(0x6004) }, |
2269 | { } | 2353 | { } |
2270 | }; | 2354 | }; |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index dfc9e08e7f70..fd23a3790605 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
@@ -14,6 +14,8 @@ | |||
14 | /* maximum packet length for USB devices */ | 14 | /* maximum packet length for USB devices */ |
15 | #define WACOM_PKGLEN_MAX 64 | 15 | #define WACOM_PKGLEN_MAX 64 |
16 | 16 | ||
17 | #define WACOM_NAME_MAX 64 | ||
18 | |||
17 | /* packet length for individual models */ | 19 | /* packet length for individual models */ |
18 | #define WACOM_PKGLEN_PENPRTN 7 | 20 | #define WACOM_PKGLEN_PENPRTN 7 |
19 | #define WACOM_PKGLEN_GRAPHIRE 8 | 21 | #define WACOM_PKGLEN_GRAPHIRE 8 |
@@ -76,10 +78,14 @@ enum { | |||
76 | INTUOS5S, | 78 | INTUOS5S, |
77 | INTUOS5, | 79 | INTUOS5, |
78 | INTUOS5L, | 80 | INTUOS5L, |
81 | INTUOSPS, | ||
82 | INTUOSPM, | ||
83 | INTUOSPL, | ||
79 | WACOM_21UX2, | 84 | WACOM_21UX2, |
80 | WACOM_22HD, | 85 | WACOM_22HD, |
81 | DTK, | 86 | DTK, |
82 | WACOM_24HD, | 87 | WACOM_24HD, |
88 | CINTIQ_HYBRID, | ||
83 | CINTIQ, | 89 | CINTIQ, |
84 | WACOM_BEE, | 90 | WACOM_BEE, |
85 | WACOM_13HD, | 91 | WACOM_13HD, |
@@ -126,7 +132,7 @@ struct wacom_shared { | |||
126 | }; | 132 | }; |
127 | 133 | ||
128 | struct wacom_wac { | 134 | struct wacom_wac { |
129 | char name[64]; | 135 | char name[WACOM_NAME_MAX]; |
130 | unsigned char *data; | 136 | unsigned char *data; |
131 | int tool[2]; | 137 | int tool[2]; |
132 | int id[2]; | 138 | int id[2]; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 3b9758b5f4d7..00d1e547b211 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -389,7 +389,7 @@ config TOUCHSCREEN_MCS5000 | |||
389 | 389 | ||
390 | config TOUCHSCREEN_MMS114 | 390 | config TOUCHSCREEN_MMS114 |
391 | tristate "MELFAS MMS114 touchscreen" | 391 | tristate "MELFAS MMS114 touchscreen" |
392 | depends on I2C && GENERIC_HARDIRQS | 392 | depends on I2C |
393 | help | 393 | help |
394 | Say Y here if you have the MELFAS MMS114 touchscreen controller | 394 | Say Y here if you have the MELFAS MMS114 touchscreen controller |
395 | chip in your system. | 395 | chip in your system. |
@@ -845,7 +845,7 @@ config TOUCHSCREEN_TSC_SERIO | |||
845 | 845 | ||
846 | config TOUCHSCREEN_TSC2005 | 846 | config TOUCHSCREEN_TSC2005 |
847 | tristate "TSC2005 based touchscreens" | 847 | tristate "TSC2005 based touchscreens" |
848 | depends on SPI_MASTER && GENERIC_HARDIRQS | 848 | depends on SPI_MASTER |
849 | help | 849 | help |
850 | Say Y here if you have a TSC2005 based touchscreen. | 850 | Say Y here if you have a TSC2005 based touchscreen. |
851 | 851 | ||
@@ -919,4 +919,17 @@ config TOUCHSCREEN_TPS6507X | |||
919 | To compile this driver as a module, choose M here: the | 919 | To compile this driver as a module, choose M here: the |
920 | module will be called tps6507x_ts. | 920 | module will be called tps6507x_ts. |
921 | 921 | ||
922 | config TOUCHSCREEN_ZFORCE | ||
923 | tristate "Neonode zForce infrared touchscreens" | ||
924 | depends on I2C | ||
925 | depends on GPIOLIB | ||
926 | help | ||
927 | Say Y here if you have a touchscreen using the zforce | ||
928 | infraread technology from Neonode. | ||
929 | |||
930 | If unsure, say N. | ||
931 | |||
932 | To compile this driver as a module, choose M here: the | ||
933 | module will be called zforce_ts. | ||
934 | |||
922 | endif | 935 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index f5216c1bf53e..7587883b8d38 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -75,3 +75,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | |||
75 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 75 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
76 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | 76 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o |
77 | obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o | 77 | obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o |
78 | obj-$(CONFIG_TOUCHSCREEN_ZFORCE) += zforce_ts.o | ||
diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index f3a174a83c82..69834dd3c313 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c | |||
@@ -806,7 +806,6 @@ err_free_irq: | |||
806 | err_free_mem: | 806 | err_free_mem: |
807 | input_free_device(input_dev); | 807 | input_free_device(input_dev); |
808 | kfree(ts); | 808 | kfree(ts); |
809 | spi_set_drvdata(spi, NULL); | ||
810 | return err; | 809 | return err; |
811 | } | 810 | } |
812 | 811 | ||
@@ -823,7 +822,6 @@ static int ad7877_remove(struct spi_device *spi) | |||
823 | kfree(ts); | 822 | kfree(ts); |
824 | 823 | ||
825 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); | 824 | dev_dbg(&spi->dev, "unregistered touchscreen\n"); |
826 | spi_set_drvdata(spi, NULL); | ||
827 | 825 | ||
828 | return 0; | 826 | return 0; |
829 | } | 827 | } |
diff --git a/drivers/input/touchscreen/ad7879-spi.c b/drivers/input/touchscreen/ad7879-spi.c index 606da5bd6115..1a7b1143536e 100644 --- a/drivers/input/touchscreen/ad7879-spi.c +++ b/drivers/input/touchscreen/ad7879-spi.c | |||
@@ -142,7 +142,6 @@ static int ad7879_spi_remove(struct spi_device *spi) | |||
142 | struct ad7879 *ts = spi_get_drvdata(spi); | 142 | struct ad7879 *ts = spi_get_drvdata(spi); |
143 | 143 | ||
144 | ad7879_remove(ts); | 144 | ad7879_remove(ts); |
145 | spi_set_drvdata(spi, NULL); | ||
146 | 145 | ||
147 | return 0; | 146 | return 0; |
148 | } | 147 | } |
diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index d038575f49db..42d830efa316 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c | |||
@@ -2113,7 +2113,6 @@ error_startup: | |||
2113 | error_request_irq: | 2113 | error_request_irq: |
2114 | if (cd->cpdata->init) | 2114 | if (cd->cpdata->init) |
2115 | cd->cpdata->init(cd->cpdata, 0, dev); | 2115 | cd->cpdata->init(cd->cpdata, 0, dev); |
2116 | dev_set_drvdata(dev, NULL); | ||
2117 | error_free_xfer: | 2116 | error_free_xfer: |
2118 | kfree(cd->xfer_buf); | 2117 | kfree(cd->xfer_buf); |
2119 | error_free_cd: | 2118 | error_free_cd: |
@@ -2151,7 +2150,6 @@ int cyttsp4_remove(struct cyttsp4 *cd) | |||
2151 | free_irq(cd->irq, cd); | 2150 | free_irq(cd->irq, cd); |
2152 | if (cd->cpdata->init) | 2151 | if (cd->cpdata->init) |
2153 | cd->cpdata->init(cd->cpdata, 0, dev); | 2152 | cd->cpdata->init(cd->cpdata, 0, dev); |
2154 | dev_set_drvdata(dev, NULL); | ||
2155 | cyttsp4_free_si_ptrs(cd); | 2153 | cyttsp4_free_si_ptrs(cd); |
2156 | kfree(cd); | 2154 | kfree(cd); |
2157 | return 0; | 2155 | return 0; |
diff --git a/drivers/input/touchscreen/cyttsp4_spi.c b/drivers/input/touchscreen/cyttsp4_spi.c index a71e1141d638..b19434cebbf6 100644 --- a/drivers/input/touchscreen/cyttsp4_spi.c +++ b/drivers/input/touchscreen/cyttsp4_spi.c | |||
@@ -171,10 +171,7 @@ static int cyttsp4_spi_probe(struct spi_device *spi) | |||
171 | ts = cyttsp4_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq, | 171 | ts = cyttsp4_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq, |
172 | CY_SPI_DATA_BUF_SIZE); | 172 | CY_SPI_DATA_BUF_SIZE); |
173 | 173 | ||
174 | if (IS_ERR(ts)) | 174 | return PTR_ERR_OR_ZERO(ts); |
175 | return PTR_ERR(ts); | ||
176 | |||
177 | return 0; | ||
178 | } | 175 | } |
179 | 176 | ||
180 | static int cyttsp4_spi_remove(struct spi_device *spi) | 177 | static int cyttsp4_spi_remove(struct spi_device *spi) |
diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index ef5fcb0945e9..054d22583248 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c | |||
@@ -273,7 +273,7 @@ static struct i2c_driver egalax_ts_driver = { | |||
273 | .name = "egalax_ts", | 273 | .name = "egalax_ts", |
274 | .owner = THIS_MODULE, | 274 | .owner = THIS_MODULE, |
275 | .pm = &egalax_ts_pm_ops, | 275 | .pm = &egalax_ts_pm_ops, |
276 | .of_match_table = of_match_ptr(egalax_ts_dt_ids), | 276 | .of_match_table = egalax_ts_dt_ids, |
277 | }, | 277 | }, |
278 | .id_table = egalax_ts_id, | 278 | .id_table = egalax_ts_id, |
279 | .probe = egalax_ts_probe, | 279 | .probe = egalax_ts_probe, |
diff --git a/drivers/input/touchscreen/htcpen.c b/drivers/input/touchscreen/htcpen.c index 66500852341b..92e2243fb77d 100644 --- a/drivers/input/touchscreen/htcpen.c +++ b/drivers/input/touchscreen/htcpen.c | |||
@@ -186,8 +186,6 @@ static int htcpen_isa_remove(struct device *dev, unsigned int id) | |||
186 | release_region(HTCPEN_PORT_INIT, 1); | 186 | release_region(HTCPEN_PORT_INIT, 1); |
187 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); | 187 | release_region(HTCPEN_PORT_IRQ_CLEAR, 1); |
188 | 188 | ||
189 | dev_set_drvdata(dev, NULL); | ||
190 | |||
191 | return 0; | 189 | return 0; |
192 | } | 190 | } |
193 | 191 | ||
diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 1740a2496371..2f03b2f289dd 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/input.h> | 24 | #include <linux/input.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/of.h> | ||
27 | #include <linux/of_gpio.h> | 28 | #include <linux/of_gpio.h> |
28 | #include <linux/pm_qos.h> | 29 | #include <linux/pm_qos.h> |
29 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 50fb1293874e..ad7564296ddf 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c | |||
@@ -24,8 +24,9 @@ | |||
24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/input/ti_am335x_tsc.h> | ||
28 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/of_device.h> | ||
29 | 30 | ||
30 | #include <linux/mfd/ti_am335x_tscadc.h> | 31 | #include <linux/mfd/ti_am335x_tscadc.h> |
31 | 32 | ||
@@ -33,6 +34,13 @@ | |||
33 | #define SEQ_SETTLE 275 | 34 | #define SEQ_SETTLE 275 |
34 | #define MAX_12BIT ((1 << 12) - 1) | 35 | #define MAX_12BIT ((1 << 12) - 1) |
35 | 36 | ||
37 | static const int config_pins[] = { | ||
38 | STEPCONFIG_XPP, | ||
39 | STEPCONFIG_XNN, | ||
40 | STEPCONFIG_YPP, | ||
41 | STEPCONFIG_YNN, | ||
42 | }; | ||
43 | |||
36 | struct titsc { | 44 | struct titsc { |
37 | struct input_dev *input; | 45 | struct input_dev *input; |
38 | struct ti_tscadc_dev *mfd_tscadc; | 46 | struct ti_tscadc_dev *mfd_tscadc; |
@@ -40,7 +48,10 @@ struct titsc { | |||
40 | unsigned int wires; | 48 | unsigned int wires; |
41 | unsigned int x_plate_resistance; | 49 | unsigned int x_plate_resistance; |
42 | bool pen_down; | 50 | bool pen_down; |
43 | int steps_to_configure; | 51 | int coordinate_readouts; |
52 | u32 config_inp[4]; | ||
53 | u32 bit_xp, bit_xn, bit_yp, bit_yn; | ||
54 | u32 inp_xp, inp_xn, inp_yp, inp_yn; | ||
44 | }; | 55 | }; |
45 | 56 | ||
46 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) | 57 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) |
@@ -54,92 +65,153 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg, | |||
54 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); | 65 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); |
55 | } | 66 | } |
56 | 67 | ||
68 | static int titsc_config_wires(struct titsc *ts_dev) | ||
69 | { | ||
70 | u32 analog_line[4]; | ||
71 | u32 wire_order[4]; | ||
72 | int i, bit_cfg; | ||
73 | |||
74 | for (i = 0; i < 4; i++) { | ||
75 | /* | ||
76 | * Get the order in which TSC wires are attached | ||
77 | * w.r.t. each of the analog input lines on the EVM. | ||
78 | */ | ||
79 | analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4; | ||
80 | wire_order[i] = ts_dev->config_inp[i] & 0x0F; | ||
81 | if (WARN_ON(analog_line[i] > 7)) | ||
82 | return -EINVAL; | ||
83 | if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | for (i = 0; i < 4; i++) { | ||
88 | int an_line; | ||
89 | int wi_order; | ||
90 | |||
91 | an_line = analog_line[i]; | ||
92 | wi_order = wire_order[i]; | ||
93 | bit_cfg = config_pins[wi_order]; | ||
94 | if (bit_cfg == 0) | ||
95 | return -EINVAL; | ||
96 | switch (wi_order) { | ||
97 | case 0: | ||
98 | ts_dev->bit_xp = bit_cfg; | ||
99 | ts_dev->inp_xp = an_line; | ||
100 | break; | ||
101 | |||
102 | case 1: | ||
103 | ts_dev->bit_xn = bit_cfg; | ||
104 | ts_dev->inp_xn = an_line; | ||
105 | break; | ||
106 | |||
107 | case 2: | ||
108 | ts_dev->bit_yp = bit_cfg; | ||
109 | ts_dev->inp_yp = an_line; | ||
110 | break; | ||
111 | case 3: | ||
112 | ts_dev->bit_yn = bit_cfg; | ||
113 | ts_dev->inp_yn = an_line; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | return 0; | ||
118 | } | ||
119 | |||
57 | static void titsc_step_config(struct titsc *ts_dev) | 120 | static void titsc_step_config(struct titsc *ts_dev) |
58 | { | 121 | { |
59 | unsigned int config; | 122 | unsigned int config; |
60 | int i, total_steps; | 123 | int i; |
61 | 124 | int end_step; | |
62 | /* Configure the Step registers */ | 125 | u32 stepenable; |
63 | total_steps = 2 * ts_dev->steps_to_configure; | ||
64 | 126 | ||
65 | config = STEPCONFIG_MODE_HWSYNC | | 127 | config = STEPCONFIG_MODE_HWSYNC | |
66 | STEPCONFIG_AVG_16 | STEPCONFIG_XPP; | 128 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
67 | switch (ts_dev->wires) { | 129 | switch (ts_dev->wires) { |
68 | case 4: | 130 | case 4: |
69 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 131 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
70 | break; | 132 | break; |
71 | case 5: | 133 | case 5: |
72 | config |= STEPCONFIG_YNN | | 134 | config |= ts_dev->bit_yn | |
73 | STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | | 135 | STEPCONFIG_INP_AN4 | ts_dev->bit_xn | |
74 | STEPCONFIG_YPP; | 136 | ts_dev->bit_yp; |
75 | break; | 137 | break; |
76 | case 8: | 138 | case 8: |
77 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 139 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
78 | break; | 140 | break; |
79 | } | 141 | } |
80 | 142 | ||
81 | for (i = 1; i <= ts_dev->steps_to_configure; i++) { | 143 | /* 1 … coordinate_readouts is for X */ |
144 | end_step = ts_dev->coordinate_readouts; | ||
145 | for (i = 0; i < end_step; i++) { | ||
82 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 146 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
83 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 147 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
84 | } | 148 | } |
85 | 149 | ||
86 | config = 0; | 150 | config = 0; |
87 | config = STEPCONFIG_MODE_HWSYNC | | 151 | config = STEPCONFIG_MODE_HWSYNC | |
88 | STEPCONFIG_AVG_16 | STEPCONFIG_YNN | | 152 | STEPCONFIG_AVG_16 | ts_dev->bit_yn | |
89 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; | 153 | STEPCONFIG_INM_ADCREFM; |
90 | switch (ts_dev->wires) { | 154 | switch (ts_dev->wires) { |
91 | case 4: | 155 | case 4: |
92 | config |= STEPCONFIG_YPP; | 156 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
93 | break; | 157 | break; |
94 | case 5: | 158 | case 5: |
95 | config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | | 159 | config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | |
96 | STEPCONFIG_XNP | STEPCONFIG_YPN; | 160 | ts_dev->bit_xn | ts_dev->bit_yp; |
97 | break; | 161 | break; |
98 | case 8: | 162 | case 8: |
99 | config |= STEPCONFIG_YPP; | 163 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
100 | break; | 164 | break; |
101 | } | 165 | } |
102 | 166 | ||
103 | for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { | 167 | /* coordinate_readouts … coordinate_readouts * 2 is for Y */ |
168 | end_step = ts_dev->coordinate_readouts * 2; | ||
169 | for (i = ts_dev->coordinate_readouts; i < end_step; i++) { | ||
104 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); | 170 | titsc_writel(ts_dev, REG_STEPCONFIG(i), config); |
105 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); | 171 | titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); |
106 | } | 172 | } |
107 | 173 | ||
108 | config = 0; | ||
109 | /* Charge step configuration */ | 174 | /* Charge step configuration */ |
110 | config = STEPCONFIG_XPP | STEPCONFIG_YNN | | 175 | config = ts_dev->bit_xp | ts_dev->bit_yn | |
111 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | | 176 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | |
112 | STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; | 177 | STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); |
113 | 178 | ||
114 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); | 179 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
115 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); | 180 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); |
116 | 181 | ||
117 | config = 0; | 182 | /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */ |
118 | /* Configure to calculate pressure */ | ||
119 | config = STEPCONFIG_MODE_HWSYNC | | 183 | config = STEPCONFIG_MODE_HWSYNC | |
120 | STEPCONFIG_AVG_16 | STEPCONFIG_YPP | | 184 | STEPCONFIG_AVG_16 | ts_dev->bit_yp | |
121 | STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; | 185 | ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | |
122 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); | 186 | STEPCONFIG_INP(ts_dev->inp_xp); |
123 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), | 187 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
188 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), | ||
124 | STEPCONFIG_OPENDLY); | 189 | STEPCONFIG_OPENDLY); |
125 | 190 | ||
126 | config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; | 191 | end_step++; |
127 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); | 192 | config |= STEPCONFIG_INP(ts_dev->inp_yn); |
128 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), | 193 | titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); |
194 | titsc_writel(ts_dev, REG_STEPDELAY(end_step), | ||
129 | STEPCONFIG_OPENDLY); | 195 | STEPCONFIG_OPENDLY); |
130 | 196 | ||
131 | titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); | 197 | /* The steps1 … end and bit 0 for TS_Charge */ |
198 | stepenable = (1 << (end_step + 2)) - 1; | ||
199 | am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); | ||
132 | } | 200 | } |
133 | 201 | ||
134 | static void titsc_read_coordinates(struct titsc *ts_dev, | 202 | static void titsc_read_coordinates(struct titsc *ts_dev, |
135 | unsigned int *x, unsigned int *y) | 203 | u32 *x, u32 *y, u32 *z1, u32 *z2) |
136 | { | 204 | { |
137 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); | 205 | unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); |
138 | unsigned int prev_val_x = ~0, prev_val_y = ~0; | 206 | unsigned int prev_val_x = ~0, prev_val_y = ~0; |
139 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; | 207 | unsigned int prev_diff_x = ~0, prev_diff_y = ~0; |
140 | unsigned int read, diff; | 208 | unsigned int read, diff; |
141 | unsigned int i, channel; | 209 | unsigned int i, channel; |
210 | unsigned int creads = ts_dev->coordinate_readouts; | ||
142 | 211 | ||
212 | *z1 = *z2 = 0; | ||
213 | if (fifocount % (creads * 2 + 2)) | ||
214 | fifocount -= fifocount % (creads * 2 + 2); | ||
143 | /* | 215 | /* |
144 | * Delta filter is used to remove large variations in sampled | 216 | * Delta filter is used to remove large variations in sampled |
145 | * values from ADC. The filter tries to predict where the next | 217 | * values from ADC. The filter tries to predict where the next |
@@ -148,32 +220,32 @@ static void titsc_read_coordinates(struct titsc *ts_dev, | |||
148 | * algorithm compares the difference with that of a present value, | 220 | * algorithm compares the difference with that of a present value, |
149 | * if true the value is reported to the sub system. | 221 | * if true the value is reported to the sub system. |
150 | */ | 222 | */ |
151 | for (i = 0; i < fifocount - 1; i++) { | 223 | for (i = 0; i < fifocount; i++) { |
152 | read = titsc_readl(ts_dev, REG_FIFO0); | 224 | read = titsc_readl(ts_dev, REG_FIFO0); |
153 | channel = read & 0xf0000; | 225 | |
154 | channel = channel >> 0x10; | 226 | channel = (read & 0xf0000) >> 16; |
155 | if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) { | 227 | read &= 0xfff; |
156 | read &= 0xfff; | 228 | if (channel < creads) { |
157 | diff = abs(read - prev_val_x); | 229 | diff = abs(read - prev_val_x); |
158 | if (diff < prev_diff_x) { | 230 | if (diff < prev_diff_x) { |
159 | prev_diff_x = diff; | 231 | prev_diff_x = diff; |
160 | *x = read; | 232 | *x = read; |
161 | } | 233 | } |
162 | prev_val_x = read; | 234 | prev_val_x = read; |
163 | } | ||
164 | 235 | ||
165 | read = titsc_readl(ts_dev, REG_FIFO1); | 236 | } else if (channel < creads * 2) { |
166 | channel = read & 0xf0000; | ||
167 | channel = channel >> 0x10; | ||
168 | if ((channel >= ts_dev->steps_to_configure) && | ||
169 | (channel < (2 * ts_dev->steps_to_configure - 1))) { | ||
170 | read &= 0xfff; | ||
171 | diff = abs(read - prev_val_y); | 237 | diff = abs(read - prev_val_y); |
172 | if (diff < prev_diff_y) { | 238 | if (diff < prev_diff_y) { |
173 | prev_diff_y = diff; | 239 | prev_diff_y = diff; |
174 | *y = read; | 240 | *y = read; |
175 | } | 241 | } |
176 | prev_val_y = read; | 242 | prev_val_y = read; |
243 | |||
244 | } else if (channel < creads * 2 + 1) { | ||
245 | *z1 = read; | ||
246 | |||
247 | } else if (channel < creads * 2 + 2) { | ||
248 | *z2 = read; | ||
177 | } | 249 | } |
178 | } | 250 | } |
179 | } | 251 | } |
@@ -186,23 +258,11 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
186 | unsigned int x = 0, y = 0; | 258 | unsigned int x = 0, y = 0; |
187 | unsigned int z1, z2, z; | 259 | unsigned int z1, z2, z; |
188 | unsigned int fsm; | 260 | unsigned int fsm; |
189 | unsigned int fifo1count, fifo0count; | ||
190 | int i; | ||
191 | 261 | ||
192 | status = titsc_readl(ts_dev, REG_IRQSTATUS); | 262 | status = titsc_readl(ts_dev, REG_IRQSTATUS); |
193 | if (status & IRQENB_FIFO0THRES) { | 263 | if (status & IRQENB_FIFO0THRES) { |
194 | titsc_read_coordinates(ts_dev, &x, &y); | ||
195 | 264 | ||
196 | z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff; | 265 | titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); |
197 | z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff; | ||
198 | |||
199 | fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT); | ||
200 | for (i = 0; i < fifo1count; i++) | ||
201 | titsc_readl(ts_dev, REG_FIFO1); | ||
202 | |||
203 | fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT); | ||
204 | for (i = 0; i < fifo0count; i++) | ||
205 | titsc_readl(ts_dev, REG_FIFO0); | ||
206 | 266 | ||
207 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { | 267 | if (ts_dev->pen_down && z1 != 0 && z2 != 0) { |
208 | /* | 268 | /* |
@@ -210,10 +270,10 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
210 | * Resistance(touch) = x plate resistance * | 270 | * Resistance(touch) = x plate resistance * |
211 | * x postion/4096 * ((z2 / z1) - 1) | 271 | * x postion/4096 * ((z2 / z1) - 1) |
212 | */ | 272 | */ |
213 | z = z2 - z1; | 273 | z = z1 - z2; |
214 | z *= x; | 274 | z *= x; |
215 | z *= ts_dev->x_plate_resistance; | 275 | z *= ts_dev->x_plate_resistance; |
216 | z /= z1; | 276 | z /= z2; |
217 | z = (z + 2047) >> 12; | 277 | z = (z + 2047) >> 12; |
218 | 278 | ||
219 | if (z <= MAX_12BIT) { | 279 | if (z <= MAX_12BIT) { |
@@ -248,10 +308,60 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
248 | irqclr |= IRQENB_PENUP; | 308 | irqclr |= IRQENB_PENUP; |
249 | } | 309 | } |
250 | 310 | ||
251 | titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); | 311 | if (status & IRQENB_HW_PEN) { |
312 | |||
313 | titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); | ||
314 | titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); | ||
315 | } | ||
316 | |||
317 | if (irqclr) { | ||
318 | titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); | ||
319 | am335x_tsc_se_update(ts_dev->mfd_tscadc); | ||
320 | return IRQ_HANDLED; | ||
321 | } | ||
322 | return IRQ_NONE; | ||
323 | } | ||
324 | |||
325 | static int titsc_parse_dt(struct platform_device *pdev, | ||
326 | struct titsc *ts_dev) | ||
327 | { | ||
328 | struct device_node *node = pdev->dev.of_node; | ||
329 | int err; | ||
330 | |||
331 | if (!node) | ||
332 | return -EINVAL; | ||
333 | |||
334 | err = of_property_read_u32(node, "ti,wires", &ts_dev->wires); | ||
335 | if (err < 0) | ||
336 | return err; | ||
337 | switch (ts_dev->wires) { | ||
338 | case 4: | ||
339 | case 5: | ||
340 | case 8: | ||
341 | break; | ||
342 | default: | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | |||
346 | err = of_property_read_u32(node, "ti,x-plate-resistance", | ||
347 | &ts_dev->x_plate_resistance); | ||
348 | if (err < 0) | ||
349 | return err; | ||
252 | 350 | ||
253 | titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); | 351 | /* |
254 | return IRQ_HANDLED; | 352 | * Try with the new binding first. If it fails, try again with |
353 | * bogus, miss-spelled version. | ||
354 | */ | ||
355 | err = of_property_read_u32(node, "ti,coordinate-readouts", | ||
356 | &ts_dev->coordinate_readouts); | ||
357 | if (err < 0) | ||
358 | err = of_property_read_u32(node, "ti,coordiante-readouts", | ||
359 | &ts_dev->coordinate_readouts); | ||
360 | if (err < 0) | ||
361 | return err; | ||
362 | |||
363 | return of_property_read_u32_array(node, "ti,wire-config", | ||
364 | ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp)); | ||
255 | } | 365 | } |
256 | 366 | ||
257 | /* | 367 | /* |
@@ -262,17 +372,9 @@ static int titsc_probe(struct platform_device *pdev) | |||
262 | { | 372 | { |
263 | struct titsc *ts_dev; | 373 | struct titsc *ts_dev; |
264 | struct input_dev *input_dev; | 374 | struct input_dev *input_dev; |
265 | struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; | 375 | struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev); |
266 | struct mfd_tscadc_board *pdata; | ||
267 | int err; | 376 | int err; |
268 | 377 | ||
269 | pdata = tscadc_dev->dev->platform_data; | ||
270 | |||
271 | if (!pdata) { | ||
272 | dev_err(&pdev->dev, "Could not find platform data\n"); | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | /* Allocate memory for device */ | 378 | /* Allocate memory for device */ |
277 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); | 379 | ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); |
278 | input_dev = input_allocate_device(); | 380 | input_dev = input_allocate_device(); |
@@ -286,9 +388,12 @@ static int titsc_probe(struct platform_device *pdev) | |||
286 | ts_dev->mfd_tscadc = tscadc_dev; | 388 | ts_dev->mfd_tscadc = tscadc_dev; |
287 | ts_dev->input = input_dev; | 389 | ts_dev->input = input_dev; |
288 | ts_dev->irq = tscadc_dev->irq; | 390 | ts_dev->irq = tscadc_dev->irq; |
289 | ts_dev->wires = pdata->tsc_init->wires; | 391 | |
290 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; | 392 | err = titsc_parse_dt(pdev, ts_dev); |
291 | ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; | 393 | if (err) { |
394 | dev_err(&pdev->dev, "Could not find valid DT data.\n"); | ||
395 | goto err_free_mem; | ||
396 | } | ||
292 | 397 | ||
293 | err = request_irq(ts_dev->irq, titsc_irq, | 398 | err = request_irq(ts_dev->irq, titsc_irq, |
294 | 0, pdev->dev.driver->name, ts_dev); | 399 | 0, pdev->dev.driver->name, ts_dev); |
@@ -298,8 +403,14 @@ static int titsc_probe(struct platform_device *pdev) | |||
298 | } | 403 | } |
299 | 404 | ||
300 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); | 405 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); |
406 | err = titsc_config_wires(ts_dev); | ||
407 | if (err) { | ||
408 | dev_err(&pdev->dev, "wrong i/p wire configuration\n"); | ||
409 | goto err_free_irq; | ||
410 | } | ||
301 | titsc_step_config(ts_dev); | 411 | titsc_step_config(ts_dev); |
302 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); | 412 | titsc_writel(ts_dev, REG_FIFO0THR, |
413 | ts_dev->coordinate_readouts * 2 + 2 - 1); | ||
303 | 414 | ||
304 | input_dev->name = "ti-tsc"; | 415 | input_dev->name = "ti-tsc"; |
305 | input_dev->dev.parent = &pdev->dev; | 416 | input_dev->dev.parent = &pdev->dev; |
@@ -329,11 +440,16 @@ err_free_mem: | |||
329 | 440 | ||
330 | static int titsc_remove(struct platform_device *pdev) | 441 | static int titsc_remove(struct platform_device *pdev) |
331 | { | 442 | { |
332 | struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; | 443 | struct titsc *ts_dev = platform_get_drvdata(pdev); |
333 | struct titsc *ts_dev = tscadc_dev->tsc; | 444 | u32 steps; |
334 | 445 | ||
335 | free_irq(ts_dev->irq, ts_dev); | 446 | free_irq(ts_dev->irq, ts_dev); |
336 | 447 | ||
448 | /* total steps followed by the enable mask */ | ||
449 | steps = 2 * ts_dev->coordinate_readouts + 2; | ||
450 | steps = (1 << steps) - 1; | ||
451 | am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps); | ||
452 | |||
337 | input_unregister_device(ts_dev->input); | 453 | input_unregister_device(ts_dev->input); |
338 | 454 | ||
339 | kfree(ts_dev); | 455 | kfree(ts_dev); |
@@ -343,10 +459,11 @@ static int titsc_remove(struct platform_device *pdev) | |||
343 | #ifdef CONFIG_PM | 459 | #ifdef CONFIG_PM |
344 | static int titsc_suspend(struct device *dev) | 460 | static int titsc_suspend(struct device *dev) |
345 | { | 461 | { |
346 | struct ti_tscadc_dev *tscadc_dev = dev->platform_data; | 462 | struct titsc *ts_dev = dev_get_drvdata(dev); |
347 | struct titsc *ts_dev = tscadc_dev->tsc; | 463 | struct ti_tscadc_dev *tscadc_dev; |
348 | unsigned int idle; | 464 | unsigned int idle; |
349 | 465 | ||
466 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | ||
350 | if (device_may_wakeup(tscadc_dev->dev)) { | 467 | if (device_may_wakeup(tscadc_dev->dev)) { |
351 | idle = titsc_readl(ts_dev, REG_IRQENABLE); | 468 | idle = titsc_readl(ts_dev, REG_IRQENABLE); |
352 | titsc_writel(ts_dev, REG_IRQENABLE, | 469 | titsc_writel(ts_dev, REG_IRQENABLE, |
@@ -358,9 +475,10 @@ static int titsc_suspend(struct device *dev) | |||
358 | 475 | ||
359 | static int titsc_resume(struct device *dev) | 476 | static int titsc_resume(struct device *dev) |
360 | { | 477 | { |
361 | struct ti_tscadc_dev *tscadc_dev = dev->platform_data; | 478 | struct titsc *ts_dev = dev_get_drvdata(dev); |
362 | struct titsc *ts_dev = tscadc_dev->tsc; | 479 | struct ti_tscadc_dev *tscadc_dev; |
363 | 480 | ||
481 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | ||
364 | if (device_may_wakeup(tscadc_dev->dev)) { | 482 | if (device_may_wakeup(tscadc_dev->dev)) { |
365 | titsc_writel(ts_dev, REG_IRQWAKEUP, | 483 | titsc_writel(ts_dev, REG_IRQWAKEUP, |
366 | 0x00); | 484 | 0x00); |
@@ -368,7 +486,7 @@ static int titsc_resume(struct device *dev) | |||
368 | } | 486 | } |
369 | titsc_step_config(ts_dev); | 487 | titsc_step_config(ts_dev); |
370 | titsc_writel(ts_dev, REG_FIFO0THR, | 488 | titsc_writel(ts_dev, REG_FIFO0THR, |
371 | ts_dev->steps_to_configure); | 489 | ts_dev->coordinate_readouts * 2 + 2 - 1); |
372 | return 0; | 490 | return 0; |
373 | } | 491 | } |
374 | 492 | ||
@@ -381,13 +499,20 @@ static const struct dev_pm_ops titsc_pm_ops = { | |||
381 | #define TITSC_PM_OPS NULL | 499 | #define TITSC_PM_OPS NULL |
382 | #endif | 500 | #endif |
383 | 501 | ||
502 | static const struct of_device_id ti_tsc_dt_ids[] = { | ||
503 | { .compatible = "ti,am3359-tsc", }, | ||
504 | { } | ||
505 | }; | ||
506 | MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids); | ||
507 | |||
384 | static struct platform_driver ti_tsc_driver = { | 508 | static struct platform_driver ti_tsc_driver = { |
385 | .probe = titsc_probe, | 509 | .probe = titsc_probe, |
386 | .remove = titsc_remove, | 510 | .remove = titsc_remove, |
387 | .driver = { | 511 | .driver = { |
388 | .name = "tsc", | 512 | .name = "TI-am335x-tsc", |
389 | .owner = THIS_MODULE, | 513 | .owner = THIS_MODULE, |
390 | .pm = TITSC_PM_OPS, | 514 | .pm = TITSC_PM_OPS, |
515 | .of_match_table = ti_tsc_dt_ids, | ||
391 | }, | 516 | }, |
392 | }; | 517 | }; |
393 | module_platform_driver(ti_tsc_driver); | 518 | module_platform_driver(ti_tsc_driver); |
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 7213e8b07e79..811353353917 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c | |||
@@ -678,7 +678,6 @@ static int tsc2005_probe(struct spi_device *spi) | |||
678 | err_remove_sysfs: | 678 | err_remove_sysfs: |
679 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); | 679 | sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group); |
680 | err_clear_drvdata: | 680 | err_clear_drvdata: |
681 | spi_set_drvdata(spi, NULL); | ||
682 | free_irq(spi->irq, ts); | 681 | free_irq(spi->irq, ts); |
683 | err_free_mem: | 682 | err_free_mem: |
684 | input_free_device(input_dev); | 683 | input_free_device(input_dev); |
@@ -696,7 +695,6 @@ static int tsc2005_remove(struct spi_device *spi) | |||
696 | input_unregister_device(ts->idev); | 695 | input_unregister_device(ts->idev); |
697 | kfree(ts); | 696 | kfree(ts); |
698 | 697 | ||
699 | spi_set_drvdata(spi, NULL); | ||
700 | return 0; | 698 | return 0; |
701 | } | 699 | } |
702 | 700 | ||
diff --git a/drivers/input/touchscreen/zforce_ts.c b/drivers/input/touchscreen/zforce_ts.c new file mode 100644 index 000000000000..75762d6ff3ba --- /dev/null +++ b/drivers/input/touchscreen/zforce_ts.c | |||
@@ -0,0 +1,836 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012-2013 MundoReader S.L. | ||
3 | * Author: Heiko Stuebner <heiko@sntech.de> | ||
4 | * | ||
5 | * based in parts on Nook zforce driver | ||
6 | * | ||
7 | * Copyright (C) 2010 Barnes & Noble, Inc. | ||
8 | * Author: Pieter Truter<ptruter@intrinsyc.com> | ||
9 | * | ||
10 | * This software is licensed under the terms of the GNU General Public | ||
11 | * License version 2, as published by the Free Software Foundation, and | ||
12 | * may be copied, distributed, and modified under those terms. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/hrtimer.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/input.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/sysfs.h> | ||
30 | #include <linux/input/mt.h> | ||
31 | #include <linux/platform_data/zforce_ts.h> | ||
32 | |||
33 | #define WAIT_TIMEOUT msecs_to_jiffies(1000) | ||
34 | |||
35 | #define FRAME_START 0xee | ||
36 | |||
37 | /* Offsets of the different parts of the payload the controller sends */ | ||
38 | #define PAYLOAD_HEADER 0 | ||
39 | #define PAYLOAD_LENGTH 1 | ||
40 | #define PAYLOAD_BODY 2 | ||
41 | |||
42 | /* Response offsets */ | ||
43 | #define RESPONSE_ID 0 | ||
44 | #define RESPONSE_DATA 1 | ||
45 | |||
46 | /* Commands */ | ||
47 | #define COMMAND_DEACTIVATE 0x00 | ||
48 | #define COMMAND_INITIALIZE 0x01 | ||
49 | #define COMMAND_RESOLUTION 0x02 | ||
50 | #define COMMAND_SETCONFIG 0x03 | ||
51 | #define COMMAND_DATAREQUEST 0x04 | ||
52 | #define COMMAND_SCANFREQ 0x08 | ||
53 | #define COMMAND_STATUS 0X1e | ||
54 | |||
55 | /* | ||
56 | * Responses the controller sends as a result of | ||
57 | * command requests | ||
58 | */ | ||
59 | #define RESPONSE_DEACTIVATE 0x00 | ||
60 | #define RESPONSE_INITIALIZE 0x01 | ||
61 | #define RESPONSE_RESOLUTION 0x02 | ||
62 | #define RESPONSE_SETCONFIG 0x03 | ||
63 | #define RESPONSE_SCANFREQ 0x08 | ||
64 | #define RESPONSE_STATUS 0X1e | ||
65 | |||
66 | /* | ||
67 | * Notifications are send by the touch controller without | ||
68 | * being requested by the driver and include for example | ||
69 | * touch indications | ||
70 | */ | ||
71 | #define NOTIFICATION_TOUCH 0x04 | ||
72 | #define NOTIFICATION_BOOTCOMPLETE 0x07 | ||
73 | #define NOTIFICATION_OVERRUN 0x25 | ||
74 | #define NOTIFICATION_PROXIMITY 0x26 | ||
75 | #define NOTIFICATION_INVALID_COMMAND 0xfe | ||
76 | |||
77 | #define ZFORCE_REPORT_POINTS 2 | ||
78 | #define ZFORCE_MAX_AREA 0xff | ||
79 | |||
80 | #define STATE_DOWN 0 | ||
81 | #define STATE_MOVE 1 | ||
82 | #define STATE_UP 2 | ||
83 | |||
84 | #define SETCONFIG_DUALTOUCH (1 << 0) | ||
85 | |||
86 | struct zforce_point { | ||
87 | int coord_x; | ||
88 | int coord_y; | ||
89 | int state; | ||
90 | int id; | ||
91 | int area_major; | ||
92 | int area_minor; | ||
93 | int orientation; | ||
94 | int pressure; | ||
95 | int prblty; | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * @client the i2c_client | ||
100 | * @input the input device | ||
101 | * @suspending in the process of going to suspend (don't emit wakeup | ||
102 | * events for commands executed to suspend the device) | ||
103 | * @suspended device suspended | ||
104 | * @access_mutex serialize i2c-access, to keep multipart reads together | ||
105 | * @command_done completion to wait for the command result | ||
106 | * @command_mutex serialize commands send to the ic | ||
107 | * @command_waiting the id of the command that that is currently waiting | ||
108 | * for a result | ||
109 | * @command_result returned result of the command | ||
110 | */ | ||
111 | struct zforce_ts { | ||
112 | struct i2c_client *client; | ||
113 | struct input_dev *input; | ||
114 | const struct zforce_ts_platdata *pdata; | ||
115 | char phys[32]; | ||
116 | |||
117 | bool suspending; | ||
118 | bool suspended; | ||
119 | bool boot_complete; | ||
120 | |||
121 | /* Firmware version information */ | ||
122 | u16 version_major; | ||
123 | u16 version_minor; | ||
124 | u16 version_build; | ||
125 | u16 version_rev; | ||
126 | |||
127 | struct mutex access_mutex; | ||
128 | |||
129 | struct completion command_done; | ||
130 | struct mutex command_mutex; | ||
131 | int command_waiting; | ||
132 | int command_result; | ||
133 | }; | ||
134 | |||
135 | static int zforce_command(struct zforce_ts *ts, u8 cmd) | ||
136 | { | ||
137 | struct i2c_client *client = ts->client; | ||
138 | char buf[3]; | ||
139 | int ret; | ||
140 | |||
141 | dev_dbg(&client->dev, "%s: 0x%x\n", __func__, cmd); | ||
142 | |||
143 | buf[0] = FRAME_START; | ||
144 | buf[1] = 1; /* data size, command only */ | ||
145 | buf[2] = cmd; | ||
146 | |||
147 | mutex_lock(&ts->access_mutex); | ||
148 | ret = i2c_master_send(client, &buf[0], ARRAY_SIZE(buf)); | ||
149 | mutex_unlock(&ts->access_mutex); | ||
150 | if (ret < 0) { | ||
151 | dev_err(&client->dev, "i2c send data request error: %d\n", ret); | ||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int zforce_send_wait(struct zforce_ts *ts, const char *buf, int len) | ||
159 | { | ||
160 | struct i2c_client *client = ts->client; | ||
161 | int ret; | ||
162 | |||
163 | ret = mutex_trylock(&ts->command_mutex); | ||
164 | if (!ret) { | ||
165 | dev_err(&client->dev, "already waiting for a command\n"); | ||
166 | return -EBUSY; | ||
167 | } | ||
168 | |||
169 | dev_dbg(&client->dev, "sending %d bytes for command 0x%x\n", | ||
170 | buf[1], buf[2]); | ||
171 | |||
172 | ts->command_waiting = buf[2]; | ||
173 | |||
174 | mutex_lock(&ts->access_mutex); | ||
175 | ret = i2c_master_send(client, buf, len); | ||
176 | mutex_unlock(&ts->access_mutex); | ||
177 | if (ret < 0) { | ||
178 | dev_err(&client->dev, "i2c send data request error: %d\n", ret); | ||
179 | goto unlock; | ||
180 | } | ||
181 | |||
182 | dev_dbg(&client->dev, "waiting for result for command 0x%x\n", buf[2]); | ||
183 | |||
184 | if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0) { | ||
185 | ret = -ETIME; | ||
186 | goto unlock; | ||
187 | } | ||
188 | |||
189 | ret = ts->command_result; | ||
190 | |||
191 | unlock: | ||
192 | mutex_unlock(&ts->command_mutex); | ||
193 | return ret; | ||
194 | } | ||
195 | |||
196 | static int zforce_command_wait(struct zforce_ts *ts, u8 cmd) | ||
197 | { | ||
198 | struct i2c_client *client = ts->client; | ||
199 | char buf[3]; | ||
200 | int ret; | ||
201 | |||
202 | dev_dbg(&client->dev, "%s: 0x%x\n", __func__, cmd); | ||
203 | |||
204 | buf[0] = FRAME_START; | ||
205 | buf[1] = 1; /* data size, command only */ | ||
206 | buf[2] = cmd; | ||
207 | |||
208 | ret = zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); | ||
209 | if (ret < 0) { | ||
210 | dev_err(&client->dev, "i2c send data request error: %d\n", ret); | ||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int zforce_resolution(struct zforce_ts *ts, u16 x, u16 y) | ||
218 | { | ||
219 | struct i2c_client *client = ts->client; | ||
220 | char buf[7] = { FRAME_START, 5, COMMAND_RESOLUTION, | ||
221 | (x & 0xff), ((x >> 8) & 0xff), | ||
222 | (y & 0xff), ((y >> 8) & 0xff) }; | ||
223 | |||
224 | dev_dbg(&client->dev, "set resolution to (%d,%d)\n", x, y); | ||
225 | |||
226 | return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); | ||
227 | } | ||
228 | |||
229 | static int zforce_scan_frequency(struct zforce_ts *ts, u16 idle, u16 finger, | ||
230 | u16 stylus) | ||
231 | { | ||
232 | struct i2c_client *client = ts->client; | ||
233 | char buf[9] = { FRAME_START, 7, COMMAND_SCANFREQ, | ||
234 | (idle & 0xff), ((idle >> 8) & 0xff), | ||
235 | (finger & 0xff), ((finger >> 8) & 0xff), | ||
236 | (stylus & 0xff), ((stylus >> 8) & 0xff) }; | ||
237 | |||
238 | dev_dbg(&client->dev, "set scan frequency to (idle: %d, finger: %d, stylus: %d)\n", | ||
239 | idle, finger, stylus); | ||
240 | |||
241 | return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); | ||
242 | } | ||
243 | |||
244 | static int zforce_setconfig(struct zforce_ts *ts, char b1) | ||
245 | { | ||
246 | struct i2c_client *client = ts->client; | ||
247 | char buf[7] = { FRAME_START, 5, COMMAND_SETCONFIG, | ||
248 | b1, 0, 0, 0 }; | ||
249 | |||
250 | dev_dbg(&client->dev, "set config to (%d)\n", b1); | ||
251 | |||
252 | return zforce_send_wait(ts, &buf[0], ARRAY_SIZE(buf)); | ||
253 | } | ||
254 | |||
255 | static int zforce_start(struct zforce_ts *ts) | ||
256 | { | ||
257 | struct i2c_client *client = ts->client; | ||
258 | const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev); | ||
259 | int ret; | ||
260 | |||
261 | dev_dbg(&client->dev, "starting device\n"); | ||
262 | |||
263 | ret = zforce_command_wait(ts, COMMAND_INITIALIZE); | ||
264 | if (ret) { | ||
265 | dev_err(&client->dev, "Unable to initialize, %d\n", ret); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | ret = zforce_resolution(ts, pdata->x_max, pdata->y_max); | ||
270 | if (ret) { | ||
271 | dev_err(&client->dev, "Unable to set resolution, %d\n", ret); | ||
272 | goto error; | ||
273 | } | ||
274 | |||
275 | ret = zforce_scan_frequency(ts, 10, 50, 50); | ||
276 | if (ret) { | ||
277 | dev_err(&client->dev, "Unable to set scan frequency, %d\n", | ||
278 | ret); | ||
279 | goto error; | ||
280 | } | ||
281 | |||
282 | if (zforce_setconfig(ts, SETCONFIG_DUALTOUCH)) { | ||
283 | dev_err(&client->dev, "Unable to set config\n"); | ||
284 | goto error; | ||
285 | } | ||
286 | |||
287 | /* start sending touch events */ | ||
288 | ret = zforce_command(ts, COMMAND_DATAREQUEST); | ||
289 | if (ret) { | ||
290 | dev_err(&client->dev, "Unable to request data\n"); | ||
291 | goto error; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Per NN, initial cal. take max. of 200msec. | ||
296 | * Allow time to complete this calibration | ||
297 | */ | ||
298 | msleep(200); | ||
299 | |||
300 | return 0; | ||
301 | |||
302 | error: | ||
303 | zforce_command_wait(ts, COMMAND_DEACTIVATE); | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | static int zforce_stop(struct zforce_ts *ts) | ||
308 | { | ||
309 | struct i2c_client *client = ts->client; | ||
310 | int ret; | ||
311 | |||
312 | dev_dbg(&client->dev, "stopping device\n"); | ||
313 | |||
314 | /* Deactivates touch sensing and puts the device into sleep. */ | ||
315 | ret = zforce_command_wait(ts, COMMAND_DEACTIVATE); | ||
316 | if (ret != 0) { | ||
317 | dev_err(&client->dev, "could not deactivate device, %d\n", | ||
318 | ret); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int zforce_touch_event(struct zforce_ts *ts, u8 *payload) | ||
326 | { | ||
327 | struct i2c_client *client = ts->client; | ||
328 | const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev); | ||
329 | struct zforce_point point; | ||
330 | int count, i, num = 0; | ||
331 | |||
332 | count = payload[0]; | ||
333 | if (count > ZFORCE_REPORT_POINTS) { | ||
334 | dev_warn(&client->dev, "to many coordinates %d, expected max %d\n", | ||
335 | count, ZFORCE_REPORT_POINTS); | ||
336 | count = ZFORCE_REPORT_POINTS; | ||
337 | } | ||
338 | |||
339 | for (i = 0; i < count; i++) { | ||
340 | point.coord_x = | ||
341 | payload[9 * i + 2] << 8 | payload[9 * i + 1]; | ||
342 | point.coord_y = | ||
343 | payload[9 * i + 4] << 8 | payload[9 * i + 3]; | ||
344 | |||
345 | if (point.coord_x > pdata->x_max || | ||
346 | point.coord_y > pdata->y_max) { | ||
347 | dev_warn(&client->dev, "coordinates (%d,%d) invalid\n", | ||
348 | point.coord_x, point.coord_y); | ||
349 | point.coord_x = point.coord_y = 0; | ||
350 | } | ||
351 | |||
352 | point.state = payload[9 * i + 5] & 0x03; | ||
353 | point.id = (payload[9 * i + 5] & 0xfc) >> 2; | ||
354 | |||
355 | /* determine touch major, minor and orientation */ | ||
356 | point.area_major = max(payload[9 * i + 6], | ||
357 | payload[9 * i + 7]); | ||
358 | point.area_minor = min(payload[9 * i + 6], | ||
359 | payload[9 * i + 7]); | ||
360 | point.orientation = payload[9 * i + 6] > payload[9 * i + 7]; | ||
361 | |||
362 | point.pressure = payload[9 * i + 8]; | ||
363 | point.prblty = payload[9 * i + 9]; | ||
364 | |||
365 | dev_dbg(&client->dev, | ||
366 | "point %d/%d: state %d, id %d, pressure %d, prblty %d, x %d, y %d, amajor %d, aminor %d, ori %d\n", | ||
367 | i, count, point.state, point.id, | ||
368 | point.pressure, point.prblty, | ||
369 | point.coord_x, point.coord_y, | ||
370 | point.area_major, point.area_minor, | ||
371 | point.orientation); | ||
372 | |||
373 | /* the zforce id starts with "1", so needs to be decreased */ | ||
374 | input_mt_slot(ts->input, point.id - 1); | ||
375 | |||
376 | input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, | ||
377 | point.state != STATE_UP); | ||
378 | |||
379 | if (point.state != STATE_UP) { | ||
380 | input_report_abs(ts->input, ABS_MT_POSITION_X, | ||
381 | point.coord_x); | ||
382 | input_report_abs(ts->input, ABS_MT_POSITION_Y, | ||
383 | point.coord_y); | ||
384 | input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, | ||
385 | point.area_major); | ||
386 | input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, | ||
387 | point.area_minor); | ||
388 | input_report_abs(ts->input, ABS_MT_ORIENTATION, | ||
389 | point.orientation); | ||
390 | num++; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | input_mt_sync_frame(ts->input); | ||
395 | |||
396 | input_mt_report_finger_count(ts->input, num); | ||
397 | |||
398 | input_sync(ts->input); | ||
399 | |||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | static int zforce_read_packet(struct zforce_ts *ts, u8 *buf) | ||
404 | { | ||
405 | struct i2c_client *client = ts->client; | ||
406 | int ret; | ||
407 | |||
408 | mutex_lock(&ts->access_mutex); | ||
409 | |||
410 | /* read 2 byte message header */ | ||
411 | ret = i2c_master_recv(client, buf, 2); | ||
412 | if (ret < 0) { | ||
413 | dev_err(&client->dev, "error reading header: %d\n", ret); | ||
414 | goto unlock; | ||
415 | } | ||
416 | |||
417 | if (buf[PAYLOAD_HEADER] != FRAME_START) { | ||
418 | dev_err(&client->dev, "invalid frame start: %d\n", buf[0]); | ||
419 | ret = -EIO; | ||
420 | goto unlock; | ||
421 | } | ||
422 | |||
423 | if (buf[PAYLOAD_LENGTH] <= 0 || buf[PAYLOAD_LENGTH] > 255) { | ||
424 | dev_err(&client->dev, "invalid payload length: %d\n", | ||
425 | buf[PAYLOAD_LENGTH]); | ||
426 | ret = -EIO; | ||
427 | goto unlock; | ||
428 | } | ||
429 | |||
430 | /* read the message */ | ||
431 | ret = i2c_master_recv(client, &buf[PAYLOAD_BODY], buf[PAYLOAD_LENGTH]); | ||
432 | if (ret < 0) { | ||
433 | dev_err(&client->dev, "error reading payload: %d\n", ret); | ||
434 | goto unlock; | ||
435 | } | ||
436 | |||
437 | dev_dbg(&client->dev, "read %d bytes for response command 0x%x\n", | ||
438 | buf[PAYLOAD_LENGTH], buf[PAYLOAD_BODY]); | ||
439 | |||
440 | unlock: | ||
441 | mutex_unlock(&ts->access_mutex); | ||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | static void zforce_complete(struct zforce_ts *ts, int cmd, int result) | ||
446 | { | ||
447 | struct i2c_client *client = ts->client; | ||
448 | |||
449 | if (ts->command_waiting == cmd) { | ||
450 | dev_dbg(&client->dev, "completing command 0x%x\n", cmd); | ||
451 | ts->command_result = result; | ||
452 | complete(&ts->command_done); | ||
453 | } else { | ||
454 | dev_dbg(&client->dev, "command %d not for us\n", cmd); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | static irqreturn_t zforce_interrupt(int irq, void *dev_id) | ||
459 | { | ||
460 | struct zforce_ts *ts = dev_id; | ||
461 | struct i2c_client *client = ts->client; | ||
462 | const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev); | ||
463 | int ret; | ||
464 | u8 payload_buffer[512]; | ||
465 | u8 *payload; | ||
466 | |||
467 | /* | ||
468 | * When suspended, emit a wakeup signal if necessary and return. | ||
469 | * Due to the level-interrupt we will get re-triggered later. | ||
470 | */ | ||
471 | if (ts->suspended) { | ||
472 | if (device_may_wakeup(&client->dev)) | ||
473 | pm_wakeup_event(&client->dev, 500); | ||
474 | msleep(20); | ||
475 | return IRQ_HANDLED; | ||
476 | } | ||
477 | |||
478 | dev_dbg(&client->dev, "handling interrupt\n"); | ||
479 | |||
480 | /* Don't emit wakeup events from commands run by zforce_suspend */ | ||
481 | if (!ts->suspending && device_may_wakeup(&client->dev)) | ||
482 | pm_stay_awake(&client->dev); | ||
483 | |||
484 | while (!gpio_get_value(pdata->gpio_int)) { | ||
485 | ret = zforce_read_packet(ts, payload_buffer); | ||
486 | if (ret < 0) { | ||
487 | dev_err(&client->dev, "could not read packet, ret: %d\n", | ||
488 | ret); | ||
489 | break; | ||
490 | } | ||
491 | |||
492 | payload = &payload_buffer[PAYLOAD_BODY]; | ||
493 | |||
494 | switch (payload[RESPONSE_ID]) { | ||
495 | case NOTIFICATION_TOUCH: | ||
496 | /* | ||
497 | * Always report touch-events received while | ||
498 | * suspending, when being a wakeup source | ||
499 | */ | ||
500 | if (ts->suspending && device_may_wakeup(&client->dev)) | ||
501 | pm_wakeup_event(&client->dev, 500); | ||
502 | zforce_touch_event(ts, &payload[RESPONSE_DATA]); | ||
503 | break; | ||
504 | |||
505 | case NOTIFICATION_BOOTCOMPLETE: | ||
506 | ts->boot_complete = payload[RESPONSE_DATA]; | ||
507 | zforce_complete(ts, payload[RESPONSE_ID], 0); | ||
508 | break; | ||
509 | |||
510 | case RESPONSE_INITIALIZE: | ||
511 | case RESPONSE_DEACTIVATE: | ||
512 | case RESPONSE_SETCONFIG: | ||
513 | case RESPONSE_RESOLUTION: | ||
514 | case RESPONSE_SCANFREQ: | ||
515 | zforce_complete(ts, payload[RESPONSE_ID], | ||
516 | payload[RESPONSE_DATA]); | ||
517 | break; | ||
518 | |||
519 | case RESPONSE_STATUS: | ||
520 | /* | ||
521 | * Version Payload Results | ||
522 | * [2:major] [2:minor] [2:build] [2:rev] | ||
523 | */ | ||
524 | ts->version_major = (payload[RESPONSE_DATA + 1] << 8) | | ||
525 | payload[RESPONSE_DATA]; | ||
526 | ts->version_minor = (payload[RESPONSE_DATA + 3] << 8) | | ||
527 | payload[RESPONSE_DATA + 2]; | ||
528 | ts->version_build = (payload[RESPONSE_DATA + 5] << 8) | | ||
529 | payload[RESPONSE_DATA + 4]; | ||
530 | ts->version_rev = (payload[RESPONSE_DATA + 7] << 8) | | ||
531 | payload[RESPONSE_DATA + 6]; | ||
532 | dev_dbg(&ts->client->dev, "Firmware Version %04x:%04x %04x:%04x\n", | ||
533 | ts->version_major, ts->version_minor, | ||
534 | ts->version_build, ts->version_rev); | ||
535 | |||
536 | zforce_complete(ts, payload[RESPONSE_ID], 0); | ||
537 | break; | ||
538 | |||
539 | case NOTIFICATION_INVALID_COMMAND: | ||
540 | dev_err(&ts->client->dev, "invalid command: 0x%x\n", | ||
541 | payload[RESPONSE_DATA]); | ||
542 | break; | ||
543 | |||
544 | default: | ||
545 | dev_err(&ts->client->dev, "unrecognized response id: 0x%x\n", | ||
546 | payload[RESPONSE_ID]); | ||
547 | break; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | if (!ts->suspending && device_may_wakeup(&client->dev)) | ||
552 | pm_relax(&client->dev); | ||
553 | |||
554 | dev_dbg(&client->dev, "finished interrupt\n"); | ||
555 | |||
556 | return IRQ_HANDLED; | ||
557 | } | ||
558 | |||
559 | static int zforce_input_open(struct input_dev *dev) | ||
560 | { | ||
561 | struct zforce_ts *ts = input_get_drvdata(dev); | ||
562 | int ret; | ||
563 | |||
564 | ret = zforce_start(ts); | ||
565 | if (ret) | ||
566 | return ret; | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static void zforce_input_close(struct input_dev *dev) | ||
572 | { | ||
573 | struct zforce_ts *ts = input_get_drvdata(dev); | ||
574 | struct i2c_client *client = ts->client; | ||
575 | int ret; | ||
576 | |||
577 | ret = zforce_stop(ts); | ||
578 | if (ret) | ||
579 | dev_warn(&client->dev, "stopping zforce failed\n"); | ||
580 | |||
581 | return; | ||
582 | } | ||
583 | |||
584 | #ifdef CONFIG_PM_SLEEP | ||
585 | static int zforce_suspend(struct device *dev) | ||
586 | { | ||
587 | struct i2c_client *client = to_i2c_client(dev); | ||
588 | struct zforce_ts *ts = i2c_get_clientdata(client); | ||
589 | struct input_dev *input = ts->input; | ||
590 | int ret = 0; | ||
591 | |||
592 | mutex_lock(&input->mutex); | ||
593 | ts->suspending = true; | ||
594 | |||
595 | /* | ||
596 | * When configured as a wakeup source device should always wake | ||
597 | * the system, therefore start device if necessary. | ||
598 | */ | ||
599 | if (device_may_wakeup(&client->dev)) { | ||
600 | dev_dbg(&client->dev, "suspend while being a wakeup source\n"); | ||
601 | |||
602 | /* Need to start device, if not open, to be a wakeup source. */ | ||
603 | if (!input->users) { | ||
604 | ret = zforce_start(ts); | ||
605 | if (ret) | ||
606 | goto unlock; | ||
607 | } | ||
608 | |||
609 | enable_irq_wake(client->irq); | ||
610 | } else if (input->users) { | ||
611 | dev_dbg(&client->dev, "suspend without being a wakeup source\n"); | ||
612 | |||
613 | ret = zforce_stop(ts); | ||
614 | if (ret) | ||
615 | goto unlock; | ||
616 | |||
617 | disable_irq(client->irq); | ||
618 | } | ||
619 | |||
620 | ts->suspended = true; | ||
621 | |||
622 | unlock: | ||
623 | ts->suspending = false; | ||
624 | mutex_unlock(&input->mutex); | ||
625 | |||
626 | return ret; | ||
627 | } | ||
628 | |||
629 | static int zforce_resume(struct device *dev) | ||
630 | { | ||
631 | struct i2c_client *client = to_i2c_client(dev); | ||
632 | struct zforce_ts *ts = i2c_get_clientdata(client); | ||
633 | struct input_dev *input = ts->input; | ||
634 | int ret = 0; | ||
635 | |||
636 | mutex_lock(&input->mutex); | ||
637 | |||
638 | ts->suspended = false; | ||
639 | |||
640 | if (device_may_wakeup(&client->dev)) { | ||
641 | dev_dbg(&client->dev, "resume from being a wakeup source\n"); | ||
642 | |||
643 | disable_irq_wake(client->irq); | ||
644 | |||
645 | /* need to stop device if it was not open on suspend */ | ||
646 | if (!input->users) { | ||
647 | ret = zforce_stop(ts); | ||
648 | if (ret) | ||
649 | goto unlock; | ||
650 | } | ||
651 | } else if (input->users) { | ||
652 | dev_dbg(&client->dev, "resume without being a wakeup source\n"); | ||
653 | |||
654 | enable_irq(client->irq); | ||
655 | |||
656 | ret = zforce_start(ts); | ||
657 | if (ret < 0) | ||
658 | goto unlock; | ||
659 | } | ||
660 | |||
661 | unlock: | ||
662 | mutex_unlock(&input->mutex); | ||
663 | |||
664 | return ret; | ||
665 | } | ||
666 | #endif | ||
667 | |||
668 | static SIMPLE_DEV_PM_OPS(zforce_pm_ops, zforce_suspend, zforce_resume); | ||
669 | |||
670 | static void zforce_reset(void *data) | ||
671 | { | ||
672 | struct zforce_ts *ts = data; | ||
673 | |||
674 | gpio_set_value(ts->pdata->gpio_rst, 0); | ||
675 | } | ||
676 | |||
677 | static int zforce_probe(struct i2c_client *client, | ||
678 | const struct i2c_device_id *id) | ||
679 | { | ||
680 | const struct zforce_ts_platdata *pdata = dev_get_platdata(&client->dev); | ||
681 | struct zforce_ts *ts; | ||
682 | struct input_dev *input_dev; | ||
683 | int ret; | ||
684 | |||
685 | if (!pdata) | ||
686 | return -EINVAL; | ||
687 | |||
688 | ts = devm_kzalloc(&client->dev, sizeof(struct zforce_ts), GFP_KERNEL); | ||
689 | if (!ts) | ||
690 | return -ENOMEM; | ||
691 | |||
692 | ret = devm_gpio_request_one(&client->dev, pdata->gpio_int, GPIOF_IN, | ||
693 | "zforce_ts_int"); | ||
694 | if (ret) { | ||
695 | dev_err(&client->dev, "request of gpio %d failed, %d\n", | ||
696 | pdata->gpio_int, ret); | ||
697 | return ret; | ||
698 | } | ||
699 | |||
700 | ret = devm_gpio_request_one(&client->dev, pdata->gpio_rst, | ||
701 | GPIOF_OUT_INIT_LOW, "zforce_ts_rst"); | ||
702 | if (ret) { | ||
703 | dev_err(&client->dev, "request of gpio %d failed, %d\n", | ||
704 | pdata->gpio_rst, ret); | ||
705 | return ret; | ||
706 | } | ||
707 | |||
708 | ret = devm_add_action(&client->dev, zforce_reset, ts); | ||
709 | if (ret) { | ||
710 | dev_err(&client->dev, "failed to register reset action, %d\n", | ||
711 | ret); | ||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | snprintf(ts->phys, sizeof(ts->phys), | ||
716 | "%s/input0", dev_name(&client->dev)); | ||
717 | |||
718 | input_dev = devm_input_allocate_device(&client->dev); | ||
719 | if (!input_dev) { | ||
720 | dev_err(&client->dev, "could not allocate input device\n"); | ||
721 | return -ENOMEM; | ||
722 | } | ||
723 | |||
724 | mutex_init(&ts->access_mutex); | ||
725 | mutex_init(&ts->command_mutex); | ||
726 | |||
727 | ts->pdata = pdata; | ||
728 | ts->client = client; | ||
729 | ts->input = input_dev; | ||
730 | |||
731 | input_dev->name = "Neonode zForce touchscreen"; | ||
732 | input_dev->phys = ts->phys; | ||
733 | input_dev->id.bustype = BUS_I2C; | ||
734 | |||
735 | input_dev->open = zforce_input_open; | ||
736 | input_dev->close = zforce_input_close; | ||
737 | |||
738 | __set_bit(EV_KEY, input_dev->evbit); | ||
739 | __set_bit(EV_SYN, input_dev->evbit); | ||
740 | __set_bit(EV_ABS, input_dev->evbit); | ||
741 | |||
742 | /* For multi touch */ | ||
743 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, | ||
744 | pdata->x_max, 0, 0); | ||
745 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, | ||
746 | pdata->y_max, 0, 0); | ||
747 | |||
748 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, | ||
749 | ZFORCE_MAX_AREA, 0, 0); | ||
750 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, | ||
751 | ZFORCE_MAX_AREA, 0, 0); | ||
752 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); | ||
753 | input_mt_init_slots(input_dev, ZFORCE_REPORT_POINTS, INPUT_MT_DIRECT); | ||
754 | |||
755 | input_set_drvdata(ts->input, ts); | ||
756 | |||
757 | init_completion(&ts->command_done); | ||
758 | |||
759 | /* | ||
760 | * The zforce pulls the interrupt low when it has data ready. | ||
761 | * After it is triggered the isr thread runs until all the available | ||
762 | * packets have been read and the interrupt is high again. | ||
763 | * Therefore we can trigger the interrupt anytime it is low and do | ||
764 | * not need to limit it to the interrupt edge. | ||
765 | */ | ||
766 | ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, | ||
767 | zforce_interrupt, | ||
768 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
769 | input_dev->name, ts); | ||
770 | if (ret) { | ||
771 | dev_err(&client->dev, "irq %d request failed\n", client->irq); | ||
772 | return ret; | ||
773 | } | ||
774 | |||
775 | i2c_set_clientdata(client, ts); | ||
776 | |||
777 | /* let the controller boot */ | ||
778 | gpio_set_value(pdata->gpio_rst, 1); | ||
779 | |||
780 | ts->command_waiting = NOTIFICATION_BOOTCOMPLETE; | ||
781 | if (wait_for_completion_timeout(&ts->command_done, WAIT_TIMEOUT) == 0) | ||
782 | dev_warn(&client->dev, "bootcomplete timed out\n"); | ||
783 | |||
784 | /* need to start device to get version information */ | ||
785 | ret = zforce_command_wait(ts, COMMAND_INITIALIZE); | ||
786 | if (ret) { | ||
787 | dev_err(&client->dev, "unable to initialize, %d\n", ret); | ||
788 | return ret; | ||
789 | } | ||
790 | |||
791 | /* this gets the firmware version among other informations */ | ||
792 | ret = zforce_command_wait(ts, COMMAND_STATUS); | ||
793 | if (ret < 0) { | ||
794 | dev_err(&client->dev, "couldn't get status, %d\n", ret); | ||
795 | zforce_stop(ts); | ||
796 | return ret; | ||
797 | } | ||
798 | |||
799 | /* stop device and put it into sleep until it is opened */ | ||
800 | ret = zforce_stop(ts); | ||
801 | if (ret < 0) | ||
802 | return ret; | ||
803 | |||
804 | device_set_wakeup_capable(&client->dev, true); | ||
805 | |||
806 | ret = input_register_device(input_dev); | ||
807 | if (ret) { | ||
808 | dev_err(&client->dev, "could not register input device, %d\n", | ||
809 | ret); | ||
810 | return ret; | ||
811 | } | ||
812 | |||
813 | return 0; | ||
814 | } | ||
815 | |||
816 | static struct i2c_device_id zforce_idtable[] = { | ||
817 | { "zforce-ts", 0 }, | ||
818 | { } | ||
819 | }; | ||
820 | MODULE_DEVICE_TABLE(i2c, zforce_idtable); | ||
821 | |||
822 | static struct i2c_driver zforce_driver = { | ||
823 | .driver = { | ||
824 | .owner = THIS_MODULE, | ||
825 | .name = "zforce-ts", | ||
826 | .pm = &zforce_pm_ops, | ||
827 | }, | ||
828 | .probe = zforce_probe, | ||
829 | .id_table = zforce_idtable, | ||
830 | }; | ||
831 | |||
832 | module_i2c_driver(zforce_driver); | ||
833 | |||
834 | MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>"); | ||
835 | MODULE_DESCRIPTION("zForce TouchScreen Driver"); | ||
836 | MODULE_LICENSE("GPL"); | ||