linux/drivers/hid/hid-multitouch.c
<<
>>
Prefs
   1/*
   2 *  HID driver for multitouch panels
   3 *
   4 *  Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr>
   5 *  Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
   6 *  Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
   7 *
   8 *  This code is partly based on hid-egalax.c:
   9 *
  10 *  Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
  11 *  Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
  12 *  Copyright (c) 2010 Canonical, Ltd.
  13 *
  14 */
  15
  16/*
  17 * This program is free software; you can redistribute it and/or modify it
  18 * under the terms of the GNU General Public License as published by the Free
  19 * Software Foundation; either version 2 of the License, or (at your option)
  20 * any later version.
  21 */
  22
  23#include <linux/device.h>
  24#include <linux/hid.h>
  25#include <linux/module.h>
  26#include <linux/slab.h>
  27#include <linux/usb.h>
  28#include <linux/input/mt.h>
  29#include "usbhid/usbhid.h"
  30
  31
  32MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
  33MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
  34MODULE_DESCRIPTION("HID multitouch panels");
  35MODULE_LICENSE("GPL");
  36
  37#include "hid-ids.h"
  38
  39/* quirks to control the device */
  40#define MT_QUIRK_NOT_SEEN_MEANS_UP      (1 << 0)
  41#define MT_QUIRK_SLOT_IS_CONTACTID      (1 << 1)
  42#define MT_QUIRK_CYPRESS                (1 << 2)
  43#define MT_QUIRK_SLOT_IS_CONTACTNUMBER  (1 << 3)
  44#define MT_QUIRK_VALID_IS_INRANGE       (1 << 4)
  45#define MT_QUIRK_VALID_IS_CONFIDENCE    (1 << 5)
  46#define MT_QUIRK_EGALAX_XYZ_FIXUP       (1 << 6)
  47
  48struct mt_slot {
  49        __s32 x, y, p, w, h;
  50        __s32 contactid;        /* the device ContactID assigned to this slot */
  51        bool touch_state;       /* is the touch valid? */
  52        bool seen_in_this_frame;/* has this slot been updated */
  53};
  54
  55struct mt_device {
  56        struct mt_slot curdata; /* placeholder of incoming data */
  57        struct mt_class *mtclass;       /* our mt device class */
  58        unsigned last_field_index;      /* last field index of the report */
  59        unsigned last_slot_field;       /* the last field of a slot */
  60        __s8 inputmode;         /* InputMode HID feature, -1 if non-existent */
  61        __u8 num_received;      /* how many contacts we received */
  62        __u8 num_expected;      /* expected last contact index */
  63        bool curvalid;          /* is the current contact valid? */
  64        struct mt_slot slots[0];        /* first slot */
  65};
  66
  67struct mt_class {
  68        __s32 name;     /* MT_CLS */
  69        __s32 quirks;
  70        __s32 sn_move;  /* Signal/noise ratio for move events */
  71        __s32 sn_pressure;      /* Signal/noise ratio for pressure events */
  72        __u8 maxcontacts;
  73};
  74
  75/* classes of device behavior */
  76#define MT_CLS_DEFAULT                          1
  77#define MT_CLS_DUAL_INRANGE_CONTACTID           2
  78#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER       3
  79#define MT_CLS_CYPRESS                          4
  80#define MT_CLS_EGALAX                           5
  81
  82/*
  83 * these device-dependent functions determine what slot corresponds
  84 * to a valid contact that was just read.
  85 */
  86
  87static int cypress_compute_slot(struct mt_device *td)
  88{
  89        if (td->curdata.contactid != 0 || td->num_received == 0)
  90                return td->curdata.contactid;
  91        else
  92                return -1;
  93}
  94
  95static int find_slot_from_contactid(struct mt_device *td)
  96{
  97        int i;
  98        for (i = 0; i < td->mtclass->maxcontacts; ++i) {
  99                if (td->slots[i].contactid == td->curdata.contactid &&
 100                        td->slots[i].touch_state)
 101                        return i;
 102        }
 103        for (i = 0; i < td->mtclass->maxcontacts; ++i) {
 104                if (!td->slots[i].seen_in_this_frame &&
 105                        !td->slots[i].touch_state)
 106                        return i;
 107        }
 108        /* should not occurs. If this happens that means
 109         * that the device sent more touches that it says
 110         * in the report descriptor. It is ignored then. */
 111        return -1;
 112}
 113
 114struct mt_class mt_classes[] = {
 115        { .name = MT_CLS_DEFAULT,
 116                .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
 117                .maxcontacts = 10 },
 118        { .name = MT_CLS_DUAL_INRANGE_CONTACTID,
 119                .quirks = MT_QUIRK_VALID_IS_INRANGE |
 120                        MT_QUIRK_SLOT_IS_CONTACTID,
 121                .maxcontacts = 2 },
 122        { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
 123                .quirks = MT_QUIRK_VALID_IS_INRANGE |
 124                        MT_QUIRK_SLOT_IS_CONTACTNUMBER,
 125                .maxcontacts = 2 },
 126        { .name = MT_CLS_CYPRESS,
 127                .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
 128                        MT_QUIRK_CYPRESS,
 129                .maxcontacts = 10 },
 130
 131        { .name = MT_CLS_EGALAX,
 132                .quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
 133                        MT_QUIRK_VALID_IS_INRANGE |
 134                        MT_QUIRK_EGALAX_XYZ_FIXUP,
 135                .maxcontacts = 2,
 136                .sn_move = 4096,
 137                .sn_pressure = 32,
 138        },
 139        { }
 140};
 141
 142static void mt_feature_mapping(struct hid_device *hdev,
 143                struct hid_field *field, struct hid_usage *usage)
 144{
 145        if (usage->hid == HID_DG_INPUTMODE) {
 146                struct mt_device *td = hid_get_drvdata(hdev);
 147                td->inputmode = field->report->id;
 148        }
 149}
 150
 151static void set_abs(struct input_dev *input, unsigned int code,
 152                struct hid_field *field, int snratio)
 153{
 154        int fmin = field->logical_minimum;
 155        int fmax = field->logical_maximum;
 156        int fuzz = snratio ? (fmax - fmin) / snratio : 0;
 157        input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
 158}
 159
 160static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 161                struct hid_field *field, struct hid_usage *usage,
 162                unsigned long **bit, int *max)
 163{
 164        struct mt_device *td = hid_get_drvdata(hdev);
 165        struct mt_class *cls = td->mtclass;
 166        __s32 quirks = cls->quirks;
 167
 168        switch (usage->hid & HID_USAGE_PAGE) {
 169
 170        case HID_UP_GENDESK:
 171                switch (usage->hid) {
 172                case HID_GD_X:
 173                        if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
 174                                field->logical_maximum = 32760;
 175                        hid_map_usage(hi, usage, bit, max,
 176                                        EV_ABS, ABS_MT_POSITION_X);
 177                        set_abs(hi->input, ABS_MT_POSITION_X, field,
 178                                cls->sn_move);
 179                        /* touchscreen emulation */
 180                        set_abs(hi->input, ABS_X, field, cls->sn_move);
 181                        td->last_slot_field = usage->hid;
 182                        return 1;
 183                case HID_GD_Y:
 184                        if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
 185                                field->logical_maximum = 32760;
 186                        hid_map_usage(hi, usage, bit, max,
 187                                        EV_ABS, ABS_MT_POSITION_Y);
 188                        set_abs(hi->input, ABS_MT_POSITION_Y, field,
 189                                cls->sn_move);
 190                        /* touchscreen emulation */
 191                        set_abs(hi->input, ABS_Y, field, cls->sn_move);
 192                        td->last_slot_field = usage->hid;
 193                        return 1;
 194                }
 195                return 0;
 196
 197        case HID_UP_DIGITIZER:
 198                switch (usage->hid) {
 199                case HID_DG_INRANGE:
 200                        td->last_slot_field = usage->hid;
 201                        return 1;
 202                case HID_DG_CONFIDENCE:
 203                        td->last_slot_field = usage->hid;
 204                        return 1;
 205                case HID_DG_TIPSWITCH:
 206                        hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
 207                        input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
 208                        td->last_slot_field = usage->hid;
 209                        return 1;
 210                case HID_DG_CONTACTID:
 211                        input_mt_init_slots(hi->input,
 212                                        td->mtclass->maxcontacts);
 213                        td->last_slot_field = usage->hid;
 214                        return 1;
 215                case HID_DG_WIDTH:
 216                        hid_map_usage(hi, usage, bit, max,
 217                                        EV_ABS, ABS_MT_TOUCH_MAJOR);
 218                        td->last_slot_field = usage->hid;
 219                        return 1;
 220                case HID_DG_HEIGHT:
 221                        hid_map_usage(hi, usage, bit, max,
 222                                        EV_ABS, ABS_MT_TOUCH_MINOR);
 223                        field->logical_maximum = 1;
 224                        field->logical_minimum = 0;
 225                        set_abs(hi->input, ABS_MT_ORIENTATION, field, 0);
 226                        td->last_slot_field = usage->hid;
 227                        return 1;
 228                case HID_DG_TIPPRESSURE:
 229                        if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
 230                                field->logical_minimum = 0;
 231                        hid_map_usage(hi, usage, bit, max,
 232                                        EV_ABS, ABS_MT_PRESSURE);
 233                        set_abs(hi->input, ABS_MT_PRESSURE, field,
 234                                cls->sn_pressure);
 235                        /* touchscreen emulation */
 236                        set_abs(hi->input, ABS_PRESSURE, field,
 237                                cls->sn_pressure);
 238                        td->last_slot_field = usage->hid;
 239                        return 1;
 240                case HID_DG_CONTACTCOUNT:
 241                        td->last_field_index = field->report->maxfield - 1;
 242                        return 1;
 243                case HID_DG_CONTACTMAX:
 244                        /* we don't set td->last_slot_field as contactcount and
 245                         * contact max are global to the report */
 246                        return -1;
 247                }
 248                /* let hid-input decide for the others */
 249                return 0;
 250
 251        case 0xff000000:
 252                /* we do not want to map these: no input-oriented meaning */
 253                return -1;
 254        }
 255
 256        return 0;
 257}
 258
 259static int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 260                struct hid_field *field, struct hid_usage *usage,
 261                unsigned long **bit, int *max)
 262{
 263        if (usage->type == EV_KEY || usage->type == EV_ABS)
 264                set_bit(usage->type, hi->input->evbit);
 265
 266        return -1;
 267}
 268
 269static int mt_compute_slot(struct mt_device *td)
 270{
 271        __s32 quirks = td->mtclass->quirks;
 272
 273        if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
 274                return td->curdata.contactid;
 275
 276        if (quirks & MT_QUIRK_CYPRESS)
 277                return cypress_compute_slot(td);
 278
 279        if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
 280                return td->num_received;
 281
 282        return find_slot_from_contactid(td);
 283}
 284
 285/*
 286 * this function is called when a whole contact has been processed,
 287 * so that it can assign it to a slot and store the data there
 288 */
 289static void mt_complete_slot(struct mt_device *td)
 290{
 291        td->curdata.seen_in_this_frame = true;
 292        if (td->curvalid) {
 293                int slotnum = mt_compute_slot(td);
 294
 295                if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
 296                        td->slots[slotnum] = td->curdata;
 297        }
 298        td->num_received++;
 299}
 300
 301
 302/*
 303 * this function is called when a whole packet has been received and processed,
 304 * so that it can decide what to send to the input layer.
 305 */
 306static void mt_emit_event(struct mt_device *td, struct input_dev *input)
 307{
 308        int i;
 309
 310        for (i = 0; i < td->mtclass->maxcontacts; ++i) {
 311                struct mt_slot *s = &(td->slots[i]);
 312                if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
 313                        !s->seen_in_this_frame) {
 314                        s->touch_state = false;
 315                }
 316
 317                input_mt_slot(input, i);
 318                input_mt_report_slot_state(input, MT_TOOL_FINGER,
 319                        s->touch_state);
 320                if (s->touch_state) {
 321                        input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
 322                        input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
 323                        input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
 324                        input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w);
 325                        input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h);
 326                }
 327                s->seen_in_this_frame = false;
 328
 329        }
 330
 331        input_mt_report_pointer_emulation(input, true);
 332        input_sync(input);
 333        td->num_received = 0;
 334}
 335
 336
 337
 338static int mt_event(struct hid_device *hid, struct hid_field *field,
 339                                struct hid_usage *usage, __s32 value)
 340{
 341        struct mt_device *td = hid_get_drvdata(hid);
 342        __s32 quirks = td->mtclass->quirks;
 343
 344        if (hid->claimed & HID_CLAIMED_INPUT) {
 345                switch (usage->hid) {
 346                case HID_DG_INRANGE:
 347                        if (quirks & MT_QUIRK_VALID_IS_INRANGE)
 348                                td->curvalid = value;
 349                        break;
 350                case HID_DG_TIPSWITCH:
 351                        if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
 352                                td->curvalid = value;
 353                        td->curdata.touch_state = value;
 354                        break;
 355                case HID_DG_CONFIDENCE:
 356                        if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
 357                                td->curvalid = value;
 358                        break;
 359                case HID_DG_CONTACTID:
 360                        td->curdata.contactid = value;
 361                        break;
 362                case HID_DG_TIPPRESSURE:
 363                        td->curdata.p = value;
 364                        break;
 365                case HID_GD_X:
 366                        td->curdata.x = value;
 367                        break;
 368                case HID_GD_Y:
 369                        td->curdata.y = value;
 370                        break;
 371                case HID_DG_WIDTH:
 372                        td->curdata.w = value;
 373                        break;
 374                case HID_DG_HEIGHT:
 375                        td->curdata.h = value;
 376                        break;
 377                case HID_DG_CONTACTCOUNT:
 378                        /*
 379                         * Includes multi-packet support where subsequent
 380                         * packets are sent with zero contactcount.
 381                         */
 382                        if (value)
 383                                td->num_expected = value;
 384                        break;
 385
 386                default:
 387                        /* fallback to the generic hidinput handling */
 388                        return 0;
 389                }
 390
 391                if (usage->hid == td->last_slot_field) {
 392                        mt_complete_slot(td);
 393                        if (!td->last_field_index)
 394                                mt_emit_event(td, field->hidinput->input);
 395                }
 396
 397                if (field->index == td->last_field_index
 398                        && td->num_received >= td->num_expected)
 399                        mt_emit_event(td, field->hidinput->input);
 400
 401        }
 402
 403        /* we have handled the hidinput part, now remains hiddev */
 404        if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
 405                hid->hiddev_hid_event(hid, field, usage, value);
 406
 407        return 1;
 408}
 409
 410static void mt_set_input_mode(struct hid_device *hdev)
 411{
 412        struct mt_device *td = hid_get_drvdata(hdev);
 413        struct hid_report *r;
 414        struct hid_report_enum *re;
 415
 416        if (td->inputmode < 0)
 417                return;
 418
 419        re = &(hdev->report_enum[HID_FEATURE_REPORT]);
 420        r = re->report_id_hash[td->inputmode];
 421        if (r) {
 422                r->field[0]->value[0] = 0x02;
 423                usbhid_submit_report(hdev, r, USB_DIR_OUT);
 424        }
 425}
 426
 427static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 428{
 429        int ret, i;
 430        struct mt_device *td;
 431        struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
 432
 433        for (i = 0; mt_classes[i].name ; i++) {
 434                if (id->driver_data == mt_classes[i].name) {
 435                        mtclass = &(mt_classes[i]);
 436                        break;
 437                }
 438        }
 439
 440        /* This allows the driver to correctly support devices
 441         * that emit events over several HID messages.
 442         */
 443        hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
 444
 445        td = kzalloc(sizeof(struct mt_device) +
 446                                mtclass->maxcontacts * sizeof(struct mt_slot),
 447                                GFP_KERNEL);
 448        if (!td) {
 449                dev_err(&hdev->dev, "cannot allocate multitouch data\n");
 450                return -ENOMEM;
 451        }
 452        td->mtclass = mtclass;
 453        td->inputmode = -1;
 454        hid_set_drvdata(hdev, td);
 455
 456        ret = hid_parse(hdev);
 457        if (ret != 0)
 458                goto fail;
 459
 460        ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
 461        if (ret)
 462                goto fail;
 463
 464        mt_set_input_mode(hdev);
 465
 466        return 0;
 467
 468fail:
 469        kfree(td);
 470        return ret;
 471}
 472
 473#ifdef CONFIG_PM
 474static int mt_reset_resume(struct hid_device *hdev)
 475{
 476        mt_set_input_mode(hdev);
 477        return 0;
 478}
 479#endif
 480
 481static void mt_remove(struct hid_device *hdev)
 482{
 483        struct mt_device *td = hid_get_drvdata(hdev);
 484        hid_hw_stop(hdev);
 485        kfree(td);
 486        hid_set_drvdata(hdev, NULL);
 487}
 488
 489static const struct hid_device_id mt_devices[] = {
 490
 491        /* Cypress panel */
 492        { .driver_data = MT_CLS_CYPRESS,
 493                HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
 494                        USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
 495
 496        /* GeneralTouch panel */
 497        { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
 498                HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
 499                        USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
 500
 501        /* IRTOUCH panels */
 502        { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
 503                HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
 504                        USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
 505
 506        /* PixCir-based panels */
 507        { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
 508                HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
 509                        USB_DEVICE_ID_HANVON_MULTITOUCH) },
 510        { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
 511                HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
 512                        USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
 513
 514        /* Resistive eGalax devices */
 515        {  .driver_data = MT_CLS_EGALAX,
 516                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
 517                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
 518        {  .driver_data = MT_CLS_EGALAX,
 519                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
 520                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
 521
 522        /* Capacitive eGalax devices */
 523        {  .driver_data = MT_CLS_EGALAX,
 524                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
 525                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
 526        {  .driver_data = MT_CLS_EGALAX,
 527                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
 528                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
 529        {  .driver_data = MT_CLS_EGALAX,
 530                HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
 531                        USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
 532
 533        { }
 534};
 535MODULE_DEVICE_TABLE(hid, mt_devices);
 536
 537static const struct hid_usage_id mt_grabbed_usages[] = {
 538        { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
 539        { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
 540};
 541
 542static struct hid_driver mt_driver = {
 543        .name = "hid-multitouch",
 544        .id_table = mt_devices,
 545        .probe = mt_probe,
 546        .remove = mt_remove,
 547        .input_mapping = mt_input_mapping,
 548        .input_mapped = mt_input_mapped,
 549        .feature_mapping = mt_feature_mapping,
 550        .usage_table = mt_grabbed_usages,
 551        .event = mt_event,
 552#ifdef CONFIG_PM
 553        .reset_resume = mt_reset_resume,
 554#endif
 555};
 556
 557static int __init mt_init(void)
 558{
 559        return hid_register_driver(&mt_driver);
 560}
 561
 562static void __exit mt_exit(void)
 563{
 564        hid_unregister_driver(&mt_driver);
 565}
 566
 567module_init(mt_init);
 568module_exit(mt_exit);
 569