diff options
Diffstat (limited to 'drivers/input')
43 files changed, 1721 insertions, 441 deletions
diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 5f04b2d94635..99cc784e1264 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c | |||
| @@ -98,8 +98,7 @@ static int input_leds_connect(struct input_handler *handler, | |||
| 98 | if (!num_leds) | 98 | if (!num_leds) |
| 99 | return -ENXIO; | 99 | return -ENXIO; |
| 100 | 100 | ||
| 101 | leds = kzalloc(sizeof(*leds) + num_leds * sizeof(*leds->leds), | 101 | leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL); |
| 102 | GFP_KERNEL); | ||
| 103 | if (!leds) | 102 | if (!leds) |
| 104 | return -ENOMEM; | 103 | return -ENOMEM; |
| 105 | 104 | ||
diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index a1bbec9cda8d..cf30523c6ef6 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c | |||
| @@ -49,7 +49,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, | |||
| 49 | if (mt) | 49 | if (mt) |
| 50 | return mt->num_slots != num_slots ? -EINVAL : 0; | 50 | return mt->num_slots != num_slots ? -EINVAL : 0; |
| 51 | 51 | ||
| 52 | mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL); | 52 | mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); |
| 53 | if (!mt) | 53 | if (!mt) |
| 54 | goto err_mem; | 54 | goto err_mem; |
| 55 | 55 | ||
diff --git a/drivers/input/input.c b/drivers/input/input.c index 9785546420a7..6365c1958264 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -1943,8 +1943,7 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
| 1943 | break; | 1943 | break; |
| 1944 | 1944 | ||
| 1945 | default: | 1945 | default: |
| 1946 | pr_err("input_set_capability: unknown type %u (code %u)\n", | 1946 | pr_err("%s: unknown type %u (code %u)\n", __func__, type, code); |
| 1947 | type, code); | ||
| 1948 | dump_stack(); | 1947 | dump_stack(); |
| 1949 | return; | 1948 | return; |
| 1950 | } | 1949 | } |
diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c index 005d852a06e9..f051993c568e 100644 --- a/drivers/input/joystick/as5011.c +++ b/drivers/input/joystick/as5011.c | |||
| @@ -269,9 +269,7 @@ static int as5011_probe(struct i2c_client *client, | |||
| 269 | input_dev->id.bustype = BUS_I2C; | 269 | input_dev->id.bustype = BUS_I2C; |
| 270 | input_dev->dev.parent = &client->dev; | 270 | input_dev->dev.parent = &client->dev; |
| 271 | 271 | ||
| 272 | __set_bit(EV_KEY, input_dev->evbit); | 272 | input_set_capability(input_dev, EV_KEY, BTN_JOYSTICK); |
| 273 | __set_bit(EV_ABS, input_dev->evbit); | ||
| 274 | __set_bit(BTN_JOYSTICK, input_dev->keybit); | ||
| 275 | 273 | ||
| 276 | input_set_abs_params(input_dev, ABS_X, | 274 | input_set_abs_params(input_dev, ABS_X, |
| 277 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); | 275 | AS5011_MIN_AXIS, AS5011_MAX_AXIS, AS5011_FUZZ, AS5011_FLAT); |
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index 2ffb2e8bdc3b..4e10ffdf8a36 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c | |||
| @@ -862,7 +862,7 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
| 862 | 862 | ||
| 863 | case GC_N64: | 863 | case GC_N64: |
| 864 | for (i = 0; i < 10; i++) | 864 | for (i = 0; i < 10; i++) |
| 865 | __set_bit(gc_n64_btn[i], input_dev->keybit); | 865 | input_set_capability(input_dev, EV_KEY, gc_n64_btn[i]); |
| 866 | 866 | ||
| 867 | for (i = 0; i < 2; i++) { | 867 | for (i = 0; i < 2; i++) { |
| 868 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); | 868 | input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2); |
| @@ -879,26 +879,27 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
| 879 | break; | 879 | break; |
| 880 | 880 | ||
| 881 | case GC_SNESMOUSE: | 881 | case GC_SNESMOUSE: |
| 882 | __set_bit(BTN_LEFT, input_dev->keybit); | 882 | input_set_capability(input_dev, EV_KEY, BTN_LEFT); |
| 883 | __set_bit(BTN_RIGHT, input_dev->keybit); | 883 | input_set_capability(input_dev, EV_KEY, BTN_RIGHT); |
| 884 | __set_bit(REL_X, input_dev->relbit); | 884 | input_set_capability(input_dev, EV_REL, REL_X); |
| 885 | __set_bit(REL_Y, input_dev->relbit); | 885 | input_set_capability(input_dev, EV_REL, REL_Y); |
| 886 | break; | 886 | break; |
| 887 | 887 | ||
| 888 | case GC_SNES: | 888 | case GC_SNES: |
| 889 | for (i = 4; i < 8; i++) | 889 | for (i = 4; i < 8; i++) |
| 890 | __set_bit(gc_snes_btn[i], input_dev->keybit); | 890 | input_set_capability(input_dev, EV_KEY, gc_snes_btn[i]); |
| 891 | /* fall through */ | 891 | /* fall through */ |
| 892 | case GC_NES: | 892 | case GC_NES: |
| 893 | for (i = 0; i < 4; i++) | 893 | for (i = 0; i < 4; i++) |
| 894 | __set_bit(gc_snes_btn[i], input_dev->keybit); | 894 | input_set_capability(input_dev, EV_KEY, gc_snes_btn[i]); |
| 895 | break; | 895 | break; |
| 896 | 896 | ||
| 897 | case GC_MULTI2: | 897 | case GC_MULTI2: |
| 898 | __set_bit(BTN_THUMB, input_dev->keybit); | 898 | input_set_capability(input_dev, EV_KEY, BTN_THUMB); |
| 899 | /* fall through */ | 899 | /* fall through */ |
| 900 | case GC_MULTI: | 900 | case GC_MULTI: |
| 901 | __set_bit(BTN_TRIGGER, input_dev->keybit); | 901 | input_set_capability(input_dev, EV_KEY, BTN_TRIGGER); |
| 902 | /* fall through */ | ||
| 902 | break; | 903 | break; |
| 903 | 904 | ||
| 904 | case GC_PSX: | 905 | case GC_PSX: |
| @@ -906,15 +907,17 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type) | |||
| 906 | input_set_abs_params(input_dev, | 907 | input_set_abs_params(input_dev, |
| 907 | gc_psx_abs[i], 4, 252, 0, 2); | 908 | gc_psx_abs[i], 4, 252, 0, 2); |
| 908 | for (i = 0; i < 12; i++) | 909 | for (i = 0; i < 12; i++) |
| 909 | __set_bit(gc_psx_btn[i], input_dev->keybit); | 910 | input_set_capability(input_dev, EV_KEY, gc_psx_btn[i]); |
| 911 | break; | ||
| 910 | 912 | ||
| 911 | break; | 913 | break; |
| 912 | 914 | ||
| 913 | case GC_DDR: | 915 | case GC_DDR: |
| 914 | for (i = 0; i < 4; i++) | 916 | for (i = 0; i < 4; i++) |
| 915 | __set_bit(gc_psx_ddr_btn[i], input_dev->keybit); | 917 | input_set_capability(input_dev, EV_KEY, |
| 918 | gc_psx_ddr_btn[i]); | ||
| 916 | for (i = 0; i < 12; i++) | 919 | for (i = 0; i < 12; i++) |
| 917 | __set_bit(gc_psx_btn[i], input_dev->keybit); | 920 | input_set_capability(input_dev, EV_KEY, gc_psx_btn[i]); |
| 918 | 921 | ||
| 919 | break; | 922 | break; |
| 920 | } | 923 | } |
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index d1c6e4846a4a..7f4dff9a566f 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c | |||
| @@ -80,7 +80,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr | |||
| 80 | 80 | ||
| 81 | timeout = gameport_time(gameport, 10000); /* 10 ms */ | 81 | timeout = gameport_time(gameport, 10000); /* 10 ms */ |
| 82 | 82 | ||
| 83 | buf = kmalloc(BUF_SIZE * sizeof(struct joydump), GFP_KERNEL); | 83 | buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL); |
| 84 | if (!buf) { | 84 | if (!buf) { |
| 85 | printk(KERN_INFO "joydump: no memory for testing\n"); | 85 | printk(KERN_INFO "joydump: no memory for testing\n"); |
| 86 | goto jd_end; | 86 | goto jd_end; |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 06e9650b3b30..48e36acbeb49 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -86,8 +86,10 @@ | |||
| 86 | 86 | ||
| 87 | #define XPAD_PKT_LEN 64 | 87 | #define XPAD_PKT_LEN 64 |
| 88 | 88 | ||
| 89 | /* xbox d-pads should map to buttons, as is required for DDR pads | 89 | /* |
| 90 | but we map them to axes when possible to simplify things */ | 90 | * xbox d-pads should map to buttons, as is required for DDR pads |
| 91 | * but we map them to axes when possible to simplify things | ||
| 92 | */ | ||
| 91 | #define MAP_DPAD_TO_BUTTONS (1 << 0) | 93 | #define MAP_DPAD_TO_BUTTONS (1 << 0) |
| 92 | #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) | 94 | #define MAP_TRIGGERS_TO_BUTTONS (1 << 1) |
| 93 | #define MAP_STICKS_TO_NULL (1 << 2) | 95 | #define MAP_STICKS_TO_NULL (1 << 2) |
| @@ -123,6 +125,7 @@ static const struct xpad_device { | |||
| 123 | u8 mapping; | 125 | u8 mapping; |
| 124 | u8 xtype; | 126 | u8 xtype; |
| 125 | } xpad_device[] = { | 127 | } xpad_device[] = { |
| 128 | { 0x0079, 0x18d4, "GPD Win 2 Controller", 0, XTYPE_XBOX360 }, | ||
| 126 | { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, | 129 | { 0x044f, 0x0f00, "Thrustmaster Wheel", 0, XTYPE_XBOX }, |
| 127 | { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, | 130 | { 0x044f, 0x0f03, "Thrustmaster Wheel", 0, XTYPE_XBOX }, |
| 128 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, | 131 | { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", 0, XTYPE_XBOX }, |
| @@ -387,15 +390,15 @@ static const signed short xpad_abs_triggers[] = { | |||
| 387 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, | 390 | * match against vendor id as well. Wired Xbox 360 devices have protocol 1, |
| 388 | * wireless controllers have protocol 129. | 391 | * wireless controllers have protocol 129. |
| 389 | */ | 392 | */ |
| 390 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend,pr) \ | 393 | #define XPAD_XBOX360_VENDOR_PROTOCOL(vend, pr) \ |
| 391 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ | 394 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, \ |
| 392 | .idVendor = (vend), \ | 395 | .idVendor = (vend), \ |
| 393 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ | 396 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, \ |
| 394 | .bInterfaceSubClass = 93, \ | 397 | .bInterfaceSubClass = 93, \ |
| 395 | .bInterfaceProtocol = (pr) | 398 | .bInterfaceProtocol = (pr) |
| 396 | #define XPAD_XBOX360_VENDOR(vend) \ | 399 | #define XPAD_XBOX360_VENDOR(vend) \ |
| 397 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,1) }, \ | 400 | { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 1) }, \ |
| 398 | { XPAD_XBOX360_VENDOR_PROTOCOL(vend,129) } | 401 | { XPAD_XBOX360_VENDOR_PROTOCOL((vend), 129) } |
| 399 | 402 | ||
| 400 | /* The Xbox One controller uses subclass 71 and protocol 208. */ | 403 | /* The Xbox One controller uses subclass 71 and protocol 208. */ |
| 401 | #define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \ | 404 | #define XPAD_XBOXONE_VENDOR_PROTOCOL(vend, pr) \ |
| @@ -405,10 +408,11 @@ static const signed short xpad_abs_triggers[] = { | |||
| 405 | .bInterfaceSubClass = 71, \ | 408 | .bInterfaceSubClass = 71, \ |
| 406 | .bInterfaceProtocol = (pr) | 409 | .bInterfaceProtocol = (pr) |
| 407 | #define XPAD_XBOXONE_VENDOR(vend) \ | 410 | #define XPAD_XBOXONE_VENDOR(vend) \ |
| 408 | { XPAD_XBOXONE_VENDOR_PROTOCOL(vend, 208) } | 411 | { XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) } |
| 409 | 412 | ||
| 410 | static const struct usb_device_id xpad_table[] = { | 413 | static const struct usb_device_id xpad_table[] = { |
| 411 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ | 414 | { USB_INTERFACE_INFO('X', 'B', 0) }, /* X-Box USB-IF not approved class */ |
| 415 | XPAD_XBOX360_VENDOR(0x0079), /* GPD Win 2 Controller */ | ||
| 412 | XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ | 416 | XPAD_XBOX360_VENDOR(0x044f), /* Thrustmaster X-Box 360 controllers */ |
| 413 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ | 417 | XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ |
| 414 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ | 418 | XPAD_XBOXONE_VENDOR(0x045e), /* Microsoft X-Box One controllers */ |
| @@ -1573,7 +1577,6 @@ static void xpad_close(struct input_dev *dev) | |||
| 1573 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | 1577 | static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) |
| 1574 | { | 1578 | { |
| 1575 | struct usb_xpad *xpad = input_get_drvdata(input_dev); | 1579 | struct usb_xpad *xpad = input_get_drvdata(input_dev); |
| 1576 | set_bit(abs, input_dev->absbit); | ||
| 1577 | 1580 | ||
| 1578 | switch (abs) { | 1581 | switch (abs) { |
| 1579 | case ABS_X: | 1582 | case ABS_X: |
| @@ -1593,6 +1596,9 @@ static void xpad_set_up_abs(struct input_dev *input_dev, signed short abs) | |||
| 1593 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ | 1596 | case ABS_HAT0Y: /* the d-pad (only if dpad is mapped to axes */ |
| 1594 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); | 1597 | input_set_abs_params(input_dev, abs, -1, 1, 0, 0); |
| 1595 | break; | 1598 | break; |
| 1599 | default: | ||
| 1600 | input_set_abs_params(input_dev, abs, 0, 0, 0, 0); | ||
| 1601 | break; | ||
| 1596 | } | 1602 | } |
| 1597 | } | 1603 | } |
| 1598 | 1604 | ||
| @@ -1633,10 +1639,7 @@ static int xpad_init_input(struct usb_xpad *xpad) | |||
| 1633 | input_dev->close = xpad_close; | 1639 | input_dev->close = xpad_close; |
| 1634 | } | 1640 | } |
| 1635 | 1641 | ||
| 1636 | __set_bit(EV_KEY, input_dev->evbit); | ||
| 1637 | |||
| 1638 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { | 1642 | if (!(xpad->mapping & MAP_STICKS_TO_NULL)) { |
| 1639 | __set_bit(EV_ABS, input_dev->evbit); | ||
| 1640 | /* set up axes */ | 1643 | /* set up axes */ |
| 1641 | for (i = 0; xpad_abs[i] >= 0; i++) | 1644 | for (i = 0; xpad_abs[i] >= 0; i++) |
| 1642 | xpad_set_up_abs(input_dev, xpad_abs[i]); | 1645 | xpad_set_up_abs(input_dev, xpad_abs[i]); |
| @@ -1644,21 +1647,22 @@ static int xpad_init_input(struct usb_xpad *xpad) | |||
| 1644 | 1647 | ||
| 1645 | /* set up standard buttons */ | 1648 | /* set up standard buttons */ |
| 1646 | for (i = 0; xpad_common_btn[i] >= 0; i++) | 1649 | for (i = 0; xpad_common_btn[i] >= 0; i++) |
| 1647 | __set_bit(xpad_common_btn[i], input_dev->keybit); | 1650 | input_set_capability(input_dev, EV_KEY, xpad_common_btn[i]); |
| 1648 | 1651 | ||
| 1649 | /* set up model-specific ones */ | 1652 | /* set up model-specific ones */ |
| 1650 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || | 1653 | if (xpad->xtype == XTYPE_XBOX360 || xpad->xtype == XTYPE_XBOX360W || |
| 1651 | xpad->xtype == XTYPE_XBOXONE) { | 1654 | xpad->xtype == XTYPE_XBOXONE) { |
| 1652 | for (i = 0; xpad360_btn[i] >= 0; i++) | 1655 | for (i = 0; xpad360_btn[i] >= 0; i++) |
| 1653 | __set_bit(xpad360_btn[i], input_dev->keybit); | 1656 | input_set_capability(input_dev, EV_KEY, xpad360_btn[i]); |
| 1654 | } else { | 1657 | } else { |
| 1655 | for (i = 0; xpad_btn[i] >= 0; i++) | 1658 | for (i = 0; xpad_btn[i] >= 0; i++) |
| 1656 | __set_bit(xpad_btn[i], input_dev->keybit); | 1659 | input_set_capability(input_dev, EV_KEY, xpad_btn[i]); |
| 1657 | } | 1660 | } |
| 1658 | 1661 | ||
| 1659 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { | 1662 | if (xpad->mapping & MAP_DPAD_TO_BUTTONS) { |
| 1660 | for (i = 0; xpad_btn_pad[i] >= 0; i++) | 1663 | for (i = 0; xpad_btn_pad[i] >= 0; i++) |
| 1661 | __set_bit(xpad_btn_pad[i], input_dev->keybit); | 1664 | input_set_capability(input_dev, EV_KEY, |
| 1665 | xpad_btn_pad[i]); | ||
| 1662 | } | 1666 | } |
| 1663 | 1667 | ||
| 1664 | /* | 1668 | /* |
| @@ -1675,7 +1679,8 @@ static int xpad_init_input(struct usb_xpad *xpad) | |||
| 1675 | 1679 | ||
| 1676 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { | 1680 | if (xpad->mapping & MAP_TRIGGERS_TO_BUTTONS) { |
| 1677 | for (i = 0; xpad_btn_triggers[i] >= 0; i++) | 1681 | for (i = 0; xpad_btn_triggers[i] >= 0; i++) |
| 1678 | __set_bit(xpad_btn_triggers[i], input_dev->keybit); | 1682 | input_set_capability(input_dev, EV_KEY, |
| 1683 | xpad_btn_triggers[i]); | ||
| 1679 | } else { | 1684 | } else { |
| 1680 | for (i = 0; xpad_abs_triggers[i] >= 0; i++) | 1685 | for (i = 0; xpad_abs_triggers[i] >= 0; i++) |
| 1681 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); | 1686 | xpad_set_up_abs(input_dev, xpad_abs_triggers[i]); |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 2b469cc47a78..6bd97ffee761 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -747,4 +747,13 @@ config KEYBOARD_BCM | |||
| 747 | To compile this driver as a module, choose M here: the | 747 | To compile this driver as a module, choose M here: the |
| 748 | module will be called bcm-keypad. | 748 | module will be called bcm-keypad. |
| 749 | 749 | ||
| 750 | config KEYBOARD_MTK_PMIC | ||
| 751 | tristate "MediaTek PMIC keys support" | ||
| 752 | depends on MFD_MT6397 | ||
| 753 | help | ||
| 754 | Say Y here if you want to use the pmic keys (powerkey/homekey). | ||
| 755 | |||
| 756 | To compile this driver as a module, choose M here: the | ||
| 757 | module will be called pmic-keys. | ||
| 758 | |||
| 750 | endif | 759 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 8fab920afa58..182e92985dbf 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
| @@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o | |||
| 40 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o | 40 | obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o |
| 41 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o | 41 | obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o |
| 42 | obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o | 42 | obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o |
| 43 | obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o | ||
| 43 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o | 44 | obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o |
| 44 | obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o | 45 | obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o |
| 45 | obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o | 46 | obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o |
diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 1a1eacae3ea1..312916f99597 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c | |||
| @@ -357,8 +357,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, | |||
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | priv = devm_kzalloc(dev, | 359 | priv = devm_kzalloc(dev, |
| 360 | sizeof(*priv) + | 360 | struct_size(priv, keycodes, cap->num_channels), |
| 361 | cap->num_channels * sizeof(priv->keycodes[0]), | ||
| 362 | GFP_KERNEL); | 361 | GFP_KERNEL); |
| 363 | if (!priv) | 362 | if (!priv) |
| 364 | return -ENOMEM; | 363 | return -ENOMEM; |
diff --git a/drivers/input/keyboard/clps711x-keypad.c b/drivers/input/keyboard/clps711x-keypad.c index 997e3e97f573..e319f745771a 100644 --- a/drivers/input/keyboard/clps711x-keypad.c +++ b/drivers/input/keyboard/clps711x-keypad.c | |||
| @@ -109,8 +109,8 @@ static int clps711x_keypad_probe(struct platform_device *pdev) | |||
| 109 | if (priv->row_count < 1) | 109 | if (priv->row_count < 1) |
| 110 | return -EINVAL; | 110 | return -EINVAL; |
| 111 | 111 | ||
| 112 | priv->gpio_data = devm_kzalloc(dev, | 112 | priv->gpio_data = devm_kcalloc(dev, |
| 113 | sizeof(*priv->gpio_data) * priv->row_count, | 113 | priv->row_count, sizeof(*priv->gpio_data), |
| 114 | GFP_KERNEL); | 114 | GFP_KERNEL); |
| 115 | if (!priv->gpio_data) | 115 | if (!priv->gpio_data) |
| 116 | return -ENOMEM; | 116 | return -ENOMEM; |
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 79eb29550c34..489ddd37bd4e 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c | |||
| @@ -244,24 +244,35 @@ static int cros_ec_keyb_work(struct notifier_block *nb, | |||
| 244 | 244 | ||
| 245 | switch (ckdev->ec->event_data.event_type) { | 245 | switch (ckdev->ec->event_data.event_type) { |
| 246 | case EC_MKBP_EVENT_KEY_MATRIX: | 246 | case EC_MKBP_EVENT_KEY_MATRIX: |
| 247 | /* | 247 | if (device_may_wakeup(ckdev->dev)) { |
| 248 | * If EC is not the wake source, discard key state changes | 248 | pm_wakeup_event(ckdev->dev, 0); |
| 249 | * during suspend. | 249 | } else { |
| 250 | */ | 250 | /* |
| 251 | if (queued_during_suspend) | 251 | * If keyboard is not wake enabled, discard key state |
| 252 | return NOTIFY_OK; | 252 | * changes during suspend. Switches will be re-checked |
| 253 | * in cros_ec_keyb_resume() to be sure nothing is lost. | ||
| 254 | */ | ||
| 255 | if (queued_during_suspend) | ||
| 256 | return NOTIFY_OK; | ||
| 257 | } | ||
| 253 | 258 | ||
| 254 | if (ckdev->ec->event_size != ckdev->cols) { | 259 | if (ckdev->ec->event_size != ckdev->cols) { |
| 255 | dev_err(ckdev->dev, | 260 | dev_err(ckdev->dev, |
| 256 | "Discarded incomplete key matrix event.\n"); | 261 | "Discarded incomplete key matrix event.\n"); |
| 257 | return NOTIFY_OK; | 262 | return NOTIFY_OK; |
| 258 | } | 263 | } |
| 264 | |||
| 259 | cros_ec_keyb_process(ckdev, | 265 | cros_ec_keyb_process(ckdev, |
| 260 | ckdev->ec->event_data.data.key_matrix, | 266 | ckdev->ec->event_data.data.key_matrix, |
| 261 | ckdev->ec->event_size); | 267 | ckdev->ec->event_size); |
| 262 | break; | 268 | break; |
| 263 | 269 | ||
| 264 | case EC_MKBP_EVENT_SYSRQ: | 270 | case EC_MKBP_EVENT_SYSRQ: |
| 271 | if (device_may_wakeup(ckdev->dev)) | ||
| 272 | pm_wakeup_event(ckdev->dev, 0); | ||
| 273 | else if (queued_during_suspend) | ||
| 274 | return NOTIFY_OK; | ||
| 275 | |||
| 265 | val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq); | 276 | val = get_unaligned_le32(&ckdev->ec->event_data.data.sysrq); |
| 266 | dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val); | 277 | dev_dbg(ckdev->dev, "sysrq code from EC: %#x\n", val); |
| 267 | handle_sysrq(val); | 278 | handle_sysrq(val); |
| @@ -269,12 +280,9 @@ static int cros_ec_keyb_work(struct notifier_block *nb, | |||
| 269 | 280 | ||
| 270 | case EC_MKBP_EVENT_BUTTON: | 281 | case EC_MKBP_EVENT_BUTTON: |
| 271 | case EC_MKBP_EVENT_SWITCH: | 282 | case EC_MKBP_EVENT_SWITCH: |
| 272 | /* | 283 | if (device_may_wakeup(ckdev->dev)) |
| 273 | * If EC is not the wake source, discard key state | 284 | pm_wakeup_event(ckdev->dev, 0); |
| 274 | * changes during suspend. Switches will be re-checked in | 285 | else if (queued_during_suspend) |
| 275 | * cros_ec_keyb_resume() to be sure nothing is lost. | ||
| 276 | */ | ||
| 277 | if (queued_during_suspend) | ||
| 278 | return NOTIFY_OK; | 286 | return NOTIFY_OK; |
| 279 | 287 | ||
| 280 | if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { | 288 | if (ckdev->ec->event_data.event_type == EC_MKBP_EVENT_BUTTON) { |
| @@ -639,6 +647,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) | |||
| 639 | return err; | 647 | return err; |
| 640 | } | 648 | } |
| 641 | 649 | ||
| 650 | device_init_wakeup(ckdev->dev, true); | ||
| 642 | return 0; | 651 | return 0; |
| 643 | } | 652 | } |
| 644 | 653 | ||
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 41614c185918..f51ae09596ef 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c | |||
| @@ -443,9 +443,9 @@ matrix_keypad_parse_dt(struct device *dev) | |||
| 443 | of_property_read_u32(np, "col-scan-delay-us", | 443 | of_property_read_u32(np, "col-scan-delay-us", |
| 444 | &pdata->col_scan_delay_us); | 444 | &pdata->col_scan_delay_us); |
| 445 | 445 | ||
| 446 | gpios = devm_kzalloc(dev, | 446 | gpios = devm_kcalloc(dev, |
| 447 | sizeof(unsigned int) * | 447 | pdata->num_row_gpios + pdata->num_col_gpios, |
| 448 | (pdata->num_row_gpios + pdata->num_col_gpios), | 448 | sizeof(unsigned int), |
| 449 | GFP_KERNEL); | 449 | GFP_KERNEL); |
| 450 | if (!gpios) { | 450 | if (!gpios) { |
| 451 | dev_err(dev, "could not allocate memory for gpios\n"); | 451 | dev_err(dev, "could not allocate memory for gpios\n"); |
diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c new file mode 100644 index 000000000000..02c67a1749fc --- /dev/null +++ b/drivers/input/keyboard/mtk-pmic-keys.c | |||
| @@ -0,0 +1,339 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2017 MediaTek, Inc. | ||
| 3 | * | ||
| 4 | * Author: Chen Zhong <chen.zhong@mediatek.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/input.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/regmap.h> | ||
| 26 | #include <linux/mfd/mt6323/registers.h> | ||
| 27 | #include <linux/mfd/mt6397/registers.h> | ||
| 28 | #include <linux/mfd/mt6397/core.h> | ||
| 29 | |||
| 30 | #define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1 | ||
| 31 | #define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6 | ||
| 32 | #define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1 | ||
| 33 | #define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5 | ||
| 34 | #define MTK_PMIC_RST_DU_MASK 0x3 | ||
| 35 | #define MTK_PMIC_RST_DU_SHIFT 8 | ||
| 36 | |||
| 37 | #define MTK_PMIC_PWRKEY_RST \ | ||
| 38 | (MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT) | ||
| 39 | #define MTK_PMIC_HOMEKEY_RST \ | ||
| 40 | (MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT) | ||
| 41 | |||
| 42 | #define MTK_PMIC_PWRKEY_INDEX 0 | ||
| 43 | #define MTK_PMIC_HOMEKEY_INDEX 1 | ||
| 44 | #define MTK_PMIC_MAX_KEY_COUNT 2 | ||
| 45 | |||
| 46 | struct mtk_pmic_keys_regs { | ||
| 47 | u32 deb_reg; | ||
| 48 | u32 deb_mask; | ||
| 49 | u32 intsel_reg; | ||
| 50 | u32 intsel_mask; | ||
| 51 | }; | ||
| 52 | |||
| 53 | #define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \ | ||
| 54 | _intsel_reg, _intsel_mask) \ | ||
| 55 | { \ | ||
| 56 | .deb_reg = _deb_reg, \ | ||
| 57 | .deb_mask = _deb_mask, \ | ||
| 58 | .intsel_reg = _intsel_reg, \ | ||
| 59 | .intsel_mask = _intsel_mask, \ | ||
| 60 | } | ||
| 61 | |||
| 62 | struct mtk_pmic_regs { | ||
| 63 | const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT]; | ||
| 64 | u32 pmic_rst_reg; | ||
| 65 | }; | ||
| 66 | |||
| 67 | static const struct mtk_pmic_regs mt6397_regs = { | ||
| 68 | .keys_regs[MTK_PMIC_PWRKEY_INDEX] = | ||
| 69 | MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS, | ||
| 70 | 0x8, MT6397_INT_RSV, 0x10), | ||
| 71 | .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = | ||
| 72 | MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2, | ||
| 73 | 0x10, MT6397_INT_RSV, 0x8), | ||
| 74 | .pmic_rst_reg = MT6397_TOP_RST_MISC, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static const struct mtk_pmic_regs mt6323_regs = { | ||
| 78 | .keys_regs[MTK_PMIC_PWRKEY_INDEX] = | ||
| 79 | MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, | ||
| 80 | 0x2, MT6323_INT_MISC_CON, 0x10), | ||
| 81 | .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = | ||
| 82 | MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, | ||
| 83 | 0x4, MT6323_INT_MISC_CON, 0x8), | ||
| 84 | .pmic_rst_reg = MT6323_TOP_RST_MISC, | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct mtk_pmic_keys_info { | ||
| 88 | struct mtk_pmic_keys *keys; | ||
| 89 | const struct mtk_pmic_keys_regs *regs; | ||
| 90 | unsigned int keycode; | ||
| 91 | int irq; | ||
| 92 | bool wakeup:1; | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct mtk_pmic_keys { | ||
| 96 | struct input_dev *input_dev; | ||
| 97 | struct device *dev; | ||
| 98 | struct regmap *regmap; | ||
| 99 | struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT]; | ||
| 100 | }; | ||
| 101 | |||
| 102 | enum mtk_pmic_keys_lp_mode { | ||
| 103 | LP_DISABLE, | ||
| 104 | LP_ONEKEY, | ||
| 105 | LP_TWOKEY, | ||
| 106 | }; | ||
| 107 | |||
| 108 | static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys, | ||
| 109 | u32 pmic_rst_reg) | ||
| 110 | { | ||
| 111 | int ret; | ||
| 112 | u32 long_press_mode, long_press_debounce; | ||
| 113 | |||
| 114 | ret = of_property_read_u32(keys->dev->of_node, | ||
| 115 | "power-off-time-sec", &long_press_debounce); | ||
| 116 | if (ret) | ||
| 117 | long_press_debounce = 0; | ||
| 118 | |||
| 119 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 120 | MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT, | ||
| 121 | long_press_debounce << MTK_PMIC_RST_DU_SHIFT); | ||
| 122 | |||
| 123 | ret = of_property_read_u32(keys->dev->of_node, | ||
| 124 | "mediatek,long-press-mode", &long_press_mode); | ||
| 125 | if (ret) | ||
| 126 | long_press_mode = LP_DISABLE; | ||
| 127 | |||
| 128 | switch (long_press_mode) { | ||
| 129 | case LP_ONEKEY: | ||
| 130 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 131 | MTK_PMIC_PWRKEY_RST, | ||
| 132 | MTK_PMIC_PWRKEY_RST); | ||
| 133 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 134 | MTK_PMIC_HOMEKEY_RST, | ||
| 135 | 0); | ||
| 136 | break; | ||
| 137 | case LP_TWOKEY: | ||
| 138 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 139 | MTK_PMIC_PWRKEY_RST, | ||
| 140 | MTK_PMIC_PWRKEY_RST); | ||
| 141 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 142 | MTK_PMIC_HOMEKEY_RST, | ||
| 143 | MTK_PMIC_HOMEKEY_RST); | ||
| 144 | break; | ||
| 145 | case LP_DISABLE: | ||
| 146 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 147 | MTK_PMIC_PWRKEY_RST, | ||
| 148 | 0); | ||
| 149 | regmap_update_bits(keys->regmap, pmic_rst_reg, | ||
| 150 | MTK_PMIC_HOMEKEY_RST, | ||
| 151 | 0); | ||
| 152 | break; | ||
| 153 | default: | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data) | ||
| 159 | { | ||
| 160 | struct mtk_pmic_keys_info *info = data; | ||
| 161 | u32 key_deb, pressed; | ||
| 162 | |||
| 163 | regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb); | ||
| 164 | |||
| 165 | key_deb &= info->regs->deb_mask; | ||
| 166 | |||
| 167 | pressed = !key_deb; | ||
| 168 | |||
| 169 | input_report_key(info->keys->input_dev, info->keycode, pressed); | ||
| 170 | input_sync(info->keys->input_dev); | ||
| 171 | |||
| 172 | dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n", | ||
| 173 | pressed ? "pressed" : "released", info->keycode); | ||
| 174 | |||
| 175 | return IRQ_HANDLED; | ||
| 176 | } | ||
| 177 | |||
| 178 | static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys, | ||
| 179 | struct mtk_pmic_keys_info *info) | ||
| 180 | { | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | info->keys = keys; | ||
| 184 | |||
| 185 | ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg, | ||
| 186 | info->regs->intsel_mask, | ||
| 187 | info->regs->intsel_mask); | ||
| 188 | if (ret < 0) | ||
| 189 | return ret; | ||
| 190 | |||
| 191 | ret = devm_request_threaded_irq(keys->dev, info->irq, NULL, | ||
| 192 | mtk_pmic_keys_irq_handler_thread, | ||
| 193 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, | ||
| 194 | "mtk-pmic-keys", info); | ||
| 195 | if (ret) { | ||
| 196 | dev_err(keys->dev, "Failed to request IRQ: %d: %d\n", | ||
| 197 | info->irq, ret); | ||
| 198 | return ret; | ||
| 199 | } | ||
| 200 | |||
| 201 | input_set_capability(keys->input_dev, EV_KEY, info->keycode); | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev) | ||
| 207 | { | ||
| 208 | struct mtk_pmic_keys *keys = dev_get_drvdata(dev); | ||
| 209 | int index; | ||
| 210 | |||
| 211 | for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { | ||
| 212 | if (keys->keys[index].wakeup) | ||
| 213 | enable_irq_wake(keys->keys[index].irq); | ||
| 214 | } | ||
| 215 | |||
| 216 | return 0; | ||
| 217 | } | ||
| 218 | |||
| 219 | static int __maybe_unused mtk_pmic_keys_resume(struct device *dev) | ||
| 220 | { | ||
| 221 | struct mtk_pmic_keys *keys = dev_get_drvdata(dev); | ||
| 222 | int index; | ||
| 223 | |||
| 224 | for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { | ||
| 225 | if (keys->keys[index].wakeup) | ||
| 226 | disable_irq_wake(keys->keys[index].irq); | ||
| 227 | } | ||
| 228 | |||
| 229 | return 0; | ||
| 230 | } | ||
| 231 | |||
| 232 | static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend, | ||
| 233 | mtk_pmic_keys_resume); | ||
| 234 | |||
| 235 | static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = { | ||
| 236 | { | ||
| 237 | .compatible = "mediatek,mt6397-keys", | ||
| 238 | .data = &mt6397_regs, | ||
| 239 | }, { | ||
| 240 | .compatible = "mediatek,mt6323-keys", | ||
| 241 | .data = &mt6323_regs, | ||
| 242 | }, { | ||
| 243 | /* sentinel */ | ||
| 244 | } | ||
| 245 | }; | ||
| 246 | MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl); | ||
| 247 | |||
| 248 | static int mtk_pmic_keys_probe(struct platform_device *pdev) | ||
| 249 | { | ||
| 250 | int error, index = 0; | ||
| 251 | unsigned int keycount; | ||
| 252 | struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent); | ||
| 253 | struct device_node *node = pdev->dev.of_node, *child; | ||
| 254 | struct mtk_pmic_keys *keys; | ||
| 255 | const struct mtk_pmic_regs *mtk_pmic_regs; | ||
| 256 | struct input_dev *input_dev; | ||
| 257 | const struct of_device_id *of_id = | ||
| 258 | of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev); | ||
| 259 | |||
| 260 | keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL); | ||
| 261 | if (!keys) | ||
| 262 | return -ENOMEM; | ||
| 263 | |||
| 264 | keys->dev = &pdev->dev; | ||
| 265 | keys->regmap = pmic_chip->regmap; | ||
| 266 | mtk_pmic_regs = of_id->data; | ||
| 267 | |||
| 268 | keys->input_dev = input_dev = devm_input_allocate_device(keys->dev); | ||
| 269 | if (!input_dev) { | ||
| 270 | dev_err(keys->dev, "input allocate device fail.\n"); | ||
| 271 | return -ENOMEM; | ||
| 272 | } | ||
| 273 | |||
| 274 | input_dev->name = "mtk-pmic-keys"; | ||
| 275 | input_dev->id.bustype = BUS_HOST; | ||
| 276 | input_dev->id.vendor = 0x0001; | ||
| 277 | input_dev->id.product = 0x0001; | ||
| 278 | input_dev->id.version = 0x0001; | ||
| 279 | |||
| 280 | keycount = of_get_available_child_count(node); | ||
| 281 | if (keycount > MTK_PMIC_MAX_KEY_COUNT) { | ||
| 282 | dev_err(keys->dev, "too many keys defined (%d)\n", keycount); | ||
| 283 | return -EINVAL; | ||
| 284 | } | ||
| 285 | |||
| 286 | for_each_child_of_node(node, child) { | ||
| 287 | keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index]; | ||
| 288 | |||
| 289 | keys->keys[index].irq = platform_get_irq(pdev, index); | ||
| 290 | if (keys->keys[index].irq < 0) | ||
| 291 | return keys->keys[index].irq; | ||
| 292 | |||
| 293 | error = of_property_read_u32(child, | ||
| 294 | "linux,keycodes", &keys->keys[index].keycode); | ||
| 295 | if (error) { | ||
| 296 | dev_err(keys->dev, | ||
| 297 | "failed to read key:%d linux,keycode property: %d\n", | ||
| 298 | index, error); | ||
| 299 | return error; | ||
| 300 | } | ||
| 301 | |||
| 302 | if (of_property_read_bool(child, "wakeup-source")) | ||
| 303 | keys->keys[index].wakeup = true; | ||
| 304 | |||
| 305 | error = mtk_pmic_key_setup(keys, &keys->keys[index]); | ||
| 306 | if (error) | ||
| 307 | return error; | ||
| 308 | |||
| 309 | index++; | ||
| 310 | } | ||
| 311 | |||
| 312 | error = input_register_device(input_dev); | ||
| 313 | if (error) { | ||
| 314 | dev_err(&pdev->dev, | ||
| 315 | "register input device failed (%d)\n", error); | ||
| 316 | return error; | ||
| 317 | } | ||
| 318 | |||
| 319 | mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg); | ||
| 320 | |||
| 321 | platform_set_drvdata(pdev, keys); | ||
| 322 | |||
| 323 | return 0; | ||
| 324 | } | ||
| 325 | |||
| 326 | static struct platform_driver pmic_keys_pdrv = { | ||
| 327 | .probe = mtk_pmic_keys_probe, | ||
| 328 | .driver = { | ||
| 329 | .name = "mtk-pmic-keys", | ||
| 330 | .of_match_table = of_mtk_pmic_keys_match_tbl, | ||
| 331 | .pm = &mtk_pmic_keys_pm_ops, | ||
| 332 | }, | ||
| 333 | }; | ||
| 334 | |||
| 335 | module_platform_driver(pmic_keys_pdrv); | ||
| 336 | |||
| 337 | MODULE_LICENSE("GPL v2"); | ||
| 338 | MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>"); | ||
| 339 | MODULE_DESCRIPTION("MTK pmic-keys driver v0.1"); | ||
diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 940d38b08e6b..46406345742b 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c | |||
| @@ -337,7 +337,8 @@ static int omap4_keypad_probe(struct platform_device *pdev) | |||
| 337 | 337 | ||
| 338 | keypad_data->row_shift = get_count_order(keypad_data->cols); | 338 | keypad_data->row_shift = get_count_order(keypad_data->cols); |
| 339 | max_keys = keypad_data->rows << keypad_data->row_shift; | 339 | max_keys = keypad_data->rows << keypad_data->row_shift; |
| 340 | keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), | 340 | keypad_data->keymap = kcalloc(max_keys, |
| 341 | sizeof(keypad_data->keymap[0]), | ||
| 341 | GFP_KERNEL); | 342 | GFP_KERNEL); |
| 342 | if (!keypad_data->keymap) { | 343 | if (!keypad_data->keymap) { |
| 343 | dev_err(&pdev->dev, "Not enough memory for keymap\n"); | 344 | dev_err(&pdev->dev, "Not enough memory for keymap\n"); |
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 316414465c77..1fe1aa2adf85 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c | |||
| @@ -281,7 +281,7 @@ samsung_keypad_parse_dt(struct device *dev) | |||
| 281 | 281 | ||
| 282 | key_count = of_get_child_count(np); | 282 | key_count = of_get_child_count(np); |
| 283 | keymap_data->keymap_size = key_count; | 283 | keymap_data->keymap_size = key_count; |
| 284 | keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL); | 284 | keymap = devm_kcalloc(dev, key_count, sizeof(uint32_t), GFP_KERNEL); |
| 285 | if (!keymap) { | 285 | if (!keymap) { |
| 286 | dev_err(dev, "could not allocate memory for keymap\n"); | 286 | dev_err(dev, "could not allocate memory for keymap\n"); |
| 287 | return ERR_PTR(-ENOMEM); | 287 | return ERR_PTR(-ENOMEM); |
diff --git a/drivers/input/matrix-keymap.c b/drivers/input/matrix-keymap.c index 8ccefc15c7a4..8b3a5758451e 100644 --- a/drivers/input/matrix-keymap.c +++ b/drivers/input/matrix-keymap.c | |||
| @@ -170,8 +170,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data, | |||
| 170 | return -EINVAL; | 170 | return -EINVAL; |
| 171 | 171 | ||
| 172 | if (!keymap) { | 172 | if (!keymap) { |
| 173 | keymap = devm_kzalloc(input_dev->dev.parent, | 173 | keymap = devm_kcalloc(input_dev->dev.parent, |
| 174 | max_keys * sizeof(*keymap), | 174 | max_keys, sizeof(*keymap), |
| 175 | GFP_KERNEL); | 175 | GFP_KERNEL); |
| 176 | if (!keymap) { | 176 | if (!keymap) { |
| 177 | dev_err(input_dev->dev.parent, | 177 | dev_err(input_dev->dev.parent, |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index ded5b84e336d..d8fd58fdf050 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
| @@ -22,7 +22,7 @@ MODULE_LICENSE("GPL"); | |||
| 22 | /* | 22 | /* |
| 23 | * ATI Remote Wonder II Channel Configuration | 23 | * ATI Remote Wonder II Channel Configuration |
| 24 | * | 24 | * |
| 25 | * The remote control can by assigned one of sixteen "channels" in order to facilitate | 25 | * The remote control can be assigned one of sixteen "channels" in order to facilitate |
| 26 | * the use of multiple remote controls within range of each other. | 26 | * the use of multiple remote controls within range of each other. |
| 27 | * A remote's "channel" may be altered by pressing and holding the "PC" button for | 27 | * A remote's "channel" may be altered by pressing and holding the "PC" button for |
| 28 | * approximately 3 seconds, after which the button will slowly flash the count of the | 28 | * approximately 3 seconds, after which the button will slowly flash the count of the |
diff --git a/drivers/input/misc/hp_sdc_rtc.c b/drivers/input/misc/hp_sdc_rtc.c index 49b34de0aed4..47eb8ca729fe 100644 --- a/drivers/input/misc/hp_sdc_rtc.c +++ b/drivers/input/misc/hp_sdc_rtc.c | |||
| @@ -509,18 +509,6 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v) | |||
| 509 | #undef NY | 509 | #undef NY |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | static int hp_sdc_rtc_proc_open(struct inode *inode, struct file *file) | ||
| 513 | { | ||
| 514 | return single_open(file, hp_sdc_rtc_proc_show, NULL); | ||
| 515 | } | ||
| 516 | |||
| 517 | static const struct file_operations hp_sdc_rtc_proc_fops = { | ||
| 518 | .open = hp_sdc_rtc_proc_open, | ||
| 519 | .read = seq_read, | ||
| 520 | .llseek = seq_lseek, | ||
| 521 | .release = single_release, | ||
| 522 | }; | ||
| 523 | |||
| 524 | static int hp_sdc_rtc_ioctl(struct file *file, | 512 | static int hp_sdc_rtc_ioctl(struct file *file, |
| 525 | unsigned int cmd, unsigned long arg) | 513 | unsigned int cmd, unsigned long arg) |
| 526 | { | 514 | { |
| @@ -713,7 +701,7 @@ static int __init hp_sdc_rtc_init(void) | |||
| 713 | if (misc_register(&hp_sdc_rtc_dev) != 0) | 701 | if (misc_register(&hp_sdc_rtc_dev) != 0) |
| 714 | printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n"); | 702 | printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n"); |
| 715 | 703 | ||
| 716 | proc_create("driver/rtc", 0, NULL, &hp_sdc_rtc_proc_fops); | 704 | proc_create_single("driver/rtc", 0, NULL, hp_sdc_rtc_proc_show); |
| 717 | 705 | ||
| 718 | printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " | 706 | printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded " |
| 719 | "(RTC v " RTC_VERSION ")\n"); | 707 | "(RTC v " RTC_VERSION ")\n"); |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 1588aecafff7..6d304381fc30 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
| @@ -283,8 +283,8 @@ static int rotary_encoder_probe(struct platform_device *pdev) | |||
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | encoder->irq = | 285 | encoder->irq = |
| 286 | devm_kzalloc(dev, | 286 | devm_kcalloc(dev, |
| 287 | sizeof(*encoder->irq) * encoder->gpios->ndescs, | 287 | encoder->gpios->ndescs, sizeof(*encoder->irq), |
| 288 | GFP_KERNEL); | 288 | GFP_KERNEL); |
| 289 | if (!encoder->irq) | 289 | if (!encoder->irq) |
| 290 | return -ENOMEM; | 290 | return -ENOMEM; |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 89ebb8f39fee..f27f23f2d99a 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
| @@ -133,6 +133,18 @@ config MOUSE_PS2_ELANTECH | |||
| 133 | 133 | ||
| 134 | If unsure, say N. | 134 | If unsure, say N. |
| 135 | 135 | ||
| 136 | config MOUSE_PS2_ELANTECH_SMBUS | ||
| 137 | bool "Elantech PS/2 SMbus companion" if EXPERT | ||
| 138 | default y | ||
| 139 | depends on MOUSE_PS2 && MOUSE_PS2_ELANTECH | ||
| 140 | depends on I2C=y || I2C=MOUSE_PS2 | ||
| 141 | select MOUSE_PS2_SMBUS | ||
| 142 | help | ||
| 143 | Say Y here if you have a Elantech touchpad connected to | ||
| 144 | to an SMBus, but enumerated through PS/2. | ||
| 145 | |||
| 146 | If unsure, say Y. | ||
| 147 | |||
| 136 | config MOUSE_PS2_SENTELIC | 148 | config MOUSE_PS2_SENTELIC |
| 137 | bool "Sentelic Finger Sensing Pad PS/2 protocol extension" | 149 | bool "Sentelic Finger Sensing Pad PS/2 protocol extension" |
| 138 | depends on MOUSE_PS2 | 150 | depends on MOUSE_PS2 |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 38f9501acdf0..cb5579716dba 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -2049,14 +2049,11 @@ static int alps_hw_init_v1_v2(struct psmouse *psmouse) | |||
| 2049 | return 0; | 2049 | return 0; |
| 2050 | } | 2050 | } |
| 2051 | 2051 | ||
| 2052 | static int alps_hw_init_v6(struct psmouse *psmouse) | 2052 | /* Must be in passthrough mode when calling this function */ |
| 2053 | static int alps_trackstick_enter_extended_mode_v3_v6(struct psmouse *psmouse) | ||
| 2053 | { | 2054 | { |
| 2054 | unsigned char param[2] = {0xC8, 0x14}; | 2055 | unsigned char param[2] = {0xC8, 0x14}; |
| 2055 | 2056 | ||
| 2056 | /* Enter passthrough mode to let trackpoint enter 6byte raw mode */ | ||
| 2057 | if (alps_passthrough_mode_v2(psmouse, true)) | ||
| 2058 | return -1; | ||
| 2059 | |||
| 2060 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 2057 | if (ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
| 2061 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 2058 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
| 2062 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | 2059 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || |
| @@ -2064,9 +2061,25 @@ static int alps_hw_init_v6(struct psmouse *psmouse) | |||
| 2064 | ps2_command(&psmouse->ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE)) | 2061 | ps2_command(&psmouse->ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE)) |
| 2065 | return -1; | 2062 | return -1; |
| 2066 | 2063 | ||
| 2064 | return 0; | ||
| 2065 | } | ||
| 2066 | |||
| 2067 | static int alps_hw_init_v6(struct psmouse *psmouse) | ||
| 2068 | { | ||
| 2069 | int ret; | ||
| 2070 | |||
| 2071 | /* Enter passthrough mode to let trackpoint enter 6byte raw mode */ | ||
| 2072 | if (alps_passthrough_mode_v2(psmouse, true)) | ||
| 2073 | return -1; | ||
| 2074 | |||
| 2075 | ret = alps_trackstick_enter_extended_mode_v3_v6(psmouse); | ||
| 2076 | |||
| 2067 | if (alps_passthrough_mode_v2(psmouse, false)) | 2077 | if (alps_passthrough_mode_v2(psmouse, false)) |
| 2068 | return -1; | 2078 | return -1; |
| 2069 | 2079 | ||
| 2080 | if (ret) | ||
| 2081 | return ret; | ||
| 2082 | |||
| 2070 | if (alps_absolute_mode_v6(psmouse)) { | 2083 | if (alps_absolute_mode_v6(psmouse)) { |
| 2071 | psmouse_err(psmouse, "Failed to enable absolute mode\n"); | 2084 | psmouse_err(psmouse, "Failed to enable absolute mode\n"); |
| 2072 | return -1; | 2085 | return -1; |
| @@ -2140,10 +2153,18 @@ error: | |||
| 2140 | 2153 | ||
| 2141 | static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) | 2154 | static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) |
| 2142 | { | 2155 | { |
| 2143 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 2144 | int ret = 0; | 2156 | int ret = 0; |
| 2157 | int reg_val; | ||
| 2145 | unsigned char param[4]; | 2158 | unsigned char param[4]; |
| 2146 | 2159 | ||
| 2160 | /* | ||
| 2161 | * We need to configure trackstick to report data for touchpad in | ||
| 2162 | * extended format. And also we need to tell touchpad to expect data | ||
| 2163 | * from trackstick in extended format. Without this configuration | ||
| 2164 | * trackstick packets sent from touchpad are in basic format which is | ||
| 2165 | * different from what we expect. | ||
| 2166 | */ | ||
| 2167 | |||
| 2147 | if (alps_passthrough_mode_v3(psmouse, reg_base, true)) | 2168 | if (alps_passthrough_mode_v3(psmouse, reg_base, true)) |
| 2148 | return -EIO; | 2169 | return -EIO; |
| 2149 | 2170 | ||
| @@ -2161,39 +2182,36 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) | |||
| 2161 | ret = -ENODEV; | 2182 | ret = -ENODEV; |
| 2162 | } else { | 2183 | } else { |
| 2163 | psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); | 2184 | psmouse_dbg(psmouse, "trackstick E7 report: %3ph\n", param); |
| 2164 | 2185 | if (alps_trackstick_enter_extended_mode_v3_v6(psmouse)) { | |
| 2165 | /* | 2186 | psmouse_err(psmouse, "Failed to enter into trackstick extended mode\n"); |
| 2166 | * Not sure what this does, but it is absolutely | ||
| 2167 | * essential. Without it, the touchpad does not | ||
| 2168 | * work at all and the trackstick just emits normal | ||
| 2169 | * PS/2 packets. | ||
| 2170 | */ | ||
| 2171 | if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
| 2172 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
| 2173 | ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || | ||
| 2174 | alps_command_mode_send_nibble(psmouse, 0x9) || | ||
| 2175 | alps_command_mode_send_nibble(psmouse, 0x4)) { | ||
| 2176 | psmouse_err(psmouse, | ||
| 2177 | "Error sending magic E6 sequence\n"); | ||
| 2178 | ret = -EIO; | 2187 | ret = -EIO; |
| 2179 | goto error; | ||
| 2180 | } | 2188 | } |
| 2189 | } | ||
| 2190 | |||
| 2191 | if (alps_passthrough_mode_v3(psmouse, reg_base, false)) | ||
| 2192 | return -EIO; | ||
| 2193 | |||
| 2194 | if (ret) | ||
| 2195 | return ret; | ||
| 2181 | 2196 | ||
| 2197 | if (alps_enter_command_mode(psmouse)) | ||
| 2198 | return -EIO; | ||
| 2199 | |||
| 2200 | reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08); | ||
| 2201 | if (reg_val == -1) { | ||
| 2202 | ret = -EIO; | ||
| 2203 | } else { | ||
| 2182 | /* | 2204 | /* |
| 2183 | * This ensures the trackstick packets are in the format | 2205 | * Tell touchpad that trackstick is now in extended mode. |
| 2184 | * supported by this driver. If bit 1 isn't set the packet | 2206 | * If bit 1 isn't set the packet format is different. |
| 2185 | * format is different. | ||
| 2186 | */ | 2207 | */ |
| 2187 | if (alps_enter_command_mode(psmouse) || | 2208 | reg_val |= BIT(1); |
| 2188 | alps_command_mode_write_reg(psmouse, | 2209 | if (__alps_command_mode_write_reg(psmouse, reg_val)) |
| 2189 | reg_base + 0x08, 0x82) || | ||
| 2190 | alps_exit_command_mode(psmouse)) | ||
| 2191 | ret = -EIO; | 2210 | ret = -EIO; |
| 2192 | } | 2211 | } |
| 2193 | 2212 | ||
| 2194 | error: | 2213 | if (alps_exit_command_mode(psmouse)) |
| 2195 | if (alps_passthrough_mode_v3(psmouse, reg_base, false)) | 2214 | return -EIO; |
| 2196 | ret = -EIO; | ||
| 2197 | 2215 | ||
| 2198 | return ret; | 2216 | return ret; |
| 2199 | } | 2217 | } |
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 75e757520ef0..8ff75114e762 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/jiffies.h> | 36 | #include <linux/jiffies.h> |
| 37 | #include <linux/completion.h> | 37 | #include <linux/completion.h> |
| 38 | #include <linux/of.h> | 38 | #include <linux/of.h> |
| 39 | #include <linux/property.h> | ||
| 39 | #include <linux/regulator/consumer.h> | 40 | #include <linux/regulator/consumer.h> |
| 40 | #include <asm/unaligned.h> | 41 | #include <asm/unaligned.h> |
| 41 | 42 | ||
| @@ -51,6 +52,7 @@ | |||
| 51 | #define ETP_MAX_FINGERS 5 | 52 | #define ETP_MAX_FINGERS 5 |
| 52 | #define ETP_FINGER_DATA_LEN 5 | 53 | #define ETP_FINGER_DATA_LEN 5 |
| 53 | #define ETP_REPORT_ID 0x5D | 54 | #define ETP_REPORT_ID 0x5D |
| 55 | #define ETP_TP_REPORT_ID 0x5E | ||
| 54 | #define ETP_REPORT_ID_OFFSET 2 | 56 | #define ETP_REPORT_ID_OFFSET 2 |
| 55 | #define ETP_TOUCH_INFO_OFFSET 3 | 57 | #define ETP_TOUCH_INFO_OFFSET 3 |
| 56 | #define ETP_FINGER_DATA_OFFSET 4 | 58 | #define ETP_FINGER_DATA_OFFSET 4 |
| @@ -61,6 +63,7 @@ | |||
| 61 | struct elan_tp_data { | 63 | struct elan_tp_data { |
| 62 | struct i2c_client *client; | 64 | struct i2c_client *client; |
| 63 | struct input_dev *input; | 65 | struct input_dev *input; |
| 66 | struct input_dev *tp_input; /* trackpoint input node */ | ||
| 64 | struct regulator *vcc; | 67 | struct regulator *vcc; |
| 65 | 68 | ||
| 66 | const struct elan_transport_ops *ops; | 69 | const struct elan_transport_ops *ops; |
| @@ -930,6 +933,33 @@ static void elan_report_absolute(struct elan_tp_data *data, u8 *packet) | |||
| 930 | input_sync(input); | 933 | input_sync(input); |
| 931 | } | 934 | } |
| 932 | 935 | ||
| 936 | static void elan_report_trackpoint(struct elan_tp_data *data, u8 *report) | ||
| 937 | { | ||
| 938 | struct input_dev *input = data->tp_input; | ||
| 939 | u8 *packet = &report[ETP_REPORT_ID_OFFSET + 1]; | ||
| 940 | int x, y; | ||
| 941 | |||
| 942 | if (!data->tp_input) { | ||
| 943 | dev_warn_once(&data->client->dev, | ||
| 944 | "received a trackpoint report while no trackpoint device has been created. Please report upstream.\n"); | ||
| 945 | return; | ||
| 946 | } | ||
| 947 | |||
| 948 | input_report_key(input, BTN_LEFT, packet[0] & 0x01); | ||
| 949 | input_report_key(input, BTN_RIGHT, packet[0] & 0x02); | ||
| 950 | input_report_key(input, BTN_MIDDLE, packet[0] & 0x04); | ||
| 951 | |||
| 952 | if ((packet[3] & 0x0F) == 0x06) { | ||
| 953 | x = packet[4] - (int)((packet[1] ^ 0x80) << 1); | ||
| 954 | y = (int)((packet[2] ^ 0x80) << 1) - packet[5]; | ||
| 955 | |||
| 956 | input_report_rel(input, REL_X, x); | ||
| 957 | input_report_rel(input, REL_Y, y); | ||
| 958 | } | ||
| 959 | |||
| 960 | input_sync(input); | ||
| 961 | } | ||
| 962 | |||
| 933 | static irqreturn_t elan_isr(int irq, void *dev_id) | 963 | static irqreturn_t elan_isr(int irq, void *dev_id) |
| 934 | { | 964 | { |
| 935 | struct elan_tp_data *data = dev_id; | 965 | struct elan_tp_data *data = dev_id; |
| @@ -951,11 +981,17 @@ static irqreturn_t elan_isr(int irq, void *dev_id) | |||
| 951 | if (error) | 981 | if (error) |
| 952 | goto out; | 982 | goto out; |
| 953 | 983 | ||
| 954 | if (report[ETP_REPORT_ID_OFFSET] != ETP_REPORT_ID) | 984 | switch (report[ETP_REPORT_ID_OFFSET]) { |
| 985 | case ETP_REPORT_ID: | ||
| 986 | elan_report_absolute(data, report); | ||
| 987 | break; | ||
| 988 | case ETP_TP_REPORT_ID: | ||
| 989 | elan_report_trackpoint(data, report); | ||
| 990 | break; | ||
| 991 | default: | ||
| 955 | dev_err(dev, "invalid report id data (%x)\n", | 992 | dev_err(dev, "invalid report id data (%x)\n", |
| 956 | report[ETP_REPORT_ID_OFFSET]); | 993 | report[ETP_REPORT_ID_OFFSET]); |
| 957 | else | 994 | } |
| 958 | elan_report_absolute(data, report); | ||
| 959 | 995 | ||
| 960 | out: | 996 | out: |
| 961 | return IRQ_HANDLED; | 997 | return IRQ_HANDLED; |
| @@ -966,6 +1002,36 @@ out: | |||
| 966 | * Elan initialization functions | 1002 | * Elan initialization functions |
| 967 | ****************************************************************** | 1003 | ****************************************************************** |
| 968 | */ | 1004 | */ |
| 1005 | |||
| 1006 | static int elan_setup_trackpoint_input_device(struct elan_tp_data *data) | ||
| 1007 | { | ||
| 1008 | struct device *dev = &data->client->dev; | ||
| 1009 | struct input_dev *input; | ||
| 1010 | |||
| 1011 | input = devm_input_allocate_device(dev); | ||
| 1012 | if (!input) | ||
| 1013 | return -ENOMEM; | ||
| 1014 | |||
| 1015 | input->name = "Elan TrackPoint"; | ||
| 1016 | input->id.bustype = BUS_I2C; | ||
| 1017 | input->id.vendor = ELAN_VENDOR_ID; | ||
| 1018 | input->id.product = data->product_id; | ||
| 1019 | input_set_drvdata(input, data); | ||
| 1020 | |||
| 1021 | input_set_capability(input, EV_REL, REL_X); | ||
| 1022 | input_set_capability(input, EV_REL, REL_Y); | ||
| 1023 | input_set_capability(input, EV_KEY, BTN_LEFT); | ||
| 1024 | input_set_capability(input, EV_KEY, BTN_RIGHT); | ||
| 1025 | input_set_capability(input, EV_KEY, BTN_MIDDLE); | ||
| 1026 | |||
| 1027 | __set_bit(INPUT_PROP_POINTER, input->propbit); | ||
| 1028 | __set_bit(INPUT_PROP_POINTING_STICK, input->propbit); | ||
| 1029 | |||
| 1030 | data->tp_input = input; | ||
| 1031 | |||
| 1032 | return 0; | ||
| 1033 | } | ||
| 1034 | |||
| 969 | static int elan_setup_input_device(struct elan_tp_data *data) | 1035 | static int elan_setup_input_device(struct elan_tp_data *data) |
| 970 | { | 1036 | { |
| 971 | struct device *dev = &data->client->dev; | 1037 | struct device *dev = &data->client->dev; |
| @@ -1140,6 +1206,12 @@ static int elan_probe(struct i2c_client *client, | |||
| 1140 | if (error) | 1206 | if (error) |
| 1141 | return error; | 1207 | return error; |
| 1142 | 1208 | ||
| 1209 | if (device_property_read_bool(&client->dev, "elan,trackpoint")) { | ||
| 1210 | error = elan_setup_trackpoint_input_device(data); | ||
| 1211 | if (error) | ||
| 1212 | return error; | ||
| 1213 | } | ||
| 1214 | |||
| 1143 | /* | 1215 | /* |
| 1144 | * Platform code (ACPI, DTS) should normally set up interrupt | 1216 | * Platform code (ACPI, DTS) should normally set up interrupt |
| 1145 | * for us, but in case it did not let's fall back to using falling | 1217 | * for us, but in case it did not let's fall back to using falling |
| @@ -1177,6 +1249,16 @@ static int elan_probe(struct i2c_client *client, | |||
| 1177 | return error; | 1249 | return error; |
| 1178 | } | 1250 | } |
| 1179 | 1251 | ||
| 1252 | if (data->tp_input) { | ||
| 1253 | error = input_register_device(data->tp_input); | ||
| 1254 | if (error) { | ||
| 1255 | dev_err(&client->dev, | ||
| 1256 | "failed to register TrackPoint input device: %d\n", | ||
| 1257 | error); | ||
| 1258 | return error; | ||
| 1259 | } | ||
| 1260 | } | ||
| 1261 | |||
| 1180 | /* | 1262 | /* |
| 1181 | * Systems using device tree should set up wakeup via DTS, | 1263 | * Systems using device tree should set up wakeup via DTS, |
| 1182 | * the rest will configure device as wakeup source by default. | 1264 | * the rest will configure device as wakeup source by default. |
| @@ -1262,6 +1344,7 @@ static const struct acpi_device_id elan_acpi_id[] = { | |||
| 1262 | { "ELAN060B", 0 }, | 1344 | { "ELAN060B", 0 }, |
| 1263 | { "ELAN060C", 0 }, | 1345 | { "ELAN060C", 0 }, |
| 1264 | { "ELAN0611", 0 }, | 1346 | { "ELAN0611", 0 }, |
| 1347 | { "ELAN0612", 0 }, | ||
| 1265 | { "ELAN1000", 0 }, | 1348 | { "ELAN1000", 0 }, |
| 1266 | { } | 1349 | { } |
| 1267 | }; | 1350 | }; |
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c index 29f99529b187..cfcb32559925 100644 --- a/drivers/input/mouse/elan_i2c_smbus.c +++ b/drivers/input/mouse/elan_i2c_smbus.c | |||
| @@ -130,7 +130,7 @@ static int elan_smbus_get_baseline_data(struct i2c_client *client, | |||
| 130 | bool max_baseline, u8 *value) | 130 | bool max_baseline, u8 *value) |
| 131 | { | 131 | { |
| 132 | int error; | 132 | int error; |
| 133 | u8 val[3]; | 133 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 134 | 134 | ||
| 135 | error = i2c_smbus_read_block_data(client, | 135 | error = i2c_smbus_read_block_data(client, |
| 136 | max_baseline ? | 136 | max_baseline ? |
| @@ -149,7 +149,7 @@ static int elan_smbus_get_version(struct i2c_client *client, | |||
| 149 | bool iap, u8 *version) | 149 | bool iap, u8 *version) |
| 150 | { | 150 | { |
| 151 | int error; | 151 | int error; |
| 152 | u8 val[3]; | 152 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 153 | 153 | ||
| 154 | error = i2c_smbus_read_block_data(client, | 154 | error = i2c_smbus_read_block_data(client, |
| 155 | iap ? ETP_SMBUS_IAP_VERSION_CMD : | 155 | iap ? ETP_SMBUS_IAP_VERSION_CMD : |
| @@ -170,7 +170,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, | |||
| 170 | u8 *clickpad) | 170 | u8 *clickpad) |
| 171 | { | 171 | { |
| 172 | int error; | 172 | int error; |
| 173 | u8 val[3]; | 173 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 174 | 174 | ||
| 175 | error = i2c_smbus_read_block_data(client, | 175 | error = i2c_smbus_read_block_data(client, |
| 176 | ETP_SMBUS_SM_VERSION_CMD, val); | 176 | ETP_SMBUS_SM_VERSION_CMD, val); |
| @@ -188,7 +188,7 @@ static int elan_smbus_get_sm_version(struct i2c_client *client, | |||
| 188 | static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id) | 188 | static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id) |
| 189 | { | 189 | { |
| 190 | int error; | 190 | int error; |
| 191 | u8 val[3]; | 191 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 192 | 192 | ||
| 193 | error = i2c_smbus_read_block_data(client, | 193 | error = i2c_smbus_read_block_data(client, |
| 194 | ETP_SMBUS_UNIQUEID_CMD, val); | 194 | ETP_SMBUS_UNIQUEID_CMD, val); |
| @@ -205,7 +205,7 @@ static int elan_smbus_get_checksum(struct i2c_client *client, | |||
| 205 | bool iap, u16 *csum) | 205 | bool iap, u16 *csum) |
| 206 | { | 206 | { |
| 207 | int error; | 207 | int error; |
| 208 | u8 val[3]; | 208 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 209 | 209 | ||
| 210 | error = i2c_smbus_read_block_data(client, | 210 | error = i2c_smbus_read_block_data(client, |
| 211 | iap ? ETP_SMBUS_FW_CHECKSUM_CMD : | 211 | iap ? ETP_SMBUS_FW_CHECKSUM_CMD : |
| @@ -226,7 +226,7 @@ static int elan_smbus_get_max(struct i2c_client *client, | |||
| 226 | { | 226 | { |
| 227 | int ret; | 227 | int ret; |
| 228 | int error; | 228 | int error; |
| 229 | u8 val[3]; | 229 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 230 | 230 | ||
| 231 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); | 231 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RANGE_CMD, val); |
| 232 | if (ret != 3) { | 232 | if (ret != 3) { |
| @@ -246,7 +246,7 @@ static int elan_smbus_get_resolution(struct i2c_client *client, | |||
| 246 | { | 246 | { |
| 247 | int ret; | 247 | int ret; |
| 248 | int error; | 248 | int error; |
| 249 | u8 val[3]; | 249 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 250 | 250 | ||
| 251 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RESOLUTION_CMD, val); | 251 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_RESOLUTION_CMD, val); |
| 252 | if (ret != 3) { | 252 | if (ret != 3) { |
| @@ -267,7 +267,7 @@ static int elan_smbus_get_num_traces(struct i2c_client *client, | |||
| 267 | { | 267 | { |
| 268 | int ret; | 268 | int ret; |
| 269 | int error; | 269 | int error; |
| 270 | u8 val[3]; | 270 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 271 | 271 | ||
| 272 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_XY_TRACENUM_CMD, val); | 272 | ret = i2c_smbus_read_block_data(client, ETP_SMBUS_XY_TRACENUM_CMD, val); |
| 273 | if (ret != 3) { | 273 | if (ret != 3) { |
| @@ -294,7 +294,7 @@ static int elan_smbus_iap_get_mode(struct i2c_client *client, | |||
| 294 | { | 294 | { |
| 295 | int error; | 295 | int error; |
| 296 | u16 constant; | 296 | u16 constant; |
| 297 | u8 val[3]; | 297 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 298 | 298 | ||
| 299 | error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); | 299 | error = i2c_smbus_read_block_data(client, ETP_SMBUS_IAP_CTRL_CMD, val); |
| 300 | if (error < 0) { | 300 | if (error < 0) { |
| @@ -345,7 +345,7 @@ static int elan_smbus_prepare_fw_update(struct i2c_client *client) | |||
| 345 | int len; | 345 | int len; |
| 346 | int error; | 346 | int error; |
| 347 | enum tp_mode mode; | 347 | enum tp_mode mode; |
| 348 | u8 val[3]; | 348 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 349 | u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; | 349 | u8 cmd[4] = {0x0F, 0x78, 0x00, 0x06}; |
| 350 | u16 password; | 350 | u16 password; |
| 351 | 351 | ||
| @@ -419,7 +419,7 @@ static int elan_smbus_write_fw_block(struct i2c_client *client, | |||
| 419 | struct device *dev = &client->dev; | 419 | struct device *dev = &client->dev; |
| 420 | int error; | 420 | int error; |
| 421 | u16 result; | 421 | u16 result; |
| 422 | u8 val[3]; | 422 | u8 val[I2C_SMBUS_BLOCK_MAX] = {0}; |
| 423 | 423 | ||
| 424 | /* | 424 | /* |
| 425 | * Due to the limitation of smbus protocol limiting | 425 | * Due to the limitation of smbus protocol limiting |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index db47a5e1d114..fb4d902c4403 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
| @@ -14,17 +14,20 @@ | |||
| 14 | #include <linux/dmi.h> | 14 | #include <linux/dmi.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/i2c.h> | ||
| 17 | #include <linux/input.h> | 18 | #include <linux/input.h> |
| 18 | #include <linux/input/mt.h> | 19 | #include <linux/input/mt.h> |
| 20 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/serio.h> | 21 | #include <linux/serio.h> |
| 20 | #include <linux/libps2.h> | 22 | #include <linux/libps2.h> |
| 21 | #include <asm/unaligned.h> | 23 | #include <asm/unaligned.h> |
| 22 | #include "psmouse.h" | 24 | #include "psmouse.h" |
| 23 | #include "elantech.h" | 25 | #include "elantech.h" |
| 26 | #include "elan_i2c.h" | ||
| 24 | 27 | ||
| 25 | #define elantech_debug(fmt, ...) \ | 28 | #define elantech_debug(fmt, ...) \ |
| 26 | do { \ | 29 | do { \ |
| 27 | if (etd->debug) \ | 30 | if (etd->info.debug) \ |
| 28 | psmouse_printk(KERN_DEBUG, psmouse, \ | 31 | psmouse_printk(KERN_DEBUG, psmouse, \ |
| 29 | fmt, ##__VA_ARGS__); \ | 32 | fmt, ##__VA_ARGS__); \ |
| 30 | } while (0) | 33 | } while (0) |
| @@ -105,7 +108,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
| 105 | if (reg > 0x11 && reg < 0x20) | 108 | if (reg > 0x11 && reg < 0x20) |
| 106 | return -1; | 109 | return -1; |
| 107 | 110 | ||
| 108 | switch (etd->hw_version) { | 111 | switch (etd->info.hw_version) { |
| 109 | case 1: | 112 | case 1: |
| 110 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_READ) || | 113 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_READ) || |
| 111 | ps2_sliced_command(&psmouse->ps2dev, reg) || | 114 | ps2_sliced_command(&psmouse->ps2dev, reg) || |
| @@ -137,7 +140,7 @@ static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, | |||
| 137 | 140 | ||
| 138 | if (rc) | 141 | if (rc) |
| 139 | psmouse_err(psmouse, "failed to read register 0x%02x.\n", reg); | 142 | psmouse_err(psmouse, "failed to read register 0x%02x.\n", reg); |
| 140 | else if (etd->hw_version != 4) | 143 | else if (etd->info.hw_version != 4) |
| 141 | *val = param[0]; | 144 | *val = param[0]; |
| 142 | else | 145 | else |
| 143 | *val = param[1]; | 146 | *val = param[1]; |
| @@ -160,7 +163,7 @@ static int elantech_write_reg(struct psmouse *psmouse, unsigned char reg, | |||
| 160 | if (reg > 0x11 && reg < 0x20) | 163 | if (reg > 0x11 && reg < 0x20) |
| 161 | return -1; | 164 | return -1; |
| 162 | 165 | ||
| 163 | switch (etd->hw_version) { | 166 | switch (etd->info.hw_version) { |
| 164 | case 1: | 167 | case 1: |
| 165 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_WRITE) || | 168 | if (ps2_sliced_command(&psmouse->ps2dev, ETP_REGISTER_WRITE) || |
| 166 | ps2_sliced_command(&psmouse->ps2dev, reg) || | 169 | ps2_sliced_command(&psmouse->ps2dev, reg) || |
| @@ -237,7 +240,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 237 | unsigned char *packet = psmouse->packet; | 240 | unsigned char *packet = psmouse->packet; |
| 238 | int fingers; | 241 | int fingers; |
| 239 | 242 | ||
| 240 | if (etd->fw_version < 0x020000) { | 243 | if (etd->info.fw_version < 0x020000) { |
| 241 | /* | 244 | /* |
| 242 | * byte 0: D U p1 p2 1 p3 R L | 245 | * byte 0: D U p1 p2 1 p3 R L |
| 243 | * byte 1: f 0 th tw x9 x8 y9 y8 | 246 | * byte 1: f 0 th tw x9 x8 y9 y8 |
| @@ -252,7 +255,7 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 252 | fingers = (packet[0] & 0xc0) >> 6; | 255 | fingers = (packet[0] & 0xc0) >> 6; |
| 253 | } | 256 | } |
| 254 | 257 | ||
| 255 | if (etd->jumpy_cursor) { | 258 | if (etd->info.jumpy_cursor) { |
| 256 | if (fingers != 1) { | 259 | if (fingers != 1) { |
| 257 | etd->single_finger_reports = 0; | 260 | etd->single_finger_reports = 0; |
| 258 | } else if (etd->single_finger_reports < 2) { | 261 | } else if (etd->single_finger_reports < 2) { |
| @@ -282,8 +285,8 @@ static void elantech_report_absolute_v1(struct psmouse *psmouse) | |||
| 282 | 285 | ||
| 283 | psmouse_report_standard_buttons(dev, packet[0]); | 286 | psmouse_report_standard_buttons(dev, packet[0]); |
| 284 | 287 | ||
| 285 | if (etd->fw_version < 0x020000 && | 288 | if (etd->info.fw_version < 0x020000 && |
| 286 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { | 289 | (etd->info.capabilities[0] & ETP_CAP_HAS_ROCKER)) { |
| 287 | /* rocker up */ | 290 | /* rocker up */ |
| 288 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); | 291 | input_report_key(dev, BTN_FORWARD, packet[0] & 0x40); |
| 289 | /* rocker down */ | 292 | /* rocker down */ |
| @@ -391,7 +394,7 @@ static void elantech_report_absolute_v2(struct psmouse *psmouse) | |||
| 391 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 394 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
| 392 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); | 395 | input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4); |
| 393 | psmouse_report_standard_buttons(dev, packet[0]); | 396 | psmouse_report_standard_buttons(dev, packet[0]); |
| 394 | if (etd->reports_pressure) { | 397 | if (etd->info.reports_pressure) { |
| 395 | input_report_abs(dev, ABS_PRESSURE, pres); | 398 | input_report_abs(dev, ABS_PRESSURE, pres); |
| 396 | input_report_abs(dev, ABS_TOOL_WIDTH, width); | 399 | input_report_abs(dev, ABS_TOOL_WIDTH, width); |
| 397 | } | 400 | } |
| @@ -444,7 +447,7 @@ static void elantech_report_trackpoint(struct psmouse *psmouse, | |||
| 444 | 447 | ||
| 445 | default: | 448 | default: |
| 446 | /* Dump unexpected packet sequences if debug=1 (default) */ | 449 | /* Dump unexpected packet sequences if debug=1 (default) */ |
| 447 | if (etd->debug == 1) | 450 | if (etd->info.debug == 1) |
| 448 | elantech_packet_dump(psmouse); | 451 | elantech_packet_dump(psmouse); |
| 449 | 452 | ||
| 450 | break; | 453 | break; |
| @@ -523,7 +526,7 @@ static void elantech_report_absolute_v3(struct psmouse *psmouse, | |||
| 523 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); | 526 | input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3); |
| 524 | 527 | ||
| 525 | /* For clickpads map both buttons to BTN_LEFT */ | 528 | /* For clickpads map both buttons to BTN_LEFT */ |
| 526 | if (etd->fw_version & 0x001000) | 529 | if (etd->info.fw_version & 0x001000) |
| 527 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | 530 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); |
| 528 | else | 531 | else |
| 529 | psmouse_report_standard_buttons(dev, packet[0]); | 532 | psmouse_report_standard_buttons(dev, packet[0]); |
| @@ -541,7 +544,7 @@ static void elantech_input_sync_v4(struct psmouse *psmouse) | |||
| 541 | unsigned char *packet = psmouse->packet; | 544 | unsigned char *packet = psmouse->packet; |
| 542 | 545 | ||
| 543 | /* For clickpads map both buttons to BTN_LEFT */ | 546 | /* For clickpads map both buttons to BTN_LEFT */ |
| 544 | if (etd->fw_version & 0x001000) | 547 | if (etd->info.fw_version & 0x001000) |
| 545 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); | 548 | input_report_key(dev, BTN_LEFT, packet[0] & 0x03); |
| 546 | else | 549 | else |
| 547 | psmouse_report_standard_buttons(dev, packet[0]); | 550 | psmouse_report_standard_buttons(dev, packet[0]); |
| @@ -669,7 +672,7 @@ static int elantech_packet_check_v1(struct psmouse *psmouse) | |||
| 669 | unsigned char p1, p2, p3; | 672 | unsigned char p1, p2, p3; |
| 670 | 673 | ||
| 671 | /* Parity bits are placed differently */ | 674 | /* Parity bits are placed differently */ |
| 672 | if (etd->fw_version < 0x020000) { | 675 | if (etd->info.fw_version < 0x020000) { |
| 673 | /* byte 0: D U p1 p2 1 p3 R L */ | 676 | /* byte 0: D U p1 p2 1 p3 R L */ |
| 674 | p1 = (packet[0] & 0x20) >> 5; | 677 | p1 = (packet[0] & 0x20) >> 5; |
| 675 | p2 = (packet[0] & 0x10) >> 4; | 678 | p2 = (packet[0] & 0x10) >> 4; |
| @@ -714,7 +717,7 @@ static int elantech_packet_check_v2(struct psmouse *psmouse) | |||
| 714 | * With all three cases, if the constant bits are not exactly what I | 717 | * With all three cases, if the constant bits are not exactly what I |
| 715 | * expected, I consider them invalid. | 718 | * expected, I consider them invalid. |
| 716 | */ | 719 | */ |
| 717 | if (etd->reports_pressure) | 720 | if (etd->info.reports_pressure) |
| 718 | return (packet[0] & 0x0c) == 0x04 && | 721 | return (packet[0] & 0x0c) == 0x04 && |
| 719 | (packet[3] & 0x0f) == 0x02; | 722 | (packet[3] & 0x0f) == 0x02; |
| 720 | 723 | ||
| @@ -751,7 +754,7 @@ static int elantech_packet_check_v3(struct psmouse *psmouse) | |||
| 751 | * If the hardware flag 'crc_enabled' is set the packets have | 754 | * If the hardware flag 'crc_enabled' is set the packets have |
| 752 | * different signatures. | 755 | * different signatures. |
| 753 | */ | 756 | */ |
| 754 | if (etd->crc_enabled) { | 757 | if (etd->info.crc_enabled) { |
| 755 | if ((packet[3] & 0x09) == 0x08) | 758 | if ((packet[3] & 0x09) == 0x08) |
| 756 | return PACKET_V3_HEAD; | 759 | return PACKET_V3_HEAD; |
| 757 | 760 | ||
| @@ -782,7 +785,7 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) | |||
| 782 | return PACKET_TRACKPOINT; | 785 | return PACKET_TRACKPOINT; |
| 783 | 786 | ||
| 784 | /* This represents the version of IC body. */ | 787 | /* This represents the version of IC body. */ |
| 785 | ic_version = (etd->fw_version & 0x0f0000) >> 16; | 788 | ic_version = (etd->info.fw_version & 0x0f0000) >> 16; |
| 786 | 789 | ||
| 787 | /* | 790 | /* |
| 788 | * Sanity check based on the constant bits of a packet. | 791 | * Sanity check based on the constant bits of a packet. |
| @@ -791,9 +794,9 @@ static int elantech_packet_check_v4(struct psmouse *psmouse) | |||
| 791 | * the IC body, but are the same for every packet, | 794 | * the IC body, but are the same for every packet, |
| 792 | * regardless of the type. | 795 | * regardless of the type. |
| 793 | */ | 796 | */ |
| 794 | if (etd->crc_enabled) | 797 | if (etd->info.crc_enabled) |
| 795 | sanity_check = ((packet[3] & 0x08) == 0x00); | 798 | sanity_check = ((packet[3] & 0x08) == 0x00); |
| 796 | else if (ic_version == 7 && etd->samples[1] == 0x2A) | 799 | else if (ic_version == 7 && etd->info.samples[1] == 0x2A) |
| 797 | sanity_check = ((packet[3] & 0x1c) == 0x10); | 800 | sanity_check = ((packet[3] & 0x1c) == 0x10); |
| 798 | else | 801 | else |
| 799 | sanity_check = ((packet[0] & 0x0c) == 0x04 && | 802 | sanity_check = ((packet[0] & 0x0c) == 0x04 && |
| @@ -827,12 +830,12 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
| 827 | if (psmouse->pktcnt < psmouse->pktsize) | 830 | if (psmouse->pktcnt < psmouse->pktsize) |
| 828 | return PSMOUSE_GOOD_DATA; | 831 | return PSMOUSE_GOOD_DATA; |
| 829 | 832 | ||
| 830 | if (etd->debug > 1) | 833 | if (etd->info.debug > 1) |
| 831 | elantech_packet_dump(psmouse); | 834 | elantech_packet_dump(psmouse); |
| 832 | 835 | ||
| 833 | switch (etd->hw_version) { | 836 | switch (etd->info.hw_version) { |
| 834 | case 1: | 837 | case 1: |
| 835 | if (etd->paritycheck && !elantech_packet_check_v1(psmouse)) | 838 | if (etd->info.paritycheck && !elantech_packet_check_v1(psmouse)) |
| 836 | return PSMOUSE_BAD_DATA; | 839 | return PSMOUSE_BAD_DATA; |
| 837 | 840 | ||
| 838 | elantech_report_absolute_v1(psmouse); | 841 | elantech_report_absolute_v1(psmouse); |
| @@ -843,7 +846,7 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse) | |||
| 843 | if (elantech_debounce_check_v2(psmouse)) | 846 | if (elantech_debounce_check_v2(psmouse)) |
| 844 | return PSMOUSE_FULL_PACKET; | 847 | return PSMOUSE_FULL_PACKET; |
| 845 | 848 | ||
| 846 | if (etd->paritycheck && !elantech_packet_check_v2(psmouse)) | 849 | if (etd->info.paritycheck && !elantech_packet_check_v2(psmouse)) |
| 847 | return PSMOUSE_BAD_DATA; | 850 | return PSMOUSE_BAD_DATA; |
| 848 | 851 | ||
| 849 | elantech_report_absolute_v2(psmouse); | 852 | elantech_report_absolute_v2(psmouse); |
| @@ -916,7 +919,7 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
| 916 | int tries = ETP_READ_BACK_TRIES; | 919 | int tries = ETP_READ_BACK_TRIES; |
| 917 | int rc = 0; | 920 | int rc = 0; |
| 918 | 921 | ||
| 919 | switch (etd->hw_version) { | 922 | switch (etd->info.hw_version) { |
| 920 | case 1: | 923 | case 1: |
| 921 | etd->reg_10 = 0x16; | 924 | etd->reg_10 = 0x16; |
| 922 | etd->reg_11 = 0x8f; | 925 | etd->reg_11 = 0x8f; |
| @@ -939,7 +942,7 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
| 939 | break; | 942 | break; |
| 940 | 943 | ||
| 941 | case 3: | 944 | case 3: |
| 942 | if (etd->set_hw_resolution) | 945 | if (etd->info.set_hw_resolution) |
| 943 | etd->reg_10 = 0x0b; | 946 | etd->reg_10 = 0x0b; |
| 944 | else | 947 | else |
| 945 | etd->reg_10 = 0x01; | 948 | etd->reg_10 = 0x01; |
| @@ -976,7 +979,7 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
| 976 | if (rc) { | 979 | if (rc) { |
| 977 | psmouse_err(psmouse, | 980 | psmouse_err(psmouse, |
| 978 | "failed to read back register 0x10.\n"); | 981 | "failed to read back register 0x10.\n"); |
| 979 | } else if (etd->hw_version == 1 && | 982 | } else if (etd->info.hw_version == 1 && |
| 980 | !(val & ETP_R10_ABSOLUTE_MODE)) { | 983 | !(val & ETP_R10_ABSOLUTE_MODE)) { |
| 981 | psmouse_err(psmouse, | 984 | psmouse_err(psmouse, |
| 982 | "touchpad refuses to switch to absolute mode.\n"); | 985 | "touchpad refuses to switch to absolute mode.\n"); |
| @@ -997,10 +1000,11 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
| 997 | unsigned int *width) | 1000 | unsigned int *width) |
| 998 | { | 1001 | { |
| 999 | struct elantech_data *etd = psmouse->private; | 1002 | struct elantech_data *etd = psmouse->private; |
| 1003 | struct elantech_device_info *info = &etd->info; | ||
| 1000 | unsigned char param[3]; | 1004 | unsigned char param[3]; |
| 1001 | unsigned char traces; | 1005 | unsigned char traces; |
| 1002 | 1006 | ||
| 1003 | switch (etd->hw_version) { | 1007 | switch (info->hw_version) { |
| 1004 | case 1: | 1008 | case 1: |
| 1005 | *x_min = ETP_XMIN_V1; | 1009 | *x_min = ETP_XMIN_V1; |
| 1006 | *y_min = ETP_YMIN_V1; | 1010 | *y_min = ETP_YMIN_V1; |
| @@ -1009,9 +1013,9 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
| 1009 | break; | 1013 | break; |
| 1010 | 1014 | ||
| 1011 | case 2: | 1015 | case 2: |
| 1012 | if (etd->fw_version == 0x020800 || | 1016 | if (info->fw_version == 0x020800 || |
| 1013 | etd->fw_version == 0x020b00 || | 1017 | info->fw_version == 0x020b00 || |
| 1014 | etd->fw_version == 0x020030) { | 1018 | info->fw_version == 0x020030) { |
| 1015 | *x_min = ETP_XMIN_V2; | 1019 | *x_min = ETP_XMIN_V2; |
| 1016 | *y_min = ETP_YMIN_V2; | 1020 | *y_min = ETP_YMIN_V2; |
| 1017 | *x_max = ETP_XMAX_V2; | 1021 | *x_max = ETP_XMAX_V2; |
| @@ -1020,35 +1024,35 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
| 1020 | int i; | 1024 | int i; |
| 1021 | int fixed_dpi; | 1025 | int fixed_dpi; |
| 1022 | 1026 | ||
| 1023 | i = (etd->fw_version > 0x020800 && | 1027 | i = (info->fw_version > 0x020800 && |
| 1024 | etd->fw_version < 0x020900) ? 1 : 2; | 1028 | info->fw_version < 0x020900) ? 1 : 2; |
| 1025 | 1029 | ||
| 1026 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | 1030 | if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) |
| 1027 | return -1; | 1031 | return -1; |
| 1028 | 1032 | ||
| 1029 | fixed_dpi = param[1] & 0x10; | 1033 | fixed_dpi = param[1] & 0x10; |
| 1030 | 1034 | ||
| 1031 | if (((etd->fw_version >> 16) == 0x14) && fixed_dpi) { | 1035 | if (((info->fw_version >> 16) == 0x14) && fixed_dpi) { |
| 1032 | if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) | 1036 | if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, param)) |
| 1033 | return -1; | 1037 | return -1; |
| 1034 | 1038 | ||
| 1035 | *x_max = (etd->capabilities[1] - i) * param[1] / 2; | 1039 | *x_max = (info->capabilities[1] - i) * param[1] / 2; |
| 1036 | *y_max = (etd->capabilities[2] - i) * param[2] / 2; | 1040 | *y_max = (info->capabilities[2] - i) * param[2] / 2; |
| 1037 | } else if (etd->fw_version == 0x040216) { | 1041 | } else if (info->fw_version == 0x040216) { |
| 1038 | *x_max = 819; | 1042 | *x_max = 819; |
| 1039 | *y_max = 405; | 1043 | *y_max = 405; |
| 1040 | } else if (etd->fw_version == 0x040219 || etd->fw_version == 0x040215) { | 1044 | } else if (info->fw_version == 0x040219 || info->fw_version == 0x040215) { |
| 1041 | *x_max = 900; | 1045 | *x_max = 900; |
| 1042 | *y_max = 500; | 1046 | *y_max = 500; |
| 1043 | } else { | 1047 | } else { |
| 1044 | *x_max = (etd->capabilities[1] - i) * 64; | 1048 | *x_max = (info->capabilities[1] - i) * 64; |
| 1045 | *y_max = (etd->capabilities[2] - i) * 64; | 1049 | *y_max = (info->capabilities[2] - i) * 64; |
| 1046 | } | 1050 | } |
| 1047 | } | 1051 | } |
| 1048 | break; | 1052 | break; |
| 1049 | 1053 | ||
| 1050 | case 3: | 1054 | case 3: |
| 1051 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | 1055 | if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) |
| 1052 | return -1; | 1056 | return -1; |
| 1053 | 1057 | ||
| 1054 | *x_max = (0x0f & param[0]) << 8 | param[1]; | 1058 | *x_max = (0x0f & param[0]) << 8 | param[1]; |
| @@ -1056,12 +1060,12 @@ static int elantech_set_range(struct psmouse *psmouse, | |||
| 1056 | break; | 1060 | break; |
| 1057 | 1061 | ||
| 1058 | case 4: | 1062 | case 4: |
| 1059 | if (etd->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) | 1063 | if (info->send_cmd(psmouse, ETP_FW_ID_QUERY, param)) |
| 1060 | return -1; | 1064 | return -1; |
| 1061 | 1065 | ||
| 1062 | *x_max = (0x0f & param[0]) << 8 | param[1]; | 1066 | *x_max = (0x0f & param[0]) << 8 | param[1]; |
| 1063 | *y_max = (0xf0 & param[0]) << 4 | param[2]; | 1067 | *y_max = (0xf0 & param[0]) << 4 | param[2]; |
| 1064 | traces = etd->capabilities[1]; | 1068 | traces = info->capabilities[1]; |
| 1065 | if ((traces < 2) || (traces > *x_max)) | 1069 | if ((traces < 2) || (traces > *x_max)) |
| 1066 | return -1; | 1070 | return -1; |
| 1067 | 1071 | ||
| @@ -1083,7 +1087,8 @@ static unsigned int elantech_convert_res(unsigned int val) | |||
| 1083 | 1087 | ||
| 1084 | static int elantech_get_resolution_v4(struct psmouse *psmouse, | 1088 | static int elantech_get_resolution_v4(struct psmouse *psmouse, |
| 1085 | unsigned int *x_res, | 1089 | unsigned int *x_res, |
| 1086 | unsigned int *y_res) | 1090 | unsigned int *y_res, |
| 1091 | unsigned int *bus) | ||
| 1087 | { | 1092 | { |
| 1088 | unsigned char param[3]; | 1093 | unsigned char param[3]; |
| 1089 | 1094 | ||
| @@ -1092,6 +1097,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, | |||
| 1092 | 1097 | ||
| 1093 | *x_res = elantech_convert_res(param[1] & 0x0f); | 1098 | *x_res = elantech_convert_res(param[1] & 0x0f); |
| 1094 | *y_res = elantech_convert_res((param[1] & 0xf0) >> 4); | 1099 | *y_res = elantech_convert_res((param[1] & 0xf0) >> 4); |
| 1100 | *bus = param[2]; | ||
| 1095 | 1101 | ||
| 1096 | return 0; | 1102 | return 0; |
| 1097 | } | 1103 | } |
| @@ -1140,7 +1146,7 @@ static void elantech_set_buttonpad_prop(struct psmouse *psmouse) | |||
| 1140 | struct input_dev *dev = psmouse->dev; | 1146 | struct input_dev *dev = psmouse->dev; |
| 1141 | struct elantech_data *etd = psmouse->private; | 1147 | struct elantech_data *etd = psmouse->private; |
| 1142 | 1148 | ||
| 1143 | if (etd->fw_version & 0x001000) { | 1149 | if (etd->info.fw_version & 0x001000) { |
| 1144 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); | 1150 | __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); |
| 1145 | __clear_bit(BTN_RIGHT, dev->keybit); | 1151 | __clear_bit(BTN_RIGHT, dev->keybit); |
| 1146 | } | 1152 | } |
| @@ -1176,8 +1182,8 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
| 1176 | { | 1182 | { |
| 1177 | struct input_dev *dev = psmouse->dev; | 1183 | struct input_dev *dev = psmouse->dev; |
| 1178 | struct elantech_data *etd = psmouse->private; | 1184 | struct elantech_data *etd = psmouse->private; |
| 1185 | struct elantech_device_info *info = &etd->info; | ||
| 1179 | unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; | 1186 | unsigned int x_min = 0, y_min = 0, x_max = 0, y_max = 0, width = 0; |
| 1180 | unsigned int x_res = 31, y_res = 31; | ||
| 1181 | 1187 | ||
| 1182 | if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) | 1188 | if (elantech_set_range(psmouse, &x_min, &y_min, &x_max, &y_max, &width)) |
| 1183 | return -1; | 1189 | return -1; |
| @@ -1197,11 +1203,11 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
| 1197 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); | 1203 | __set_bit(BTN_TOOL_DOUBLETAP, dev->keybit); |
| 1198 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); | 1204 | __set_bit(BTN_TOOL_TRIPLETAP, dev->keybit); |
| 1199 | 1205 | ||
| 1200 | switch (etd->hw_version) { | 1206 | switch (info->hw_version) { |
| 1201 | case 1: | 1207 | case 1: |
| 1202 | /* Rocker button */ | 1208 | /* Rocker button */ |
| 1203 | if (etd->fw_version < 0x020000 && | 1209 | if (info->fw_version < 0x020000 && |
| 1204 | (etd->capabilities[0] & ETP_CAP_HAS_ROCKER)) { | 1210 | (info->capabilities[0] & ETP_CAP_HAS_ROCKER)) { |
| 1205 | __set_bit(BTN_FORWARD, dev->keybit); | 1211 | __set_bit(BTN_FORWARD, dev->keybit); |
| 1206 | __set_bit(BTN_BACK, dev->keybit); | 1212 | __set_bit(BTN_BACK, dev->keybit); |
| 1207 | } | 1213 | } |
| @@ -1214,11 +1220,11 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
| 1214 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1220 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
| 1215 | /* fall through */ | 1221 | /* fall through */ |
| 1216 | case 3: | 1222 | case 3: |
| 1217 | if (etd->hw_version == 3) | 1223 | if (info->hw_version == 3) |
| 1218 | elantech_set_buttonpad_prop(psmouse); | 1224 | elantech_set_buttonpad_prop(psmouse); |
| 1219 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); | 1225 | input_set_abs_params(dev, ABS_X, x_min, x_max, 0, 0); |
| 1220 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); | 1226 | input_set_abs_params(dev, ABS_Y, y_min, y_max, 0, 0); |
| 1221 | if (etd->reports_pressure) { | 1227 | if (info->reports_pressure) { |
| 1222 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, | 1228 | input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2, |
| 1223 | ETP_PMAX_V2, 0, 0); | 1229 | ETP_PMAX_V2, 0, 0); |
| 1224 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 1230 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
| @@ -1230,13 +1236,6 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
| 1230 | break; | 1236 | break; |
| 1231 | 1237 | ||
| 1232 | case 4: | 1238 | case 4: |
| 1233 | if (elantech_get_resolution_v4(psmouse, &x_res, &y_res)) { | ||
| 1234 | /* | ||
| 1235 | * if query failed, print a warning and leave the values | ||
| 1236 | * zero to resemble synaptics.c behavior. | ||
| 1237 | */ | ||
| 1238 | psmouse_warn(psmouse, "couldn't query resolution data.\n"); | ||
| 1239 | } | ||
| 1240 | elantech_set_buttonpad_prop(psmouse); | 1239 | elantech_set_buttonpad_prop(psmouse); |
| 1241 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); | 1240 | __set_bit(BTN_TOOL_QUADTAP, dev->keybit); |
| 1242 | /* For X to recognize me as touchpad. */ | 1241 | /* For X to recognize me as touchpad. */ |
| @@ -1265,11 +1264,11 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
| 1265 | break; | 1264 | break; |
| 1266 | } | 1265 | } |
| 1267 | 1266 | ||
| 1268 | input_abs_set_res(dev, ABS_X, x_res); | 1267 | input_abs_set_res(dev, ABS_X, info->x_res); |
| 1269 | input_abs_set_res(dev, ABS_Y, y_res); | 1268 | input_abs_set_res(dev, ABS_Y, info->y_res); |
| 1270 | if (etd->hw_version > 1) { | 1269 | if (info->hw_version > 1) { |
| 1271 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); | 1270 | input_abs_set_res(dev, ABS_MT_POSITION_X, info->x_res); |
| 1272 | input_abs_set_res(dev, ABS_MT_POSITION_Y, y_res); | 1271 | input_abs_set_res(dev, ABS_MT_POSITION_Y, info->y_res); |
| 1273 | } | 1272 | } |
| 1274 | 1273 | ||
| 1275 | etd->y_max = y_max; | 1274 | etd->y_max = y_max; |
| @@ -1317,7 +1316,7 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse, | |||
| 1317 | return err; | 1316 | return err; |
| 1318 | 1317 | ||
| 1319 | /* Do we need to preserve some bits for version 2 hardware too? */ | 1318 | /* Do we need to preserve some bits for version 2 hardware too? */ |
| 1320 | if (etd->hw_version == 1) { | 1319 | if (etd->info.hw_version == 1) { |
| 1321 | if (attr->reg == 0x10) | 1320 | if (attr->reg == 0x10) |
| 1322 | /* Force absolute mode always on */ | 1321 | /* Force absolute mode always on */ |
| 1323 | value |= ETP_R10_ABSOLUTE_MODE; | 1322 | value |= ETP_R10_ABSOLUTE_MODE; |
| @@ -1337,11 +1336,22 @@ static ssize_t elantech_set_int_attr(struct psmouse *psmouse, | |||
| 1337 | .field_offset = offsetof(struct elantech_data, _name), \ | 1336 | .field_offset = offsetof(struct elantech_data, _name), \ |
| 1338 | .reg = _register, \ | 1337 | .reg = _register, \ |
| 1339 | }; \ | 1338 | }; \ |
| 1340 | PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ | 1339 | PSMOUSE_DEFINE_ATTR(_name, 0644, \ |
| 1341 | &elantech_attr_##_name, \ | 1340 | &elantech_attr_##_name, \ |
| 1342 | elantech_show_int_attr, \ | 1341 | elantech_show_int_attr, \ |
| 1343 | elantech_set_int_attr) | 1342 | elantech_set_int_attr) |
| 1344 | 1343 | ||
| 1344 | #define ELANTECH_INFO_ATTR(_name) \ | ||
| 1345 | static struct elantech_attr_data elantech_attr_##_name = { \ | ||
| 1346 | .field_offset = offsetof(struct elantech_data, info) + \ | ||
| 1347 | offsetof(struct elantech_device_info, _name), \ | ||
| 1348 | .reg = 0, \ | ||
| 1349 | }; \ | ||
| 1350 | PSMOUSE_DEFINE_ATTR(_name, 0644, \ | ||
| 1351 | &elantech_attr_##_name, \ | ||
| 1352 | elantech_show_int_attr, \ | ||
| 1353 | elantech_set_int_attr) | ||
| 1354 | |||
| 1345 | ELANTECH_INT_ATTR(reg_07, 0x07); | 1355 | ELANTECH_INT_ATTR(reg_07, 0x07); |
| 1346 | ELANTECH_INT_ATTR(reg_10, 0x10); | 1356 | ELANTECH_INT_ATTR(reg_10, 0x10); |
| 1347 | ELANTECH_INT_ATTR(reg_11, 0x11); | 1357 | ELANTECH_INT_ATTR(reg_11, 0x11); |
| @@ -1352,9 +1362,9 @@ ELANTECH_INT_ATTR(reg_23, 0x23); | |||
| 1352 | ELANTECH_INT_ATTR(reg_24, 0x24); | 1362 | ELANTECH_INT_ATTR(reg_24, 0x24); |
| 1353 | ELANTECH_INT_ATTR(reg_25, 0x25); | 1363 | ELANTECH_INT_ATTR(reg_25, 0x25); |
| 1354 | ELANTECH_INT_ATTR(reg_26, 0x26); | 1364 | ELANTECH_INT_ATTR(reg_26, 0x26); |
| 1355 | ELANTECH_INT_ATTR(debug, 0); | 1365 | ELANTECH_INFO_ATTR(debug); |
| 1356 | ELANTECH_INT_ATTR(paritycheck, 0); | 1366 | ELANTECH_INFO_ATTR(paritycheck); |
| 1357 | ELANTECH_INT_ATTR(crc_enabled, 0); | 1367 | ELANTECH_INFO_ATTR(crc_enabled); |
| 1358 | 1368 | ||
| 1359 | static struct attribute *elantech_attrs[] = { | 1369 | static struct attribute *elantech_attrs[] = { |
| 1360 | &psmouse_attr_reg_07.dattr.attr, | 1370 | &psmouse_attr_reg_07.dattr.attr, |
| @@ -1469,6 +1479,12 @@ static void elantech_disconnect(struct psmouse *psmouse) | |||
| 1469 | { | 1479 | { |
| 1470 | struct elantech_data *etd = psmouse->private; | 1480 | struct elantech_data *etd = psmouse->private; |
| 1471 | 1481 | ||
| 1482 | /* | ||
| 1483 | * We might have left a breadcrumb when trying to | ||
| 1484 | * set up SMbus companion. | ||
| 1485 | */ | ||
| 1486 | psmouse_smbus_cleanup(psmouse); | ||
| 1487 | |||
| 1472 | if (etd->tp_dev) | 1488 | if (etd->tp_dev) |
| 1473 | input_unregister_device(etd->tp_dev); | 1489 | input_unregister_device(etd->tp_dev); |
| 1474 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, | 1490 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, |
| @@ -1588,25 +1604,25 @@ static const struct dmi_system_id no_hw_res_dmi_table[] = { | |||
| 1588 | /* | 1604 | /* |
| 1589 | * determine hardware version and set some properties according to it. | 1605 | * determine hardware version and set some properties according to it. |
| 1590 | */ | 1606 | */ |
| 1591 | static int elantech_set_properties(struct elantech_data *etd) | 1607 | static int elantech_set_properties(struct elantech_device_info *info) |
| 1592 | { | 1608 | { |
| 1593 | /* This represents the version of IC body. */ | 1609 | /* This represents the version of IC body. */ |
| 1594 | int ver = (etd->fw_version & 0x0f0000) >> 16; | 1610 | int ver = (info->fw_version & 0x0f0000) >> 16; |
| 1595 | 1611 | ||
| 1596 | /* Early version of Elan touchpads doesn't obey the rule. */ | 1612 | /* Early version of Elan touchpads doesn't obey the rule. */ |
| 1597 | if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) | 1613 | if (info->fw_version < 0x020030 || info->fw_version == 0x020600) |
| 1598 | etd->hw_version = 1; | 1614 | info->hw_version = 1; |
| 1599 | else { | 1615 | else { |
| 1600 | switch (ver) { | 1616 | switch (ver) { |
| 1601 | case 2: | 1617 | case 2: |
| 1602 | case 4: | 1618 | case 4: |
| 1603 | etd->hw_version = 2; | 1619 | info->hw_version = 2; |
| 1604 | break; | 1620 | break; |
| 1605 | case 5: | 1621 | case 5: |
| 1606 | etd->hw_version = 3; | 1622 | info->hw_version = 3; |
| 1607 | break; | 1623 | break; |
| 1608 | case 6 ... 15: | 1624 | case 6 ... 15: |
| 1609 | etd->hw_version = 4; | 1625 | info->hw_version = 4; |
| 1610 | break; | 1626 | break; |
| 1611 | default: | 1627 | default: |
| 1612 | return -1; | 1628 | return -1; |
| @@ -1614,100 +1630,88 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
| 1614 | } | 1630 | } |
| 1615 | 1631 | ||
| 1616 | /* decide which send_cmd we're gonna use early */ | 1632 | /* decide which send_cmd we're gonna use early */ |
| 1617 | etd->send_cmd = etd->hw_version >= 3 ? elantech_send_cmd : | 1633 | info->send_cmd = info->hw_version >= 3 ? elantech_send_cmd : |
| 1618 | synaptics_send_cmd; | 1634 | synaptics_send_cmd; |
| 1619 | 1635 | ||
| 1620 | /* Turn on packet checking by default */ | 1636 | /* Turn on packet checking by default */ |
| 1621 | etd->paritycheck = 1; | 1637 | info->paritycheck = 1; |
| 1622 | 1638 | ||
| 1623 | /* | 1639 | /* |
| 1624 | * This firmware suffers from misreporting coordinates when | 1640 | * This firmware suffers from misreporting coordinates when |
| 1625 | * a touch action starts causing the mouse cursor or scrolled page | 1641 | * a touch action starts causing the mouse cursor or scrolled page |
| 1626 | * to jump. Enable a workaround. | 1642 | * to jump. Enable a workaround. |
| 1627 | */ | 1643 | */ |
| 1628 | etd->jumpy_cursor = | 1644 | info->jumpy_cursor = |
| 1629 | (etd->fw_version == 0x020022 || etd->fw_version == 0x020600); | 1645 | (info->fw_version == 0x020022 || info->fw_version == 0x020600); |
| 1630 | 1646 | ||
| 1631 | if (etd->hw_version > 1) { | 1647 | if (info->hw_version > 1) { |
| 1632 | /* For now show extra debug information */ | 1648 | /* For now show extra debug information */ |
| 1633 | etd->debug = 1; | 1649 | info->debug = 1; |
| 1634 | 1650 | ||
| 1635 | if (etd->fw_version >= 0x020800) | 1651 | if (info->fw_version >= 0x020800) |
| 1636 | etd->reports_pressure = true; | 1652 | info->reports_pressure = true; |
| 1637 | } | 1653 | } |
| 1638 | 1654 | ||
| 1639 | /* | 1655 | /* |
| 1640 | * The signatures of v3 and v4 packets change depending on the | 1656 | * The signatures of v3 and v4 packets change depending on the |
| 1641 | * value of this hardware flag. | 1657 | * value of this hardware flag. |
| 1642 | */ | 1658 | */ |
| 1643 | etd->crc_enabled = (etd->fw_version & 0x4000) == 0x4000 || | 1659 | info->crc_enabled = (info->fw_version & 0x4000) == 0x4000 || |
| 1644 | dmi_check_system(elantech_dmi_force_crc_enabled); | 1660 | dmi_check_system(elantech_dmi_force_crc_enabled); |
| 1645 | 1661 | ||
| 1646 | /* Enable real hardware resolution on hw_version 3 ? */ | 1662 | /* Enable real hardware resolution on hw_version 3 ? */ |
| 1647 | etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); | 1663 | info->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); |
| 1648 | 1664 | ||
| 1649 | return 0; | 1665 | return 0; |
| 1650 | } | 1666 | } |
| 1651 | 1667 | ||
| 1652 | /* | 1668 | static int elantech_query_info(struct psmouse *psmouse, |
| 1653 | * Initialize the touchpad and create sysfs entries | 1669 | struct elantech_device_info *info) |
| 1654 | */ | ||
| 1655 | int elantech_init(struct psmouse *psmouse) | ||
| 1656 | { | 1670 | { |
| 1657 | struct elantech_data *etd; | ||
| 1658 | int i; | ||
| 1659 | int error = -EINVAL; | ||
| 1660 | unsigned char param[3]; | 1671 | unsigned char param[3]; |
| 1661 | struct input_dev *tp_dev; | ||
| 1662 | 1672 | ||
| 1663 | psmouse->private = etd = kzalloc(sizeof(struct elantech_data), GFP_KERNEL); | 1673 | memset(info, 0, sizeof(*info)); |
| 1664 | if (!etd) | ||
| 1665 | return -ENOMEM; | ||
| 1666 | |||
| 1667 | psmouse_reset(psmouse); | ||
| 1668 | |||
| 1669 | etd->parity[0] = 1; | ||
| 1670 | for (i = 1; i < 256; i++) | ||
| 1671 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; | ||
| 1672 | 1674 | ||
| 1673 | /* | 1675 | /* |
| 1674 | * Do the version query again so we can store the result | 1676 | * Do the version query again so we can store the result |
| 1675 | */ | 1677 | */ |
| 1676 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { | 1678 | if (synaptics_send_cmd(psmouse, ETP_FW_VERSION_QUERY, param)) { |
| 1677 | psmouse_err(psmouse, "failed to query firmware version.\n"); | 1679 | psmouse_err(psmouse, "failed to query firmware version.\n"); |
| 1678 | goto init_fail; | 1680 | return -EINVAL; |
| 1679 | } | 1681 | } |
| 1680 | etd->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; | 1682 | info->fw_version = (param[0] << 16) | (param[1] << 8) | param[2]; |
| 1681 | 1683 | ||
| 1682 | if (elantech_set_properties(etd)) { | 1684 | if (elantech_set_properties(info)) { |
| 1683 | psmouse_err(psmouse, "unknown hardware version, aborting...\n"); | 1685 | psmouse_err(psmouse, "unknown hardware version, aborting...\n"); |
| 1684 | goto init_fail; | 1686 | return -EINVAL; |
| 1685 | } | 1687 | } |
| 1686 | psmouse_info(psmouse, | 1688 | psmouse_info(psmouse, |
| 1687 | "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n", | 1689 | "assuming hardware version %d (with firmware version 0x%02x%02x%02x)\n", |
| 1688 | etd->hw_version, param[0], param[1], param[2]); | 1690 | info->hw_version, param[0], param[1], param[2]); |
| 1689 | 1691 | ||
| 1690 | if (etd->send_cmd(psmouse, ETP_CAPABILITIES_QUERY, | 1692 | if (info->send_cmd(psmouse, ETP_CAPABILITIES_QUERY, |
| 1691 | etd->capabilities)) { | 1693 | info->capabilities)) { |
| 1692 | psmouse_err(psmouse, "failed to query capabilities.\n"); | 1694 | psmouse_err(psmouse, "failed to query capabilities.\n"); |
| 1693 | goto init_fail; | 1695 | return -EINVAL; |
| 1694 | } | 1696 | } |
| 1695 | psmouse_info(psmouse, | 1697 | psmouse_info(psmouse, |
| 1696 | "Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", | 1698 | "Synaptics capabilities query result 0x%02x, 0x%02x, 0x%02x.\n", |
| 1697 | etd->capabilities[0], etd->capabilities[1], | 1699 | info->capabilities[0], info->capabilities[1], |
| 1698 | etd->capabilities[2]); | 1700 | info->capabilities[2]); |
| 1699 | 1701 | ||
| 1700 | if (etd->hw_version != 1) { | 1702 | if (info->hw_version != 1) { |
| 1701 | if (etd->send_cmd(psmouse, ETP_SAMPLE_QUERY, etd->samples)) { | 1703 | if (info->send_cmd(psmouse, ETP_SAMPLE_QUERY, info->samples)) { |
| 1702 | psmouse_err(psmouse, "failed to query sample data\n"); | 1704 | psmouse_err(psmouse, "failed to query sample data\n"); |
| 1703 | goto init_fail; | 1705 | return -EINVAL; |
| 1704 | } | 1706 | } |
| 1705 | psmouse_info(psmouse, | 1707 | psmouse_info(psmouse, |
| 1706 | "Elan sample query result %02x, %02x, %02x\n", | 1708 | "Elan sample query result %02x, %02x, %02x\n", |
| 1707 | etd->samples[0], etd->samples[1], etd->samples[2]); | 1709 | info->samples[0], |
| 1710 | info->samples[1], | ||
| 1711 | info->samples[2]); | ||
| 1708 | } | 1712 | } |
| 1709 | 1713 | ||
| 1710 | if (etd->samples[1] == 0x74 && etd->hw_version == 0x03) { | 1714 | if (info->samples[1] == 0x74 && info->hw_version == 0x03) { |
| 1711 | /* | 1715 | /* |
| 1712 | * This module has a bug which makes absolute mode | 1716 | * This module has a bug which makes absolute mode |
| 1713 | * unusable, so let's abort so we'll be using standard | 1717 | * unusable, so let's abort so we'll be using standard |
| @@ -1715,16 +1719,181 @@ int elantech_init(struct psmouse *psmouse) | |||
| 1715 | */ | 1719 | */ |
| 1716 | psmouse_info(psmouse, | 1720 | psmouse_info(psmouse, |
| 1717 | "absolute mode broken, forcing standard PS/2 protocol\n"); | 1721 | "absolute mode broken, forcing standard PS/2 protocol\n"); |
| 1722 | return -ENODEV; | ||
| 1723 | } | ||
| 1724 | |||
| 1725 | /* The MSB indicates the presence of the trackpoint */ | ||
| 1726 | info->has_trackpoint = (info->capabilities[0] & 0x80) == 0x80; | ||
| 1727 | |||
| 1728 | info->x_res = 31; | ||
| 1729 | info->y_res = 31; | ||
| 1730 | if (info->hw_version == 4) { | ||
| 1731 | if (elantech_get_resolution_v4(psmouse, | ||
| 1732 | &info->x_res, | ||
| 1733 | &info->y_res, | ||
| 1734 | &info->bus)) { | ||
| 1735 | psmouse_warn(psmouse, | ||
| 1736 | "failed to query resolution data.\n"); | ||
| 1737 | } | ||
| 1738 | } | ||
| 1739 | |||
| 1740 | return 0; | ||
| 1741 | } | ||
| 1742 | |||
| 1743 | #if defined(CONFIG_MOUSE_PS2_ELANTECH_SMBUS) | ||
| 1744 | |||
| 1745 | /* | ||
| 1746 | * The newest Elantech device can use a secondary bus (over SMBus) which | ||
| 1747 | * provides a better bandwidth and allow a better control of the touchpads. | ||
| 1748 | * This is used to decide if we need to use this bus or not. | ||
| 1749 | */ | ||
| 1750 | enum { | ||
| 1751 | ELANTECH_SMBUS_NOT_SET = -1, | ||
| 1752 | ELANTECH_SMBUS_OFF, | ||
| 1753 | ELANTECH_SMBUS_ON, | ||
| 1754 | }; | ||
| 1755 | |||
| 1756 | static int elantech_smbus = IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) ? | ||
| 1757 | ELANTECH_SMBUS_NOT_SET : ELANTECH_SMBUS_OFF; | ||
| 1758 | module_param_named(elantech_smbus, elantech_smbus, int, 0644); | ||
| 1759 | MODULE_PARM_DESC(elantech_smbus, "Use a secondary bus for the Elantech device."); | ||
| 1760 | |||
| 1761 | static int elantech_create_smbus(struct psmouse *psmouse, | ||
| 1762 | struct elantech_device_info *info, | ||
| 1763 | bool leave_breadcrumbs) | ||
| 1764 | { | ||
| 1765 | const struct property_entry i2c_properties[] = { | ||
| 1766 | PROPERTY_ENTRY_BOOL("elan,trackpoint"), | ||
| 1767 | { }, | ||
| 1768 | }; | ||
| 1769 | struct i2c_board_info smbus_board = { | ||
| 1770 | I2C_BOARD_INFO("elan_i2c", 0x15), | ||
| 1771 | .flags = I2C_CLIENT_HOST_NOTIFY, | ||
| 1772 | }; | ||
| 1773 | |||
| 1774 | if (info->has_trackpoint) | ||
| 1775 | smbus_board.properties = i2c_properties; | ||
| 1776 | |||
| 1777 | return psmouse_smbus_init(psmouse, &smbus_board, NULL, 0, false, | ||
| 1778 | leave_breadcrumbs); | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | /** | ||
| 1782 | * elantech_setup_smbus - called once the PS/2 devices are enumerated | ||
| 1783 | * and decides to instantiate a SMBus InterTouch device. | ||
| 1784 | */ | ||
| 1785 | static int elantech_setup_smbus(struct psmouse *psmouse, | ||
| 1786 | struct elantech_device_info *info, | ||
| 1787 | bool leave_breadcrumbs) | ||
| 1788 | { | ||
| 1789 | int error; | ||
| 1790 | |||
| 1791 | if (elantech_smbus == ELANTECH_SMBUS_OFF) | ||
| 1792 | return -ENXIO; | ||
| 1793 | |||
| 1794 | if (elantech_smbus == ELANTECH_SMBUS_NOT_SET) { | ||
| 1795 | /* | ||
| 1796 | * New ICs are enabled by default. | ||
| 1797 | * Old ICs are up to the user to decide. | ||
| 1798 | */ | ||
| 1799 | if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | ||
| 1800 | return -ENXIO; | ||
| 1801 | } | ||
| 1802 | |||
| 1803 | psmouse_info(psmouse, "Trying to set up SMBus access\n"); | ||
| 1804 | |||
| 1805 | error = elantech_create_smbus(psmouse, info, leave_breadcrumbs); | ||
| 1806 | if (error) { | ||
| 1807 | if (error == -EAGAIN) | ||
| 1808 | psmouse_info(psmouse, "SMbus companion is not ready yet\n"); | ||
| 1809 | else | ||
| 1810 | psmouse_err(psmouse, "unable to create intertouch device\n"); | ||
| 1811 | |||
| 1812 | return error; | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | return 0; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | static bool elantech_use_host_notify(struct psmouse *psmouse, | ||
| 1819 | struct elantech_device_info *info) | ||
| 1820 | { | ||
| 1821 | if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | ||
| 1822 | return true; | ||
| 1823 | |||
| 1824 | switch (info->bus) { | ||
| 1825 | case ETP_BUS_PS2_ONLY: | ||
| 1826 | /* expected case */ | ||
| 1827 | break; | ||
| 1828 | case ETP_BUS_SMB_ALERT_ONLY: | ||
| 1829 | /* fall-through */ | ||
| 1830 | case ETP_BUS_PS2_SMB_ALERT: | ||
| 1831 | psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n"); | ||
| 1832 | break; | ||
| 1833 | case ETP_BUS_SMB_HST_NTFY_ONLY: | ||
| 1834 | /* fall-through */ | ||
| 1835 | case ETP_BUS_PS2_SMB_HST_NTFY: | ||
| 1836 | return true; | ||
| 1837 | default: | ||
| 1838 | psmouse_dbg(psmouse, | ||
| 1839 | "Ignoring SMBus bus provider %d.\n", | ||
| 1840 | info->bus); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | return false; | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | int elantech_init_smbus(struct psmouse *psmouse) | ||
| 1847 | { | ||
| 1848 | struct elantech_device_info info; | ||
| 1849 | int error = -EINVAL; | ||
| 1850 | |||
| 1851 | psmouse_reset(psmouse); | ||
| 1852 | |||
| 1853 | error = elantech_query_info(psmouse, &info); | ||
| 1854 | if (error) | ||
| 1855 | goto init_fail; | ||
| 1856 | |||
| 1857 | if (info.hw_version < 4) { | ||
| 1858 | error = -ENXIO; | ||
| 1718 | goto init_fail; | 1859 | goto init_fail; |
| 1719 | } | 1860 | } |
| 1720 | 1861 | ||
| 1862 | return elantech_create_smbus(psmouse, &info, false); | ||
| 1863 | init_fail: | ||
| 1864 | psmouse_reset(psmouse); | ||
| 1865 | return error; | ||
| 1866 | } | ||
| 1867 | #endif /* CONFIG_MOUSE_PS2_ELANTECH_SMBUS */ | ||
| 1868 | |||
| 1869 | /* | ||
| 1870 | * Initialize the touchpad and create sysfs entries | ||
| 1871 | */ | ||
| 1872 | static int elantech_setup_ps2(struct psmouse *psmouse, | ||
| 1873 | struct elantech_device_info *info) | ||
| 1874 | { | ||
| 1875 | struct elantech_data *etd; | ||
| 1876 | int i; | ||
| 1877 | int error = -EINVAL; | ||
| 1878 | struct input_dev *tp_dev; | ||
| 1879 | |||
| 1880 | psmouse->private = etd = kzalloc(sizeof(*etd), GFP_KERNEL); | ||
| 1881 | if (!etd) | ||
| 1882 | return -ENOMEM; | ||
| 1883 | |||
| 1884 | etd->info = *info; | ||
| 1885 | |||
| 1886 | etd->parity[0] = 1; | ||
| 1887 | for (i = 1; i < 256; i++) | ||
| 1888 | etd->parity[i] = etd->parity[i & (i - 1)] ^ 1; | ||
| 1889 | |||
| 1721 | if (elantech_set_absolute_mode(psmouse)) { | 1890 | if (elantech_set_absolute_mode(psmouse)) { |
| 1722 | psmouse_err(psmouse, | 1891 | psmouse_err(psmouse, |
| 1723 | "failed to put touchpad into absolute mode.\n"); | 1892 | "failed to put touchpad into absolute mode.\n"); |
| 1724 | goto init_fail; | 1893 | goto init_fail; |
| 1725 | } | 1894 | } |
| 1726 | 1895 | ||
| 1727 | if (etd->fw_version == 0x381f17) { | 1896 | if (info->fw_version == 0x381f17) { |
| 1728 | etd->original_set_rate = psmouse->set_rate; | 1897 | etd->original_set_rate = psmouse->set_rate; |
| 1729 | psmouse->set_rate = elantech_set_rate_restore_reg_07; | 1898 | psmouse->set_rate = elantech_set_rate_restore_reg_07; |
| 1730 | } | 1899 | } |
| @@ -1743,8 +1912,7 @@ int elantech_init(struct psmouse *psmouse) | |||
| 1743 | goto init_fail; | 1912 | goto init_fail; |
| 1744 | } | 1913 | } |
| 1745 | 1914 | ||
| 1746 | /* The MSB indicates the presence of the trackpoint */ | 1915 | if (info->has_trackpoint) { |
| 1747 | if ((etd->capabilities[0] & 0x80) == 0x80) { | ||
| 1748 | tp_dev = input_allocate_device(); | 1916 | tp_dev = input_allocate_device(); |
| 1749 | 1917 | ||
| 1750 | if (!tp_dev) { | 1918 | if (!tp_dev) { |
| @@ -1780,7 +1948,7 @@ int elantech_init(struct psmouse *psmouse) | |||
| 1780 | psmouse->protocol_handler = elantech_process_byte; | 1948 | psmouse->protocol_handler = elantech_process_byte; |
| 1781 | psmouse->disconnect = elantech_disconnect; | 1949 | psmouse->disconnect = elantech_disconnect; |
| 1782 | psmouse->reconnect = elantech_reconnect; | 1950 | psmouse->reconnect = elantech_reconnect; |
| 1783 | psmouse->pktsize = etd->hw_version > 1 ? 6 : 4; | 1951 | psmouse->pktsize = info->hw_version > 1 ? 6 : 4; |
| 1784 | 1952 | ||
| 1785 | return 0; | 1953 | return 0; |
| 1786 | init_fail_tp_reg: | 1954 | init_fail_tp_reg: |
| @@ -1789,7 +1957,70 @@ int elantech_init(struct psmouse *psmouse) | |||
| 1789 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, | 1957 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, |
| 1790 | &elantech_attr_group); | 1958 | &elantech_attr_group); |
| 1791 | init_fail: | 1959 | init_fail: |
| 1792 | psmouse_reset(psmouse); | ||
| 1793 | kfree(etd); | 1960 | kfree(etd); |
| 1794 | return error; | 1961 | return error; |
| 1795 | } | 1962 | } |
| 1963 | |||
| 1964 | int elantech_init_ps2(struct psmouse *psmouse) | ||
| 1965 | { | ||
| 1966 | struct elantech_device_info info; | ||
| 1967 | int error = -EINVAL; | ||
| 1968 | |||
| 1969 | psmouse_reset(psmouse); | ||
| 1970 | |||
| 1971 | error = elantech_query_info(psmouse, &info); | ||
| 1972 | if (error) | ||
| 1973 | goto init_fail; | ||
| 1974 | |||
| 1975 | error = elantech_setup_ps2(psmouse, &info); | ||
| 1976 | if (error) | ||
| 1977 | goto init_fail; | ||
| 1978 | |||
| 1979 | return 0; | ||
| 1980 | init_fail: | ||
| 1981 | psmouse_reset(psmouse); | ||
| 1982 | return error; | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | int elantech_init(struct psmouse *psmouse) | ||
| 1986 | { | ||
| 1987 | struct elantech_device_info info; | ||
| 1988 | int error = -EINVAL; | ||
| 1989 | |||
| 1990 | psmouse_reset(psmouse); | ||
| 1991 | |||
| 1992 | error = elantech_query_info(psmouse, &info); | ||
| 1993 | if (error) | ||
| 1994 | goto init_fail; | ||
| 1995 | |||
| 1996 | #if defined(CONFIG_MOUSE_PS2_ELANTECH_SMBUS) | ||
| 1997 | |||
| 1998 | if (elantech_use_host_notify(psmouse, &info)) { | ||
| 1999 | if (!IS_ENABLED(CONFIG_MOUSE_ELAN_I2C_SMBUS) || | ||
| 2000 | !IS_ENABLED(CONFIG_MOUSE_PS2_ELANTECH_SMBUS)) { | ||
| 2001 | psmouse_warn(psmouse, | ||
| 2002 | "The touchpad can support a better bus than the too old PS/2 protocol. " | ||
| 2003 | "Make sure MOUSE_PS2_ELANTECH_SMBUS and MOUSE_ELAN_I2C_SMBUS are enabled to get a better touchpad experience.\n"); | ||
| 2004 | } | ||
| 2005 | error = elantech_setup_smbus(psmouse, &info, true); | ||
| 2006 | if (!error) | ||
| 2007 | return PSMOUSE_ELANTECH_SMBUS; | ||
| 2008 | } | ||
| 2009 | |||
| 2010 | #endif /* CONFIG_MOUSE_PS2_ELANTECH_SMBUS */ | ||
| 2011 | |||
| 2012 | error = elantech_setup_ps2(psmouse, &info); | ||
| 2013 | if (error < 0) { | ||
| 2014 | /* | ||
| 2015 | * Not using any flavor of Elantech support, so clean up | ||
| 2016 | * SMbus breadcrumbs, if any. | ||
| 2017 | */ | ||
| 2018 | psmouse_smbus_cleanup(psmouse); | ||
| 2019 | goto init_fail; | ||
| 2020 | } | ||
| 2021 | |||
| 2022 | return PSMOUSE_ELANTECH; | ||
| 2023 | init_fail: | ||
| 2024 | psmouse_reset(psmouse); | ||
| 2025 | return error; | ||
| 2026 | } | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index e1cbf409d9c8..119727085a60 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
| @@ -107,6 +107,30 @@ | |||
| 107 | #define ETP_WEIGHT_VALUE 5 | 107 | #define ETP_WEIGHT_VALUE 5 |
| 108 | 108 | ||
| 109 | /* | 109 | /* |
| 110 | * Bus information on 3rd byte of query ETP_RESOLUTION_QUERY(0x04) | ||
| 111 | */ | ||
| 112 | #define ETP_BUS_PS2_ONLY 0 | ||
| 113 | #define ETP_BUS_SMB_ALERT_ONLY 1 | ||
| 114 | #define ETP_BUS_SMB_HST_NTFY_ONLY 2 | ||
| 115 | #define ETP_BUS_PS2_SMB_ALERT 3 | ||
| 116 | #define ETP_BUS_PS2_SMB_HST_NTFY 4 | ||
| 117 | |||
| 118 | /* | ||
| 119 | * New ICs are either using SMBus Host Notify or just plain PS2. | ||
| 120 | * | ||
| 121 | * ETP_FW_VERSION_QUERY is: | ||
| 122 | * Byte 1: | ||
| 123 | * - bit 0..3: IC BODY | ||
| 124 | * Byte 2: | ||
| 125 | * - bit 4: HiddenButton | ||
| 126 | * - bit 5: PS2_SMBUS_NOTIFY | ||
| 127 | * - bit 6: PS2CRCCheck | ||
| 128 | */ | ||
| 129 | #define ETP_NEW_IC_SMBUS_HOST_NOTIFY(fw_version) \ | ||
| 130 | ((((fw_version) & 0x0f2000) == 0x0f2000) && \ | ||
| 131 | ((fw_version) & 0x0000ff) > 0) | ||
| 132 | |||
| 133 | /* | ||
| 110 | * The base position for one finger, v4 hardware | 134 | * The base position for one finger, v4 hardware |
| 111 | */ | 135 | */ |
| 112 | struct finger_pos { | 136 | struct finger_pos { |
| @@ -114,6 +138,25 @@ struct finger_pos { | |||
| 114 | unsigned int y; | 138 | unsigned int y; |
| 115 | }; | 139 | }; |
| 116 | 140 | ||
| 141 | struct elantech_device_info { | ||
| 142 | unsigned char capabilities[3]; | ||
| 143 | unsigned char samples[3]; | ||
| 144 | unsigned char debug; | ||
| 145 | unsigned char hw_version; | ||
| 146 | unsigned int fw_version; | ||
| 147 | unsigned int x_res; | ||
| 148 | unsigned int y_res; | ||
| 149 | unsigned int bus; | ||
| 150 | bool paritycheck; | ||
| 151 | bool jumpy_cursor; | ||
| 152 | bool reports_pressure; | ||
| 153 | bool crc_enabled; | ||
| 154 | bool set_hw_resolution; | ||
| 155 | bool has_trackpoint; | ||
| 156 | int (*send_cmd)(struct psmouse *psmouse, unsigned char c, | ||
| 157 | unsigned char *param); | ||
| 158 | }; | ||
| 159 | |||
| 117 | struct elantech_data { | 160 | struct elantech_data { |
| 118 | struct input_dev *tp_dev; /* Relative device for trackpoint */ | 161 | struct input_dev *tp_dev; /* Relative device for trackpoint */ |
| 119 | char tp_phys[32]; | 162 | char tp_phys[32]; |
| @@ -127,27 +170,18 @@ struct elantech_data { | |||
| 127 | unsigned char reg_24; | 170 | unsigned char reg_24; |
| 128 | unsigned char reg_25; | 171 | unsigned char reg_25; |
| 129 | unsigned char reg_26; | 172 | unsigned char reg_26; |
| 130 | unsigned char debug; | ||
| 131 | unsigned char capabilities[3]; | ||
| 132 | unsigned char samples[3]; | ||
| 133 | bool paritycheck; | ||
| 134 | bool jumpy_cursor; | ||
| 135 | bool reports_pressure; | ||
| 136 | bool crc_enabled; | ||
| 137 | bool set_hw_resolution; | ||
| 138 | unsigned char hw_version; | ||
| 139 | unsigned int fw_version; | ||
| 140 | unsigned int single_finger_reports; | 173 | unsigned int single_finger_reports; |
| 141 | unsigned int y_max; | 174 | unsigned int y_max; |
| 142 | unsigned int width; | 175 | unsigned int width; |
| 143 | struct finger_pos mt[ETP_MAX_FINGERS]; | 176 | struct finger_pos mt[ETP_MAX_FINGERS]; |
| 144 | unsigned char parity[256]; | 177 | unsigned char parity[256]; |
| 145 | int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param); | 178 | struct elantech_device_info info; |
| 146 | void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); | 179 | void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate); |
| 147 | }; | 180 | }; |
| 148 | 181 | ||
| 149 | #ifdef CONFIG_MOUSE_PS2_ELANTECH | 182 | #ifdef CONFIG_MOUSE_PS2_ELANTECH |
| 150 | int elantech_detect(struct psmouse *psmouse, bool set_properties); | 183 | int elantech_detect(struct psmouse *psmouse, bool set_properties); |
| 184 | int elantech_init_ps2(struct psmouse *psmouse); | ||
| 151 | int elantech_init(struct psmouse *psmouse); | 185 | int elantech_init(struct psmouse *psmouse); |
| 152 | #else | 186 | #else |
| 153 | static inline int elantech_detect(struct psmouse *psmouse, bool set_properties) | 187 | static inline int elantech_detect(struct psmouse *psmouse, bool set_properties) |
| @@ -158,6 +192,19 @@ static inline int elantech_init(struct psmouse *psmouse) | |||
| 158 | { | 192 | { |
| 159 | return -ENOSYS; | 193 | return -ENOSYS; |
| 160 | } | 194 | } |
| 195 | static inline int elantech_init_ps2(struct psmouse *psmouse) | ||
| 196 | { | ||
| 197 | return -ENOSYS; | ||
| 198 | } | ||
| 161 | #endif /* CONFIG_MOUSE_PS2_ELANTECH */ | 199 | #endif /* CONFIG_MOUSE_PS2_ELANTECH */ |
| 162 | 200 | ||
| 201 | #if defined(CONFIG_MOUSE_PS2_ELANTECH_SMBUS) | ||
| 202 | int elantech_init_smbus(struct psmouse *psmouse); | ||
| 203 | #else | ||
| 204 | static inline int elantech_init_smbus(struct psmouse *psmouse) | ||
| 205 | { | ||
| 206 | return -ENOSYS; | ||
| 207 | } | ||
| 208 | #endif /* CONFIG_MOUSE_PS2_ELANTECH_SMBUS */ | ||
| 209 | |||
| 163 | #endif | 210 | #endif |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 8900c3166ebf..5ff5b1952be0 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -856,7 +856,17 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 856 | .name = "ETPS/2", | 856 | .name = "ETPS/2", |
| 857 | .alias = "elantech", | 857 | .alias = "elantech", |
| 858 | .detect = elantech_detect, | 858 | .detect = elantech_detect, |
| 859 | .init = elantech_init, | 859 | .init = elantech_init_ps2, |
| 860 | }, | ||
| 861 | #endif | ||
| 862 | #ifdef CONFIG_MOUSE_PS2_ELANTECH_SMBUS | ||
| 863 | { | ||
| 864 | .type = PSMOUSE_ELANTECH_SMBUS, | ||
| 865 | .name = "ETSMBus", | ||
| 866 | .alias = "elantech-smbus", | ||
| 867 | .detect = elantech_detect, | ||
| 868 | .init = elantech_init_smbus, | ||
| 869 | .smbus_companion = true, | ||
| 860 | }, | 870 | }, |
| 861 | #endif | 871 | #endif |
| 862 | #ifdef CONFIG_MOUSE_PS2_SENTELIC | 872 | #ifdef CONFIG_MOUSE_PS2_SENTELIC |
| @@ -1158,8 +1168,13 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
| 1158 | /* Try Elantech touchpad */ | 1168 | /* Try Elantech touchpad */ |
| 1159 | if (max_proto > PSMOUSE_IMEX && | 1169 | if (max_proto > PSMOUSE_IMEX && |
| 1160 | psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH, | 1170 | psmouse_try_protocol(psmouse, PSMOUSE_ELANTECH, |
| 1161 | &max_proto, set_properties, true)) { | 1171 | &max_proto, set_properties, false)) { |
| 1162 | return PSMOUSE_ELANTECH; | 1172 | if (!set_properties) |
| 1173 | return PSMOUSE_ELANTECH; | ||
| 1174 | |||
| 1175 | ret = elantech_init(psmouse); | ||
| 1176 | if (ret >= 0) | ||
| 1177 | return ret; | ||
| 1163 | } | 1178 | } |
| 1164 | 1179 | ||
| 1165 | if (max_proto > PSMOUSE_IMEX) { | 1180 | if (max_proto > PSMOUSE_IMEX) { |
diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c index c7ac24d119c1..852d4b486ddb 100644 --- a/drivers/input/mouse/psmouse-smbus.c +++ b/drivers/input/mouse/psmouse-smbus.c | |||
| @@ -23,6 +23,7 @@ struct psmouse_smbus_dev { | |||
| 23 | struct i2c_client *client; | 23 | struct i2c_client *client; |
| 24 | struct list_head node; | 24 | struct list_head node; |
| 25 | bool dead; | 25 | bool dead; |
| 26 | bool need_deactivate; | ||
| 26 | }; | 27 | }; |
| 27 | 28 | ||
| 28 | static LIST_HEAD(psmouse_smbus_list); | 29 | static LIST_HEAD(psmouse_smbus_list); |
| @@ -118,7 +119,10 @@ static psmouse_ret_t psmouse_smbus_process_byte(struct psmouse *psmouse) | |||
| 118 | 119 | ||
| 119 | static int psmouse_smbus_reconnect(struct psmouse *psmouse) | 120 | static int psmouse_smbus_reconnect(struct psmouse *psmouse) |
| 120 | { | 121 | { |
| 121 | psmouse_deactivate(psmouse); | 122 | struct psmouse_smbus_dev *smbdev = psmouse->private; |
| 123 | |||
| 124 | if (smbdev->need_deactivate) | ||
| 125 | psmouse_deactivate(psmouse); | ||
| 122 | 126 | ||
| 123 | return 0; | 127 | return 0; |
| 124 | } | 128 | } |
| @@ -225,6 +229,7 @@ void psmouse_smbus_cleanup(struct psmouse *psmouse) | |||
| 225 | int psmouse_smbus_init(struct psmouse *psmouse, | 229 | int psmouse_smbus_init(struct psmouse *psmouse, |
| 226 | const struct i2c_board_info *board, | 230 | const struct i2c_board_info *board, |
| 227 | const void *pdata, size_t pdata_size, | 231 | const void *pdata, size_t pdata_size, |
| 232 | bool need_deactivate, | ||
| 228 | bool leave_breadcrumbs) | 233 | bool leave_breadcrumbs) |
| 229 | { | 234 | { |
| 230 | struct psmouse_smbus_dev *smbdev; | 235 | struct psmouse_smbus_dev *smbdev; |
| @@ -236,13 +241,20 @@ int psmouse_smbus_init(struct psmouse *psmouse, | |||
| 236 | 241 | ||
| 237 | smbdev->psmouse = psmouse; | 242 | smbdev->psmouse = psmouse; |
| 238 | smbdev->board = *board; | 243 | smbdev->board = *board; |
| 244 | smbdev->need_deactivate = need_deactivate; | ||
| 239 | 245 | ||
| 240 | smbdev->board.platform_data = kmemdup(pdata, pdata_size, GFP_KERNEL); | 246 | if (pdata) { |
| 241 | if (!smbdev->board.platform_data) { | 247 | smbdev->board.platform_data = kmemdup(pdata, pdata_size, |
| 242 | kfree(smbdev); | 248 | GFP_KERNEL); |
| 243 | return -ENOMEM; | 249 | if (!smbdev->board.platform_data) { |
| 250 | kfree(smbdev); | ||
| 251 | return -ENOMEM; | ||
| 252 | } | ||
| 244 | } | 253 | } |
| 245 | 254 | ||
| 255 | if (need_deactivate) | ||
| 256 | psmouse_deactivate(psmouse); | ||
| 257 | |||
| 246 | psmouse->private = smbdev; | 258 | psmouse->private = smbdev; |
| 247 | psmouse->protocol_handler = psmouse_smbus_process_byte; | 259 | psmouse->protocol_handler = psmouse_smbus_process_byte; |
| 248 | psmouse->reconnect = psmouse_smbus_reconnect; | 260 | psmouse->reconnect = psmouse_smbus_reconnect; |
| @@ -250,8 +262,6 @@ int psmouse_smbus_init(struct psmouse *psmouse, | |||
| 250 | psmouse->disconnect = psmouse_smbus_disconnect; | 262 | psmouse->disconnect = psmouse_smbus_disconnect; |
| 251 | psmouse->resync_time = 0; | 263 | psmouse->resync_time = 0; |
| 252 | 264 | ||
| 253 | psmouse_deactivate(psmouse); | ||
| 254 | |||
| 255 | mutex_lock(&psmouse_smbus_mutex); | 265 | mutex_lock(&psmouse_smbus_mutex); |
| 256 | list_add_tail(&smbdev->node, &psmouse_smbus_list); | 266 | list_add_tail(&smbdev->node, &psmouse_smbus_list); |
| 257 | mutex_unlock(&psmouse_smbus_mutex); | 267 | mutex_unlock(&psmouse_smbus_mutex); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index 71ac50082c8b..64c3a5d3fb3e 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
| @@ -68,6 +68,7 @@ enum psmouse_type { | |||
| 68 | PSMOUSE_VMMOUSE, | 68 | PSMOUSE_VMMOUSE, |
| 69 | PSMOUSE_BYD, | 69 | PSMOUSE_BYD, |
| 70 | PSMOUSE_SYNAPTICS_SMBUS, | 70 | PSMOUSE_SYNAPTICS_SMBUS, |
| 71 | PSMOUSE_ELANTECH_SMBUS, | ||
| 71 | PSMOUSE_AUTO /* This one should always be last */ | 72 | PSMOUSE_AUTO /* This one should always be last */ |
| 72 | }; | 73 | }; |
| 73 | 74 | ||
| @@ -224,6 +225,7 @@ struct i2c_board_info; | |||
| 224 | int psmouse_smbus_init(struct psmouse *psmouse, | 225 | int psmouse_smbus_init(struct psmouse *psmouse, |
| 225 | const struct i2c_board_info *board, | 226 | const struct i2c_board_info *board, |
| 226 | const void *pdata, size_t pdata_size, | 227 | const void *pdata, size_t pdata_size, |
| 228 | bool need_deactivate, | ||
| 227 | bool leave_breadcrumbs); | 229 | bool leave_breadcrumbs); |
| 228 | void psmouse_smbus_cleanup(struct psmouse *psmouse); | 230 | void psmouse_smbus_cleanup(struct psmouse *psmouse); |
| 229 | 231 | ||
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 60f2c463d1cc..55d33500d55e 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -172,6 +172,12 @@ static const char * const smbus_pnp_ids[] = { | |||
| 172 | "LEN0048", /* X1 Carbon 3 */ | 172 | "LEN0048", /* X1 Carbon 3 */ |
| 173 | "LEN0046", /* X250 */ | 173 | "LEN0046", /* X250 */ |
| 174 | "LEN004a", /* W541 */ | 174 | "LEN004a", /* W541 */ |
| 175 | "LEN0071", /* T480 */ | ||
| 176 | "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */ | ||
| 177 | "LEN0073", /* X1 Carbon G5 (Elantech) */ | ||
| 178 | "LEN0092", /* X1 Carbon 6 */ | ||
| 179 | "LEN0096", /* X280 */ | ||
| 180 | "LEN0097", /* X280 -> ALPS trackpoint */ | ||
| 175 | "LEN200f", /* T450s */ | 181 | "LEN200f", /* T450s */ |
| 176 | NULL | 182 | NULL |
| 177 | }; | 183 | }; |
| @@ -1748,7 +1754,7 @@ static int synaptics_create_intertouch(struct psmouse *psmouse, | |||
| 1748 | }; | 1754 | }; |
| 1749 | 1755 | ||
| 1750 | return psmouse_smbus_init(psmouse, &intertouch_board, | 1756 | return psmouse_smbus_init(psmouse, &intertouch_board, |
| 1751 | &pdata, sizeof(pdata), | 1757 | &pdata, sizeof(pdata), true, |
| 1752 | leave_breadcrumbs); | 1758 | leave_breadcrumbs); |
| 1753 | } | 1759 | } |
| 1754 | 1760 | ||
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index f5954981e9ee..7d29053dfb0f 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c | |||
| @@ -636,9 +636,10 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr, | |||
| 636 | rdesc->num_registers = bitmap_weight(rdesc->presense_map, | 636 | rdesc->num_registers = bitmap_weight(rdesc->presense_map, |
| 637 | RMI_REG_DESC_PRESENSE_BITS); | 637 | RMI_REG_DESC_PRESENSE_BITS); |
| 638 | 638 | ||
| 639 | rdesc->registers = devm_kzalloc(&d->dev, rdesc->num_registers * | 639 | rdesc->registers = devm_kcalloc(&d->dev, |
| 640 | sizeof(struct rmi_register_desc_item), | 640 | rdesc->num_registers, |
| 641 | GFP_KERNEL); | 641 | sizeof(struct rmi_register_desc_item), |
| 642 | GFP_KERNEL); | ||
| 642 | if (!rdesc->registers) | 643 | if (!rdesc->registers) |
| 643 | return -ENOMEM; | 644 | return -ENOMEM; |
| 644 | 645 | ||
| @@ -1061,7 +1062,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data) | |||
| 1061 | data->num_of_irq_regs = (data->irq_count + 7) / 8; | 1062 | data->num_of_irq_regs = (data->irq_count + 7) / 8; |
| 1062 | 1063 | ||
| 1063 | size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); | 1064 | size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long); |
| 1064 | data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL); | 1065 | data->irq_memory = devm_kcalloc(dev, size, 4, GFP_KERNEL); |
| 1065 | if (!data->irq_memory) { | 1066 | if (!data->irq_memory) { |
| 1066 | dev_err(dev, "Failed to allocate memory for irq masks.\n"); | 1067 | dev_err(dev, "Failed to allocate memory for irq masks.\n"); |
| 1067 | return -ENOMEM; | 1068 | return -ENOMEM; |
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c index bc5e37f30ac1..12a233251793 100644 --- a/drivers/input/rmi4/rmi_f11.c +++ b/drivers/input/rmi4/rmi_f11.c | |||
| @@ -1190,14 +1190,15 @@ static int rmi_f11_initialize(struct rmi_function *fn) | |||
| 1190 | f11->sensor.attn_size += f11->sensor.nbr_fingers * 2; | 1190 | f11->sensor.attn_size += f11->sensor.nbr_fingers * 2; |
| 1191 | 1191 | ||
| 1192 | /* allocate the in-kernel tracking buffers */ | 1192 | /* allocate the in-kernel tracking buffers */ |
| 1193 | sensor->tracking_pos = devm_kzalloc(&fn->dev, | 1193 | sensor->tracking_pos = devm_kcalloc(&fn->dev, |
| 1194 | sizeof(struct input_mt_pos) * sensor->nbr_fingers, | 1194 | sensor->nbr_fingers, sizeof(struct input_mt_pos), |
| 1195 | GFP_KERNEL); | ||
| 1196 | sensor->tracking_slots = devm_kcalloc(&fn->dev, | ||
| 1197 | sensor->nbr_fingers, sizeof(int), GFP_KERNEL); | ||
| 1198 | sensor->objs = devm_kcalloc(&fn->dev, | ||
| 1199 | sensor->nbr_fingers, | ||
| 1200 | sizeof(struct rmi_2d_sensor_abs_object), | ||
| 1195 | GFP_KERNEL); | 1201 | GFP_KERNEL); |
| 1196 | sensor->tracking_slots = devm_kzalloc(&fn->dev, | ||
| 1197 | sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); | ||
| 1198 | sensor->objs = devm_kzalloc(&fn->dev, | ||
| 1199 | sizeof(struct rmi_2d_sensor_abs_object) | ||
| 1200 | * sensor->nbr_fingers, GFP_KERNEL); | ||
| 1201 | if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) | 1202 | if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) |
| 1202 | return -ENOMEM; | 1203 | return -ENOMEM; |
| 1203 | 1204 | ||
diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c index 8b0db086d68a..a3d1aa88f2a9 100644 --- a/drivers/input/rmi4/rmi_f12.c +++ b/drivers/input/rmi4/rmi_f12.c | |||
| @@ -502,14 +502,15 @@ static int rmi_f12_probe(struct rmi_function *fn) | |||
| 502 | } | 502 | } |
| 503 | 503 | ||
| 504 | /* allocate the in-kernel tracking buffers */ | 504 | /* allocate the in-kernel tracking buffers */ |
| 505 | sensor->tracking_pos = devm_kzalloc(&fn->dev, | 505 | sensor->tracking_pos = devm_kcalloc(&fn->dev, |
| 506 | sizeof(struct input_mt_pos) * sensor->nbr_fingers, | 506 | sensor->nbr_fingers, sizeof(struct input_mt_pos), |
| 507 | GFP_KERNEL); | ||
| 508 | sensor->tracking_slots = devm_kcalloc(&fn->dev, | ||
| 509 | sensor->nbr_fingers, sizeof(int), GFP_KERNEL); | ||
| 510 | sensor->objs = devm_kcalloc(&fn->dev, | ||
| 511 | sensor->nbr_fingers, | ||
| 512 | sizeof(struct rmi_2d_sensor_abs_object), | ||
| 507 | GFP_KERNEL); | 513 | GFP_KERNEL); |
| 508 | sensor->tracking_slots = devm_kzalloc(&fn->dev, | ||
| 509 | sizeof(int) * sensor->nbr_fingers, GFP_KERNEL); | ||
| 510 | sensor->objs = devm_kzalloc(&fn->dev, | ||
| 511 | sizeof(struct rmi_2d_sensor_abs_object) | ||
| 512 | * sensor->nbr_fingers, GFP_KERNEL); | ||
| 513 | if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) | 514 | if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs) |
| 514 | return -ENOMEM; | 515 | return -ENOMEM; |
| 515 | 516 | ||
diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c index 5343f2c08f15..e8a59d164019 100644 --- a/drivers/input/rmi4/rmi_f54.c +++ b/drivers/input/rmi4/rmi_f54.c | |||
| @@ -685,7 +685,7 @@ static int rmi_f54_probe(struct rmi_function *fn) | |||
| 685 | rx = f54->num_rx_electrodes; | 685 | rx = f54->num_rx_electrodes; |
| 686 | tx = f54->num_tx_electrodes; | 686 | tx = f54->num_tx_electrodes; |
| 687 | f54->report_data = devm_kzalloc(&fn->dev, | 687 | f54->report_data = devm_kzalloc(&fn->dev, |
| 688 | sizeof(u16) * tx * rx, | 688 | array3_size(tx, rx, sizeof(u16)), |
| 689 | GFP_KERNEL); | 689 | GFP_KERNEL); |
| 690 | if (f54->report_data == NULL) | 690 | if (f54->report_data == NULL) |
| 691 | return -ENOMEM; | 691 | return -ENOMEM; |
diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c index 082defc329a8..33b8c6e7ac0a 100644 --- a/drivers/input/rmi4/rmi_spi.c +++ b/drivers/input/rmi4/rmi_spi.c | |||
| @@ -69,7 +69,7 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) | |||
| 69 | buf_size = RMI_SPI_XFER_SIZE_LIMIT; | 69 | buf_size = RMI_SPI_XFER_SIZE_LIMIT; |
| 70 | 70 | ||
| 71 | tmp = rmi_spi->rx_buf; | 71 | tmp = rmi_spi->rx_buf; |
| 72 | buf = devm_kzalloc(&spi->dev, buf_size * 2, | 72 | buf = devm_kcalloc(&spi->dev, buf_size, 2, |
| 73 | GFP_KERNEL | GFP_DMA); | 73 | GFP_KERNEL | GFP_DMA); |
| 74 | if (!buf) | 74 | if (!buf) |
| 75 | return -ENOMEM; | 75 | return -ENOMEM; |
| @@ -96,9 +96,10 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len) | |||
| 96 | * per byte delays. | 96 | * per byte delays. |
| 97 | */ | 97 | */ |
| 98 | tmp = rmi_spi->rx_xfers; | 98 | tmp = rmi_spi->rx_xfers; |
| 99 | xfer_buf = devm_kzalloc(&spi->dev, | 99 | xfer_buf = devm_kcalloc(&spi->dev, |
| 100 | (rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count) | 100 | rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count, |
| 101 | * sizeof(struct spi_transfer), GFP_KERNEL); | 101 | sizeof(struct spi_transfer), |
| 102 | GFP_KERNEL); | ||
| 102 | if (!xfer_buf) | 103 | if (!xfer_buf) |
| 103 | return -ENOMEM; | 104 | return -ENOMEM; |
| 104 | 105 | ||
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 3e613afa10b4..32267c1afebc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -164,6 +164,17 @@ config TOUCHSCREEN_CHIPONE_ICN8318 | |||
| 164 | To compile this driver as a module, choose M here: the | 164 | To compile this driver as a module, choose M here: the |
| 165 | module will be called chipone_icn8318. | 165 | module will be called chipone_icn8318. |
| 166 | 166 | ||
| 167 | config TOUCHSCREEN_CHIPONE_ICN8505 | ||
| 168 | tristate "chipone icn8505 touchscreen controller" | ||
| 169 | depends on I2C && ACPI | ||
| 170 | help | ||
| 171 | Say Y here if you have a ChipOne icn8505 based I2C touchscreen. | ||
| 172 | |||
| 173 | If unsure, say N. | ||
| 174 | |||
| 175 | To compile this driver as a module, choose M here: the | ||
| 176 | module will be called chipone_icn8505. | ||
| 177 | |||
| 167 | config TOUCHSCREEN_CY8CTMG110 | 178 | config TOUCHSCREEN_CY8CTMG110 |
| 168 | tristate "cy8ctmg110 touchscreen" | 179 | tristate "cy8ctmg110 touchscreen" |
| 169 | depends on I2C | 180 | depends on I2C |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index dddae7973436..fd4fd32fb73f 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -19,6 +19,7 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o | |||
| 19 | obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o | 19 | obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o |
| 20 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o | 20 | obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o |
| 21 | obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o | 21 | obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o |
| 22 | obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505) += chipone_icn8505.o | ||
| 22 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o | 23 | obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o |
| 23 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o | 24 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o |
| 24 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o cyttsp_i2c_common.o | 25 | obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o cyttsp_i2c_common.o |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 09194721aed2..54fe190fd4bc 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -194,6 +194,8 @@ enum t100_type { | |||
| 194 | 194 | ||
| 195 | /* Delay times */ | 195 | /* Delay times */ |
| 196 | #define MXT_BACKUP_TIME 50 /* msec */ | 196 | #define MXT_BACKUP_TIME 50 /* msec */ |
| 197 | #define MXT_RESET_GPIO_TIME 20 /* msec */ | ||
| 198 | #define MXT_RESET_INVALID_CHG 100 /* msec */ | ||
| 197 | #define MXT_RESET_TIME 200 /* msec */ | 199 | #define MXT_RESET_TIME 200 /* msec */ |
| 198 | #define MXT_RESET_TIMEOUT 3000 /* msec */ | 200 | #define MXT_RESET_TIMEOUT 3000 /* msec */ |
| 199 | #define MXT_CRC_TIMEOUT 1000 /* msec */ | 201 | #define MXT_CRC_TIMEOUT 1000 /* msec */ |
| @@ -1208,7 +1210,7 @@ static int mxt_soft_reset(struct mxt_data *data) | |||
| 1208 | return ret; | 1210 | return ret; |
| 1209 | 1211 | ||
| 1210 | /* Ignore CHG line for 100ms after reset */ | 1212 | /* Ignore CHG line for 100ms after reset */ |
| 1211 | msleep(100); | 1213 | msleep(MXT_RESET_INVALID_CHG); |
| 1212 | 1214 | ||
| 1213 | mxt_acquire_irq(data); | 1215 | mxt_acquire_irq(data); |
| 1214 | 1216 | ||
| @@ -2999,142 +3001,6 @@ static int mxt_parse_device_properties(struct mxt_data *data) | |||
| 2999 | return 0; | 3001 | return 0; |
| 3000 | } | 3002 | } |
| 3001 | 3003 | ||
| 3002 | #ifdef CONFIG_ACPI | ||
| 3003 | |||
| 3004 | struct mxt_acpi_platform_data { | ||
| 3005 | const char *hid; | ||
| 3006 | const struct property_entry *props; | ||
| 3007 | }; | ||
| 3008 | |||
| 3009 | static unsigned int samus_touchpad_buttons[] = { | ||
| 3010 | KEY_RESERVED, | ||
| 3011 | KEY_RESERVED, | ||
| 3012 | KEY_RESERVED, | ||
| 3013 | BTN_LEFT | ||
| 3014 | }; | ||
| 3015 | |||
| 3016 | static const struct property_entry samus_touchpad_props[] = { | ||
| 3017 | PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", samus_touchpad_buttons), | ||
| 3018 | { } | ||
| 3019 | }; | ||
| 3020 | |||
| 3021 | static struct mxt_acpi_platform_data samus_platform_data[] = { | ||
| 3022 | { | ||
| 3023 | /* Touchpad */ | ||
| 3024 | .hid = "ATML0000", | ||
| 3025 | .props = samus_touchpad_props, | ||
| 3026 | }, | ||
| 3027 | { | ||
| 3028 | /* Touchscreen */ | ||
| 3029 | .hid = "ATML0001", | ||
| 3030 | }, | ||
| 3031 | { } | ||
| 3032 | }; | ||
| 3033 | |||
| 3034 | static unsigned int chromebook_tp_buttons[] = { | ||
| 3035 | KEY_RESERVED, | ||
| 3036 | KEY_RESERVED, | ||
| 3037 | KEY_RESERVED, | ||
| 3038 | KEY_RESERVED, | ||
| 3039 | KEY_RESERVED, | ||
| 3040 | BTN_LEFT | ||
| 3041 | }; | ||
| 3042 | |||
| 3043 | static const struct property_entry chromebook_tp_props[] = { | ||
| 3044 | PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_tp_buttons), | ||
| 3045 | { } | ||
| 3046 | }; | ||
| 3047 | |||
| 3048 | static struct mxt_acpi_platform_data chromebook_platform_data[] = { | ||
| 3049 | { | ||
| 3050 | /* Touchpad */ | ||
| 3051 | .hid = "ATML0000", | ||
| 3052 | .props = chromebook_tp_props, | ||
| 3053 | }, | ||
| 3054 | { | ||
| 3055 | /* Touchscreen */ | ||
| 3056 | .hid = "ATML0001", | ||
| 3057 | }, | ||
| 3058 | { } | ||
| 3059 | }; | ||
| 3060 | |||
| 3061 | static const struct dmi_system_id mxt_dmi_table[] = { | ||
| 3062 | { | ||
| 3063 | /* 2015 Google Pixel */ | ||
| 3064 | .ident = "Chromebook Pixel 2", | ||
| 3065 | .matches = { | ||
| 3066 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | ||
| 3067 | DMI_MATCH(DMI_PRODUCT_NAME, "Samus"), | ||
| 3068 | }, | ||
| 3069 | .driver_data = samus_platform_data, | ||
| 3070 | }, | ||
| 3071 | { | ||
| 3072 | /* Samsung Chromebook Pro */ | ||
| 3073 | .ident = "Samsung Chromebook Pro", | ||
| 3074 | .matches = { | ||
| 3075 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | ||
| 3076 | DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), | ||
| 3077 | }, | ||
| 3078 | .driver_data = samus_platform_data, | ||
| 3079 | }, | ||
| 3080 | { | ||
| 3081 | /* Other Google Chromebooks */ | ||
| 3082 | .ident = "Chromebook", | ||
| 3083 | .matches = { | ||
| 3084 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | ||
| 3085 | }, | ||
| 3086 | .driver_data = chromebook_platform_data, | ||
| 3087 | }, | ||
| 3088 | { } | ||
| 3089 | }; | ||
| 3090 | |||
| 3091 | static int mxt_prepare_acpi_properties(struct i2c_client *client) | ||
| 3092 | { | ||
| 3093 | struct acpi_device *adev; | ||
| 3094 | const struct dmi_system_id *system_id; | ||
| 3095 | const struct mxt_acpi_platform_data *acpi_pdata; | ||
| 3096 | |||
| 3097 | adev = ACPI_COMPANION(&client->dev); | ||
| 3098 | if (!adev) | ||
| 3099 | return -ENOENT; | ||
| 3100 | |||
| 3101 | system_id = dmi_first_match(mxt_dmi_table); | ||
| 3102 | if (!system_id) | ||
| 3103 | return -ENOENT; | ||
| 3104 | |||
| 3105 | acpi_pdata = system_id->driver_data; | ||
| 3106 | if (!acpi_pdata) | ||
| 3107 | return -ENOENT; | ||
| 3108 | |||
| 3109 | while (acpi_pdata->hid) { | ||
| 3110 | if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) { | ||
| 3111 | /* | ||
| 3112 | * Remove previously installed properties if we | ||
| 3113 | * are probing this device not for the very first | ||
| 3114 | * time. | ||
| 3115 | */ | ||
| 3116 | device_remove_properties(&client->dev); | ||
| 3117 | |||
| 3118 | /* | ||
| 3119 | * Now install the platform-specific properties | ||
| 3120 | * that are missing from ACPI. | ||
| 3121 | */ | ||
| 3122 | device_add_properties(&client->dev, acpi_pdata->props); | ||
| 3123 | break; | ||
| 3124 | } | ||
| 3125 | |||
| 3126 | acpi_pdata++; | ||
| 3127 | } | ||
| 3128 | |||
| 3129 | return 0; | ||
| 3130 | } | ||
| 3131 | #else | ||
| 3132 | static int mxt_prepare_acpi_properties(struct i2c_client *client) | ||
| 3133 | { | ||
| 3134 | return -ENOENT; | ||
| 3135 | } | ||
| 3136 | #endif | ||
| 3137 | |||
| 3138 | static const struct dmi_system_id chromebook_T9_suspend_dmi[] = { | 3004 | static const struct dmi_system_id chromebook_T9_suspend_dmi[] = { |
| 3139 | { | 3005 | { |
| 3140 | .matches = { | 3006 | .matches = { |
| @@ -3156,6 +3022,18 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 3156 | int error; | 3022 | int error; |
| 3157 | 3023 | ||
| 3158 | /* | 3024 | /* |
| 3025 | * Ignore devices that do not have device properties attached to | ||
| 3026 | * them, as we need help determining whether we are dealing with | ||
| 3027 | * touch screen or touchpad. | ||
| 3028 | * | ||
| 3029 | * So far on x86 the only users of Atmel touch controllers are | ||
| 3030 | * Chromebooks, and chromeos_laptop driver will ensure that | ||
| 3031 | * necessary properties are provided (if firmware does not do that). | ||
| 3032 | */ | ||
| 3033 | if (!device_property_present(&client->dev, "compatible")) | ||
| 3034 | return -ENXIO; | ||
| 3035 | |||
| 3036 | /* | ||
| 3159 | * Ignore ACPI devices representing bootloader mode. | 3037 | * Ignore ACPI devices representing bootloader mode. |
| 3160 | * | 3038 | * |
| 3161 | * This is a bit of a hack: Google Chromebook BIOS creates ACPI | 3039 | * This is a bit of a hack: Google Chromebook BIOS creates ACPI |
| @@ -3186,10 +3064,6 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 3186 | data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ? | 3064 | data->suspend_mode = dmi_check_system(chromebook_T9_suspend_dmi) ? |
| 3187 | MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP; | 3065 | MXT_SUSPEND_T9_CTRL : MXT_SUSPEND_DEEP_SLEEP; |
| 3188 | 3066 | ||
| 3189 | error = mxt_prepare_acpi_properties(client); | ||
| 3190 | if (error && error != -ENOENT) | ||
| 3191 | return error; | ||
| 3192 | |||
| 3193 | error = mxt_parse_device_properties(data); | 3067 | error = mxt_parse_device_properties(data); |
| 3194 | if (error) | 3068 | if (error) |
| 3195 | return error; | 3069 | return error; |
| @@ -3210,20 +3084,14 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
| 3210 | return error; | 3084 | return error; |
| 3211 | } | 3085 | } |
| 3212 | 3086 | ||
| 3087 | disable_irq(client->irq); | ||
| 3088 | |||
| 3213 | if (data->reset_gpio) { | 3089 | if (data->reset_gpio) { |
| 3214 | data->in_bootloader = true; | 3090 | msleep(MXT_RESET_GPIO_TIME); |
| 3215 | msleep(MXT_RESET_TIME); | ||
| 3216 | reinit_completion(&data->bl_completion); | ||
| 3217 | gpiod_set_value(data->reset_gpio, 1); | 3091 | gpiod_set_value(data->reset_gpio, 1); |
| 3218 | error = mxt_wait_for_completion(data, &data->bl_completion, | 3092 | msleep(MXT_RESET_INVALID_CHG); |
| 3219 | MXT_RESET_TIMEOUT); | ||
| 3220 | if (error) | ||
| 3221 | return error; | ||
| 3222 | data->in_bootloader = false; | ||
| 3223 | } | 3093 | } |
| 3224 | 3094 | ||
| 3225 | disable_irq(client->irq); | ||
| 3226 | |||
| 3227 | error = mxt_initialize(data); | 3095 | error = mxt_initialize(data); |
| 3228 | if (error) | 3096 | if (error) |
| 3229 | return error; | 3097 | return error; |
diff --git a/drivers/input/touchscreen/chipone_icn8505.c b/drivers/input/touchscreen/chipone_icn8505.c new file mode 100644 index 000000000000..c768186ce856 --- /dev/null +++ b/drivers/input/touchscreen/chipone_icn8505.c | |||
| @@ -0,0 +1,520 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Driver for ChipOne icn8505 i2c touchscreen controller | ||
| 4 | * | ||
| 5 | * Copyright (c) 2015-2018 Red Hat Inc. | ||
| 6 | * | ||
| 7 | * Red Hat authors: | ||
| 8 | * Hans de Goede <hdegoede@redhat.com> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <asm/unaligned.h> | ||
| 12 | #include <linux/acpi.h> | ||
| 13 | #include <linux/crc32.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/firmware.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/i2c.h> | ||
| 18 | #include <linux/input.h> | ||
| 19 | #include <linux/input/mt.h> | ||
| 20 | #include <linux/input/touchscreen.h> | ||
| 21 | #include <linux/module.h> | ||
| 22 | |||
| 23 | /* Normal operation mode defines */ | ||
| 24 | #define ICN8505_REG_ADDR_WIDTH 16 | ||
| 25 | |||
| 26 | #define ICN8505_REG_POWER 0x0004 | ||
| 27 | #define ICN8505_REG_TOUCHDATA 0x1000 | ||
| 28 | #define ICN8505_REG_CONFIGDATA 0x8000 | ||
| 29 | |||
| 30 | /* ICN8505_REG_POWER commands */ | ||
| 31 | #define ICN8505_POWER_ACTIVE 0x00 | ||
| 32 | #define ICN8505_POWER_MONITOR 0x01 | ||
| 33 | #define ICN8505_POWER_HIBERNATE 0x02 | ||
| 34 | /* | ||
| 35 | * The Android driver uses these to turn on/off the charger filter, but the | ||
| 36 | * filter is way too aggressive making e.g. onscreen keyboards unusable. | ||
| 37 | */ | ||
| 38 | #define ICN8505_POWER_ENA_CHARGER_MODE 0x55 | ||
| 39 | #define ICN8505_POWER_DIS_CHARGER_MODE 0x66 | ||
| 40 | |||
| 41 | #define ICN8505_MAX_TOUCHES 10 | ||
| 42 | |||
| 43 | /* Programming mode defines */ | ||
| 44 | #define ICN8505_PROG_I2C_ADDR 0x30 | ||
| 45 | #define ICN8505_PROG_REG_ADDR_WIDTH 24 | ||
| 46 | |||
| 47 | #define MAX_FW_UPLOAD_TRIES 3 | ||
| 48 | |||
| 49 | struct icn8505_touch { | ||
| 50 | u8 slot; | ||
| 51 | u8 x[2]; | ||
| 52 | u8 y[2]; | ||
| 53 | u8 pressure; /* Seems more like finger width then pressure really */ | ||
| 54 | u8 event; | ||
| 55 | /* The difference between 2 and 3 is unclear */ | ||
| 56 | #define ICN8505_EVENT_NO_DATA 1 /* No finger seen yet since wakeup */ | ||
| 57 | #define ICN8505_EVENT_UPDATE1 2 /* New or updated coordinates */ | ||
| 58 | #define ICN8505_EVENT_UPDATE2 3 /* New or updated coordinates */ | ||
| 59 | #define ICN8505_EVENT_END 4 /* Finger lifted */ | ||
| 60 | } __packed; | ||
| 61 | |||
| 62 | struct icn8505_touch_data { | ||
| 63 | u8 softbutton; | ||
| 64 | u8 touch_count; | ||
| 65 | struct icn8505_touch touches[ICN8505_MAX_TOUCHES]; | ||
| 66 | } __packed; | ||
| 67 | |||
| 68 | struct icn8505_data { | ||
| 69 | struct i2c_client *client; | ||
| 70 | struct input_dev *input; | ||
| 71 | struct gpio_desc *wake_gpio; | ||
| 72 | struct touchscreen_properties prop; | ||
| 73 | char firmware_name[32]; | ||
| 74 | }; | ||
| 75 | |||
| 76 | static int icn8505_read_xfer(struct i2c_client *client, u16 i2c_addr, | ||
| 77 | int reg_addr, int reg_addr_width, | ||
| 78 | void *data, int len, bool silent) | ||
| 79 | { | ||
| 80 | u8 buf[3]; | ||
| 81 | int i, ret; | ||
| 82 | struct i2c_msg msg[2] = { | ||
| 83 | { | ||
| 84 | .addr = i2c_addr, | ||
| 85 | .buf = buf, | ||
| 86 | .len = reg_addr_width / 8, | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | .addr = i2c_addr, | ||
| 90 | .flags = I2C_M_RD, | ||
| 91 | .buf = data, | ||
| 92 | .len = len, | ||
| 93 | } | ||
| 94 | }; | ||
| 95 | |||
| 96 | for (i = 0; i < (reg_addr_width / 8); i++) | ||
| 97 | buf[i] = (reg_addr >> (reg_addr_width - (i + 1) * 8)) & 0xff; | ||
| 98 | |||
| 99 | ret = i2c_transfer(client->adapter, msg, 2); | ||
| 100 | if (ret != ARRAY_SIZE(msg)) { | ||
| 101 | if (ret >= 0) | ||
| 102 | ret = -EIO; | ||
| 103 | if (!silent) | ||
| 104 | dev_err(&client->dev, | ||
| 105 | "Error reading addr %#x reg %#x: %d\n", | ||
| 106 | i2c_addr, reg_addr, ret); | ||
| 107 | return ret; | ||
| 108 | } | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int icn8505_write_xfer(struct i2c_client *client, u16 i2c_addr, | ||
| 114 | int reg_addr, int reg_addr_width, | ||
| 115 | const void *data, int len, bool silent) | ||
| 116 | { | ||
| 117 | u8 buf[3 + 32]; /* 3 bytes for 24 bit reg-addr + 32 bytes max len */ | ||
| 118 | int i, ret; | ||
| 119 | struct i2c_msg msg = { | ||
| 120 | .addr = i2c_addr, | ||
| 121 | .buf = buf, | ||
| 122 | .len = reg_addr_width / 8 + len, | ||
| 123 | }; | ||
| 124 | |||
| 125 | if (WARN_ON(len > 32)) | ||
| 126 | return -EINVAL; | ||
| 127 | |||
| 128 | for (i = 0; i < (reg_addr_width / 8); i++) | ||
| 129 | buf[i] = (reg_addr >> (reg_addr_width - (i + 1) * 8)) & 0xff; | ||
| 130 | |||
| 131 | memcpy(buf + reg_addr_width / 8, data, len); | ||
| 132 | |||
| 133 | ret = i2c_transfer(client->adapter, &msg, 1); | ||
| 134 | if (ret != 1) { | ||
| 135 | if (ret >= 0) | ||
| 136 | ret = -EIO; | ||
| 137 | if (!silent) | ||
| 138 | dev_err(&client->dev, | ||
| 139 | "Error writing addr %#x reg %#x: %d\n", | ||
| 140 | i2c_addr, reg_addr, ret); | ||
| 141 | return ret; | ||
| 142 | } | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int icn8505_read_data(struct icn8505_data *icn8505, int reg, | ||
| 148 | void *buf, int len) | ||
| 149 | { | ||
| 150 | return icn8505_read_xfer(icn8505->client, icn8505->client->addr, reg, | ||
| 151 | ICN8505_REG_ADDR_WIDTH, buf, len, false); | ||
| 152 | } | ||
| 153 | |||
| 154 | static int icn8505_read_reg_silent(struct icn8505_data *icn8505, int reg) | ||
| 155 | { | ||
| 156 | u8 buf; | ||
| 157 | int error; | ||
| 158 | |||
| 159 | error = icn8505_read_xfer(icn8505->client, icn8505->client->addr, reg, | ||
| 160 | ICN8505_REG_ADDR_WIDTH, &buf, 1, true); | ||
| 161 | if (error) | ||
| 162 | return error; | ||
| 163 | |||
| 164 | return buf; | ||
| 165 | } | ||
| 166 | |||
| 167 | static int icn8505_write_reg(struct icn8505_data *icn8505, int reg, u8 val) | ||
| 168 | { | ||
| 169 | return icn8505_write_xfer(icn8505->client, icn8505->client->addr, reg, | ||
| 170 | ICN8505_REG_ADDR_WIDTH, &val, 1, false); | ||
| 171 | } | ||
| 172 | |||
| 173 | static int icn8505_read_prog_data(struct icn8505_data *icn8505, int reg, | ||
| 174 | void *buf, int len) | ||
| 175 | { | ||
| 176 | return icn8505_read_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg, | ||
| 177 | ICN8505_PROG_REG_ADDR_WIDTH, buf, len, false); | ||
| 178 | } | ||
| 179 | |||
| 180 | static int icn8505_write_prog_data(struct icn8505_data *icn8505, int reg, | ||
| 181 | const void *buf, int len) | ||
| 182 | { | ||
| 183 | return icn8505_write_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg, | ||
| 184 | ICN8505_PROG_REG_ADDR_WIDTH, buf, len, false); | ||
| 185 | } | ||
| 186 | |||
| 187 | static int icn8505_write_prog_reg(struct icn8505_data *icn8505, int reg, u8 val) | ||
| 188 | { | ||
| 189 | return icn8505_write_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg, | ||
| 190 | ICN8505_PROG_REG_ADDR_WIDTH, &val, 1, false); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* | ||
| 194 | * Note this function uses a number of magic register addresses and values, | ||
| 195 | * there are deliberately no defines for these because the algorithm is taken | ||
| 196 | * from the icn85xx Android driver and I do not want to make up possibly wrong | ||
| 197 | * names for the addresses and/or values. | ||
| 198 | */ | ||
| 199 | static int icn8505_try_fw_upload(struct icn8505_data *icn8505, | ||
| 200 | const struct firmware *fw) | ||
| 201 | { | ||
| 202 | struct device *dev = &icn8505->client->dev; | ||
| 203 | size_t offset, count; | ||
| 204 | int error; | ||
| 205 | u8 buf[4]; | ||
| 206 | u32 crc; | ||
| 207 | |||
| 208 | /* Put the controller in programming mode */ | ||
| 209 | error = icn8505_write_prog_reg(icn8505, 0xcc3355, 0x5a); | ||
| 210 | if (error) | ||
| 211 | return error; | ||
| 212 | |||
| 213 | usleep_range(2000, 5000); | ||
| 214 | |||
| 215 | error = icn8505_write_prog_reg(icn8505, 0x040400, 0x01); | ||
| 216 | if (error) | ||
| 217 | return error; | ||
| 218 | |||
| 219 | usleep_range(2000, 5000); | ||
| 220 | |||
| 221 | error = icn8505_read_prog_data(icn8505, 0x040002, buf, 1); | ||
| 222 | if (error) | ||
| 223 | return error; | ||
| 224 | |||
| 225 | if (buf[0] != 0x85) { | ||
| 226 | dev_err(dev, "Failed to enter programming mode\n"); | ||
| 227 | return -ENODEV; | ||
| 228 | } | ||
| 229 | |||
| 230 | usleep_range(1000, 5000); | ||
| 231 | |||
| 232 | /* Enable CRC mode */ | ||
| 233 | error = icn8505_write_prog_reg(icn8505, 0x40028, 1); | ||
| 234 | if (error) | ||
| 235 | return error; | ||
| 236 | |||
| 237 | /* Send the firmware to SRAM */ | ||
| 238 | for (offset = 0; offset < fw->size; offset += count) { | ||
| 239 | count = min_t(size_t, fw->size - offset, 32); | ||
| 240 | error = icn8505_write_prog_data(icn8505, offset, | ||
| 241 | fw->data + offset, count); | ||
| 242 | if (error) | ||
| 243 | return error; | ||
| 244 | } | ||
| 245 | |||
| 246 | /* Disable CRC mode */ | ||
| 247 | error = icn8505_write_prog_reg(icn8505, 0x40028, 0); | ||
| 248 | if (error) | ||
| 249 | return error; | ||
| 250 | |||
| 251 | /* Get and check length and CRC */ | ||
| 252 | error = icn8505_read_prog_data(icn8505, 0x40034, buf, 2); | ||
| 253 | if (error) | ||
| 254 | return error; | ||
| 255 | |||
| 256 | if (get_unaligned_le16(buf) != fw->size) { | ||
| 257 | dev_warn(dev, "Length mismatch after uploading fw\n"); | ||
| 258 | return -EIO; | ||
| 259 | } | ||
| 260 | |||
| 261 | error = icn8505_read_prog_data(icn8505, 0x4002c, buf, 4); | ||
| 262 | if (error) | ||
| 263 | return error; | ||
| 264 | |||
| 265 | crc = crc32_be(0, fw->data, fw->size); | ||
| 266 | if (get_unaligned_le32(buf) != crc) { | ||
| 267 | dev_warn(dev, "CRC mismatch after uploading fw\n"); | ||
| 268 | return -EIO; | ||
| 269 | } | ||
| 270 | |||
| 271 | /* Boot controller from SRAM */ | ||
| 272 | error = icn8505_write_prog_reg(icn8505, 0x40400, 0x03); | ||
| 273 | if (error) | ||
| 274 | return error; | ||
| 275 | |||
| 276 | usleep_range(2000, 5000); | ||
| 277 | return 0; | ||
| 278 | } | ||
| 279 | |||
| 280 | static int icn8505_upload_fw(struct icn8505_data *icn8505) | ||
| 281 | { | ||
| 282 | struct device *dev = &icn8505->client->dev; | ||
| 283 | const struct firmware *fw; | ||
| 284 | int i, error; | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Always load the firmware, even if we don't need it at boot, we | ||
| 288 | * we may need it at resume. Having loaded it once will make the | ||
| 289 | * firmware class code cache it at suspend/resume. | ||
| 290 | */ | ||
| 291 | error = request_firmware(&fw, icn8505->firmware_name, dev); | ||
| 292 | if (error) { | ||
| 293 | dev_err(dev, "Firmware request error %d\n", error); | ||
| 294 | return error; | ||
| 295 | } | ||
| 296 | |||
| 297 | /* Check if the controller is not already up and running */ | ||
| 298 | if (icn8505_read_reg_silent(icn8505, 0x000a) == 0x85) | ||
| 299 | goto success; | ||
| 300 | |||
| 301 | for (i = 1; i <= MAX_FW_UPLOAD_TRIES; i++) { | ||
| 302 | error = icn8505_try_fw_upload(icn8505, fw); | ||
| 303 | if (!error) | ||
| 304 | goto success; | ||
| 305 | |||
| 306 | dev_err(dev, "Failed to upload firmware: %d (attempt %d/%d)\n", | ||
| 307 | error, i, MAX_FW_UPLOAD_TRIES); | ||
| 308 | usleep_range(2000, 5000); | ||
| 309 | } | ||
| 310 | |||
| 311 | success: | ||
| 312 | release_firmware(fw); | ||
| 313 | return error; | ||
| 314 | } | ||
| 315 | |||
| 316 | static bool icn8505_touch_active(u8 event) | ||
| 317 | { | ||
| 318 | return event == ICN8505_EVENT_UPDATE1 || | ||
| 319 | event == ICN8505_EVENT_UPDATE2; | ||
| 320 | } | ||
| 321 | |||
| 322 | static irqreturn_t icn8505_irq(int irq, void *dev_id) | ||
| 323 | { | ||
| 324 | struct icn8505_data *icn8505 = dev_id; | ||
| 325 | struct device *dev = &icn8505->client->dev; | ||
| 326 | struct icn8505_touch_data touch_data; | ||
| 327 | int i, error; | ||
| 328 | |||
| 329 | error = icn8505_read_data(icn8505, ICN8505_REG_TOUCHDATA, | ||
| 330 | &touch_data, sizeof(touch_data)); | ||
| 331 | if (error) { | ||
| 332 | dev_err(dev, "Error reading touch data: %d\n", error); | ||
| 333 | return IRQ_HANDLED; | ||
| 334 | } | ||
| 335 | |||
| 336 | if (touch_data.touch_count > ICN8505_MAX_TOUCHES) { | ||
| 337 | dev_warn(dev, "Too many touches %d > %d\n", | ||
| 338 | touch_data.touch_count, ICN8505_MAX_TOUCHES); | ||
| 339 | touch_data.touch_count = ICN8505_MAX_TOUCHES; | ||
| 340 | } | ||
| 341 | |||
| 342 | for (i = 0; i < touch_data.touch_count; i++) { | ||
| 343 | struct icn8505_touch *touch = &touch_data.touches[i]; | ||
| 344 | bool act = icn8505_touch_active(touch->event); | ||
| 345 | |||
| 346 | input_mt_slot(icn8505->input, touch->slot); | ||
| 347 | input_mt_report_slot_state(icn8505->input, MT_TOOL_FINGER, act); | ||
| 348 | if (!act) | ||
| 349 | continue; | ||
| 350 | |||
| 351 | touchscreen_report_pos(icn8505->input, &icn8505->prop, | ||
| 352 | get_unaligned_le16(touch->x), | ||
| 353 | get_unaligned_le16(touch->y), | ||
| 354 | true); | ||
| 355 | } | ||
| 356 | |||
| 357 | input_mt_sync_frame(icn8505->input); | ||
| 358 | input_report_key(icn8505->input, KEY_LEFTMETA, | ||
| 359 | touch_data.softbutton == 1); | ||
| 360 | input_sync(icn8505->input); | ||
| 361 | |||
| 362 | return IRQ_HANDLED; | ||
| 363 | } | ||
| 364 | |||
| 365 | static int icn8505_probe_acpi(struct icn8505_data *icn8505, struct device *dev) | ||
| 366 | { | ||
| 367 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
| 368 | const char *subsys = "unknown"; | ||
| 369 | struct acpi_device *adev; | ||
| 370 | union acpi_object *obj; | ||
| 371 | acpi_status status; | ||
| 372 | |||
| 373 | adev = ACPI_COMPANION(dev); | ||
| 374 | if (!adev) | ||
| 375 | return -ENODEV; | ||
| 376 | |||
| 377 | status = acpi_evaluate_object(adev->handle, "_SUB", NULL, &buffer); | ||
| 378 | if (ACPI_SUCCESS(status)) { | ||
| 379 | obj = buffer.pointer; | ||
| 380 | if (obj->type == ACPI_TYPE_STRING) | ||
| 381 | subsys = obj->string.pointer; | ||
| 382 | else | ||
| 383 | dev_warn(dev, "Warning ACPI _SUB did not return a string\n"); | ||
| 384 | } else { | ||
| 385 | dev_warn(dev, "Warning ACPI _SUB failed: %#x\n", status); | ||
| 386 | buffer.pointer = NULL; | ||
| 387 | } | ||
| 388 | |||
| 389 | snprintf(icn8505->firmware_name, sizeof(icn8505->firmware_name), | ||
| 390 | "chipone/icn8505-%s.fw", subsys); | ||
| 391 | |||
| 392 | kfree(buffer.pointer); | ||
| 393 | return 0; | ||
| 394 | } | ||
| 395 | |||
| 396 | static int icn8505_probe(struct i2c_client *client) | ||
| 397 | { | ||
| 398 | struct device *dev = &client->dev; | ||
| 399 | struct icn8505_data *icn8505; | ||
| 400 | struct input_dev *input; | ||
| 401 | __le16 resolution[2]; | ||
| 402 | int error; | ||
| 403 | |||
| 404 | if (!client->irq) { | ||
| 405 | dev_err(dev, "No irq specified\n"); | ||
| 406 | return -EINVAL; | ||
| 407 | } | ||
| 408 | |||
| 409 | icn8505 = devm_kzalloc(dev, sizeof(*icn8505), GFP_KERNEL); | ||
| 410 | if (!icn8505) | ||
| 411 | return -ENOMEM; | ||
| 412 | |||
| 413 | input = devm_input_allocate_device(dev); | ||
| 414 | if (!input) | ||
| 415 | return -ENOMEM; | ||
| 416 | |||
| 417 | input->name = client->name; | ||
| 418 | input->id.bustype = BUS_I2C; | ||
| 419 | |||
| 420 | input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); | ||
| 421 | input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); | ||
| 422 | input_set_capability(input, EV_KEY, KEY_LEFTMETA); | ||
| 423 | |||
| 424 | icn8505->client = client; | ||
| 425 | icn8505->input = input; | ||
| 426 | input_set_drvdata(input, icn8505); | ||
| 427 | |||
| 428 | error = icn8505_probe_acpi(icn8505, dev); | ||
| 429 | if (error) | ||
| 430 | return error; | ||
| 431 | |||
| 432 | error = icn8505_upload_fw(icn8505); | ||
| 433 | if (error) | ||
| 434 | return error; | ||
| 435 | |||
| 436 | error = icn8505_read_data(icn8505, ICN8505_REG_CONFIGDATA, | ||
| 437 | resolution, sizeof(resolution)); | ||
| 438 | if (error) { | ||
| 439 | dev_err(dev, "Error reading resolution: %d\n", error); | ||
| 440 | return error; | ||
| 441 | } | ||
| 442 | |||
| 443 | input_set_abs_params(input, ABS_MT_POSITION_X, 0, | ||
| 444 | le16_to_cpu(resolution[0]) - 1, 0, 0); | ||
| 445 | input_set_abs_params(input, ABS_MT_POSITION_Y, 0, | ||
| 446 | le16_to_cpu(resolution[1]) - 1, 0, 0); | ||
| 447 | |||
| 448 | touchscreen_parse_properties(input, true, &icn8505->prop); | ||
| 449 | if (!input_abs_get_max(input, ABS_MT_POSITION_X) || | ||
| 450 | !input_abs_get_max(input, ABS_MT_POSITION_Y)) { | ||
| 451 | dev_err(dev, "Error touchscreen-size-x and/or -y missing\n"); | ||
| 452 | return -EINVAL; | ||
| 453 | } | ||
| 454 | |||
| 455 | error = input_mt_init_slots(input, ICN8505_MAX_TOUCHES, | ||
| 456 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); | ||
| 457 | if (error) | ||
| 458 | return error; | ||
| 459 | |||
| 460 | error = devm_request_threaded_irq(dev, client->irq, NULL, icn8505_irq, | ||
| 461 | IRQF_ONESHOT, client->name, icn8505); | ||
| 462 | if (error) { | ||
| 463 | dev_err(dev, "Error requesting irq: %d\n", error); | ||
| 464 | return error; | ||
| 465 | } | ||
| 466 | |||
| 467 | error = input_register_device(input); | ||
| 468 | if (error) | ||
| 469 | return error; | ||
| 470 | |||
| 471 | i2c_set_clientdata(client, icn8505); | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | static int __maybe_unused icn8505_suspend(struct device *dev) | ||
| 476 | { | ||
| 477 | struct icn8505_data *icn8505 = i2c_get_clientdata(to_i2c_client(dev)); | ||
| 478 | |||
| 479 | disable_irq(icn8505->client->irq); | ||
| 480 | |||
| 481 | icn8505_write_reg(icn8505, ICN8505_REG_POWER, ICN8505_POWER_HIBERNATE); | ||
| 482 | |||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 486 | static int __maybe_unused icn8505_resume(struct device *dev) | ||
| 487 | { | ||
| 488 | struct icn8505_data *icn8505 = i2c_get_clientdata(to_i2c_client(dev)); | ||
| 489 | int error; | ||
| 490 | |||
| 491 | error = icn8505_upload_fw(icn8505); | ||
| 492 | if (error) | ||
| 493 | return error; | ||
| 494 | |||
| 495 | enable_irq(icn8505->client->irq); | ||
| 496 | return 0; | ||
| 497 | } | ||
| 498 | |||
| 499 | static SIMPLE_DEV_PM_OPS(icn8505_pm_ops, icn8505_suspend, icn8505_resume); | ||
| 500 | |||
| 501 | static const struct acpi_device_id icn8505_acpi_match[] = { | ||
| 502 | { "CHPN0001" }, | ||
| 503 | { } | ||
| 504 | }; | ||
| 505 | MODULE_DEVICE_TABLE(acpi, icn8505_acpi_match); | ||
| 506 | |||
| 507 | static struct i2c_driver icn8505_driver = { | ||
| 508 | .driver = { | ||
| 509 | .name = "chipone_icn8505", | ||
| 510 | .pm = &icn8505_pm_ops, | ||
| 511 | .acpi_match_table = icn8505_acpi_match, | ||
| 512 | }, | ||
| 513 | .probe_new = icn8505_probe, | ||
| 514 | }; | ||
| 515 | |||
| 516 | module_i2c_driver(icn8505_driver); | ||
| 517 | |||
| 518 | MODULE_DESCRIPTION("ChipOne icn8505 I2C Touchscreen Driver"); | ||
| 519 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | ||
| 520 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 9736c83dd418..f2d9c2c41885 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c | |||
| @@ -933,6 +933,7 @@ MODULE_DEVICE_TABLE(i2c, goodix_ts_id); | |||
| 933 | #ifdef CONFIG_ACPI | 933 | #ifdef CONFIG_ACPI |
| 934 | static const struct acpi_device_id goodix_acpi_match[] = { | 934 | static const struct acpi_device_id goodix_acpi_match[] = { |
| 935 | { "GDIX1001", 0 }, | 935 | { "GDIX1001", 0 }, |
| 936 | { "GDIX1002", 0 }, | ||
| 936 | { } | 937 | { } |
| 937 | }; | 938 | }; |
| 938 | MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); | 939 | MODULE_DEVICE_TABLE(acpi, goodix_acpi_match); |
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index bd5352824f77..c179060525ae 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | * found in Gateway AOL Connected Touchpad computers. | 17 | * found in Gateway AOL Connected Touchpad computers. |
| 18 | * | 18 | * |
| 19 | * Documentation for ICS MK712 can be found at: | 19 | * Documentation for ICS MK712 can be found at: |
| 20 | * http://www.idt.com/products/getDoc.cfm?docID=18713923 | 20 | * https://www.idt.com/general-parts/mk712-touch-screen-controller |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | /* | 23 | /* |
diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index f1043ae71dcc..b86c1e5fbc11 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #define SEQ_SETTLE 275 | 34 | #define SEQ_SETTLE 275 |
| 35 | #define MAX_12BIT ((1 << 12) - 1) | 35 | #define MAX_12BIT ((1 << 12) - 1) |
| 36 | 36 | ||
| 37 | #define TSC_IRQENB_MASK (IRQENB_FIFO0THRES | IRQENB_EOS | IRQENB_HW_PEN) | ||
| 38 | |||
| 37 | static const int config_pins[] = { | 39 | static const int config_pins[] = { |
| 38 | STEPCONFIG_XPP, | 40 | STEPCONFIG_XPP, |
| 39 | STEPCONFIG_XNN, | 41 | STEPCONFIG_XNN, |
| @@ -274,6 +276,7 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
| 274 | if (status & IRQENB_HW_PEN) { | 276 | if (status & IRQENB_HW_PEN) { |
| 275 | ts_dev->pen_down = true; | 277 | ts_dev->pen_down = true; |
| 276 | irqclr |= IRQENB_HW_PEN; | 278 | irqclr |= IRQENB_HW_PEN; |
| 279 | pm_stay_awake(ts_dev->mfd_tscadc->dev); | ||
| 277 | } | 280 | } |
| 278 | 281 | ||
| 279 | if (status & IRQENB_PENUP) { | 282 | if (status & IRQENB_PENUP) { |
| @@ -283,6 +286,7 @@ static irqreturn_t titsc_irq(int irq, void *dev) | |||
| 283 | input_report_key(input_dev, BTN_TOUCH, 0); | 286 | input_report_key(input_dev, BTN_TOUCH, 0); |
| 284 | input_report_abs(input_dev, ABS_PRESSURE, 0); | 287 | input_report_abs(input_dev, ABS_PRESSURE, 0); |
| 285 | input_sync(input_dev); | 288 | input_sync(input_dev); |
| 289 | pm_relax(ts_dev->mfd_tscadc->dev); | ||
| 286 | } else { | 290 | } else { |
| 287 | ts_dev->pen_down = true; | 291 | ts_dev->pen_down = true; |
| 288 | } | 292 | } |
| @@ -432,6 +436,7 @@ static int titsc_probe(struct platform_device *pdev) | |||
| 432 | goto err_free_mem; | 436 | goto err_free_mem; |
| 433 | } | 437 | } |
| 434 | 438 | ||
| 439 | titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK); | ||
| 435 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); | 440 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); |
| 436 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS); | 441 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS); |
| 437 | err = titsc_config_wires(ts_dev); | 442 | err = titsc_config_wires(ts_dev); |
| @@ -495,6 +500,7 @@ static int __maybe_unused titsc_suspend(struct device *dev) | |||
| 495 | 500 | ||
| 496 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); | 501 | tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); |
| 497 | if (device_may_wakeup(tscadc_dev->dev)) { | 502 | if (device_may_wakeup(tscadc_dev->dev)) { |
| 503 | titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK); | ||
| 498 | idle = titsc_readl(ts_dev, REG_IRQENABLE); | 504 | idle = titsc_readl(ts_dev, REG_IRQENABLE); |
| 499 | titsc_writel(ts_dev, REG_IRQENABLE, | 505 | titsc_writel(ts_dev, REG_IRQENABLE, |
| 500 | (idle | IRQENB_HW_PEN)); | 506 | (idle | IRQENB_HW_PEN)); |
| @@ -513,6 +519,7 @@ static int __maybe_unused titsc_resume(struct device *dev) | |||
| 513 | titsc_writel(ts_dev, REG_IRQWAKEUP, | 519 | titsc_writel(ts_dev, REG_IRQWAKEUP, |
| 514 | 0x00); | 520 | 0x00); |
| 515 | titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); | 521 | titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); |
| 522 | pm_relax(ts_dev->mfd_tscadc->dev); | ||
| 516 | } | 523 | } |
| 517 | titsc_step_config(ts_dev); | 524 | titsc_step_config(ts_dev); |
| 518 | titsc_writel(ts_dev, REG_FIFO0THR, | 525 | titsc_writel(ts_dev, REG_FIFO0THR, |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index c6cf90868503..d61570d64ee7 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
| @@ -440,6 +440,8 @@ static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
| 440 | #define MTOUCHUSB_RESET 7 | 440 | #define MTOUCHUSB_RESET 7 |
| 441 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 | 441 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 |
| 442 | 442 | ||
| 443 | #define MTOUCHUSB_REQ_CTRLLR_ID_LEN 16 | ||
| 444 | |||
| 443 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | 445 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
| 444 | { | 446 | { |
| 445 | if (hwcalib_xy) { | 447 | if (hwcalib_xy) { |
| @@ -454,11 +456,93 @@ static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) | |||
| 454 | return 1; | 456 | return 1; |
| 455 | } | 457 | } |
| 456 | 458 | ||
| 459 | struct mtouch_priv { | ||
| 460 | u8 fw_rev_major; | ||
| 461 | u8 fw_rev_minor; | ||
| 462 | }; | ||
| 463 | |||
| 464 | static ssize_t mtouch_firmware_rev_show(struct device *dev, | ||
| 465 | struct device_attribute *attr, char *output) | ||
| 466 | { | ||
| 467 | struct usb_interface *intf = to_usb_interface(dev); | ||
| 468 | struct usbtouch_usb *usbtouch = usb_get_intfdata(intf); | ||
| 469 | struct mtouch_priv *priv = usbtouch->priv; | ||
| 470 | |||
| 471 | return scnprintf(output, PAGE_SIZE, "%1x.%1x\n", | ||
| 472 | priv->fw_rev_major, priv->fw_rev_minor); | ||
| 473 | } | ||
| 474 | static DEVICE_ATTR(firmware_rev, 0444, mtouch_firmware_rev_show, NULL); | ||
| 475 | |||
| 476 | static struct attribute *mtouch_attrs[] = { | ||
| 477 | &dev_attr_firmware_rev.attr, | ||
| 478 | NULL | ||
| 479 | }; | ||
| 480 | |||
| 481 | static const struct attribute_group mtouch_attr_group = { | ||
| 482 | .attrs = mtouch_attrs, | ||
| 483 | }; | ||
| 484 | |||
| 485 | static int mtouch_get_fw_revision(struct usbtouch_usb *usbtouch) | ||
| 486 | { | ||
| 487 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | ||
| 488 | struct mtouch_priv *priv = usbtouch->priv; | ||
| 489 | u8 *buf; | ||
| 490 | int ret; | ||
| 491 | |||
| 492 | buf = kzalloc(MTOUCHUSB_REQ_CTRLLR_ID_LEN, GFP_NOIO); | ||
| 493 | if (!buf) | ||
| 494 | return -ENOMEM; | ||
| 495 | |||
| 496 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||
| 497 | MTOUCHUSB_REQ_CTRLLR_ID, | ||
| 498 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
| 499 | 0, 0, buf, MTOUCHUSB_REQ_CTRLLR_ID_LEN, | ||
| 500 | USB_CTRL_SET_TIMEOUT); | ||
| 501 | if (ret != MTOUCHUSB_REQ_CTRLLR_ID_LEN) { | ||
| 502 | dev_warn(&usbtouch->interface->dev, | ||
| 503 | "Failed to read FW rev: %d\n", ret); | ||
| 504 | ret = ret < 0 ? ret : -EIO; | ||
| 505 | goto free; | ||
| 506 | } | ||
| 507 | |||
| 508 | priv->fw_rev_major = buf[3]; | ||
| 509 | priv->fw_rev_minor = buf[4]; | ||
| 510 | |||
| 511 | ret = 0; | ||
| 512 | |||
| 513 | free: | ||
| 514 | kfree(buf); | ||
| 515 | return ret; | ||
| 516 | } | ||
| 517 | |||
| 518 | static int mtouch_alloc(struct usbtouch_usb *usbtouch) | ||
| 519 | { | ||
| 520 | int ret; | ||
| 521 | |||
| 522 | usbtouch->priv = kmalloc(sizeof(struct mtouch_priv), GFP_KERNEL); | ||
| 523 | if (!usbtouch->priv) | ||
| 524 | return -ENOMEM; | ||
| 525 | |||
| 526 | ret = sysfs_create_group(&usbtouch->interface->dev.kobj, | ||
| 527 | &mtouch_attr_group); | ||
| 528 | if (ret) { | ||
| 529 | kfree(usbtouch->priv); | ||
| 530 | usbtouch->priv = NULL; | ||
| 531 | return ret; | ||
| 532 | } | ||
| 533 | |||
| 534 | return 0; | ||
| 535 | } | ||
| 536 | |||
| 457 | static int mtouch_init(struct usbtouch_usb *usbtouch) | 537 | static int mtouch_init(struct usbtouch_usb *usbtouch) |
| 458 | { | 538 | { |
| 459 | int ret, i; | 539 | int ret, i; |
| 460 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); | 540 | struct usb_device *udev = interface_to_usbdev(usbtouch->interface); |
| 461 | 541 | ||
| 542 | ret = mtouch_get_fw_revision(usbtouch); | ||
| 543 | if (ret) | ||
| 544 | return ret; | ||
| 545 | |||
| 462 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 546 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
| 463 | MTOUCHUSB_RESET, | 547 | MTOUCHUSB_RESET, |
| 464 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 548 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| @@ -492,6 +576,14 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
| 492 | 576 | ||
| 493 | return 0; | 577 | return 0; |
| 494 | } | 578 | } |
| 579 | |||
| 580 | static void mtouch_exit(struct usbtouch_usb *usbtouch) | ||
| 581 | { | ||
| 582 | struct mtouch_priv *priv = usbtouch->priv; | ||
| 583 | |||
| 584 | sysfs_remove_group(&usbtouch->interface->dev.kobj, &mtouch_attr_group); | ||
| 585 | kfree(priv); | ||
| 586 | } | ||
| 495 | #endif | 587 | #endif |
| 496 | 588 | ||
| 497 | 589 | ||
| @@ -1119,7 +1211,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
| 1119 | .max_yc = 0x4000, | 1211 | .max_yc = 0x4000, |
| 1120 | .rept_size = 11, | 1212 | .rept_size = 11, |
| 1121 | .read_data = mtouch_read_data, | 1213 | .read_data = mtouch_read_data, |
| 1214 | .alloc = mtouch_alloc, | ||
| 1122 | .init = mtouch_init, | 1215 | .init = mtouch_init, |
| 1216 | .exit = mtouch_exit, | ||
| 1123 | }, | 1217 | }, |
| 1124 | #endif | 1218 | #endif |
| 1125 | 1219 | ||
