Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull more input updates from Dmitry Torokhov:
"Second round of updates for the input subsystem.

The BYD PS/2 protocol driver now uses absolute reporting mode and
should behave more like other touchpads; Synaptics driver needed to
extend one of its quirks to a newer firmware version, and a few USB
drivers got tightened up checks for the contents of their descriptors"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: sur40 - fix DMA on stack
Input: ati_remote2 - fix crashes on detecting device with invalid descriptor
Input: synaptics - handle spurious release of trackstick buttons, again
Input: synaptics-rmi4 - remove check of Non-NULL array
Input: byd - enable absolute mode
Input: ims-pcu - sanity check against missing interfaces
Input: melfas_mip4 - add hw_version sysfs attribute

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