aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--drivers/input/evdev.c13
-rw-r--r--drivers/input/input.c5
-rw-r--r--drivers/input/joystick/xpad.c2
-rw-r--r--drivers/input/keyboard/adp5588-keys.c1
-rw-r--r--drivers/input/keyboard/cros_ec_keyb.c9
-rw-r--r--drivers/input/keyboard/opencores-kbd.c72
-rw-r--r--drivers/input/misc/max77693-haptic.c2
-rw-r--r--drivers/input/misc/xen-kbdfront.c4
-rw-r--r--drivers/input/mouse/alps.c4
-rw-r--r--drivers/input/mouse/synaptics.c22
-rw-r--r--drivers/input/mouse/synaptics.h8
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h287
-rw-r--r--drivers/input/serio/i8042.c2
-rw-r--r--drivers/input/serio/serio.c4
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/ar1021_i2c.c181
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 */
739static int evdev_handle_get_val(struct evdev_client *client, 739static 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}
503EXPORT_SYMBOL(input_set_abs_params); 504EXPORT_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
293static struct usb_device_id xpad_table[] = { 294static 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
349static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume); 349static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
350 350
351#ifdef CONFIG_OF
352static const struct of_device_id cros_ec_keyb_of_match[] = {
353 { .compatible = "google,cros-ec-keyb" },
354 {},
355};
356MODULE_DEVICE_TABLE(of, cros_ec_keyb_of_match);
357#endif
358
351static struct platform_driver cros_ec_keyb_driver = { 359static 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
19struct opencores_kbd { 19struct 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
142static 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
157static struct platform_driver opencores_kbd_device_driver = { 120static 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
610static bool is_forcepad;
611
610static int synaptics_parse_hw_state(const unsigned char buf[], 612static 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
1672static 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
1670void __init synaptics_module_init(void) 1684void __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
1677static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) 1697static 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 */
210static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { 213static 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;
39module_param_named(noaux, i8042_noaux, bool, 0); 39module_param_named(noaux, i8042_noaux, bool, 0);
40MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port."); 40MODULE_PARM_DESC(noaux, "Do not probe or use AUX (mouse) port.");
41 41
42static bool i8042_nomux; 42static bool i8042_nomux = true;
43module_param_named(nomux, i8042_nomux, bool, 0); 43module_param_named(nomux, i8042_nomux, bool, 0);
44MODULE_PARM_DESC(nomux, "Do not check whether an active multiplexing controller is present."); 44MODULE_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
93config 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
93config TOUCHSCREEN_ATMEL_MXT 105config 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
13obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o 13obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
14obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o 14obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
15obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 15obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
16obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
16obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o 17obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
17obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o 18obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
18obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o 19obj-$(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
21struct ar1021_i2c {
22 struct i2c_client *client;
23 struct input_dev *input;
24 u8 data[AR1021_TOCUH_PKG_SIZE];
25};
26
27static 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
53out:
54 return IRQ_HANDLED;
55}
56
57static 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
67static 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
75static 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
134static 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
143static 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
152static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume);
153
154static const struct i2c_device_id ar1021_i2c_id[] = {
155 { "MICROCHIP_AR1021_I2C", 0 },
156 { },
157};
158MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id);
159
160static struct of_device_id ar1021_i2c_of_match[] = {
161 { .compatible = "microchip,ar1021-i2c", },
162 { }
163};
164MODULE_DEVICE_TABLE(of, ar1021_i2c_of_match);
165
166static 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};
177module_i2c_driver(ar1021_i2c_driver);
178
179MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>");
180MODULE_DESCRIPTION("Microchip AR1021 I2C Driver");
181MODULE_LICENSE("GPL");