hid-multitouch.c revision b105712469d957cf1ab223c1ea72b7ba88edb926
15519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 25519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * HID driver for multitouch panels 35519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * 45519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr> 55519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com> 65519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France 75519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * 84875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * This code is partly based on hid-egalax.c: 94875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * 104875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * Copyright (c) 2010 Stephane Chatty <chatty@enac.fr> 114875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> 124875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * Copyright (c) 2010 Canonical, Ltd. 134875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber * 14f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * This code is partly based on hid-3m-pct.c: 15f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * 16f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> 17f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> 18f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * Copyright (c) 2010 Canonical, Ltd. 19f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires * 205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * This program is free software; you can redistribute it and/or modify it 245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * under the terms of the GNU General Public License as published by the Free 255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * Software Foundation; either version 2 of the License, or (at your option) 265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * any later version. 275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/device.h> 305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/hid.h> 315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/module.h> 325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/slab.h> 335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/usb.h> 345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/input/mt.h> 355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include "usbhid/usbhid.h" 365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 385519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>"); 39ef2fafb3e233ca9cb390fc3c1461b7f3859998fcBenjamin TissoiresMODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>"); 405519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DESCRIPTION("HID multitouch panels"); 415519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_LICENSE("GPL"); 425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include "hid-ids.h" 445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* quirks to control the device */ 465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#define MT_QUIRK_NOT_SEEN_MEANS_UP (1 << 0) 475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#define MT_QUIRK_SLOT_IS_CONTACTID (1 << 1) 482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires#define MT_QUIRK_CYPRESS (1 << 2) 495572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires#define MT_QUIRK_SLOT_IS_CONTACTNUMBER (1 << 3) 50a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_QUIRK_ALWAYS_VALID (1 << 4) 51a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_QUIRK_VALID_IS_INRANGE (1 << 5) 52a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_QUIRK_VALID_IS_CONFIDENCE (1 << 6) 53a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE (1 << 8) 545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 555519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_slot { 565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires __s32 x, y, p, w, h; 575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires __s32 contactid; /* the device ContactID assigned to this slot */ 585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires bool touch_state; /* is the touch valid? */ 595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires bool seen_in_this_frame;/* has this slot been updated */ 605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 62eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstruct mt_class { 63eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 name; /* MT_CLS */ 64eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 quirks; 65eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 sn_move; /* Signal/noise ratio for move events */ 66eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 sn_width; /* Signal/noise ratio for width events */ 67eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 sn_height; /* Signal/noise ratio for height events */ 68eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 sn_pressure; /* Signal/noise ratio for pressure events */ 69eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __u8 maxcontacts; 70eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}; 71eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 725519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_device { 735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_slot curdata; /* placeholder of incoming data */ 74eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_class mtclass; /* our mt device class */ 755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned last_field_index; /* last field index of the report */ 765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned last_slot_field; /* the last field of a slot */ 77b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires int last_mt_collection; /* last known mt-related collection */ 785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ 795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires __u8 num_received; /* how many contacts we received */ 805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires __u8 num_expected; /* expected last contact index */ 819498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires __u8 maxcontacts; 825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires bool curvalid; /* is the current contact valid? */ 839498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires struct mt_slot *slots; 845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* classes of device behavior */ 8722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DEFAULT 0x0001 8822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 89a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_CLS_SERIAL 0x0002 90a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_CLS_CONFIDENCE 0x0003 915e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_CONFIDENCE_CONTACT_ID 0x0004 925e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_CONFIDENCE_MINUS_ONE 0x0005 935e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTID 0x0006 945e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER 0x0007 955e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_NSMU_CONTACTID 0x0008 96b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian#define MT_CLS_INRANGE_CONTACTNUMBER 0x0009 9722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 9822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires/* vendor specific classes */ 9922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_3M 0x0101 10022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CYPRESS 0x0102 10122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_EGALAX 0x0103 1021b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires#define MT_CLS_EGALAX_SERIAL 0x0104 1035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 1049498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires#define MT_DEFAULT_MAXCONTACT 10 1059498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 1065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 1075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * these device-dependent functions determine what slot corresponds 1085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * to a valid contact that was just read. 1095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 1105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 111a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoiresstatic int cypress_compute_slot(struct mt_device *td) 112a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires{ 113a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires if (td->curdata.contactid != 0 || td->num_received == 0) 114a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return td->curdata.contactid; 115a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires else 116a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return -1; 117a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires} 118a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 1195519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int find_slot_from_contactid(struct mt_device *td) 1205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 1215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int i; 1229498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 1235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->slots[i].contactid == td->curdata.contactid && 1245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->slots[i].touch_state) 1255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return i; 1265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 1279498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 1285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (!td->slots[i].seen_in_this_frame && 1295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires !td->slots[i].touch_state) 1305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return i; 1315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 1325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* should not occurs. If this happens that means 1335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * that the device sent more touches that it says 1345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * in the report descriptor. It is ignored then. */ 1352d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return -1; 1365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 1375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 1385519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_class mt_classes[] = { 1392d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { .name = MT_CLS_DEFAULT, 1409498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 141a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty { .name = MT_CLS_SERIAL, 142a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty .quirks = MT_QUIRK_ALWAYS_VALID}, 14322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_CONFIDENCE, 14422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, 1455e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .name = MT_CLS_CONFIDENCE_CONTACT_ID, 1465e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 1475e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID }, 14822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_CONFIDENCE_MINUS_ONE, 14922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 15022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, 1511e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .name = MT_CLS_DUAL_INRANGE_CONTACTID, 1522d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_INRANGE | 1532d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 1542d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 2 }, 1551e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 1562d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_INRANGE | 1572d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTNUMBER, 1582d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 2 }, 15922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_DUAL_NSMU_CONTACTID, 16022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 16122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 16222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .maxcontacts = 2 }, 163b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian { .name = MT_CLS_INRANGE_CONTACTNUMBER, 164b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian .quirks = MT_QUIRK_VALID_IS_INRANGE | 165b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian MT_QUIRK_SLOT_IS_CONTACTNUMBER }, 16622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 16722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* 16822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires * vendor specific classes 16922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires */ 17022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_3M, 17122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 17222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 17322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_move = 2048, 17422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_width = 128, 17522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_height = 128 }, 1762d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { .name = MT_CLS_CYPRESS, 1772d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 1782d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_CYPRESS, 1792d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 10 }, 1804875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber { .name = MT_CLS_EGALAX, 1814875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .quirks = MT_QUIRK_SLOT_IS_CONTACTID | 1822261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires MT_QUIRK_VALID_IS_INRANGE, 1834875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .sn_move = 4096, 1844875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .sn_pressure = 32, 1854875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber }, 1861b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires { .name = MT_CLS_EGALAX_SERIAL, 1871b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .quirks = MT_QUIRK_SLOT_IS_CONTACTID | 1881b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires MT_QUIRK_ALWAYS_VALID, 1891b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .sn_move = 4096, 1901b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .sn_pressure = 32, 1911b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires }, 192043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires 1932d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { } 1945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 1955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 196eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_show_quirks(struct device *dev, 197eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct device_attribute *attr, 198eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires char *buf) 199eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{ 200eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct hid_device *hdev = container_of(dev, struct hid_device, dev); 201eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 202eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 203eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return sprintf(buf, "%u\n", td->mtclass.quirks); 204eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires} 205eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 206eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_set_quirks(struct device *dev, 207eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct device_attribute *attr, 208eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires const char *buf, size_t count) 209eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{ 210eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct hid_device *hdev = container_of(dev, struct hid_device, dev); 211eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 212eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 213eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires unsigned long val; 214eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 215eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if (kstrtoul(buf, 0, &val)) 216eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return -EINVAL; 217eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 218eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->mtclass.quirks = val; 219eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 220eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return count; 221eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires} 222eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 223eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks); 224eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 225eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute *sysfs_attrs[] = { 226eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires &dev_attr_quirks.attr, 227eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires NULL 228eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}; 229eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 230eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute_group mt_attribute_group = { 231eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires .attrs = sysfs_attrs 232eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}; 233eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 234f635bd11c8d332d917fb9a4cad3071b2357d5b2aHenrik Rydbergstatic void mt_feature_mapping(struct hid_device *hdev, 2355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage) 2365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2379498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 2389498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 2399498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires switch (usage->hid) { 2409498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires case HID_DG_INPUTMODE: 2415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->inputmode = field->report->id; 2429498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires break; 2439498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires case HID_DG_CONTACTMAX: 2449498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td->maxcontacts = field->value[0]; 245eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if (td->mtclass.maxcontacts) 2469498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires /* check if the maxcontacts is given by the class */ 247eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->maxcontacts = td->mtclass.maxcontacts; 2489498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 2499498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires break; 2505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 2515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 2525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2535519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void set_abs(struct input_dev *input, unsigned int code, 2545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, int snratio) 2555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fmin = field->logical_minimum; 2575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fmax = field->logical_maximum; 2585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fuzz = snratio ? (fmax - fmin) / snratio : 0; 2595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_set_abs_params(input, code, fmin, fmax, fuzz, 0); 2605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 2615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2625519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 2635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage, 2645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned long **bit, int *max) 2655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 267eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_class *cls = &td->mtclass; 2684875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber 269658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown /* Only map fields from TouchScreen or TouchPad collections. 270658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown * We need to ignore fields that belong to other collections 271658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown * such as Mouse that might have the same GenericDesktop usages. */ 272658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown if (field->application == HID_DG_TOUCHSCREEN) 273658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown set_bit(INPUT_PROP_DIRECT, hi->input->propbit); 274658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown else if (field->application == HID_DG_TOUCHPAD) 275658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown set_bit(INPUT_PROP_POINTER, hi->input->propbit); 276658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown else 277658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown return 0; 278658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown 2792261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires /* eGalax devices provide a Digitizer.Stylus input which overrides 2802261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires * the correct Digitizers.Finger X/Y ranges. 2812261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires * Let's just ignore this input. */ 2822261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires if (field->physical == HID_DG_STYLUS) 2832261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires return -1; 2842261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires 2855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid & HID_USAGE_PAGE) { 2865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_UP_GENDESK: 2885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 2895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_X: 2905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 2915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_POSITION_X); 2925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_POSITION_X, field, 2935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_move); 2945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 2955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_X, field, cls->sn_move); 296b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 297b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 298b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 299b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_Y: 3025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_POSITION_Y); 3045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_POSITION_Y, field, 3055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_move); 3065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 3075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_Y, field, cls->sn_move); 308b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 309b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 310b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 311b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 3155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_UP_DIGITIZER: 3175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 3185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_INRANGE: 319b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 320b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 321b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 322b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONFIDENCE: 325b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 326b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 327b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 328b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPSWITCH: 3315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 3325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_set_capability(hi->input, EV_KEY, BTN_TOUCH); 333b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 334b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 335b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 336b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTID: 33950bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires if (!td->maxcontacts) 34050bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires td->maxcontacts = MT_DEFAULT_MAXCONTACT; 3419498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires input_mt_init_slots(hi->input, td->maxcontacts); 3425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->last_slot_field = usage->hid; 3432955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires td->last_field_index = field->index; 344b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_mt_collection = usage->collection_index; 3455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_WIDTH: 3475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_TOUCH_MAJOR); 349f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, 350f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires cls->sn_width); 351b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 352b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 353b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 354b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_HEIGHT: 3575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_TOUCH_MINOR); 359f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, 360f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires cls->sn_height); 3611e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires input_set_abs_params(hi->input, 3621e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires ABS_MT_ORIENTATION, 0, 1, 0, 0); 363b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 364b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 365b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 366b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPPRESSURE: 3695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_PRESSURE); 3715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_PRESSURE, field, 3725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_pressure); 3735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 3745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_PRESSURE, field, 3755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_pressure); 376b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 377b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 378b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 379b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTCOUNT: 382b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) 383b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 3845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTMAX: 3865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we don't set td->last_slot_field as contactcount and 3875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * contact max are global to the report */ 388b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) 389b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 3905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 3915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* let hid-input decide for the others */ 3935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 3945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case 0xff000000: 3965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we do not want to map these: no input-oriented meaning */ 3975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 3985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 4015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4035519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, 4045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage, 4055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned long **bit, int *max) 4065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (usage->type == EV_KEY || usage->type == EV_ABS) 4085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_bit(usage->type, hi->input->evbit); 4095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 4115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4135519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_compute_slot(struct mt_device *td) 4145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 415eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 quirks = td->mtclass.quirks; 4165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4172d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTID) 4182d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return td->curdata.contactid; 4195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4202d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_CYPRESS) 421a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return cypress_compute_slot(td); 422a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 4232d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) 4242d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return td->num_received; 4255572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires 4264a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) 4274a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires return td->curdata.contactid - 1; 4284a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires 4295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return find_slot_from_contactid(td); 4305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 4335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole contact has been processed, 4345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can assign it to a slot and store the data there 4355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 4365519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_complete_slot(struct mt_device *td) 4375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4382d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curdata.seen_in_this_frame = true; 4395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->curvalid) { 4405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int slotnum = mt_compute_slot(td); 4415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4429498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (slotnum >= 0 && slotnum < td->maxcontacts) 4432d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->slots[slotnum] = td->curdata; 4445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->num_received++; 4465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 4505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole packet has been received and processed, 4515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can decide what to send to the input layer. 4525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 4535519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_emit_event(struct mt_device *td, struct input_dev *input) 4545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int i; 4565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4579498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 4585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_slot *s = &(td->slots[i]); 459eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && 4605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires !s->seen_in_this_frame) { 4615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->touch_state = false; 4625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_slot(input, i); 4655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_report_slot_state(input, MT_TOOL_FINGER, 4665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->touch_state); 4672d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (s->touch_state) { 468f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* this finger is on the screen */ 469f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int wide = (s->w > s->h); 470f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* divided by two to match visual scale of touch */ 471f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int major = max(s->w, s->h) >> 1; 472f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int minor = min(s->w, s->h) >> 1; 473f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires 4742d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); 4752d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); 476f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 4772d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); 478f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 479f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 4802d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 4815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->seen_in_this_frame = false; 4825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_report_pointer_emulation(input, true); 4865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_sync(input); 4875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->num_received = 0; 4885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4925519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_event(struct hid_device *hid, struct hid_field *field, 4935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_usage *usage, __s32 value) 4945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hid); 496eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 quirks = td->mtclass.quirks; 4975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4989498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 4995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 5005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_INRANGE: 501a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty if (quirks & MT_QUIRK_ALWAYS_VALID) 502a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty td->curvalid = true; 503a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty else if (quirks & MT_QUIRK_VALID_IS_INRANGE) 5042d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPSWITCH: 5072d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) 5082d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.touch_state = value; 5105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONFIDENCE: 5122d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) 5132d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTID: 5165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.contactid = value; 5175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPPRESSURE: 5195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.p = value; 5205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_X: 5225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.x = value; 5235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_Y: 5255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.y = value; 5265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_WIDTH: 5285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.w = value; 5295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_HEIGHT: 5315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.h = value; 5325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTCOUNT: 5345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* 5352d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires * Includes multi-packet support where subsequent 5362d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires * packets are sent with zero contactcount. 5375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 5385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (value) 5392d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->num_expected = value; 5405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires default: 5435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* fallback to the generic hidinput handling */ 5445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 5455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 5465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 547f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg if (usage->hid == td->last_slot_field) { 5482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mt_complete_slot(td); 549f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg } 5502d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires 5512d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (field->index == td->last_field_index 5522d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires && td->num_received >= td->num_expected) 5532d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mt_emit_event(td, field->hidinput->input); 5545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5552d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we have handled the hidinput part, now remains hiddev */ 5585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) 5595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid->hiddev_hid_event(hid, field, usage, value); 5605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 5625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 5635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5645519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_set_input_mode(struct hid_device *hdev) 5655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 5665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 5675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_report *r; 5685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_report_enum *re; 5695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->inputmode < 0) 5715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return; 5725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires re = &(hdev->report_enum[HID_FEATURE_REPORT]); 5745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires r = re->report_id_hash[td->inputmode]; 5755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (r) { 5765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires r->field[0]->value[0] = 0x02; 5775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires usbhid_submit_report(hdev, r, USB_DIR_OUT); 5785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 5795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 5805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5815519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 5825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 5832d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires int ret, i; 5845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td; 5852d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ 5862d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires 5872d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires for (i = 0; mt_classes[i].name ; i++) { 5882d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (id->driver_data == mt_classes[i].name) { 5892d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mtclass = &(mt_classes[i]); 5902d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires break; 5912d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5922d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 594d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg /* This allows the driver to correctly support devices 595d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg * that emit events over several HID messages. 596d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg */ 597d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; 5985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5999498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); 6005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (!td) { 6015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires dev_err(&hdev->dev, "cannot allocate multitouch data\n"); 6025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -ENOMEM; 6035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 604eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->mtclass = *mtclass; 6055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->inputmode = -1; 606b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_mt_collection = -1; 6075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_set_drvdata(hdev, td); 6085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires ret = hid_parse(hdev); 6105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (ret != 0) 6115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires goto fail; 6125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 6142d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (ret) 6155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires goto fail; 6165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6179498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), 6189498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires GFP_KERNEL); 6199498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (!td->slots) { 6209498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); 6219498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires hid_hw_stop(hdev); 6229498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires ret = -ENOMEM; 6239498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires goto fail; 6249498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires } 6259498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 626eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); 627eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 6285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires mt_set_input_mode(hdev); 6295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 6315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6325519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresfail: 6335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires kfree(td); 6345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return ret; 6355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM 6385519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_reset_resume(struct hid_device *hdev) 6395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 6405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires mt_set_input_mode(hdev); 6415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 6425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif 6445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6455519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_remove(struct hid_device *hdev) 6465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 6475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 648eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 6495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_hw_stop(hdev); 6509498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires kfree(td->slots); 6515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires kfree(td); 6525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_set_drvdata(hdev, NULL); 6535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6555519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_device_id mt_devices[] = { 6565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 657f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* 3M panels */ 658f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires { .driver_data = MT_CLS_3M, 659f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_3M, 660f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires USB_DEVICE_ID_3M1968) }, 661f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires { .driver_data = MT_CLS_3M, 662f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_3M, 663f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires USB_DEVICE_ID_3M2256) }, 664f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires 665e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires /* ActionStar panels */ 666e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 667e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, 668e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires USB_DEVICE_ID_ACTIONSTAR_1011) }, 669e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires 670b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires /* Atmel panels */ 671b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires { .driver_data = MT_CLS_SERIAL, 672b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ATMEL, 673b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires USB_DEVICE_ID_ATMEL_MULTITOUCH) }, 674b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires 675a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires /* Cando panels */ 676a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 677a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 678a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, 679a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 680a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 681a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, 682a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 683a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 684a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, 685a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 686a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 687a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, 688a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires 689942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang /* Chunghwa Telecom touch panels */ 690942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang { .driver_data = MT_CLS_DEFAULT, 691942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, 692942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, 693942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang 69479603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires /* CVTouch panels */ 69579603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 69679603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, 69779603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires USB_DEVICE_ID_CVTOUCH_SCREEN) }, 69879603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires 699a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires /* Cypress panel */ 700a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires { .driver_data = MT_CLS_CYPRESS, 701a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, 702a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, 703a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 70422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* eGalax devices (resistive) */ 705e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 70622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 707e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, 708e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 70922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 710e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, 71122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 71222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* eGalax devices (capacitive) */ 713e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 71422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 715e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, 716e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 71722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 718e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, 719e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 72022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 721e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, 722e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 7231fd8f047490dd0ec4e4db710fcbc1bd4798d944cChris Bagwell HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 72466f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, 72566f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires { .driver_data = MT_CLS_EGALAX, 72666f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 727bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, 7281b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires { .driver_data = MT_CLS_EGALAX_SERIAL, 729bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 730e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, 73122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 732c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires /* Elo TouchSystems IntelliTouch Plus panel */ 733c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, 734c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ELO, 735c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires USB_DEVICE_ID_ELO_TS2515) }, 736c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires 7375572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires /* GeneralTouch panel */ 7381e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 7395572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 7405572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, 7415572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires 742ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires /* GoodTouch panels */ 743ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 744ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, 745ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires USB_DEVICE_ID_GOODTOUCH_000f) }, 746ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires 747545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires /* Hanvon panels */ 748545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 749545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, 750545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, 751545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires 752a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty /* Ideacom panel */ 753a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty { .driver_data = MT_CLS_SERIAL, 754a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, 755a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty USB_DEVICE_ID_IDEACOM_IDC6650) }, 756a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty 7574e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang /* Ilitek dual touch panel */ 7584e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang { .driver_data = MT_CLS_DEFAULT, 7594e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, 7604e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang USB_DEVICE_ID_ILITEK_MULTITOUCH) }, 7614e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang 7624dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires /* IRTOUCH panels */ 7634dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 7644dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, 7654dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, 7664dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires 767c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown /* LG Display panels */ 768c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown { .driver_data = MT_CLS_DEFAULT, 769c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown HID_USB_DEVICE(USB_VENDOR_ID_LG, 770c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown USB_DEVICE_ID_LG_MULTITOUCH) }, 771c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown 772df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires /* Lumio panels */ 773df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 774df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 775df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires USB_DEVICE_ID_CRYSTALTOUCH) }, 776c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 777c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 778c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, 779df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires 7804a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires /* MosArt panels */ 7814a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7824a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ASUS, 7834a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_ASUS_T91MT)}, 7844a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7854a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ASUS, 7864a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, 7874a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7884a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, 7894a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, 7904a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires 7916ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung /* PenMount panels */ 7926ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung { .driver_data = MT_CLS_CONFIDENCE, 7936ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, 7946ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung USB_DEVICE_ID_PENMOUNT_PCI) }, 7956ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung 796b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian /* PixArt optical touch screen */ 797b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, 798b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian HID_USB_DEVICE(USB_VENDOR_ID_PIXART, 799b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) }, 800b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, 801b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian HID_USB_DEVICE(USB_VENDOR_ID_PIXART, 802b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) }, 803b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian { .driver_data = MT_CLS_INRANGE_CONTACTNUMBER, 804b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian HID_USB_DEVICE(USB_VENDOR_ID_PIXART, 805b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) }, 806b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian 8075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* PixCir-based panels */ 8081e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 8095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_HANVON, 8105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires USB_DEVICE_ID_HANVON_MULTITOUCH) }, 8111e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 8125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 8135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, 8145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8155e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires /* Quanta-based panels */ 8165e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 8175e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 8185e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 8195e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 8205e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 8215e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) }, 8225e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 8235e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 8245e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) }, 8255e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires 826043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires /* Stantum panels */ 827bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 828043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, 829043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP)}, 830bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 83185a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, 832043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP_STM)}, 833bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 83485a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, 835043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP_SITRONIX)}, 836043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires 8375e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires /* Touch International panels */ 8385e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 8395e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, 8405e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, 8415e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires 842617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires /* Unitec panels */ 843617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 844617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 845617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, 846617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 847617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 848617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 849bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien /* XAT */ 850bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien { .driver_data = MT_CLS_DEFAULT, 851bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien HID_USB_DEVICE(USB_VENDOR_ID_XAT, 852bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien USB_DEVICE_ID_XAT_CSR) }, 853617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires 8545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { } 8555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8565519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DEVICE_TABLE(hid, mt_devices); 8575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8585519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_usage_id mt_grabbed_usages[] = { 8595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, 8605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} 8615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8635519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic struct hid_driver mt_driver = { 8645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .name = "hid-multitouch", 8655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .id_table = mt_devices, 8665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .probe = mt_probe, 8675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .remove = mt_remove, 8685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .input_mapping = mt_input_mapping, 8695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .input_mapped = mt_input_mapped, 8705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .feature_mapping = mt_feature_mapping, 8715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .usage_table = mt_grabbed_usages, 8725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .event = mt_event, 8735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM 8745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .reset_resume = mt_reset_resume, 8755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif 8765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8785519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int __init mt_init(void) 8795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 8805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return hid_register_driver(&mt_driver); 8815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 8825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8835519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void __exit mt_exit(void) 8845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 8855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_unregister_driver(&mt_driver); 8865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 8875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8885519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_init(mt_init); 8895519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_exit(mt_exit); 890