diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
-rw-r--r-- | drivers/input/evdev.c | 13 | ||||
-rw-r--r-- | drivers/input/input.c | 5 | ||||
-rw-r--r-- | drivers/input/joystick/xpad.c | 2 | ||||
-rw-r--r-- | drivers/input/keyboard/adp5588-keys.c | 1 | ||||
-rw-r--r-- | drivers/input/keyboard/cros_ec_keyb.c | 9 | ||||
-rw-r--r-- | drivers/input/keyboard/opencores-kbd.c | 72 | ||||
-rw-r--r-- | drivers/input/misc/max77693-haptic.c | 2 | ||||
-rw-r--r-- | drivers/input/misc/xen-kbdfront.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 22 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 8 | ||||
-rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 287 | ||||
-rw-r--r-- | drivers/input/serio/i8042.c | 2 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 4 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 12 | ||||
-rw-r--r-- | drivers/input/touchscreen/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/ar1021_i2c.c | 181 |
18 files changed, 280 insertions, 351 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b62bdcb1eb39..7dbe5ec9d9cd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1260,7 +1260,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1260 | i8042.noloop [HW] Disable the AUX Loopback command while probing | 1260 | i8042.noloop [HW] Disable the AUX Loopback command while probing |
1261 | for the AUX port | 1261 | for the AUX port |
1262 | i8042.nomux [HW] Don't check presence of an active multiplexing | 1262 | i8042.nomux [HW] Don't check presence of an active multiplexing |
1263 | controller | 1263 | controller. Default: true. |
1264 | i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX | 1264 | i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX |
1265 | controllers | 1265 | controllers |
1266 | i8042.notimeout [HW] Ignore timeout condition signalled by controller | 1266 | i8042.notimeout [HW] Ignore timeout condition signalled by controller |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index de055451d1af..bc203485716d 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -738,20 +738,23 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) | |||
738 | */ | 738 | */ |
739 | static int evdev_handle_get_val(struct evdev_client *client, | 739 | static int evdev_handle_get_val(struct evdev_client *client, |
740 | struct input_dev *dev, unsigned int type, | 740 | struct input_dev *dev, unsigned int type, |
741 | unsigned long *bits, unsigned int max, | 741 | unsigned long *bits, unsigned int maxbit, |
742 | unsigned int size, void __user *p, int compat) | 742 | unsigned int maxlen, void __user *p, |
743 | int compat) | ||
743 | { | 744 | { |
744 | int ret; | 745 | int ret; |
745 | unsigned long *mem; | 746 | unsigned long *mem; |
747 | size_t len; | ||
746 | 748 | ||
747 | mem = kmalloc(sizeof(unsigned long) * max, GFP_KERNEL); | 749 | len = BITS_TO_LONGS(maxbit) * sizeof(unsigned long); |
750 | mem = kmalloc(len, GFP_KERNEL); | ||
748 | if (!mem) | 751 | if (!mem) |
749 | return -ENOMEM; | 752 | return -ENOMEM; |
750 | 753 | ||
751 | spin_lock_irq(&dev->event_lock); | 754 | spin_lock_irq(&dev->event_lock); |
752 | spin_lock(&client->buffer_lock); | 755 | spin_lock(&client->buffer_lock); |
753 | 756 | ||
754 | memcpy(mem, bits, sizeof(unsigned long) * max); | 757 | memcpy(mem, bits, len); |
755 | 758 | ||
756 | spin_unlock(&dev->event_lock); | 759 | spin_unlock(&dev->event_lock); |
757 | 760 | ||
@@ -759,7 +762,7 @@ static int evdev_handle_get_val(struct evdev_client *client, | |||
759 | 762 | ||
760 | spin_unlock_irq(&client->buffer_lock); | 763 | spin_unlock_irq(&client->buffer_lock); |
761 | 764 | ||
762 | ret = bits_to_user(mem, max, size, p, compat); | 765 | ret = bits_to_user(mem, maxbit, maxlen, p, compat); |
763 | if (ret < 0) | 766 | if (ret < 0) |
764 | evdev_queue_syn_dropped(client); | 767 | evdev_queue_syn_dropped(client); |
765 | 768 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 29ca0bb4f561..0f175f55782b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -498,7 +498,8 @@ void input_set_abs_params(struct input_dev *dev, unsigned int axis, | |||
498 | absinfo->fuzz = fuzz; | 498 | absinfo->fuzz = fuzz; |
499 | absinfo->flat = flat; | 499 | absinfo->flat = flat; |
500 | 500 | ||
501 | dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); | 501 | __set_bit(EV_ABS, dev->evbit); |
502 | __set_bit(axis, dev->absbit); | ||
502 | } | 503 | } |
503 | EXPORT_SYMBOL(input_set_abs_params); | 504 | EXPORT_SYMBOL(input_set_abs_params); |
504 | 505 | ||
@@ -1788,7 +1789,7 @@ struct input_dev *input_allocate_device(void) | |||
1788 | INIT_LIST_HEAD(&dev->h_list); | 1789 | INIT_LIST_HEAD(&dev->h_list); |
1789 | INIT_LIST_HEAD(&dev->node); | 1790 | INIT_LIST_HEAD(&dev->node); |
1790 | 1791 | ||
1791 | dev_set_name(&dev->dev, "input%ld", | 1792 | dev_set_name(&dev->dev, "input%lu", |
1792 | (unsigned long) atomic_inc_return(&input_no) - 1); | 1793 | (unsigned long) atomic_inc_return(&input_no) - 1); |
1793 | 1794 | ||
1794 | __module_get(THIS_MODULE); | 1795 | __module_get(THIS_MODULE); |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index cd13c82ca0a1..2ed7905a068f 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -209,6 +209,7 @@ static const struct xpad_device { | |||
209 | { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 }, | 209 | { 0x24c6, 0x5501, "Hori Real Arcade Pro VX-SA", 0, XTYPE_XBOX360 }, |
210 | { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, | 210 | { 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 }, |
211 | { 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller", 0, XTYPE_XBOX360 }, | 211 | { 0x24c6, 0x5b02, "Thrustmaster, Inc. GPX Controller", 0, XTYPE_XBOX360 }, |
212 | { 0x24c6, 0x5b03, "Thrustmaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 }, | ||
212 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, | 213 | { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, |
213 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } | 214 | { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } |
214 | }; | 215 | }; |
@@ -292,6 +293,7 @@ static const signed short xpad_abs_triggers[] = { | |||
292 | 293 | ||
293 | static struct usb_device_id xpad_table[] = { | 294 | static struct usb_device_id xpad_table[] = { |
294 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ | 295 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ |
296 | XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ | ||
295 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ | 297 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ |
296 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ | 298 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ |
297 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ | 299 | XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ |
diff --git a/drivers/input/keyboard/adp5588-keys.c b/drivers/input/keyboard/adp5588-keys.c index b97ed443e0a4..21a62d0fa764 100644 --- a/drivers/input/keyboard/adp5588-keys.c +++ b/drivers/input/keyboard/adp5588-keys.c | |||
@@ -587,6 +587,7 @@ static int adp5588_probe(struct i2c_client *client, | |||
587 | 587 | ||
588 | err_free_irq: | 588 | err_free_irq: |
589 | free_irq(client->irq, kpad); | 589 | free_irq(client->irq, kpad); |
590 | cancel_delayed_work_sync(&kpad->work); | ||
590 | err_unreg_dev: | 591 | err_unreg_dev: |
591 | input_unregister_device(input); | 592 | input_unregister_device(input); |
592 | input = NULL; | 593 | input = NULL; |
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 5d773d20230a..ffa989f2c785 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c | |||
@@ -348,10 +348,19 @@ static int cros_ec_keyb_resume(struct device *dev) | |||
348 | 348 | ||
349 | static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); | 349 | static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); |
350 | 350 | ||
351 | #ifdef CONFIG_OF | ||
352 | static const struct of_device_id cros_ec_keyb_of_match[] = { | ||
353 | { .compatible = "google,cros-ec-keyb" }, | ||
354 | {}, | ||
355 | }; | ||
356 | MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match); | ||
357 | #endif | ||
358 | |||
351 | static struct platform_driver cros_ec_keyb_driver = { | 359 | static struct platform_driver cros_ec_keyb_driver = { |
352 | .probe = cros_ec_keyb_probe, | 360 | .probe = cros_ec_keyb_probe, |
353 | .driver = { | 361 | .driver = { |
354 | .name = "cros-ec-keyb", | 362 | .name = "cros-ec-keyb", |
363 | .of_match_table = of_match_ptr(cros_ec_keyb_of_match), | ||
355 | .pm = &cros_ec_keyb_pm_ops, | 364 | .pm = &cros_ec_keyb_pm_ops, |
356 | }, | 365 | }, |
357 | }; | 366 | }; |
diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index 7b9b44158ad1..62abe2c16670 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | struct opencores_kbd { | 19 | struct opencores_kbd { |
20 | struct input_dev *input; | 20 | struct input_dev *input; |
21 | struct resource *addr_res; | ||
22 | void __iomem *addr; | 21 | void __iomem *addr; |
23 | int irq; | 22 | int irq; |
24 | unsigned short keycodes[128]; | 23 | unsigned short keycodes[128]; |
@@ -56,35 +55,25 @@ static int opencores_kbd_probe(struct platform_device *pdev) | |||
56 | return -EINVAL; | 55 | return -EINVAL; |
57 | } | 56 | } |
58 | 57 | ||
59 | opencores_kbd = kzalloc(sizeof(*opencores_kbd), GFP_KERNEL); | 58 | opencores_kbd = devm_kzalloc(&pdev->dev, sizeof(*opencores_kbd), |
60 | input = input_allocate_device(); | 59 | GFP_KERNEL); |
61 | if (!opencores_kbd || !input) { | 60 | if (!opencores_kbd) |
62 | dev_err(&pdev->dev, "failed to allocate device structures\n"); | 61 | return -ENOMEM; |
63 | error = -ENOMEM; | ||
64 | goto err_free_mem; | ||
65 | } | ||
66 | |||
67 | opencores_kbd->addr_res = res; | ||
68 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
69 | if (!res) { | ||
70 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
71 | error = -EBUSY; | ||
72 | goto err_free_mem; | ||
73 | } | ||
74 | 62 | ||
75 | opencores_kbd->addr = ioremap(res->start, resource_size(res)); | 63 | input = devm_input_allocate_device(&pdev->dev); |
76 | if (!opencores_kbd->addr) { | 64 | if (!input) { |
77 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 65 | dev_err(&pdev->dev, "failed to allocate input device\n"); |
78 | error = -ENXIO; | 66 | return -ENOMEM; |
79 | goto err_rel_mem; | ||
80 | } | 67 | } |
81 | 68 | ||
82 | opencores_kbd->input = input; | 69 | opencores_kbd->input = input; |
83 | opencores_kbd->irq = irq; | 70 | |
71 | opencores_kbd->addr = devm_ioremap_resource(&pdev->dev, res); | ||
72 | if (IS_ERR(opencores_kbd->addr)) | ||
73 | error = PTR_ERR(opencores_kbd->addr); | ||
84 | 74 | ||
85 | input->name = pdev->name; | 75 | input->name = pdev->name; |
86 | input->phys = "opencores-kbd/input0"; | 76 | input->phys = "opencores-kbd/input0"; |
87 | input->dev.parent = &pdev->dev; | ||
88 | 77 | ||
89 | input_set_drvdata(input, opencores_kbd); | 78 | input_set_drvdata(input, opencores_kbd); |
90 | 79 | ||
@@ -109,54 +98,27 @@ static int opencores_kbd_probe(struct platform_device *pdev) | |||
109 | } | 98 | } |
110 | __clear_bit(KEY_RESERVED, input->keybit); | 99 | __clear_bit(KEY_RESERVED, input->keybit); |
111 | 100 | ||
112 | error = request_irq(irq, &opencores_kbd_isr, | 101 | error = devm_request_irq(&pdev->dev, irq, &opencores_kbd_isr, |
113 | IRQF_TRIGGER_RISING, pdev->name, opencores_kbd); | 102 | IRQF_TRIGGER_RISING, |
103 | pdev->name, opencores_kbd); | ||
114 | if (error) { | 104 | if (error) { |
115 | dev_err(&pdev->dev, "unable to claim irq %d\n", irq); | 105 | dev_err(&pdev->dev, "unable to claim irq %d\n", irq); |
116 | goto err_unmap_mem; | 106 | return error; |
117 | } | 107 | } |
118 | 108 | ||
119 | error = input_register_device(input); | 109 | error = input_register_device(input); |
120 | if (error) { | 110 | if (error) { |
121 | dev_err(&pdev->dev, "unable to register input device\n"); | 111 | dev_err(&pdev->dev, "unable to register input device\n"); |
122 | goto err_free_irq; | 112 | return error; |
123 | } | 113 | } |
124 | 114 | ||
125 | platform_set_drvdata(pdev, opencores_kbd); | 115 | platform_set_drvdata(pdev, opencores_kbd); |
126 | 116 | ||
127 | return 0; | 117 | return 0; |
128 | |||
129 | err_free_irq: | ||
130 | free_irq(irq, opencores_kbd); | ||
131 | err_unmap_mem: | ||
132 | iounmap(opencores_kbd->addr); | ||
133 | err_rel_mem: | ||
134 | release_mem_region(res->start, resource_size(res)); | ||
135 | err_free_mem: | ||
136 | input_free_device(input); | ||
137 | kfree(opencores_kbd); | ||
138 | |||
139 | return error; | ||
140 | } | ||
141 | |||
142 | static int opencores_kbd_remove(struct platform_device *pdev) | ||
143 | { | ||
144 | struct opencores_kbd *opencores_kbd = platform_get_drvdata(pdev); | ||
145 | |||
146 | free_irq(opencores_kbd->irq, opencores_kbd); | ||
147 | |||
148 | iounmap(opencores_kbd->addr); | ||
149 | release_mem_region(opencores_kbd->addr_res->start, | ||
150 | resource_size(opencores_kbd->addr_res)); | ||
151 | input_unregister_device(opencores_kbd->input); | ||
152 | kfree(opencores_kbd); | ||
153 | |||
154 | return 0; | ||
155 | } | 118 | } |
156 | 119 | ||
157 | static struct platform_driver opencores_kbd_device_driver = { | 120 | static struct platform_driver opencores_kbd_device_driver = { |
158 | .probe = opencores_kbd_probe, | 121 | .probe = opencores_kbd_probe, |
159 | .remove = opencores_kbd_remove, | ||
160 | .driver = { | 122 | .driver = { |
161 | .name = "opencores-kbd", | 123 | .name = "opencores-kbd", |
162 | }, | 124 | }, |
diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index d605db4d2f39..7b1fde93799e 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c | |||
@@ -152,7 +152,7 @@ static void max77693_haptic_disable(struct max77693_haptic *haptic) | |||
152 | { | 152 | { |
153 | int error; | 153 | int error; |
154 | 154 | ||
155 | if (haptic->enabled) | 155 | if (!haptic->enabled) |
156 | return; | 156 | return; |
157 | 157 | ||
158 | error = max77693_haptic_configure(haptic, false); | 158 | error = max77693_haptic_configure(haptic, false); |
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 1af28b06c713..95599e478e19 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
@@ -285,7 +285,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev, | |||
285 | error_evtchan: | 285 | error_evtchan: |
286 | xenbus_free_evtchn(dev, evtchn); | 286 | xenbus_free_evtchn(dev, evtchn); |
287 | error_grant: | 287 | error_grant: |
288 | gnttab_end_foreign_access_ref(info->gref, 0); | 288 | gnttab_end_foreign_access(info->gref, 0, 0UL); |
289 | info->gref = -1; | 289 | info->gref = -1; |
290 | return ret; | 290 | return ret; |
291 | } | 291 | } |
@@ -296,7 +296,7 @@ static void xenkbd_disconnect_backend(struct xenkbd_info *info) | |||
296 | unbind_from_irqhandler(info->irq, info); | 296 | unbind_from_irqhandler(info->irq, info); |
297 | info->irq = -1; | 297 | info->irq = -1; |
298 | if (info->gref >= 0) | 298 | if (info->gref >= 0) |
299 | gnttab_end_foreign_access_ref(info->gref, 0); | 299 | gnttab_end_foreign_access(info->gref, 0, 0UL); |
300 | info->gref = -1; | 300 | info->gref = -1; |
301 | } | 301 | } |
302 | 302 | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 35a49bf57227..2b0ae8cc8e51 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -835,8 +835,8 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
835 | f->fingers = alps_process_bitmap(priv, f); | 835 | f->fingers = alps_process_bitmap(priv, f); |
836 | } | 836 | } |
837 | 837 | ||
838 | f->left = packet[4] & 0x01; | 838 | f->left = !!(packet[4] & 0x01); |
839 | f->right = packet[4] & 0x02; | 839 | f->right = !!(packet[4] & 0x02); |
840 | 840 | ||
841 | f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | | 841 | f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | |
842 | ((packet[0] & 0x30) >> 4); | 842 | ((packet[0] & 0x30) >> 4); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 6394d9b5bfd3..9031a0a28ea4 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -607,6 +607,8 @@ static void synaptics_parse_agm(const unsigned char buf[], | |||
607 | priv->agm_pending = true; | 607 | priv->agm_pending = true; |
608 | } | 608 | } |
609 | 609 | ||
610 | static bool is_forcepad; | ||
611 | |||
610 | static int synaptics_parse_hw_state(const unsigned char buf[], | 612 | static int synaptics_parse_hw_state(const unsigned char buf[], |
611 | struct synaptics_data *priv, | 613 | struct synaptics_data *priv, |
612 | struct synaptics_hw_state *hw) | 614 | struct synaptics_hw_state *hw) |
@@ -636,7 +638,7 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
636 | hw->left = (buf[0] & 0x01) ? 1 : 0; | 638 | hw->left = (buf[0] & 0x01) ? 1 : 0; |
637 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 639 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
638 | 640 | ||
639 | if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) { | 641 | if (is_forcepad) { |
640 | /* | 642 | /* |
641 | * ForcePads, like Clickpads, use middle button | 643 | * ForcePads, like Clickpads, use middle button |
642 | * bits to report primary button clicks. | 644 | * bits to report primary button clicks. |
@@ -1667,11 +1669,29 @@ static const struct dmi_system_id __initconst cr48_dmi_table[] = { | |||
1667 | { } | 1669 | { } |
1668 | }; | 1670 | }; |
1669 | 1671 | ||
1672 | static const struct dmi_system_id forcepad_dmi_table[] __initconst = { | ||
1673 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1674 | { | ||
1675 | .matches = { | ||
1676 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
1677 | DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook Folio 1040 G1"), | ||
1678 | }, | ||
1679 | }, | ||
1680 | #endif | ||
1681 | { } | ||
1682 | }; | ||
1683 | |||
1670 | void __init synaptics_module_init(void) | 1684 | void __init synaptics_module_init(void) |
1671 | { | 1685 | { |
1672 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); | 1686 | impaired_toshiba_kbc = dmi_check_system(toshiba_dmi_table); |
1673 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); | 1687 | broken_olpc_ec = dmi_check_system(olpc_dmi_table); |
1674 | cr48_profile_sensor = dmi_check_system(cr48_dmi_table); | 1688 | cr48_profile_sensor = dmi_check_system(cr48_dmi_table); |
1689 | |||
1690 | /* | ||
1691 | * Unfortunately ForcePad capability is not exported over PS/2, | ||
1692 | * so we have to resort to checking DMI. | ||
1693 | */ | ||
1694 | is_forcepad = dmi_check_system(forcepad_dmi_table); | ||
1675 | } | 1695 | } |
1676 | 1696 | ||
1677 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | 1697 | static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index fb2e076738ae..1bd01f21783b 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -77,12 +77,9 @@ | |||
77 | * for noise. | 77 | * for noise. |
78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only | 78 | * 2 0x08 image sensor image sensor tracks 5 fingers, but only |
79 | * reports 2. | 79 | * reports 2. |
80 | * 2 0x01 uniform clickpad whole clickpad moves instead of being | ||
81 | * hinged at the top. | ||
80 | * 2 0x20 report min query 0x0f gives min coord reported | 82 | * 2 0x20 report min query 0x0f gives min coord reported |
81 | * 2 0x80 forcepad forcepad is a variant of clickpad that | ||
82 | * does not have physical buttons but rather | ||
83 | * uses pressure above certain threshold to | ||
84 | * report primary clicks. Forcepads also have | ||
85 | * clickpad bit set. | ||
86 | */ | 83 | */ |
87 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ | 84 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
88 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | 85 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ |
@@ -91,7 +88,6 @@ | |||
91 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) | 88 | #define SYN_CAP_ADV_GESTURE(ex0c) ((ex0c) & 0x080000) |
92 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) | 89 | #define SYN_CAP_REDUCED_FILTERING(ex0c) ((ex0c) & 0x000400) |
93 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) | 90 | #define SYN_CAP_IMAGE_SENSOR(ex0c) ((ex0c) & 0x000800) |
94 | #define SYN_CAP_FORCEPAD(ex0c) ((ex0c) & 0x008000) | ||
95 | 91 | ||
96 | /* synaptics modes query bits */ | 92 | /* synaptics modes query bits */ |
97 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) | 93 | #define SYN_MODE_ABSOLUTE(m) ((m) & (1 << 7)) |
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 40b7d6c0ff17..a0bcbb64d06d 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
@@ -101,6 +101,12 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
101 | }, | 101 | }, |
102 | { | 102 | { |
103 | .matches = { | 103 | .matches = { |
104 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
105 | DMI_MATCH(DMI_PRODUCT_NAME, "X750LN"), | ||
106 | }, | ||
107 | }, | ||
108 | { | ||
109 | .matches = { | ||
104 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), | 110 | DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
105 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), | 111 | DMI_MATCH(DMI_PRODUCT_NAME , "ProLiant"), |
106 | DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), | 112 | DMI_MATCH(DMI_PRODUCT_VERSION, "8500"), |
@@ -201,282 +207,17 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = { | |||
201 | }; | 207 | }; |
202 | 208 | ||
203 | /* | 209 | /* |
204 | * Some Fujitsu notebooks are having trouble with touchpads if | 210 | * Some laptops do implement active multiplexing mode correctly; |
205 | * active multiplexing mode is activated. Luckily they don't have | 211 | * unfortunately they are in minority. |
206 | * external PS/2 ports so we can safely disable it. | ||
207 | * ... apparently some Toshibas don't like MUX mode either and | ||
208 | * die horrible death on reboot. | ||
209 | */ | 212 | */ |
210 | static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { | 213 | static const struct dmi_system_id __initconst i8042_dmi_mux_table[] = { |
211 | { | ||
212 | /* Fujitsu Lifebook P7010/P7010D */ | ||
213 | .matches = { | ||
214 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
215 | DMI_MATCH(DMI_PRODUCT_NAME, "P7010"), | ||
216 | }, | ||
217 | }, | ||
218 | { | ||
219 | /* Fujitsu Lifebook P7010 */ | ||
220 | .matches = { | ||
221 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
222 | DMI_MATCH(DMI_PRODUCT_NAME, "0000000000"), | ||
223 | }, | ||
224 | }, | ||
225 | { | ||
226 | /* Fujitsu Lifebook P5020D */ | ||
227 | .matches = { | ||
228 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
229 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook P Series"), | ||
230 | }, | ||
231 | }, | ||
232 | { | ||
233 | /* Fujitsu Lifebook S2000 */ | ||
234 | .matches = { | ||
235 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
236 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), | ||
237 | }, | ||
238 | }, | ||
239 | { | ||
240 | /* Fujitsu Lifebook S6230 */ | ||
241 | .matches = { | ||
242 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
243 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), | ||
244 | }, | ||
245 | }, | ||
246 | { | ||
247 | /* Fujitsu T70H */ | ||
248 | .matches = { | ||
249 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
250 | DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), | ||
251 | }, | ||
252 | }, | ||
253 | { | ||
254 | /* Fujitsu-Siemens Lifebook T3010 */ | ||
255 | .matches = { | ||
256 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
257 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T3010"), | ||
258 | }, | ||
259 | }, | ||
260 | { | ||
261 | /* Fujitsu-Siemens Lifebook E4010 */ | ||
262 | .matches = { | ||
263 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
264 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E4010"), | ||
265 | }, | ||
266 | }, | ||
267 | { | ||
268 | /* Fujitsu-Siemens Amilo Pro 2010 */ | ||
269 | .matches = { | ||
270 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
271 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro V2010"), | ||
272 | }, | ||
273 | }, | ||
274 | { | ||
275 | /* Fujitsu-Siemens Amilo Pro 2030 */ | ||
276 | .matches = { | ||
277 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
278 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO PRO V2030"), | ||
279 | }, | ||
280 | }, | ||
281 | { | ||
282 | /* | ||
283 | * No data is coming from the touchscreen unless KBC | ||
284 | * is in legacy mode. | ||
285 | */ | ||
286 | /* Panasonic CF-29 */ | ||
287 | .matches = { | ||
288 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
289 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | ||
290 | }, | ||
291 | }, | ||
292 | { | ||
293 | /* | ||
294 | * HP Pavilion DV4017EA - | ||
295 | * errors on MUX ports are reported without raising AUXDATA | ||
296 | * causing "spurious NAK" messages. | ||
297 | */ | ||
298 | .matches = { | ||
299 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
300 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EA032EA#ABF)"), | ||
301 | }, | ||
302 | }, | ||
303 | { | ||
304 | /* | ||
305 | * HP Pavilion ZT1000 - | ||
306 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
307 | */ | ||
308 | .matches = { | ||
309 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
310 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Notebook PC"), | ||
311 | DMI_MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook ZT1000"), | ||
312 | }, | ||
313 | }, | ||
314 | { | ||
315 | /* | ||
316 | * HP Pavilion DV4270ca - | ||
317 | * like DV4017EA does not raise AUXERR for errors on MUX ports. | ||
318 | */ | ||
319 | .matches = { | ||
320 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
321 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion dv4000 (EH476UA#ABL)"), | ||
322 | }, | ||
323 | }, | ||
324 | { | ||
325 | .matches = { | ||
326 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
327 | DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), | ||
328 | }, | ||
329 | }, | ||
330 | { | ||
331 | .matches = { | ||
332 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
333 | DMI_MATCH(DMI_PRODUCT_NAME, "EQUIUM A110"), | ||
334 | }, | ||
335 | }, | ||
336 | { | ||
337 | .matches = { | ||
338 | DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), | ||
339 | DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE C850D"), | ||
340 | }, | ||
341 | }, | ||
342 | { | ||
343 | .matches = { | ||
344 | DMI_MATCH(DMI_SYS_VENDOR, "ALIENWARE"), | ||
345 | DMI_MATCH(DMI_PRODUCT_NAME, "Sentia"), | ||
346 | }, | ||
347 | }, | ||
348 | { | ||
349 | /* Sharp Actius MM20 */ | ||
350 | .matches = { | ||
351 | DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), | ||
352 | DMI_MATCH(DMI_PRODUCT_NAME, "PC-MM20 Series"), | ||
353 | }, | ||
354 | }, | ||
355 | { | ||
356 | /* Sony Vaio FS-115b */ | ||
357 | .matches = { | ||
358 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
359 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FS115B"), | ||
360 | }, | ||
361 | }, | ||
362 | { | 214 | { |
363 | /* | 215 | /* |
364 | * Sony Vaio FZ-240E - | 216 | * Panasonic CF-18 needs to be in MUX mode since the |
365 | * reset and GET ID commands issued via KBD port are | 217 | * touchscreen is on serio3 and it also has touchpad. |
366 | * sometimes being delivered to AUX3. | ||
367 | */ | 218 | */ |
368 | .matches = { | 219 | .matches = { |
369 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 220 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
370 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ240E"), | ||
371 | }, | ||
372 | }, | ||
373 | { | ||
374 | /* | ||
375 | * Most (all?) VAIOs do not have external PS/2 ports nor | ||
376 | * they implement active multiplexing properly, and | ||
377 | * MUX discovery usually messes up keyboard/touchpad. | ||
378 | */ | ||
379 | .matches = { | ||
380 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
381 | DMI_MATCH(DMI_BOARD_NAME, "VAIO"), | ||
382 | }, | ||
383 | }, | ||
384 | { | ||
385 | /* Amoi M636/A737 */ | ||
386 | .matches = { | ||
387 | DMI_MATCH(DMI_SYS_VENDOR, "Amoi Electronics CO.,LTD."), | ||
388 | DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), | ||
389 | }, | ||
390 | }, | ||
391 | { | ||
392 | /* Lenovo 3000 n100 */ | ||
393 | .matches = { | ||
394 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
395 | DMI_MATCH(DMI_PRODUCT_NAME, "076804U"), | ||
396 | }, | ||
397 | }, | ||
398 | { | ||
399 | .matches = { | ||
400 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
401 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"), | ||
402 | }, | ||
403 | }, | ||
404 | { | ||
405 | /* Acer Aspire 5710 */ | ||
406 | .matches = { | ||
407 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
408 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710"), | ||
409 | }, | ||
410 | }, | ||
411 | { | ||
412 | /* Gericom Bellagio */ | ||
413 | .matches = { | ||
414 | DMI_MATCH(DMI_SYS_VENDOR, "Gericom"), | ||
415 | DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"), | ||
416 | }, | ||
417 | }, | ||
418 | { | ||
419 | /* IBM 2656 */ | ||
420 | .matches = { | ||
421 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
422 | DMI_MATCH(DMI_PRODUCT_NAME, "2656"), | ||
423 | }, | ||
424 | }, | ||
425 | { | ||
426 | /* Dell XPS M1530 */ | ||
427 | .matches = { | ||
428 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
429 | DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"), | ||
430 | }, | ||
431 | }, | ||
432 | { | ||
433 | /* Compal HEL80I */ | ||
434 | .matches = { | ||
435 | DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"), | ||
436 | DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"), | ||
437 | }, | ||
438 | }, | ||
439 | { | ||
440 | /* Dell Vostro 1510 */ | ||
441 | .matches = { | ||
442 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
443 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), | ||
444 | }, | ||
445 | }, | ||
446 | { | ||
447 | /* Acer Aspire 5536 */ | ||
448 | .matches = { | ||
449 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
450 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"), | ||
451 | DMI_MATCH(DMI_PRODUCT_VERSION, "0100"), | ||
452 | }, | ||
453 | }, | ||
454 | { | ||
455 | /* Dell Vostro V13 */ | ||
456 | .matches = { | ||
457 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
458 | DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), | ||
459 | }, | ||
460 | }, | ||
461 | { | ||
462 | /* Newer HP Pavilion dv4 models */ | ||
463 | .matches = { | ||
464 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
465 | DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), | ||
466 | }, | ||
467 | }, | ||
468 | { | ||
469 | /* Asus X450LCP */ | ||
470 | .matches = { | ||
471 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | ||
472 | DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"), | ||
473 | }, | ||
474 | }, | ||
475 | { | ||
476 | /* Avatar AVIU-145A6 */ | ||
477 | .matches = { | ||
478 | DMI_MATCH(DMI_SYS_VENDOR, "Intel"), | ||
479 | DMI_MATCH(DMI_PRODUCT_NAME, "IC4I"), | ||
480 | }, | 221 | }, |
481 | }, | 222 | }, |
482 | { } | 223 | { } |
@@ -999,8 +740,8 @@ static int __init i8042_platform_init(void) | |||
999 | if (dmi_check_system(i8042_dmi_noloop_table)) | 740 | if (dmi_check_system(i8042_dmi_noloop_table)) |
1000 | i8042_noloop = true; | 741 | i8042_noloop = true; |
1001 | 742 | ||
1002 | if (dmi_check_system(i8042_dmi_nomux_table)) | 743 | if (dmi_check_system(i8042_dmi_mux_table)) |
1003 | i8042_nomux = true; | 744 | i8042_nomux = false; |
1004 | 745 | ||
1005 | if (dmi_check_system(i8042_dmi_notimeout_table)) | 746 | if (dmi_check_system(i8042_dmi_notimeout_table)) |
1006 | i8042_notimeout = true; | 747 | i8042_notimeout = true; |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index f5a98af3b325..9a97c2b10926 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -39,7 +39,7 @@ static bool i8042_noaux; | |||
39 | module_param_named(noaux, i8042_noaux, bool, 0); | 39 | module_param_named(noaux, i8042_noaux, bool, 0); |
40 | MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); | 40 | MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); |
41 | 41 | ||
42 | static bool i8042_nomux; | 42 | static bool i8042_nomux = true; |
43 | module_param_named(nomux, i8042_nomux, bool, 0); | 43 | module_param_named(nomux, i8042_nomux, bool, 0); |
44 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); | 44 | MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); |
45 | 45 | ||
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index b29134de983b..d399b8b0f000 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -524,8 +524,8 @@ static void serio_init_port(struct serio *serio) | |||
524 | spin_lock_init(&serio->lock); | 524 | spin_lock_init(&serio->lock); |
525 | mutex_init(&serio->drv_mutex); | 525 | mutex_init(&serio->drv_mutex); |
526 | device_initialize(&serio->dev); | 526 | device_initialize(&serio->dev); |
527 | dev_set_name(&serio->dev, "serio%ld", | 527 | dev_set_name(&serio->dev, "serio%lu", |
528 | (long)atomic_inc_return(&serio_no) - 1); | 528 | (unsigned long)atomic_inc_return(&serio_no) - 1); |
529 | serio->dev.bus = &serio_bus; | 529 | serio->dev.bus = &serio_bus; |
530 | serio->dev.release = serio_release_port; | 530 | serio->dev.release = serio_release_port; |
531 | serio->dev.groups = serio_device_attr_groups; | 531 | serio->dev.groups = serio_device_attr_groups; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6bb9a7dd23b6..e1d8003d01f8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -90,6 +90,18 @@ config TOUCHSCREEN_AD7879_SPI | |||
90 | To compile this driver as a module, choose M here: the | 90 | To compile this driver as a module, choose M here: the |
91 | module will be called ad7879-spi. | 91 | module will be called ad7879-spi. |
92 | 92 | ||
93 | config TOUCHSCREEN_AR1021_I2C | ||
94 | tristate "Microchip AR1021 i2c touchscreen" | ||
95 | depends on I2C && OF | ||
96 | help | ||
97 | Say Y here if you have the Microchip AR1021 touchscreen controller | ||
98 | chip in your system. | ||
99 | |||
100 | If unsure, say N. | ||
101 | |||
102 | To compile this driver as a module, choose M here: the | ||
103 | module will be called ar1021_i2c. | ||
104 | |||
93 | config TOUCHSCREEN_ATMEL_MXT | 105 | config TOUCHSCREEN_ATMEL_MXT |
94 | tristate "Atmel mXT I2C Touchscreen" | 106 | tristate "Atmel mXT I2C Touchscreen" |
95 | depends on I2C | 107 | depends on I2C |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 4be94fce41af..090e61cc9171 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o | |||
13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o | 13 | obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o |
14 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o | 14 | obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o |
15 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o | 15 | obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o |
16 | obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o | ||
16 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o | 17 | obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o |
17 | obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o | 18 | obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o |
18 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o | 19 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o |
diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c new file mode 100644 index 000000000000..ba30578e296e --- /dev/null +++ b/drivers/input/touchscreen/ar1021_i2c.c | |||
@@ -0,0 +1,181 @@ | |||
1 | /* | ||
2 | * Microchip AR1021 driver for I2C | ||
3 | * | ||
4 | * Author: Christian Gmeiner <christian.gmeiner@gmail.com> | ||
5 | * | ||
6 | * License: GPLv2 as published by the FSF. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/input.h> | ||
11 | #include <linux/of.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/irq.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | |||
16 | #define AR1021_TOCUH_PKG_SIZE 5 | ||
17 | |||
18 | #define AR1021_MAX_X 4095 | ||
19 | #define AR1021_MAX_Y 4095 | ||
20 | |||
21 | struct ar1021_i2c { | ||
22 | struct i2c_client *client; | ||
23 | struct input_dev *input; | ||
24 | u8 data[AR1021_TOCUH_PKG_SIZE]; | ||
25 | }; | ||
26 | |||
27 | static irqreturn_t ar1021_i2c_irq(int irq, void *dev_id) | ||
28 | { | ||
29 | struct ar1021_i2c *ar1021 = dev_id; | ||
30 | struct input_dev *input = ar1021->input; | ||
31 | u8 *data = ar1021->data; | ||
32 | unsigned int x, y, button; | ||
33 | int retval; | ||
34 | |||
35 | retval = i2c_master_recv(ar1021->client, | ||
36 | ar1021->data, sizeof(ar1021->data)); | ||
37 | if (retval != sizeof(ar1021->data)) | ||
38 | goto out; | ||
39 | |||
40 | /* sync bit set ? */ | ||
41 | if ((data[0] & 0x80) == 0) | ||
42 | goto out; | ||
43 | |||
44 | button = data[0] & BIT(0); | ||
45 | x = ((data[2] & 0x1f) << 7) | (data[1] & 0x7f); | ||
46 | y = ((data[4] & 0x1f) << 7) | (data[3] & 0x7f); | ||
47 | |||
48 | input_report_abs(input, ABS_X, x); | ||
49 | input_report_abs(input, ABS_Y, y); | ||
50 | input_report_key(input, BTN_TOUCH, button); | ||
51 | input_sync(input); | ||
52 | |||
53 | out: | ||
54 | return IRQ_HANDLED; | ||
55 | } | ||
56 | |||
57 | static int ar1021_i2c_open(struct input_dev *dev) | ||
58 | { | ||
59 | struct ar1021_i2c *ar1021 = input_get_drvdata(dev); | ||
60 | struct i2c_client *client = ar1021->client; | ||
61 | |||
62 | enable_irq(client->irq); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static void ar1021_i2c_close(struct input_dev *dev) | ||
68 | { | ||
69 | struct ar1021_i2c *ar1021 = input_get_drvdata(dev); | ||
70 | struct i2c_client *client = ar1021->client; | ||
71 | |||
72 | disable_irq(client->irq); | ||
73 | } | ||
74 | |||
75 | static int ar1021_i2c_probe(struct i2c_client *client, | ||
76 | const struct i2c_device_id *id) | ||
77 | { | ||
78 | struct ar1021_i2c *ar1021; | ||
79 | struct input_dev *input; | ||
80 | int error; | ||
81 | |||
82 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { | ||
83 | dev_err(&client->dev, "i2c_check_functionality error\n"); | ||
84 | return -ENXIO; | ||
85 | } | ||
86 | |||
87 | ar1021 = devm_kzalloc(&client->dev, sizeof(*ar1021), GFP_KERNEL); | ||
88 | if (!ar1021) | ||
89 | return -ENOMEM; | ||
90 | |||
91 | input = devm_input_allocate_device(&client->dev); | ||
92 | if (!input) | ||
93 | return -ENOMEM; | ||
94 | |||
95 | ar1021->client = client; | ||
96 | ar1021->input = input; | ||
97 | |||
98 | input->name = "ar1021 I2C Touchscreen"; | ||
99 | input->id.bustype = BUS_I2C; | ||
100 | input->dev.parent = &client->dev; | ||
101 | input->open = ar1021_i2c_open; | ||
102 | input->close = ar1021_i2c_close; | ||
103 | |||
104 | input_set_capability(input, EV_KEY, BTN_TOUCH); | ||
105 | input_set_abs_params(input, ABS_X, 0, AR1021_MAX_X, 0, 0); | ||
106 | input_set_abs_params(input, ABS_Y, 0, AR1021_MAX_Y, 0, 0); | ||
107 | |||
108 | input_set_drvdata(input, ar1021); | ||
109 | |||
110 | error = devm_request_threaded_irq(&client->dev, client->irq, | ||
111 | NULL, ar1021_i2c_irq, | ||
112 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
113 | "ar1021_i2c", ar1021); | ||
114 | if (error) { | ||
115 | dev_err(&client->dev, | ||
116 | "Failed to enable IRQ, error: %d\n", error); | ||
117 | return error; | ||
118 | } | ||
119 | |||
120 | /* Disable the IRQ, we'll enable it in ar1021_i2c_open() */ | ||
121 | disable_irq(client->irq); | ||
122 | |||
123 | error = input_register_device(ar1021->input); | ||
124 | if (error) { | ||
125 | dev_err(&client->dev, | ||
126 | "Failed to register input device, error: %d\n", error); | ||
127 | return error; | ||
128 | } | ||
129 | |||
130 | i2c_set_clientdata(client, ar1021); | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int __maybe_unused ar1021_i2c_suspend(struct device *dev) | ||
135 | { | ||
136 | struct i2c_client *client = to_i2c_client(dev); | ||
137 | |||
138 | disable_irq(client->irq); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int __maybe_unused ar1021_i2c_resume(struct device *dev) | ||
144 | { | ||
145 | struct i2c_client *client = to_i2c_client(dev); | ||
146 | |||
147 | enable_irq(client->irq); | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume); | ||
153 | |||
154 | static const struct i2c_device_id ar1021_i2c_id[] = { | ||
155 | { "MICROCHIP_AR1021_I2C", 0 }, | ||
156 | { }, | ||
157 | }; | ||
158 | MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id); | ||
159 | |||
160 | static struct of_device_id ar1021_i2c_of_match[] = { | ||
161 | { .compatible = "microchip,ar1021-i2c", }, | ||
162 | { } | ||
163 | }; | ||
164 | MODULE_DEVICE_TABLE(of, ar1021_i2c_of_match); | ||
165 | |||
166 | static struct i2c_driver ar1021_i2c_driver = { | ||
167 | .driver = { | ||
168 | .name = "ar1021_i2c", | ||
169 | .owner = THIS_MODULE, | ||
170 | .pm = &ar1021_i2c_pm, | ||
171 | .of_match_table = ar1021_i2c_of_match, | ||
172 | }, | ||
173 | |||
174 | .probe = ar1021_i2c_probe, | ||
175 | .id_table = ar1021_i2c_id, | ||
176 | }; | ||
177 | module_i2c_driver(ar1021_i2c_driver); | ||
178 | |||
179 | MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>"); | ||
180 | MODULE_DESCRIPTION("Microchip AR1021 I2C Driver"); | ||
181 | MODULE_LICENSE("GPL"); | ||