diff options
| -rw-r--r-- | drivers/input/misc/ati_remote2.c | 36 | ||||
| -rw-r--r-- | drivers/input/misc/ims-pcu.c | 4 | ||||
| -rw-r--r-- | drivers/input/mouse/byd.c | 565 | ||||
| -rw-r--r-- | drivers/input/mouse/psmouse-base.c | 2 | ||||
| -rw-r--r-- | drivers/input/mouse/synaptics.c | 5 | ||||
| -rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 5 | ||||
| -rw-r--r-- | drivers/input/touchscreen/melfas_mip4.c | 28 | ||||
| -rw-r--r-- | drivers/input/touchscreen/sur40.c | 21 |
8 files changed, 449 insertions, 217 deletions
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index cfd58e87da26..1c5914cae853 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
| @@ -817,26 +817,49 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
| 817 | 817 | ||
| 818 | ar2->udev = udev; | 818 | ar2->udev = udev; |
| 819 | 819 | ||
| 820 | /* Sanity check, first interface must have an endpoint */ | ||
| 821 | if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { | ||
| 822 | dev_err(&interface->dev, | ||
| 823 | "%s(): interface 0 must have an endpoint\n", __func__); | ||
| 824 | r = -ENODEV; | ||
| 825 | goto fail1; | ||
| 826 | } | ||
| 820 | ar2->intf[0] = interface; | 827 | ar2->intf[0] = interface; |
| 821 | ar2->ep[0] = &alt->endpoint[0].desc; | 828 | ar2->ep[0] = &alt->endpoint[0].desc; |
| 822 | 829 | ||
| 830 | /* Sanity check, the device must have two interfaces */ | ||
| 823 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); | 831 | ar2->intf[1] = usb_ifnum_to_if(udev, 1); |
| 832 | if ((udev->actconfig->desc.bNumInterfaces < 2) || !ar2->intf[1]) { | ||
| 833 | dev_err(&interface->dev, "%s(): need 2 interfaces, found %d\n", | ||
| 834 | __func__, udev->actconfig->desc.bNumInterfaces); | ||
| 835 | r = -ENODEV; | ||
| 836 | goto fail1; | ||
| 837 | } | ||
| 838 | |||
| 824 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); | 839 | r = usb_driver_claim_interface(&ati_remote2_driver, ar2->intf[1], ar2); |
| 825 | if (r) | 840 | if (r) |
| 826 | goto fail1; | 841 | goto fail1; |
| 842 | |||
| 843 | /* Sanity check, second interface must have an endpoint */ | ||
| 827 | alt = ar2->intf[1]->cur_altsetting; | 844 | alt = ar2->intf[1]->cur_altsetting; |
| 845 | if (alt->desc.bNumEndpoints < 1 || !alt->endpoint) { | ||
| 846 | dev_err(&interface->dev, | ||
| 847 | "%s(): interface 1 must have an endpoint\n", __func__); | ||
| 848 | r = -ENODEV; | ||
| 849 | goto fail2; | ||
| 850 | } | ||
| 828 | ar2->ep[1] = &alt->endpoint[0].desc; | 851 | ar2->ep[1] = &alt->endpoint[0].desc; |
| 829 | 852 | ||
| 830 | r = ati_remote2_urb_init(ar2); | 853 | r = ati_remote2_urb_init(ar2); |
| 831 | if (r) | 854 | if (r) |
| 832 | goto fail2; | 855 | goto fail3; |
| 833 | 856 | ||
| 834 | ar2->channel_mask = channel_mask; | 857 | ar2->channel_mask = channel_mask; |
| 835 | ar2->mode_mask = mode_mask; | 858 | ar2->mode_mask = mode_mask; |
| 836 | 859 | ||
| 837 | r = ati_remote2_setup(ar2, ar2->channel_mask); | 860 | r = ati_remote2_setup(ar2, ar2->channel_mask); |
| 838 | if (r) | 861 | if (r) |
| 839 | goto fail2; | 862 | goto fail3; |
| 840 | 863 | ||
| 841 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); | 864 | usb_make_path(udev, ar2->phys, sizeof(ar2->phys)); |
| 842 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); | 865 | strlcat(ar2->phys, "/input0", sizeof(ar2->phys)); |
| @@ -845,11 +868,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
| 845 | 868 | ||
| 846 | r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); | 869 | r = sysfs_create_group(&udev->dev.kobj, &ati_remote2_attr_group); |
| 847 | if (r) | 870 | if (r) |
| 848 | goto fail2; | 871 | goto fail3; |
| 849 | 872 | ||
| 850 | r = ati_remote2_input_init(ar2); | 873 | r = ati_remote2_input_init(ar2); |
| 851 | if (r) | 874 | if (r) |
| 852 | goto fail3; | 875 | goto fail4; |
| 853 | 876 | ||
| 854 | usb_set_intfdata(interface, ar2); | 877 | usb_set_intfdata(interface, ar2); |
| 855 | 878 | ||
| @@ -857,10 +880,11 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d | |||
| 857 | 880 | ||
| 858 | return 0; | 881 | return 0; |
| 859 | 882 | ||
| 860 | fail3: | 883 | fail4: |
| 861 | sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); | 884 | sysfs_remove_group(&udev->dev.kobj, &ati_remote2_attr_group); |
| 862 | fail2: | 885 | fail3: |
| 863 | ati_remote2_urb_cleanup(ar2); | 886 | ati_remote2_urb_cleanup(ar2); |
| 887 | fail2: | ||
| 864 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); | 888 | usb_driver_release_interface(&ati_remote2_driver, ar2->intf[1]); |
| 865 | fail1: | 889 | fail1: |
| 866 | kfree(ar2); | 890 | kfree(ar2); |
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index ac1fa5f44580..9c0ea36913b4 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c | |||
| @@ -1663,6 +1663,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc | |||
| 1663 | 1663 | ||
| 1664 | pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, | 1664 | pcu->ctrl_intf = usb_ifnum_to_if(pcu->udev, |
| 1665 | union_desc->bMasterInterface0); | 1665 | union_desc->bMasterInterface0); |
| 1666 | if (!pcu->ctrl_intf) | ||
| 1667 | return -EINVAL; | ||
| 1666 | 1668 | ||
| 1667 | alt = pcu->ctrl_intf->cur_altsetting; | 1669 | alt = pcu->ctrl_intf->cur_altsetting; |
| 1668 | pcu->ep_ctrl = &alt->endpoint[0].desc; | 1670 | pcu->ep_ctrl = &alt->endpoint[0].desc; |
| @@ -1670,6 +1672,8 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc | |||
| 1670 | 1672 | ||
| 1671 | pcu->data_intf = usb_ifnum_to_if(pcu->udev, | 1673 | pcu->data_intf = usb_ifnum_to_if(pcu->udev, |
| 1672 | union_desc->bSlaveInterface0); | 1674 | union_desc->bSlaveInterface0); |
| 1675 | if (!pcu->data_intf) | ||
| 1676 | return -EINVAL; | ||
| 1673 | 1677 | ||
| 1674 | alt = pcu->data_intf->cur_altsetting; | 1678 | alt = pcu->data_intf->cur_altsetting; |
| 1675 | if (alt->desc.bNumEndpoints != 2) { | 1679 | if (alt->desc.bNumEndpoints != 2) { |
diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index 9425e0f6c5ce..fdc243ca93ed 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c | |||
| @@ -12,10 +12,12 @@ | |||
| 12 | #include <linux/input.h> | 12 | #include <linux/input.h> |
| 13 | #include <linux/libps2.h> | 13 | #include <linux/libps2.h> |
| 14 | #include <linux/serio.h> | 14 | #include <linux/serio.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | 16 | ||
| 16 | #include "psmouse.h" | 17 | #include "psmouse.h" |
| 17 | #include "byd.h" | 18 | #include "byd.h" |
| 18 | 19 | ||
| 20 | /* PS2 Bits */ | ||
| 19 | #define PS2_Y_OVERFLOW BIT_MASK(7) | 21 | #define PS2_Y_OVERFLOW BIT_MASK(7) |
| 20 | #define PS2_X_OVERFLOW BIT_MASK(6) | 22 | #define PS2_X_OVERFLOW BIT_MASK(6) |
| 21 | #define PS2_Y_SIGN BIT_MASK(5) | 23 | #define PS2_Y_SIGN BIT_MASK(5) |
| @@ -26,69 +28,249 @@ | |||
| 26 | #define PS2_LEFT BIT_MASK(0) | 28 | #define PS2_LEFT BIT_MASK(0) |
| 27 | 29 | ||
| 28 | /* | 30 | /* |
| 29 | * The touchpad reports gestures in the last byte of each packet. It can take | 31 | * BYD pad constants |
| 30 | * any of the following values: | ||
| 31 | */ | 32 | */ |
| 32 | 33 | ||
| 33 | /* One-finger scrolling in one of the edge scroll zones. */ | 34 | /* |
| 34 | #define BYD_SCROLLUP 0xCA | 35 | * True device resolution is unknown, however experiments show the |
| 35 | #define BYD_SCROLLDOWN 0x36 | 36 | * resolution is about 111 units/mm. |
| 36 | #define BYD_SCROLLLEFT 0xCB | 37 | * Absolute coordinate packets are in the range 0-255 for both X and Y |
| 37 | #define BYD_SCROLLRIGHT 0x35 | 38 | * we pick ABS_X/ABS_Y dimensions which are multiples of 256 and in |
| 38 | /* Two-finger scrolling. */ | 39 | * the right ballpark given the touchpad's physical dimensions and estimate |
| 39 | #define BYD_2DOWN 0x2B | 40 | * resolution per spec sheet, device active area dimensions are |
| 40 | #define BYD_2UP 0xD5 | 41 | * 101.6 x 60.1 mm. |
| 41 | #define BYD_2LEFT 0xD6 | 42 | */ |
| 42 | #define BYD_2RIGHT 0x2A | 43 | #define BYD_PAD_WIDTH 11264 |
| 43 | /* Pinching in or out. */ | 44 | #define BYD_PAD_HEIGHT 6656 |
| 44 | #define BYD_ZOOMOUT 0xD8 | 45 | #define BYD_PAD_RESOLUTION 111 |
| 45 | #define BYD_ZOOMIN 0x28 | ||
| 46 | /* Three-finger swipe. */ | ||
| 47 | #define BYD_3UP 0xD3 | ||
| 48 | #define BYD_3DOWN 0x2D | ||
| 49 | #define BYD_3LEFT 0xD4 | ||
| 50 | #define BYD_3RIGHT 0x2C | ||
| 51 | /* Four-finger swipe. */ | ||
| 52 | #define BYD_4UP 0xCD | ||
| 53 | #define BYD_4DOWN 0x33 | ||
| 54 | 46 | ||
| 55 | int byd_detect(struct psmouse *psmouse, bool set_properties) | 47 | /* |
| 48 | * Given the above dimensions, relative packets velocity is in multiples of | ||
| 49 | * 1 unit / 11 milliseconds. We use this dt to estimate distance traveled | ||
| 50 | */ | ||
| 51 | #define BYD_DT 11 | ||
| 52 | /* Time in jiffies used to timeout various touch events (64 ms) */ | ||
| 53 | #define BYD_TOUCH_TIMEOUT msecs_to_jiffies(64) | ||
| 54 | |||
| 55 | /* BYD commands reverse engineered from windows driver */ | ||
| 56 | |||
| 57 | /* | ||
| 58 | * Swipe gesture from off-pad to on-pad | ||
| 59 | * 0 : disable | ||
| 60 | * 1 : enable | ||
| 61 | */ | ||
| 62 | #define BYD_CMD_SET_OFFSCREEN_SWIPE 0x10cc | ||
| 63 | /* | ||
| 64 | * Tap and drag delay time | ||
| 65 | * 0 : disable | ||
| 66 | * 1 - 8 : least to most delay | ||
| 67 | */ | ||
| 68 | #define BYD_CMD_SET_TAP_DRAG_DELAY_TIME 0x10cf | ||
| 69 | /* | ||
| 70 | * Physical buttons function mapping | ||
| 71 | * 0 : enable | ||
| 72 | * 4 : normal | ||
| 73 | * 5 : left button custom command | ||
| 74 | * 6 : right button custom command | ||
| 75 | * 8 : disable | ||
| 76 | */ | ||
| 77 | #define BYD_CMD_SET_PHYSICAL_BUTTONS 0x10d0 | ||
| 78 | /* | ||
| 79 | * Absolute mode (1 byte X/Y resolution) | ||
| 80 | * 0 : disable | ||
| 81 | * 2 : enable | ||
| 82 | */ | ||
| 83 | #define BYD_CMD_SET_ABSOLUTE_MODE 0x10d1 | ||
| 84 | /* | ||
| 85 | * Two finger scrolling | ||
| 86 | * 1 : vertical | ||
| 87 | * 2 : horizontal | ||
| 88 | * 3 : vertical + horizontal | ||
| 89 | * 4 : disable | ||
| 90 | */ | ||
| 91 | #define BYD_CMD_SET_TWO_FINGER_SCROLL 0x10d2 | ||
| 92 | /* | ||
| 93 | * Handedness | ||
| 94 | * 1 : right handed | ||
| 95 | * 2 : left handed | ||
| 96 | */ | ||
| 97 | #define BYD_CMD_SET_HANDEDNESS 0x10d3 | ||
| 98 | /* | ||
| 99 | * Tap to click | ||
| 100 | * 1 : enable | ||
| 101 | * 2 : disable | ||
| 102 | */ | ||
| 103 | #define BYD_CMD_SET_TAP 0x10d4 | ||
| 104 | /* | ||
| 105 | * Tap and drag | ||
| 106 | * 1 : tap and hold to drag | ||
| 107 | * 2 : tap and hold to drag + lock | ||
| 108 | * 3 : disable | ||
| 109 | */ | ||
| 110 | #define BYD_CMD_SET_TAP_DRAG 0x10d5 | ||
| 111 | /* | ||
| 112 | * Touch sensitivity | ||
| 113 | * 1 - 7 : least to most sensitive | ||
| 114 | */ | ||
| 115 | #define BYD_CMD_SET_TOUCH_SENSITIVITY 0x10d6 | ||
| 116 | /* | ||
| 117 | * One finger scrolling | ||
| 118 | * 1 : vertical | ||
| 119 | * 2 : horizontal | ||
| 120 | * 3 : vertical + horizontal | ||
| 121 | * 4 : disable | ||
| 122 | */ | ||
| 123 | #define BYD_CMD_SET_ONE_FINGER_SCROLL 0x10d7 | ||
| 124 | /* | ||
| 125 | * One finger scrolling function | ||
| 126 | * 1 : free scrolling | ||
| 127 | * 2 : edge motion | ||
| 128 | * 3 : free scrolling + edge motion | ||
| 129 | * 4 : disable | ||
| 130 | */ | ||
| 131 | #define BYD_CMD_SET_ONE_FINGER_SCROLL_FUNC 0x10d8 | ||
| 132 | /* | ||
| 133 | * Sliding speed | ||
| 134 | * 1 - 5 : slowest to fastest | ||
| 135 | */ | ||
| 136 | #define BYD_CMD_SET_SLIDING_SPEED 0x10da | ||
| 137 | /* | ||
| 138 | * Edge motion | ||
| 139 | * 1 : disable | ||
| 140 | * 2 : enable when dragging | ||
| 141 | * 3 : enable when dragging and pointing | ||
| 142 | */ | ||
| 143 | #define BYD_CMD_SET_EDGE_MOTION 0x10db | ||
| 144 | /* | ||
| 145 | * Left edge region size | ||
| 146 | * 0 - 7 : smallest to largest width | ||
| 147 | */ | ||
| 148 | #define BYD_CMD_SET_LEFT_EDGE_REGION 0x10dc | ||
| 149 | /* | ||
| 150 | * Top edge region size | ||
| 151 | * 0 - 9 : smallest to largest height | ||
| 152 | */ | ||
| 153 | #define BYD_CMD_SET_TOP_EDGE_REGION 0x10dd | ||
| 154 | /* | ||
| 155 | * Disregard palm press as clicks | ||
| 156 | * 1 - 6 : smallest to largest | ||
| 157 | */ | ||
| 158 | #define BYD_CMD_SET_PALM_CHECK 0x10de | ||
| 159 | /* | ||
| 160 | * Right edge region size | ||
| 161 | * 0 - 7 : smallest to largest width | ||
| 162 | */ | ||
| 163 | #define BYD_CMD_SET_RIGHT_EDGE_REGION 0x10df | ||
| 164 | /* | ||
| 165 | * Bottom edge region size | ||
| 166 | * 0 - 9 : smallest to largest height | ||
| 167 | */ | ||
| 168 | #define BYD_CMD_SET_BOTTOM_EDGE_REGION 0x10e1 | ||
| 169 | /* | ||
| 170 | * Multitouch gestures | ||
| 171 | * 1 : enable | ||
| 172 | * 2 : disable | ||
| 173 | */ | ||
| 174 | #define BYD_CMD_SET_MULTITOUCH 0x10e3 | ||
| 175 | /* | ||
| 176 | * Edge motion speed | ||
| 177 | * 0 : control with finger pressure | ||
| 178 | * 1 - 9 : slowest to fastest | ||
| 179 | */ | ||
| 180 | #define BYD_CMD_SET_EDGE_MOTION_SPEED 0x10e4 | ||
| 181 | /* | ||
| 182 | * Two finger scolling function | ||
| 183 | * 0 : free scrolling | ||
| 184 | * 1 : free scrolling (with momentum) | ||
| 185 | * 2 : edge motion | ||
| 186 | * 3 : free scrolling (with momentum) + edge motion | ||
| 187 | * 4 : disable | ||
| 188 | */ | ||
| 189 | #define BYD_CMD_SET_TWO_FINGER_SCROLL_FUNC 0x10e5 | ||
| 190 | |||
| 191 | /* | ||
| 192 | * The touchpad generates a mixture of absolute and relative packets, indicated | ||
| 193 | * by the the last byte of each packet being set to one of the following: | ||
| 194 | */ | ||
| 195 | #define BYD_PACKET_ABSOLUTE 0xf8 | ||
| 196 | #define BYD_PACKET_RELATIVE 0x00 | ||
| 197 | /* Multitouch gesture packets */ | ||
| 198 | #define BYD_PACKET_PINCH_IN 0xd8 | ||
| 199 | #define BYD_PACKET_PINCH_OUT 0x28 | ||
| 200 | #define BYD_PACKET_ROTATE_CLOCKWISE 0x29 | ||
| 201 | #define BYD_PACKET_ROTATE_ANTICLOCKWISE 0xd7 | ||
| 202 | #define BYD_PACKET_TWO_FINGER_SCROLL_RIGHT 0x2a | ||
| 203 | #define BYD_PACKET_TWO_FINGER_SCROLL_DOWN 0x2b | ||
| 204 | #define BYD_PACKET_TWO_FINGER_SCROLL_UP 0xd5 | ||
| 205 | #define BYD_PACKET_TWO_FINGER_SCROLL_LEFT 0xd6 | ||
| 206 | #define BYD_PACKET_THREE_FINGER_SWIPE_RIGHT 0x2c | ||
| 207 | #define BYD_PACKET_THREE_FINGER_SWIPE_DOWN 0x2d | ||
| 208 | #define BYD_PACKET_THREE_FINGER_SWIPE_UP 0xd3 | ||
| 209 | #define BYD_PACKET_THREE_FINGER_SWIPE_LEFT 0xd4 | ||
| 210 | #define BYD_PACKET_FOUR_FINGER_DOWN 0x33 | ||
| 211 | #define BYD_PACKET_FOUR_FINGER_UP 0xcd | ||
| 212 | #define BYD_PACKET_REGION_SCROLL_RIGHT 0x35 | ||
| 213 | #define BYD_PACKET_REGION_SCROLL_DOWN 0x36 | ||
| 214 | #define BYD_PACKET_REGION_SCROLL_UP 0xca | ||
| 215 | #define BYD_PACKET_REGION_SCROLL_LEFT 0xcb | ||
| 216 | #define BYD_PACKET_RIGHT_CORNER_CLICK 0xd2 | ||
| 217 | #define BYD_PACKET_LEFT_CORNER_CLICK 0x2e | ||
| 218 | #define BYD_PACKET_LEFT_AND_RIGHT_CORNER_CLICK 0x2f | ||
| 219 | #define BYD_PACKET_ONTO_PAD_SWIPE_RIGHT 0x37 | ||
| 220 | #define BYD_PACKET_ONTO_PAD_SWIPE_DOWN 0x30 | ||
| 221 | #define BYD_PACKET_ONTO_PAD_SWIPE_UP 0xd0 | ||
| 222 | #define BYD_PACKET_ONTO_PAD_SWIPE_LEFT 0xc9 | ||
| 223 | |||
| 224 | struct byd_data { | ||
| 225 | struct timer_list timer; | ||
| 226 | s32 abs_x; | ||
| 227 | s32 abs_y; | ||
| 228 | typeof(jiffies) last_touch_time; | ||
| 229 | bool btn_left; | ||
| 230 | bool btn_right; | ||
| 231 | bool touch; | ||
| 232 | }; | ||
| 233 | |||
| 234 | static void byd_report_input(struct psmouse *psmouse) | ||
| 56 | { | 235 | { |
| 57 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 236 | struct byd_data *priv = psmouse->private; |
| 58 | unsigned char param[4]; | 237 | struct input_dev *dev = psmouse->dev; |
| 59 | 238 | ||
| 60 | param[0] = 0x03; | 239 | input_report_key(dev, BTN_TOUCH, priv->touch); |
| 61 | param[1] = 0x00; | 240 | input_report_key(dev, BTN_TOOL_FINGER, priv->touch); |
| 62 | param[2] = 0x00; | ||
| 63 | param[3] = 0x00; | ||
| 64 | 241 | ||
| 65 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | 242 | input_report_abs(dev, ABS_X, priv->abs_x); |
| 66 | return -1; | 243 | input_report_abs(dev, ABS_Y, priv->abs_y); |
| 67 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | 244 | input_report_key(dev, BTN_LEFT, priv->btn_left); |
| 68 | return -1; | 245 | input_report_key(dev, BTN_RIGHT, priv->btn_right); |
| 69 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 70 | return -1; | ||
| 71 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 72 | return -1; | ||
| 73 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
| 74 | return -1; | ||
| 75 | 246 | ||
| 76 | if (param[1] != 0x03 || param[2] != 0x64) | 247 | input_sync(dev); |
| 77 | return -ENODEV; | 248 | } |
| 78 | 249 | ||
| 79 | psmouse_dbg(psmouse, "BYD touchpad detected\n"); | 250 | static void byd_clear_touch(unsigned long data) |
| 251 | { | ||
| 252 | struct psmouse *psmouse = (struct psmouse *)data; | ||
| 253 | struct byd_data *priv = psmouse->private; | ||
| 80 | 254 | ||
| 81 | if (set_properties) { | 255 | serio_pause_rx(psmouse->ps2dev.serio); |
| 82 | psmouse->vendor = "BYD"; | 256 | priv->touch = false; |
| 83 | psmouse->name = "TouchPad"; | ||
| 84 | } | ||
| 85 | 257 | ||
| 86 | return 0; | 258 | byd_report_input(psmouse); |
| 259 | |||
| 260 | serio_continue_rx(psmouse->ps2dev.serio); | ||
| 261 | |||
| 262 | /* | ||
| 263 | * Move cursor back to center of pad when we lose touch - this | ||
| 264 | * specifically improves user experience when moving cursor with one | ||
| 265 | * finger, and pressing a button with another. | ||
| 266 | */ | ||
| 267 | priv->abs_x = BYD_PAD_WIDTH / 2; | ||
| 268 | priv->abs_y = BYD_PAD_HEIGHT / 2; | ||
| 87 | } | 269 | } |
| 88 | 270 | ||
| 89 | static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | 271 | static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) |
| 90 | { | 272 | { |
| 91 | struct input_dev *dev = psmouse->dev; | 273 | struct byd_data *priv = psmouse->private; |
| 92 | u8 *pkt = psmouse->packet; | 274 | u8 *pkt = psmouse->packet; |
| 93 | 275 | ||
| 94 | if (psmouse->pktcnt > 0 && !(pkt[0] & PS2_ALWAYS_1)) { | 276 | if (psmouse->pktcnt > 0 && !(pkt[0] & PS2_ALWAYS_1)) { |
| @@ -102,53 +284,34 @@ static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | |||
| 102 | 284 | ||
| 103 | /* Otherwise, a full packet has been received */ | 285 | /* Otherwise, a full packet has been received */ |
| 104 | switch (pkt[3]) { | 286 | switch (pkt[3]) { |
| 105 | case 0: { | 287 | case BYD_PACKET_ABSOLUTE: |
| 288 | /* Only use absolute packets for the start of movement. */ | ||
| 289 | if (!priv->touch) { | ||
| 290 | /* needed to detect tap */ | ||
| 291 | typeof(jiffies) tap_time = | ||
| 292 | priv->last_touch_time + BYD_TOUCH_TIMEOUT; | ||
| 293 | priv->touch = time_after(jiffies, tap_time); | ||
| 294 | |||
| 295 | /* init abs position */ | ||
| 296 | priv->abs_x = pkt[1] * (BYD_PAD_WIDTH / 256); | ||
| 297 | priv->abs_y = (255 - pkt[2]) * (BYD_PAD_HEIGHT / 256); | ||
| 298 | } | ||
| 299 | break; | ||
| 300 | case BYD_PACKET_RELATIVE: { | ||
| 106 | /* Standard packet */ | 301 | /* Standard packet */ |
| 107 | /* Sign-extend if a sign bit is set. */ | 302 | /* Sign-extend if a sign bit is set. */ |
| 108 | unsigned int signx = pkt[0] & PS2_X_SIGN ? ~0xFF : 0; | 303 | u32 signx = pkt[0] & PS2_X_SIGN ? ~0xFF : 0; |
| 109 | unsigned int signy = pkt[0] & PS2_Y_SIGN ? ~0xFF : 0; | 304 | u32 signy = pkt[0] & PS2_Y_SIGN ? ~0xFF : 0; |
| 110 | int dx = signx | (int) pkt[1]; | 305 | s32 dx = signx | (int) pkt[1]; |
| 111 | int dy = signy | (int) pkt[2]; | 306 | s32 dy = signy | (int) pkt[2]; |
| 112 | 307 | ||
| 113 | input_report_rel(psmouse->dev, REL_X, dx); | 308 | /* Update position based on velocity */ |
| 114 | input_report_rel(psmouse->dev, REL_Y, -dy); | 309 | priv->abs_x += dx * BYD_DT; |
| 310 | priv->abs_y -= dy * BYD_DT; | ||
| 115 | 311 | ||
| 116 | input_report_key(psmouse->dev, BTN_LEFT, pkt[0] & PS2_LEFT); | 312 | priv->touch = true; |
| 117 | input_report_key(psmouse->dev, BTN_RIGHT, pkt[0] & PS2_RIGHT); | ||
| 118 | input_report_key(psmouse->dev, BTN_MIDDLE, pkt[0] & PS2_MIDDLE); | ||
| 119 | break; | 313 | break; |
| 120 | } | 314 | } |
| 121 | |||
| 122 | case BYD_SCROLLDOWN: | ||
| 123 | case BYD_2DOWN: | ||
| 124 | input_report_rel(dev, REL_WHEEL, -1); | ||
| 125 | break; | ||
| 126 | |||
| 127 | case BYD_SCROLLUP: | ||
| 128 | case BYD_2UP: | ||
| 129 | input_report_rel(dev, REL_WHEEL, 1); | ||
| 130 | break; | ||
| 131 | |||
| 132 | case BYD_SCROLLLEFT: | ||
| 133 | case BYD_2LEFT: | ||
| 134 | input_report_rel(dev, REL_HWHEEL, -1); | ||
| 135 | break; | ||
| 136 | |||
| 137 | case BYD_SCROLLRIGHT: | ||
| 138 | case BYD_2RIGHT: | ||
| 139 | input_report_rel(dev, REL_HWHEEL, 1); | ||
| 140 | break; | ||
| 141 | |||
| 142 | case BYD_ZOOMOUT: | ||
| 143 | case BYD_ZOOMIN: | ||
| 144 | case BYD_3UP: | ||
| 145 | case BYD_3DOWN: | ||
| 146 | case BYD_3LEFT: | ||
| 147 | case BYD_3RIGHT: | ||
| 148 | case BYD_4UP: | ||
| 149 | case BYD_4DOWN: | ||
| 150 | break; | ||
| 151 | |||
| 152 | default: | 315 | default: |
| 153 | psmouse_warn(psmouse, | 316 | psmouse_warn(psmouse, |
| 154 | "Unrecognized Z: pkt = %02x %02x %02x %02x\n", | 317 | "Unrecognized Z: pkt = %02x %02x %02x %02x\n", |
| @@ -157,134 +320,76 @@ static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) | |||
| 157 | return PSMOUSE_BAD_DATA; | 320 | return PSMOUSE_BAD_DATA; |
| 158 | } | 321 | } |
| 159 | 322 | ||
| 160 | input_sync(dev); | 323 | priv->btn_left = pkt[0] & PS2_LEFT; |
| 324 | priv->btn_right = pkt[0] & PS2_RIGHT; | ||
| 161 | 325 | ||
| 162 | return PSMOUSE_FULL_PACKET; | 326 | byd_report_input(psmouse); |
| 163 | } | ||
| 164 | 327 | ||
| 165 | /* Send a sequence of bytes, where each is ACKed before the next is sent. */ | 328 | /* Reset time since last touch. */ |
| 166 | static int byd_send_sequence(struct psmouse *psmouse, const u8 *seq, size_t len) | 329 | if (priv->touch) { |
| 167 | { | 330 | priv->last_touch_time = jiffies; |
| 168 | unsigned int i; | 331 | mod_timer(&priv->timer, jiffies + BYD_TOUCH_TIMEOUT); |
| 169 | |||
| 170 | for (i = 0; i < len; ++i) { | ||
| 171 | if (ps2_command(&psmouse->ps2dev, NULL, seq[i])) | ||
| 172 | return -1; | ||
| 173 | } | 332 | } |
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* Keep scrolling after fingers are removed. */ | ||
| 178 | #define SCROLL_INERTIAL 0x01 | ||
| 179 | #define SCROLL_NO_INERTIAL 0x02 | ||
| 180 | |||
| 181 | /* Clicking can be done by tapping or pressing. */ | ||
| 182 | #define CLICK_BOTH 0x01 | ||
| 183 | /* Clicking can only be done by pressing. */ | ||
| 184 | #define CLICK_PRESS_ONLY 0x02 | ||
| 185 | 333 | ||
| 186 | static int byd_enable(struct psmouse *psmouse) | 334 | return PSMOUSE_FULL_PACKET; |
| 187 | { | ||
| 188 | const u8 seq1[] = { 0xE2, 0x00, 0xE0, 0x02, 0xE0 }; | ||
| 189 | const u8 seq2[] = { | ||
| 190 | 0xD3, 0x01, | ||
| 191 | 0xD0, 0x00, | ||
| 192 | 0xD0, 0x04, | ||
| 193 | /* Whether clicking is done by tapping or pressing. */ | ||
| 194 | 0xD4, CLICK_PRESS_ONLY, | ||
| 195 | 0xD5, 0x01, | ||
| 196 | 0xD7, 0x03, | ||
| 197 | /* Vertical and horizontal one-finger scroll zone inertia. */ | ||
| 198 | 0xD8, SCROLL_INERTIAL, | ||
| 199 | 0xDA, 0x05, | ||
| 200 | 0xDB, 0x02, | ||
| 201 | 0xE4, 0x05, | ||
| 202 | 0xD6, 0x01, | ||
| 203 | 0xDE, 0x04, | ||
| 204 | 0xE3, 0x01, | ||
| 205 | 0xCF, 0x00, | ||
| 206 | 0xD2, 0x03, | ||
| 207 | /* Vertical and horizontal two-finger scrolling inertia. */ | ||
| 208 | 0xE5, SCROLL_INERTIAL, | ||
| 209 | 0xD9, 0x02, | ||
| 210 | 0xD9, 0x07, | ||
| 211 | 0xDC, 0x03, | ||
| 212 | 0xDD, 0x03, | ||
| 213 | 0xDF, 0x03, | ||
| 214 | 0xE1, 0x03, | ||
| 215 | 0xD1, 0x00, | ||
| 216 | 0xCE, 0x00, | ||
| 217 | 0xCC, 0x00, | ||
| 218 | 0xE0, 0x00, | ||
| 219 | 0xE2, 0x01 | ||
| 220 | }; | ||
| 221 | u8 param[4]; | ||
| 222 | |||
| 223 | if (byd_send_sequence(psmouse, seq1, ARRAY_SIZE(seq1))) | ||
| 224 | return -1; | ||
| 225 | |||
| 226 | /* Send a 0x01 command, which should return 4 bytes. */ | ||
| 227 | if (ps2_command(&psmouse->ps2dev, param, 0x0401)) | ||
| 228 | return -1; | ||
| 229 | |||
| 230 | if (byd_send_sequence(psmouse, seq2, ARRAY_SIZE(seq2))) | ||
| 231 | return -1; | ||
| 232 | |||
| 233 | return 0; | ||
| 234 | } | 335 | } |
| 235 | 336 | ||
| 236 | /* | 337 | static int byd_reset_touchpad(struct psmouse *psmouse) |
| 237 | * Send the set of PS/2 commands required to make it identify as an | ||
| 238 | * intellimouse with 4-byte instead of 3-byte packets. | ||
| 239 | */ | ||
| 240 | static int byd_send_intellimouse_sequence(struct psmouse *psmouse) | ||
| 241 | { | 338 | { |
| 242 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 339 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
| 243 | u8 param[4]; | 340 | u8 param[4]; |
| 244 | int i; | 341 | size_t i; |
| 342 | |||
| 245 | const struct { | 343 | const struct { |
| 246 | u16 command; | 344 | u16 command; |
| 247 | u8 arg; | 345 | u8 arg; |
| 248 | } seq[] = { | 346 | } seq[] = { |
| 249 | { PSMOUSE_CMD_RESET_BAT, 0 }, | 347 | /* |
| 250 | { PSMOUSE_CMD_RESET_BAT, 0 }, | 348 | * Intellimouse initialization sequence, to get 4-byte instead |
| 251 | { PSMOUSE_CMD_GETID, 0 }, | 349 | * of 3-byte packets. |
| 252 | { PSMOUSE_CMD_SETSCALE11, 0 }, | 350 | */ |
| 253 | { PSMOUSE_CMD_SETSCALE11, 0 }, | ||
| 254 | { PSMOUSE_CMD_SETSCALE11, 0 }, | ||
| 255 | { PSMOUSE_CMD_GETINFO, 0 }, | ||
| 256 | { PSMOUSE_CMD_SETRES, 0x03 }, | ||
| 257 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 351 | { PSMOUSE_CMD_SETRATE, 0xC8 }, |
| 258 | { PSMOUSE_CMD_SETRATE, 0x64 }, | 352 | { PSMOUSE_CMD_SETRATE, 0x64 }, |
| 259 | { PSMOUSE_CMD_SETRATE, 0x50 }, | 353 | { PSMOUSE_CMD_SETRATE, 0x50 }, |
| 260 | { PSMOUSE_CMD_GETID, 0 }, | 354 | { PSMOUSE_CMD_GETID, 0 }, |
| 261 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 355 | { PSMOUSE_CMD_ENABLE, 0 }, |
| 262 | { PSMOUSE_CMD_SETRATE, 0xC8 }, | 356 | /* |
| 263 | { PSMOUSE_CMD_SETRATE, 0x50 }, | 357 | * BYD-specific initialization, which enables absolute mode and |
| 264 | { PSMOUSE_CMD_GETID, 0 }, | 358 | * (if desired), the touchpad's built-in gesture detection. |
| 265 | { PSMOUSE_CMD_SETRATE, 0x64 }, | 359 | */ |
| 266 | { PSMOUSE_CMD_SETRES, 0x03 }, | 360 | { 0x10E2, 0x00 }, |
| 267 | { PSMOUSE_CMD_ENABLE, 0 } | 361 | { 0x10E0, 0x02 }, |
| 362 | /* The touchpad should reply with 4 seemingly-random bytes */ | ||
| 363 | { 0x14E0, 0x01 }, | ||
| 364 | /* Pairs of parameters and values. */ | ||
| 365 | { BYD_CMD_SET_HANDEDNESS, 0x01 }, | ||
| 366 | { BYD_CMD_SET_PHYSICAL_BUTTONS, 0x04 }, | ||
| 367 | { BYD_CMD_SET_TAP, 0x02 }, | ||
| 368 | { BYD_CMD_SET_ONE_FINGER_SCROLL, 0x04 }, | ||
| 369 | { BYD_CMD_SET_ONE_FINGER_SCROLL_FUNC, 0x04 }, | ||
| 370 | { BYD_CMD_SET_EDGE_MOTION, 0x01 }, | ||
| 371 | { BYD_CMD_SET_PALM_CHECK, 0x00 }, | ||
| 372 | { BYD_CMD_SET_MULTITOUCH, 0x02 }, | ||
| 373 | { BYD_CMD_SET_TWO_FINGER_SCROLL, 0x04 }, | ||
| 374 | { BYD_CMD_SET_TWO_FINGER_SCROLL_FUNC, 0x04 }, | ||
| 375 | { BYD_CMD_SET_LEFT_EDGE_REGION, 0x00 }, | ||
| 376 | { BYD_CMD_SET_TOP_EDGE_REGION, 0x00 }, | ||
| 377 | { BYD_CMD_SET_RIGHT_EDGE_REGION, 0x00 }, | ||
| 378 | { BYD_CMD_SET_BOTTOM_EDGE_REGION, 0x00 }, | ||
| 379 | { BYD_CMD_SET_ABSOLUTE_MODE, 0x02 }, | ||
| 380 | /* Finalize initialization. */ | ||
| 381 | { 0x10E0, 0x00 }, | ||
| 382 | { 0x10E2, 0x01 }, | ||
| 268 | }; | 383 | }; |
| 269 | 384 | ||
| 270 | memset(param, 0, sizeof(param)); | ||
| 271 | for (i = 0; i < ARRAY_SIZE(seq); ++i) { | 385 | for (i = 0; i < ARRAY_SIZE(seq); ++i) { |
| 386 | memset(param, 0, sizeof(param)); | ||
| 272 | param[0] = seq[i].arg; | 387 | param[0] = seq[i].arg; |
| 273 | if (ps2_command(ps2dev, param, seq[i].command)) | 388 | if (ps2_command(ps2dev, param, seq[i].command)) |
| 274 | return -1; | 389 | return -EIO; |
| 275 | } | 390 | } |
| 276 | 391 | ||
| 277 | return 0; | 392 | psmouse_set_state(psmouse, PSMOUSE_ACTIVATED); |
| 278 | } | ||
| 279 | |||
| 280 | static int byd_reset_touchpad(struct psmouse *psmouse) | ||
| 281 | { | ||
| 282 | if (byd_send_intellimouse_sequence(psmouse)) | ||
| 283 | return -EIO; | ||
| 284 | |||
| 285 | if (byd_enable(psmouse)) | ||
| 286 | return -EIO; | ||
| 287 | |||
| 288 | return 0; | 393 | return 0; |
| 289 | } | 394 | } |
| 290 | 395 | ||
| @@ -314,9 +419,50 @@ static int byd_reconnect(struct psmouse *psmouse) | |||
| 314 | return 0; | 419 | return 0; |
| 315 | } | 420 | } |
| 316 | 421 | ||
| 422 | static void byd_disconnect(struct psmouse *psmouse) | ||
| 423 | { | ||
| 424 | struct byd_data *priv = psmouse->private; | ||
| 425 | |||
| 426 | if (priv) { | ||
| 427 | del_timer(&priv->timer); | ||
| 428 | kfree(psmouse->private); | ||
| 429 | psmouse->private = NULL; | ||
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | int byd_detect(struct psmouse *psmouse, bool set_properties) | ||
| 434 | { | ||
| 435 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 436 | u8 param[4] = {0x03, 0x00, 0x00, 0x00}; | ||
| 437 | |||
| 438 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 439 | return -1; | ||
| 440 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 441 | return -1; | ||
| 442 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 443 | return -1; | ||
| 444 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES)) | ||
| 445 | return -1; | ||
| 446 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) | ||
| 447 | return -1; | ||
| 448 | |||
| 449 | if (param[1] != 0x03 || param[2] != 0x64) | ||
| 450 | return -ENODEV; | ||
| 451 | |||
| 452 | psmouse_dbg(psmouse, "BYD touchpad detected\n"); | ||
| 453 | |||
| 454 | if (set_properties) { | ||
| 455 | psmouse->vendor = "BYD"; | ||
| 456 | psmouse->name = "TouchPad"; | ||
| 457 | } | ||
| 458 | |||
| 459 | return 0; | ||
| 460 | } | ||
| 461 | |||
| 317 | int byd_init(struct psmouse *psmouse) | 462 | int byd_init(struct psmouse *psmouse) |
| 318 | { | 463 | { |
| 319 | struct input_dev *dev = psmouse->dev; | 464 | struct input_dev *dev = psmouse->dev; |
| 465 | struct byd_data *priv; | ||
| 320 | 466 | ||
| 321 | if (psmouse_reset(psmouse)) | 467 | if (psmouse_reset(psmouse)) |
| 322 | return -EIO; | 468 | return -EIO; |
| @@ -324,14 +470,39 @@ int byd_init(struct psmouse *psmouse) | |||
| 324 | if (byd_reset_touchpad(psmouse)) | 470 | if (byd_reset_touchpad(psmouse)) |
| 325 | return -EIO; | 471 | return -EIO; |
| 326 | 472 | ||
| 473 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 474 | if (!priv) | ||
| 475 | return -ENOMEM; | ||
| 476 | |||
| 477 | memset(priv, 0, sizeof(*priv)); | ||
| 478 | setup_timer(&priv->timer, byd_clear_touch, (unsigned long) psmouse); | ||
| 479 | |||
| 480 | psmouse->private = priv; | ||
| 481 | psmouse->disconnect = byd_disconnect; | ||
| 327 | psmouse->reconnect = byd_reconnect; | 482 | psmouse->reconnect = byd_reconnect; |
| 328 | psmouse->protocol_handler = byd_process_byte; | 483 | psmouse->protocol_handler = byd_process_byte; |
| 329 | psmouse->pktsize = 4; | 484 | psmouse->pktsize = 4; |
| 330 | psmouse->resync_time = 0; | 485 | psmouse->resync_time = 0; |
| 331 | 486 | ||
| 332 | __set_bit(BTN_MIDDLE, dev->keybit); | 487 | __set_bit(INPUT_PROP_POINTER, dev->propbit); |
| 333 | __set_bit(REL_WHEEL, dev->relbit); | 488 | /* Touchpad */ |
| 334 | __set_bit(REL_HWHEEL, dev->relbit); | 489 | __set_bit(BTN_TOUCH, dev->keybit); |
| 490 | __set_bit(BTN_TOOL_FINGER, dev->keybit); | ||
| 491 | /* Buttons */ | ||
| 492 | __set_bit(BTN_LEFT, dev->keybit); | ||
| 493 | __set_bit(BTN_RIGHT, dev->keybit); | ||
| 494 | __clear_bit(BTN_MIDDLE, dev->keybit); | ||
| 495 | |||
| 496 | /* Absolute position */ | ||
| 497 | __set_bit(EV_ABS, dev->evbit); | ||
| 498 | input_set_abs_params(dev, ABS_X, 0, BYD_PAD_WIDTH, 0, 0); | ||
| 499 | input_set_abs_params(dev, ABS_Y, 0, BYD_PAD_HEIGHT, 0, 0); | ||
| 500 | input_abs_set_res(dev, ABS_X, BYD_PAD_RESOLUTION); | ||
| 501 | input_abs_set_res(dev, ABS_Y, BYD_PAD_RESOLUTION); | ||
| 502 | /* No relative support */ | ||
| 503 | __clear_bit(EV_REL, dev->evbit); | ||
| 504 | __clear_bit(REL_X, dev->relbit); | ||
| 505 | __clear_bit(REL_Y, dev->relbit); | ||
| 335 | 506 | ||
| 336 | return 0; | 507 | return 0; |
| 337 | } | 508 | } |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 39d1becd35c9..5784e20542a4 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -846,7 +846,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
| 846 | #ifdef CONFIG_MOUSE_PS2_BYD | 846 | #ifdef CONFIG_MOUSE_PS2_BYD |
| 847 | { | 847 | { |
| 848 | .type = PSMOUSE_BYD, | 848 | .type = PSMOUSE_BYD, |
| 849 | .name = "BydPS/2", | 849 | .name = "BYDPS/2", |
| 850 | .alias = "byd", | 850 | .alias = "byd", |
| 851 | .detect = byd_detect, | 851 | .detect = byd_detect, |
| 852 | .init = byd_init, | 852 | .init = byd_init, |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 6025eb430c0a..a41d8328c064 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -862,8 +862,9 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse, | |||
| 862 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) | 862 | if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) |
| 863 | return; | 863 | return; |
| 864 | 864 | ||
| 865 | /* Bug in FW 8.1, buttons are reported only when ExtBit is 1 */ | 865 | /* Bug in FW 8.1 & 8.2, buttons are reported only when ExtBit is 1 */ |
| 866 | if (SYN_ID_FULL(priv->identity) == 0x801 && | 866 | if ((SYN_ID_FULL(priv->identity) == 0x801 || |
| 867 | SYN_ID_FULL(priv->identity) == 0x802) && | ||
| 867 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) | 868 | !((psmouse->packet[0] ^ psmouse->packet[3]) & 0x02)) |
| 868 | return; | 869 | return; |
| 869 | 870 | ||
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index da38f0ad80ed..faa295ec4f31 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c | |||
| @@ -126,7 +126,7 @@ static void process_one_interrupt(struct rmi_driver_data *data, | |||
| 126 | return; | 126 | return; |
| 127 | 127 | ||
| 128 | fh = to_rmi_function_handler(fn->dev.driver); | 128 | fh = to_rmi_function_handler(fn->dev.driver); |
| 129 | if (fn->irq_mask && fh->attention) { | 129 | if (fh->attention) { |
| 130 | bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask, | 130 | bitmap_and(data->fn_irq_bits, data->irq_status, fn->irq_mask, |
| 131 | data->irq_count); | 131 | data->irq_count); |
| 132 | if (!bitmap_empty(data->fn_irq_bits, data->irq_count)) | 132 | if (!bitmap_empty(data->fn_irq_bits, data->irq_count)) |
| @@ -172,8 +172,7 @@ int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) | |||
| 172 | * use irq_chip. | 172 | * use irq_chip. |
| 173 | */ | 173 | */ |
| 174 | list_for_each_entry(entry, &data->function_list, node) | 174 | list_for_each_entry(entry, &data->function_list, node) |
| 175 | if (entry->irq_mask) | 175 | process_one_interrupt(data, entry); |
| 176 | process_one_interrupt(data, entry); | ||
| 177 | 176 | ||
| 178 | if (data->input) | 177 | if (data->input) |
| 179 | input_sync(data->input); | 178 | input_sync(data->input); |
diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index 892729734c51..fb5fb9140ca9 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c | |||
| @@ -1310,8 +1310,34 @@ static ssize_t mip4_sysfs_read_fw_version(struct device *dev, | |||
| 1310 | 1310 | ||
| 1311 | static DEVICE_ATTR(fw_version, S_IRUGO, mip4_sysfs_read_fw_version, NULL); | 1311 | static DEVICE_ATTR(fw_version, S_IRUGO, mip4_sysfs_read_fw_version, NULL); |
| 1312 | 1312 | ||
| 1313 | static ssize_t mip4_sysfs_read_hw_version(struct device *dev, | ||
| 1314 | struct device_attribute *attr, | ||
| 1315 | char *buf) | ||
| 1316 | { | ||
| 1317 | struct i2c_client *client = to_i2c_client(dev); | ||
| 1318 | struct mip4_ts *ts = i2c_get_clientdata(client); | ||
| 1319 | size_t count; | ||
| 1320 | |||
| 1321 | /* Take lock to prevent racing with firmware update */ | ||
| 1322 | mutex_lock(&ts->input->mutex); | ||
| 1323 | |||
| 1324 | /* | ||
| 1325 | * product_name shows the name or version of the hardware | ||
| 1326 | * paired with current firmware in the chip. | ||
| 1327 | */ | ||
| 1328 | count = snprintf(buf, PAGE_SIZE, "%.*s\n", | ||
| 1329 | (int)sizeof(ts->product_name), ts->product_name); | ||
| 1330 | |||
| 1331 | mutex_unlock(&ts->input->mutex); | ||
| 1332 | |||
| 1333 | return count; | ||
| 1334 | } | ||
| 1335 | |||
| 1336 | static DEVICE_ATTR(hw_version, S_IRUGO, mip4_sysfs_read_hw_version, NULL); | ||
| 1337 | |||
| 1313 | static struct attribute *mip4_attrs[] = { | 1338 | static struct attribute *mip4_attrs[] = { |
| 1314 | &dev_attr_fw_version.attr, | 1339 | &dev_attr_fw_version.attr, |
| 1340 | &dev_attr_hw_version.attr, | ||
| 1315 | &dev_attr_update_fw.attr, | 1341 | &dev_attr_update_fw.attr, |
| 1316 | NULL, | 1342 | NULL, |
| 1317 | }; | 1343 | }; |
| @@ -1512,6 +1538,6 @@ static struct i2c_driver mip4_driver = { | |||
| 1512 | module_i2c_driver(mip4_driver); | 1538 | module_i2c_driver(mip4_driver); |
| 1513 | 1539 | ||
| 1514 | MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); | 1540 | MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); |
| 1515 | MODULE_VERSION("2016.03.03"); | 1541 | MODULE_VERSION("2016.03.12"); |
| 1516 | MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>"); | 1542 | MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>"); |
| 1517 | MODULE_LICENSE("GPL"); | 1543 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index b6c4d03de340..880c40b23f66 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c | |||
| @@ -197,28 +197,34 @@ static int sur40_command(struct sur40_state *dev, | |||
| 197 | static int sur40_init(struct sur40_state *dev) | 197 | static int sur40_init(struct sur40_state *dev) |
| 198 | { | 198 | { |
| 199 | int result; | 199 | int result; |
| 200 | u8 buffer[24]; | 200 | u8 *buffer; |
| 201 | |||
| 202 | buffer = kmalloc(24, GFP_KERNEL); | ||
| 203 | if (!buffer) { | ||
| 204 | result = -ENOMEM; | ||
| 205 | goto error; | ||
| 206 | } | ||
| 201 | 207 | ||
| 202 | /* stupidly replay the original MS driver init sequence */ | 208 | /* stupidly replay the original MS driver init sequence */ |
| 203 | result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12); | 209 | result = sur40_command(dev, SUR40_GET_VERSION, 0x00, buffer, 12); |
| 204 | if (result < 0) | 210 | if (result < 0) |
| 205 | return result; | 211 | goto error; |
| 206 | 212 | ||
| 207 | result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12); | 213 | result = sur40_command(dev, SUR40_GET_VERSION, 0x01, buffer, 12); |
| 208 | if (result < 0) | 214 | if (result < 0) |
| 209 | return result; | 215 | goto error; |
| 210 | 216 | ||
| 211 | result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12); | 217 | result = sur40_command(dev, SUR40_GET_VERSION, 0x02, buffer, 12); |
| 212 | if (result < 0) | 218 | if (result < 0) |
| 213 | return result; | 219 | goto error; |
| 214 | 220 | ||
| 215 | result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24); | 221 | result = sur40_command(dev, SUR40_UNKNOWN2, 0x00, buffer, 24); |
| 216 | if (result < 0) | 222 | if (result < 0) |
| 217 | return result; | 223 | goto error; |
| 218 | 224 | ||
| 219 | result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5); | 225 | result = sur40_command(dev, SUR40_UNKNOWN1, 0x00, buffer, 5); |
| 220 | if (result < 0) | 226 | if (result < 0) |
| 221 | return result; | 227 | goto error; |
| 222 | 228 | ||
| 223 | result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); | 229 | result = sur40_command(dev, SUR40_GET_VERSION, 0x03, buffer, 12); |
| 224 | 230 | ||
| @@ -226,7 +232,8 @@ static int sur40_init(struct sur40_state *dev) | |||
| 226 | * Discard the result buffer - no known data inside except | 232 | * Discard the result buffer - no known data inside except |
| 227 | * some version strings, maybe extract these sometime... | 233 | * some version strings, maybe extract these sometime... |
| 228 | */ | 234 | */ |
| 229 | 235 | error: | |
| 236 | kfree(buffer); | ||
| 230 | return result; | 237 | return result; |
| 231 | } | 238 | } |
| 232 | 239 | ||
