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