root/drivers/hid/hid-elan.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_not_elan_touchpad
  2. elan_input_mapping
  3. elan_get_device_param
  4. elan_convert_res
  5. elan_get_device_params
  6. elan_input_configured
  7. elan_report_mt_slot
  8. elan_usb_report_input
  9. elan_i2c_report_input
  10. elan_raw_event
  11. elan_start_multitouch
  12. elan_mute_led_get_brigtness
  13. elan_mute_led_set_brigtness
  14. elan_init_mute_led
  15. elan_probe
  16. elan_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * HID Driver for ELAN Touchpad
   4  *
   5  * Currently only supports touchpad found on HP Pavilion X2 10
   6  *
   7  * Copyright (c) 2016 Alexandrov Stanislav <neko@nya.ai>
   8  */
   9 
  10 #include <linux/hid.h>
  11 #include <linux/input/mt.h>
  12 #include <linux/leds.h>
  13 #include <linux/module.h>
  14 #include <linux/usb.h>
  15 
  16 #include "hid-ids.h"
  17 
  18 #define ELAN_MT_I2C             0x5d
  19 #define ELAN_SINGLE_FINGER      0x81
  20 #define ELAN_MT_FIRST_FINGER    0x82
  21 #define ELAN_MT_SECOND_FINGER   0x83
  22 #define ELAN_INPUT_REPORT_SIZE  8
  23 #define ELAN_I2C_REPORT_SIZE    32
  24 #define ELAN_FINGER_DATA_LEN    5
  25 #define ELAN_MAX_FINGERS        5
  26 #define ELAN_MAX_PRESSURE       255
  27 #define ELAN_TP_USB_INTF        1
  28 
  29 #define ELAN_FEATURE_REPORT     0x0d
  30 #define ELAN_FEATURE_SIZE       5
  31 #define ELAN_PARAM_MAX_X        6
  32 #define ELAN_PARAM_MAX_Y        7
  33 #define ELAN_PARAM_RES          8
  34 
  35 #define ELAN_MUTE_LED_REPORT    0xBC
  36 #define ELAN_LED_REPORT_SIZE    8
  37 
  38 #define ELAN_HAS_LED            BIT(0)
  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         u16 max_x;
  46         u16 max_y;
  47         u16 res_x;
  48         u16 res_y;
  49 };
  50 
  51 static int is_not_elan_touchpad(struct hid_device *hdev)
  52 {
  53         if (hdev->bus == BUS_USB) {
  54                 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
  55 
  56                 return (intf->altsetting->desc.bInterfaceNumber !=
  57                         ELAN_TP_USB_INTF);
  58         }
  59 
  60         return 0;
  61 }
  62 
  63 static int elan_input_mapping(struct hid_device *hdev, struct hid_input *hi,
  64                               struct hid_field *field, struct hid_usage *usage,
  65                               unsigned long **bit, int *max)
  66 {
  67         if (is_not_elan_touchpad(hdev))
  68                 return 0;
  69 
  70         if (field->report->id == ELAN_SINGLE_FINGER ||
  71             field->report->id == ELAN_MT_FIRST_FINGER ||
  72             field->report->id == ELAN_MT_SECOND_FINGER ||
  73             field->report->id == ELAN_MT_I2C)
  74                 return -1;
  75 
  76         return 0;
  77 }
  78 
  79 static int elan_get_device_param(struct hid_device *hdev,
  80                                  unsigned char *dmabuf, unsigned char param)
  81 {
  82         int ret;
  83 
  84         dmabuf[0] = ELAN_FEATURE_REPORT;
  85         dmabuf[1] = 0x05;
  86         dmabuf[2] = 0x03;
  87         dmabuf[3] = param;
  88         dmabuf[4] = 0x01;
  89 
  90         ret = hid_hw_raw_request(hdev, ELAN_FEATURE_REPORT, dmabuf,
  91                                  ELAN_FEATURE_SIZE, HID_FEATURE_REPORT,
  92                                  HID_REQ_SET_REPORT);
  93         if (ret != ELAN_FEATURE_SIZE) {
  94                 hid_err(hdev, "Set report error for parm %d: %d\n", param, ret);
  95                 return ret;
  96         }
  97 
  98         ret = hid_hw_raw_request(hdev, ELAN_FEATURE_REPORT, dmabuf,
  99                                  ELAN_FEATURE_SIZE, HID_FEATURE_REPORT,
 100                                  HID_REQ_GET_REPORT);
 101         if (ret != ELAN_FEATURE_SIZE) {
 102                 hid_err(hdev, "Get report error for parm %d: %d\n", param, ret);
 103                 return ret;
 104         }
 105 
 106         return 0;
 107 }
 108 
 109 static unsigned int elan_convert_res(char val)
 110 {
 111         /*
 112          * (value from firmware) * 10 + 790 = dpi
 113          * dpi * 10 / 254 = dots/mm
 114          */
 115         return (val * 10 + 790) * 10 / 254;
 116 }
 117 
 118 static int elan_get_device_params(struct hid_device *hdev)
 119 {
 120         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 121         unsigned char *dmabuf;
 122         int ret;
 123 
 124         dmabuf = kmalloc(ELAN_FEATURE_SIZE, GFP_KERNEL);
 125         if (!dmabuf)
 126                 return -ENOMEM;
 127 
 128         ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_MAX_X);
 129         if (ret)
 130                 goto err;
 131 
 132         drvdata->max_x = (dmabuf[4] << 8) | dmabuf[3];
 133 
 134         ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_MAX_Y);
 135         if (ret)
 136                 goto err;
 137 
 138         drvdata->max_y = (dmabuf[4] << 8) | dmabuf[3];
 139 
 140         ret = elan_get_device_param(hdev, dmabuf, ELAN_PARAM_RES);
 141         if (ret)
 142                 goto err;
 143 
 144         drvdata->res_x = elan_convert_res(dmabuf[3]);
 145         drvdata->res_y = elan_convert_res(dmabuf[4]);
 146 
 147 err:
 148         kfree(dmabuf);
 149         return ret;
 150 }
 151 
 152 static int elan_input_configured(struct hid_device *hdev, struct hid_input *hi)
 153 {
 154         int ret;
 155         struct input_dev *input;
 156         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 157 
 158         if (is_not_elan_touchpad(hdev))
 159                 return 0;
 160 
 161         ret = elan_get_device_params(hdev);
 162         if (ret)
 163                 return ret;
 164 
 165         input = devm_input_allocate_device(&hdev->dev);
 166         if (!input)
 167                 return -ENOMEM;
 168 
 169         input->name = "Elan Touchpad";
 170         input->phys = hdev->phys;
 171         input->uniq = hdev->uniq;
 172         input->id.bustype = hdev->bus;
 173         input->id.vendor  = hdev->vendor;
 174         input->id.product = hdev->product;
 175         input->id.version = hdev->version;
 176         input->dev.parent = &hdev->dev;
 177 
 178         input_set_abs_params(input, ABS_MT_POSITION_X, 0, drvdata->max_x,
 179                              0, 0);
 180         input_set_abs_params(input, ABS_MT_POSITION_Y, 0, drvdata->max_y,
 181                              0, 0);
 182         input_set_abs_params(input, ABS_MT_PRESSURE, 0, ELAN_MAX_PRESSURE,
 183                              0, 0);
 184 
 185         __set_bit(BTN_LEFT, input->keybit);
 186         __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
 187 
 188         ret = input_mt_init_slots(input, ELAN_MAX_FINGERS, INPUT_MT_POINTER);
 189         if (ret) {
 190                 hid_err(hdev, "Failed to init elan MT slots: %d\n", ret);
 191                 return ret;
 192         }
 193 
 194         input_abs_set_res(input, ABS_X, drvdata->res_x);
 195         input_abs_set_res(input, ABS_Y, drvdata->res_y);
 196 
 197         ret = input_register_device(input);
 198         if (ret) {
 199                 hid_err(hdev, "Failed to register elan input device: %d\n",
 200                         ret);
 201                 input_free_device(input);
 202                 return ret;
 203         }
 204 
 205         drvdata->input = input;
 206 
 207         return 0;
 208 }
 209 
 210 static void elan_report_mt_slot(struct elan_drvdata *drvdata, u8 *data,
 211                                 unsigned int slot_num)
 212 {
 213         struct input_dev *input = drvdata->input;
 214         int x, y, p;
 215 
 216         bool active = !!data;
 217 
 218         input_mt_slot(input, slot_num);
 219         input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
 220         if (active) {
 221                 x = ((data[0] & 0xF0) << 4) | data[1];
 222                 y = drvdata->max_y -
 223                     (((data[0] & 0x07) << 8) | data[2]);
 224                 p = data[4];
 225 
 226                 input_report_abs(input, ABS_MT_POSITION_X, x);
 227                 input_report_abs(input, ABS_MT_POSITION_Y, y);
 228                 input_report_abs(input, ABS_MT_PRESSURE, p);
 229         }
 230 }
 231 
 232 static void elan_usb_report_input(struct elan_drvdata *drvdata, u8 *data)
 233 {
 234         int i;
 235         struct input_dev *input = drvdata->input;
 236 
 237         /*
 238          * There is 3 types of reports: for single touch,
 239          * for multitouch - first finger and for multitouch - second finger
 240          *
 241          * packet structure for ELAN_SINGLE_FINGER and ELAN_MT_FIRST_FINGER:
 242          *
 243          * byte 1: 1   0   0   0   0   0   0   1  // 0x81 or 0x82
 244          * byte 2: 0   0   0   0   0   0   0   0  // looks like unused
 245          * byte 3: f5  f4  f3  f2  f1  0   0   L
 246          * byte 4: x12 x11 x10 x9  0?  y11 y10 y9
 247          * byte 5: x8  x7  x6  x5  x4  x3  x2  x1
 248          * byte 6: y8  y7  y6  y5  y4  y3  y2  y1
 249          * byte 7: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
 250          * byte 8: p8  p7  p6  p5  p4  p3  p2  p1
 251          *
 252          * packet structure for ELAN_MT_SECOND_FINGER:
 253          *
 254          * byte 1: 1   0   0   0   0   0   1   1  // 0x83
 255          * byte 2: x12 x11 x10 x9  0   y11 y10 y9
 256          * byte 3: x8  x7  x6  x5  x4  x3  x2  x1
 257          * byte 4: y8  y7  y6  y5  y4  y3  y2  y1
 258          * byte 5: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
 259          * byte 6: p8  p7  p6  p5  p4  p3  p2  p1
 260          * byte 7: 0   0   0   0   0   0   0   0
 261          * byte 8: 0   0   0   0   0   0   0   0
 262          *
 263          * f5-f1: finger touch bits
 264          * L: clickpad button
 265          * sy / sx: finger width / height expressed in traces, the total number
 266          *          of traces can be queried by doing a HID_REQ_SET_REPORT
 267          *          { 0x0d, 0x05, 0x03, 0x05, 0x01 } followed by a GET, in the
 268          *          returned buf, buf[3]=no-x-traces, buf[4]=no-y-traces.
 269          * p: pressure
 270          */
 271 
 272         if (data[0] == ELAN_SINGLE_FINGER) {
 273                 for (i = 0; i < ELAN_MAX_FINGERS; i++) {
 274                         if (data[2] & BIT(i + 3))
 275                                 elan_report_mt_slot(drvdata, data + 3, i);
 276                         else
 277                                 elan_report_mt_slot(drvdata, NULL, i);
 278                 }
 279                 input_report_key(input, BTN_LEFT, data[2] & 0x01);
 280         }
 281         /*
 282          * When touched with two fingers Elan touchpad will emit two HID reports
 283          * first is ELAN_MT_FIRST_FINGER and second is ELAN_MT_SECOND_FINGER
 284          * we will save ELAN_MT_FIRST_FINGER report and wait for
 285          * ELAN_MT_SECOND_FINGER to finish multitouch
 286          */
 287         if (data[0] == ELAN_MT_FIRST_FINGER) {
 288                 memcpy(drvdata->prev_report, data,
 289                        sizeof(drvdata->prev_report));
 290                 return;
 291         }
 292 
 293         if (data[0] == ELAN_MT_SECOND_FINGER) {
 294                 int first = 0;
 295                 u8 *prev_report = drvdata->prev_report;
 296 
 297                 if (prev_report[0] != ELAN_MT_FIRST_FINGER)
 298                         return;
 299 
 300                 for (i = 0; i < ELAN_MAX_FINGERS; i++) {
 301                         if (prev_report[2] & BIT(i + 3)) {
 302                                 if (!first) {
 303                                         first = 1;
 304                                         elan_report_mt_slot(drvdata, prev_report + 3, i);
 305                                 } else {
 306                                         elan_report_mt_slot(drvdata, data + 1, i);
 307                                 }
 308                         } else {
 309                                 elan_report_mt_slot(drvdata, NULL, i);
 310                         }
 311                 }
 312                 input_report_key(input, BTN_LEFT, prev_report[2] & 0x01);
 313         }
 314 
 315         input_mt_sync_frame(input);
 316         input_sync(input);
 317 }
 318 
 319 static void elan_i2c_report_input(struct elan_drvdata *drvdata, u8 *data)
 320 {
 321         struct input_dev *input = drvdata->input;
 322         u8 *finger_data;
 323         int i;
 324 
 325         /*
 326          * Elan MT touchpads in i2c mode send finger data in the same format
 327          * as in USB mode, but then with all fingers in a single packet.
 328          *
 329          * packet structure for ELAN_MT_I2C:
 330          *
 331          * byte     1: 1   0   0   1   1   1   0   1   // 0x5d
 332          * byte     2: f5  f4  f3  f2  f1  0   0   L
 333          * byte     3: x12 x11 x10 x9  0?  y11 y10 y9
 334          * byte     4: x8  x7  x6  x5  x4  x3  x2  x1
 335          * byte     5: y8  y7  y6  y5  y4  y3  y2  y1
 336          * byte     6: sy4 sy3 sy2 sy1 sx4 sx3 sx2 sx1
 337          * byte     7: p8  p7  p6  p5  p4  p3  p2  p1
 338          * byte  8-12: Same as byte 3-7 for second finger down
 339          * byte 13-17: Same as byte 3-7 for third finger down
 340          * byte 18-22: Same as byte 3-7 for fourth finger down
 341          * byte 23-27: Same as byte 3-7 for fifth finger down
 342          */
 343 
 344         finger_data = data + 2;
 345         for (i = 0; i < ELAN_MAX_FINGERS; i++) {
 346                 if (data[1] & BIT(i + 3)) {
 347                         elan_report_mt_slot(drvdata, finger_data, i);
 348                         finger_data += ELAN_FINGER_DATA_LEN;
 349                 } else {
 350                         elan_report_mt_slot(drvdata, NULL, i);
 351                 }
 352         }
 353 
 354         input_report_key(input, BTN_LEFT, data[1] & 0x01);
 355         input_mt_sync_frame(input);
 356         input_sync(input);
 357 }
 358 
 359 static int elan_raw_event(struct hid_device *hdev,
 360                           struct hid_report *report, u8 *data, int size)
 361 {
 362         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 363 
 364         if (is_not_elan_touchpad(hdev))
 365                 return 0;
 366 
 367         if (data[0] == ELAN_SINGLE_FINGER ||
 368             data[0] == ELAN_MT_FIRST_FINGER ||
 369             data[0] == ELAN_MT_SECOND_FINGER) {
 370                 if (size == ELAN_INPUT_REPORT_SIZE) {
 371                         elan_usb_report_input(drvdata, data);
 372                         return 1;
 373                 }
 374         }
 375 
 376         if (data[0] == ELAN_MT_I2C && size == ELAN_I2C_REPORT_SIZE) {
 377                 elan_i2c_report_input(drvdata, data);
 378                 return 1;
 379         }
 380 
 381         return 0;
 382 }
 383 
 384 static int elan_start_multitouch(struct hid_device *hdev)
 385 {
 386         int ret;
 387 
 388         /*
 389          * This byte sequence will enable multitouch mode and disable
 390          * mouse emulation
 391          */
 392         static const unsigned char buf[] = { 0x0D, 0x00, 0x03, 0x21, 0x00 };
 393         unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
 394 
 395         if (!dmabuf)
 396                 return -ENOMEM;
 397 
 398         ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, sizeof(buf),
 399                                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
 400 
 401         kfree(dmabuf);
 402 
 403         if (ret != sizeof(buf)) {
 404                 hid_err(hdev, "Failed to start multitouch: %d\n", ret);
 405                 return ret;
 406         }
 407 
 408         return 0;
 409 }
 410 
 411 static enum led_brightness elan_mute_led_get_brigtness(struct led_classdev *led_cdev)
 412 {
 413         struct device *dev = led_cdev->dev->parent;
 414         struct hid_device *hdev = to_hid_device(dev);
 415         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 416 
 417         return drvdata->mute_led_state;
 418 }
 419 
 420 static int elan_mute_led_set_brigtness(struct led_classdev *led_cdev,
 421                                        enum led_brightness value)
 422 {
 423         int ret;
 424         u8 led_state;
 425         struct device *dev = led_cdev->dev->parent;
 426         struct hid_device *hdev = to_hid_device(dev);
 427         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 428 
 429         unsigned char *dmabuf = kzalloc(ELAN_LED_REPORT_SIZE, GFP_KERNEL);
 430 
 431         if (!dmabuf)
 432                 return -ENOMEM;
 433 
 434         led_state = !!value;
 435 
 436         dmabuf[0] = ELAN_MUTE_LED_REPORT;
 437         dmabuf[1] = 0x02;
 438         dmabuf[2] = led_state;
 439 
 440         ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, ELAN_LED_REPORT_SIZE,
 441                                  HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
 442 
 443         kfree(dmabuf);
 444 
 445         if (ret != ELAN_LED_REPORT_SIZE) {
 446                 hid_err(hdev, "Failed to set mute led brightness: %d\n", ret);
 447                 return ret;
 448         }
 449 
 450         drvdata->mute_led_state = led_state;
 451         return 0;
 452 }
 453 
 454 static int elan_init_mute_led(struct hid_device *hdev)
 455 {
 456         struct elan_drvdata *drvdata = hid_get_drvdata(hdev);
 457         struct led_classdev *mute_led = &drvdata->mute_led;
 458 
 459         mute_led->name = "elan:red:mute";
 460         mute_led->brightness_get = elan_mute_led_get_brigtness;
 461         mute_led->brightness_set_blocking = elan_mute_led_set_brigtness;
 462         mute_led->max_brightness = LED_ON;
 463         mute_led->dev = &hdev->dev;
 464 
 465         return devm_led_classdev_register(&hdev->dev, mute_led);
 466 }
 467 
 468 static int elan_probe(struct hid_device *hdev, const struct hid_device_id *id)
 469 {
 470         int ret;
 471         struct elan_drvdata *drvdata;
 472 
 473         drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
 474 
 475         if (!drvdata)
 476                 return -ENOMEM;
 477 
 478         hid_set_drvdata(hdev, drvdata);
 479 
 480         ret = hid_parse(hdev);
 481         if (ret) {
 482                 hid_err(hdev, "Hid Parse failed\n");
 483                 return ret;
 484         }
 485 
 486         ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 487         if (ret) {
 488                 hid_err(hdev, "Hid hw start failed\n");
 489                 return ret;
 490         }
 491 
 492         if (is_not_elan_touchpad(hdev))
 493                 return 0;
 494 
 495         if (!drvdata->input) {
 496                 hid_err(hdev, "Input device is not registered\n");
 497                 ret = -ENAVAIL;
 498                 goto err;
 499         }
 500 
 501         ret = elan_start_multitouch(hdev);
 502         if (ret)
 503                 goto err;
 504 
 505         if (id->driver_data & ELAN_HAS_LED) {
 506                 ret = elan_init_mute_led(hdev);
 507                 if (ret)
 508                         goto err;
 509         }
 510 
 511         return 0;
 512 err:
 513         hid_hw_stop(hdev);
 514         return ret;
 515 }
 516 
 517 static void elan_remove(struct hid_device *hdev)
 518 {
 519         hid_hw_stop(hdev);
 520 }
 521 
 522 static const struct hid_device_id elan_devices[] = {
 523         { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2),
 524           .driver_data = ELAN_HAS_LED },
 525         { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_HP_X2_10_COVER),
 526           .driver_data = ELAN_HAS_LED },
 527         { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_TOSHIBA_CLICK_L9W) },
 528         { }
 529 };
 530 MODULE_DEVICE_TABLE(hid, elan_devices);
 531 
 532 static struct hid_driver elan_driver = {
 533         .name = "elan",
 534         .id_table = elan_devices,
 535         .input_mapping = elan_input_mapping,
 536         .input_configured = elan_input_configured,
 537         .raw_event = elan_raw_event,
 538         .probe = elan_probe,
 539         .remove = elan_remove,
 540 };
 541 
 542 module_hid_driver(elan_driver);
 543 
 544 MODULE_LICENSE("GPL");
 545 MODULE_AUTHOR("Alexandrov Stanislav");
 546 MODULE_DESCRIPTION("Driver for HID ELAN Touchpads");

/* [<][>][^][v][top][bottom][index][help] */