1 /* 2 * HID Driver for ELAN Touchpad 3 * 4 * Currently only supports touchpad found on HP Pavilion X2 10 5 * 6 * Copyright (c) 2016 Alexandrov Stanislav <neko@nya.ai> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation; either version 2 of the License, or (at your option) 11 * any later version. 12 */ 13 14 #include <linux/hid.h> 15 #include <linux/input/mt.h> 16 #include <linux/leds.h> 17 #include <linux/module.h> 18 #include <linux/usb.h> 19 20 #include "hid-ids.h" 21 22 #define ELAN_SINGLE_FINGER 0x81 23 #define ELAN_MT_FIRST_FINGER 0x82 24 #define ELAN_MT_SECOND_FINGER 0x83 25 #define ELAN_INPUT_REPORT_SIZE 8 26 27 #define ELAN_MUTE_LED_REPORT 0xBC 28 #define ELAN_LED_REPORT_SIZE 8 29 30 struct elan_touchpad_settings { 31 u8 max_fingers; 32 u16 max_x; 33 u16 max_y; 34 u8 max_area_x; 35 u8 max_area_y; 36 u8 max_w; 37 int usb_bInterfaceNumber; 38 }; 39 40 struct elan_drvdata { 41 struct input_dev *input; 42 u8 prev_report[ELAN_INPUT_REPORT_SIZE]; 43 struct led_classdev mute_led; 44 u8 mute_led_state; 45 struct elan_touchpad_settings *settings; 46 }; 47 48 static int is_not_elan_touchpad(struct hid_device *hdev) 49 { 50 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 51 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 52 53 return (intf->altsetting->desc.bInterfaceNumber != drvdata->settings->usb_bInterfaceNumber); 54 } 55 56 static int elan_input_mapping(struct hid_device *hdev, struct hid_input *hi, 57 struct hid_field *field, struct hid_usage *usage, 58 unsigned long **bit, int *max) 59 { 60 if (is_not_elan_touchpad(hdev)) 61 return 0; 62 63 if (field->report->id == ELAN_SINGLE_FINGER || 64 field->report->id == ELAN_MT_FIRST_FINGER || 65 field->report->id == ELAN_MT_SECOND_FINGER) 66 return -1; 67 68 return 0; 69 } 70 71 static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi) 72 { 73 int ret; 74 struct input_dev *input; 75 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 76 77 if (is_not_elan_touchpad(hdev)) 78 return 0; 79 80 input = devm_input_allocate_device(&hdev->dev); 81 if (!input) 82 return -ENOMEM; 83 84 input->name = "Elan Touchpad"; 85 input->phys = hdev->phys; 86 input->uniq = hdev->uniq; 87 input->id.bustype = hdev->bus; 88 input->id.vendor = hdev->vendor; 89 input->id.product = hdev->product; 90 input->id.version = hdev->version; 91 input->dev.parent = &hdev->dev; 92 93 input_set_abs_params(input, ABS_MT_POSITION_X, 0, 94 drvdata->settings->max_x, 0, 0); 95 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, 96 drvdata->settings->max_y, 0, 0); 97 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 98 drvdata->settings->max_fingers, 0, 0); 99 input_set_abs_params(input, ABS_TOOL_WIDTH, 0, 100 drvdata->settings->max_w, 0, 0); 101 102 __set_bit(BTN_LEFT, input->keybit); 103 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 104 105 ret = input_mt_init_slots(input, drvdata->settings->max_fingers, 106 INPUT_MT_POINTER); 107 if (ret) { 108 hid_err(hdev, "Failed to init elan MT slots: %d\n", ret); 109 return ret; 110 } 111 112 ret = input_register_device(input); 113 if (ret) { 114 hid_err(hdev, "Failed to register elan input device: %d\n", 115 ret); 116 input_free_device(input); 117 return ret; 118 } 119 120 drvdata->input = input; 121 122 return 0; 123 } 124 125 static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data, 126 unsigned int slot_num) 127 { 128 struct input_dev *input = drvdata->input; 129 int x, y, w; 130 131 bool active = !!data; 132 133 input_mt_slot(input, slot_num); 134 input_mt_report_slot_state(input, MT_TOOL_FINGER, active); 135 if (active) { 136 x = ((data[0] & 0xF0) << 4) | data[1]; 137 y = drvdata->settings->max_y - 138 (((data[0] & 0x07) << 8) | data[2]); 139 w = data[4]; 140 141 input_report_abs(input, ABS_MT_POSITION_X, x); 142 input_report_abs(input, ABS_MT_POSITION_Y, y); 143 input_report_abs(input, ABS_TOOL_WIDTH, w); 144 } 145 } 146 147 static void elan_report_input(struct elan_drvdata *drvdata, u8 *data) 148 { 149 int i; 150 struct input_dev *input = drvdata->input; 151 152 /* 153 * There is 3 types of reports: for single touch, 154 * for multitouch - first finger and for multitouch - second finger 155 * 156 * packet structure for ELAN_SINGLE_FINGER and ELAN_MT_FIRST_FINGER: 157 * 158 * byte 1: 1 0 0 0 0 0 0 1 // 0x81 or 0x82 159 * byte 2: 0 0 0 0 0 0 0 0 // looks like unused 160 * byte 3: f5 f4 f3 f2 f1 0 0 L 161 * byte 4: x12 x11 x10 x9 0? y11 y10 y9 162 * byte 5: x8 x7 x6 x5 x4 x3 x2 x1 163 * byte 6: y8 y7 y6 y5 y4 y3 y2 y1 164 * byte 7: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1 165 * byte 8: w8 w7 w6 w5 w4 w3 w2 w1 166 * 167 * packet structure for ELAN_MT_SECOND_FINGER: 168 * 169 * byte 1: 1 0 0 0 0 0 1 1 // 0x83 170 * byte 2: x12 x11 x10 x9 0 y11 y10 y9 171 * byte 3: x8 x7 x6 x5 x4 x3 x2 x1 172 * byte 4: y8 y7 y6 y5 y4 y3 y2 y1 173 * byte 5: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1 174 * byte 6: w8 w7 w6 w5 w4 w3 w2 w1 175 * byte 7: 0 0 0 0 0 0 0 0 176 * byte 8: 0 0 0 0 0 0 0 0 177 * 178 * f5-f1: finger touch bits 179 * L: clickpad button 180 * sy / sx: not sure yet, but this looks like rectangular 181 * area for finger 182 * w: looks like finger width 183 */ 184 185 if (data[0] == ELAN_SINGLE_FINGER) { 186 for (i = 0; i < drvdata->settings->max_fingers; i++) { 187 if (data[2] & BIT(i + 3)) 188 elan_report_mt_slot(drvdata, data + 3, i); 189 else 190 elan_report_mt_slot(drvdata, NULL, i); 191 } 192 input_report_key(input, BTN_LEFT, data[2] & 0x01); 193 } 194 /* 195 * When touched with two fingers Elan touchpad will emit two HID reports 196 * first is ELAN_MT_FIRST_FINGER and second is ELAN_MT_SECOND_FINGER 197 * we will save ELAN_MT_FIRST_FINGER report and wait for 198 * ELAN_MT_SECOND_FINGER to finish multitouch 199 */ 200 if (data[0] == ELAN_MT_FIRST_FINGER) { 201 memcpy(drvdata->prev_report, data, 202 sizeof(drvdata->prev_report)); 203 return; 204 } 205 206 if (data[0] == ELAN_MT_SECOND_FINGER) { 207 int first = 0; 208 u8 *prev_report = drvdata->prev_report; 209 210 if (prev_report[0] != ELAN_MT_FIRST_FINGER) 211 return; 212 213 for (i = 0; i < drvdata->settings->max_fingers; i++) { 214 if (prev_report[2] & BIT(i + 3)) { 215 if (!first) { 216 first = 1; 217 elan_report_mt_slot(drvdata, prev_report + 3, i); 218 } else { 219 elan_report_mt_slot(drvdata, data + 1, i); 220 } 221 } else { 222 elan_report_mt_slot(drvdata, NULL, i); 223 } 224 } 225 input_report_key(input, BTN_LEFT, prev_report[2] & 0x01); 226 } 227 228 input_mt_sync_frame(input); 229 input_sync(input); 230 } 231 232 static int elan_raw_event(struct hid_device *hdev, 233 struct hid_report *report, u8 *data, int size) 234 { 235 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 236 237 if (is_not_elan_touchpad(hdev)) 238 return 0; 239 240 if (data[0] == ELAN_SINGLE_FINGER || 241 data[0] == ELAN_MT_FIRST_FINGER || 242 data[0] == ELAN_MT_SECOND_FINGER) { 243 if (size == ELAN_INPUT_REPORT_SIZE) { 244 elan_report_input(drvdata, data); 245 return 1; 246 } 247 } 248 249 return 0; 250 } 251 252 static int elan_start_multitouch(struct hid_device *hdev) 253 { 254 int ret; 255 256 /* 257 * This byte sequence will enable multitouch mode and disable 258 * mouse emulation 259 */ 260 const unsigned char buf[] = { 0x0D, 0x00, 0x03, 0x21, 0x00 }; 261 unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL); 262 263 if (!dmabuf) 264 return -ENOMEM; 265 266 ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf), 267 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 268 269 kfree(dmabuf); 270 271 if (ret != sizeof(buf)) { 272 hid_err(hdev, "Failed to start multitouch: %d\n", ret); 273 return ret; 274 } 275 276 return 0; 277 } 278 279 static enum led_brightness elan_mute_led_get_brigtness(struct led_classdev *led_cdev) 280 { 281 struct device *dev = led_cdev->dev->parent; 282 struct hid_device *hdev = to_hid_device(dev); 283 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 284 285 return drvdata->mute_led_state; 286 } 287 288 static int elan_mute_led_set_brigtness(struct led_classdev *led_cdev, 289 enum led_brightness value) 290 { 291 int ret; 292 u8 led_state; 293 struct device *dev = led_cdev->dev->parent; 294 struct hid_device *hdev = to_hid_device(dev); 295 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 296 297 unsigned char *dmabuf = kzalloc(ELAN_LED_REPORT_SIZE, GFP_KERNEL); 298 299 if (!dmabuf) 300 return -ENOMEM; 301 302 led_state = !!value; 303 304 dmabuf[0] = ELAN_MUTE_LED_REPORT; 305 dmabuf[1] = 0x02; 306 dmabuf[2] = led_state; 307 308 ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, ELAN_LED_REPORT_SIZE, 309 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 310 311 kfree(dmabuf); 312 313 if (ret != ELAN_LED_REPORT_SIZE) { 314 hid_err(hdev, "Failed to set mute led brightness: %d\n", ret); 315 return ret; 316 } 317 318 drvdata->mute_led_state = led_state; 319 return 0; 320 } 321 322 static int elan_init_mute_led(struct hid_device *hdev) 323 { 324 struct elan_drvdata *drvdata = hid_get_drvdata(hdev); 325 struct led_classdev *mute_led = &drvdata->mute_led; 326 327 mute_led->name = "elan:red:mute"; 328 mute_led->brightness_get = elan_mute_led_get_brigtness; 329 mute_led->brightness_set_blocking = elan_mute_led_set_brigtness; 330 mute_led->max_brightness = LED_ON; 331 mute_led->dev = &hdev->dev; 332 333 return devm_led_classdev_register(&hdev->dev, mute_led); 334 } 335 336 static int elan_probe(struct hid_device *hdev, const struct hid_device_id *id) 337 { 338 int ret; 339 struct elan_drvdata *drvdata; 340 341 drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); 342 343 if (!drvdata) 344 return -ENOMEM; 345 346 drvdata->settings = (struct elan_touchpad_settings *)id->driver_data; 347 hid_set_drvdata(hdev, drvdata); 348 349 ret = hid_parse(hdev); 350 if (ret) { 351 hid_err(hdev, "Hid Parse failed\n"); 352 return ret; 353 } 354 355 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 356 if (ret) { 357 hid_err(hdev, "Hid hw start failed\n"); 358 return ret; 359 } 360 361 if (is_not_elan_touchpad(hdev)) 362 return 0; 363 364 if (!drvdata->input) { 365 hid_err(hdev, "Input device is not registred\n"); 366 ret = -ENAVAIL; 367 goto err; 368 } 369 370 ret = elan_start_multitouch(hdev); 371 if (ret) 372 goto err; 373 374 ret = elan_init_mute_led(hdev); 375 if (ret) 376 goto err; 377 378 return 0; 379 err: 380 hid_hw_stop(hdev); 381 return ret; 382 } 383 384 static void elan_remove(struct hid_device *hdev) 385 { 386 hid_hw_stop(hdev); 387 } 388 389 static const struct elan_touchpad_settings hp_x2_10_touchpad_data = { 390 .max_fingers = 5, 391 .max_x = 2930, 392 .max_y = 1250, 393 .max_area_x = 15, 394 .max_area_y = 15, 395 .max_w = 255, 396 .usb_bInterfaceNumber = 1, 397 }; 398 399 static const struct hid_device_id elan_devices[] = { 400 { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER), 401 (kernel_ulong_t)&hp_x2_10_touchpad_data}, 402 { } 403 }; 404 405 MODULE_DEVICE_TABLE(hid, elan_devices); 406 407 static struct hid_driver elan_driver = { 408 .name = "elan", 409 .id_table = elan_devices, 410 .input_mapping = elan_input_mapping, 411 .input_configured = elan_input_configured, 412 .raw_event = elan_raw_event, 413 .probe = elan_probe, 414 .remove = elan_remove, 415 }; 416 417 module_hid_driver(elan_driver); 418 419 MODULE_LICENSE("GPL"); 420 MODULE_AUTHOR("Alexandrov Stanislav"); 421 MODULE_DESCRIPTION("Driver for HID ELAN Touchpads"); 422