hid-multitouch.c revision 5e7ea11f603a0aeb77fd1bff0b242931ffe139de
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 9622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 9722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires/* vendor specific classes */ 9822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_3M 0x0101 9922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CYPRESS 0x0102 10022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_EGALAX 0x0103 1011b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires#define MT_CLS_EGALAX_SERIAL 0x0104 1025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 1039498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires#define MT_DEFAULT_MAXCONTACT 10 1049498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 1055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 1065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * these device-dependent functions determine what slot corresponds 1075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * to a valid contact that was just read. 1085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 1095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 110a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoiresstatic int cypress_compute_slot(struct mt_device *td) 111a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires{ 112a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires if (td->curdata.contactid != 0 || td->num_received == 0) 113a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return td->curdata.contactid; 114a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires else 115a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return -1; 116a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires} 117a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 1185519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int find_slot_from_contactid(struct mt_device *td) 1195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 1205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int i; 1219498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 1225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->slots[i].contactid == td->curdata.contactid && 1235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->slots[i].touch_state) 1245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return i; 1255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 1269498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 1275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (!td->slots[i].seen_in_this_frame && 1285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires !td->slots[i].touch_state) 1295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return i; 1305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 1315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* should not occurs. If this happens that means 1325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * that the device sent more touches that it says 1335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * in the report descriptor. It is ignored then. */ 1342d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return -1; 1355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 1365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 1375519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_class mt_classes[] = { 1382d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { .name = MT_CLS_DEFAULT, 1399498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP }, 140a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty { .name = MT_CLS_SERIAL, 141a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty .quirks = MT_QUIRK_ALWAYS_VALID}, 14222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_CONFIDENCE, 14322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE }, 1445e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .name = MT_CLS_CONFIDENCE_CONTACT_ID, 1455e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 1465e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID }, 14722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_CONFIDENCE_MINUS_ONE, 14822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 14922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE }, 1501e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .name = MT_CLS_DUAL_INRANGE_CONTACTID, 1512d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_INRANGE | 1522d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 1532d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 2 }, 1541e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 1552d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_INRANGE | 1562d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTNUMBER, 1572d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 2 }, 15822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_DUAL_NSMU_CONTACTID, 15922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 16022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 16122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .maxcontacts = 2 }, 16222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 16322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* 16422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires * vendor specific classes 16522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires */ 16622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires { .name = MT_CLS_3M, 16722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .quirks = MT_QUIRK_VALID_IS_CONFIDENCE | 16822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires MT_QUIRK_SLOT_IS_CONTACTID, 16922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_move = 2048, 17022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_width = 128, 17122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires .sn_height = 128 }, 1722d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { .name = MT_CLS_CYPRESS, 1732d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 1742d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires MT_QUIRK_CYPRESS, 1752d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires .maxcontacts = 10 }, 1764875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber { .name = MT_CLS_EGALAX, 1774875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .quirks = MT_QUIRK_SLOT_IS_CONTACTID | 1782261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires MT_QUIRK_VALID_IS_INRANGE, 1794875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .sn_move = 4096, 1804875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber .sn_pressure = 32, 1814875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber }, 1821b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires { .name = MT_CLS_EGALAX_SERIAL, 1831b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .quirks = MT_QUIRK_SLOT_IS_CONTACTID | 1841b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires MT_QUIRK_ALWAYS_VALID, 1851b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .sn_move = 4096, 1861b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires .sn_pressure = 32, 1871b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires }, 188043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires 1892d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires { } 1905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 1915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 192eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_show_quirks(struct device *dev, 193eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct device_attribute *attr, 194eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires char *buf) 195eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{ 196eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct hid_device *hdev = container_of(dev, struct hid_device, dev); 197eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 198eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 199eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return sprintf(buf, "%u\n", td->mtclass.quirks); 200eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires} 201eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 202eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_set_quirks(struct device *dev, 203eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct device_attribute *attr, 204eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires const char *buf, size_t count) 205eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{ 206eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct hid_device *hdev = container_of(dev, struct hid_device, dev); 207eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 208eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 209eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires unsigned long val; 210eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 211eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if (kstrtoul(buf, 0, &val)) 212eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return -EINVAL; 213eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 214eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->mtclass.quirks = val; 215eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 216eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires return count; 217eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires} 218eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 219eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks); 220eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 221eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute *sysfs_attrs[] = { 222eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires &dev_attr_quirks.attr, 223eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires NULL 224eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}; 225eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 226eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute_group mt_attribute_group = { 227eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires .attrs = sysfs_attrs 228eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}; 229eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 230f635bd11c8d332d917fb9a4cad3071b2357d5b2aHenrik Rydbergstatic void mt_feature_mapping(struct hid_device *hdev, 2315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage) 2325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2339498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 2349498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 2359498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires switch (usage->hid) { 2369498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires case HID_DG_INPUTMODE: 2375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->inputmode = field->report->id; 2389498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires break; 2399498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires case HID_DG_CONTACTMAX: 2409498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td->maxcontacts = field->value[0]; 241eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if (td->mtclass.maxcontacts) 2429498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires /* check if the maxcontacts is given by the class */ 243eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->maxcontacts = td->mtclass.maxcontacts; 2449498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 2459498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires break; 2465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 2475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 2485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2495519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void set_abs(struct input_dev *input, unsigned int code, 2505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, int snratio) 2515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fmin = field->logical_minimum; 2535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fmax = field->logical_maximum; 2545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int fuzz = snratio ? (fmax - fmin) / snratio : 0; 2555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_set_abs_params(input, code, fmin, fmax, fuzz, 0); 2565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 2575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2585519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, 2595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage, 2605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned long **bit, int *max) 2615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 2625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 263eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires struct mt_class *cls = &td->mtclass; 2644875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber 265658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown /* Only map fields from TouchScreen or TouchPad collections. 266658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown * We need to ignore fields that belong to other collections 267658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown * such as Mouse that might have the same GenericDesktop usages. */ 268658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown if (field->application == HID_DG_TOUCHSCREEN) 269658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown set_bit(INPUT_PROP_DIRECT, hi->input->propbit); 270658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown else if (field->application == HID_DG_TOUCHPAD) 271658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown set_bit(INPUT_PROP_POINTER, hi->input->propbit); 272658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown else 273658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown return 0; 274658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown 2752261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires /* eGalax devices provide a Digitizer.Stylus input which overrides 2762261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires * the correct Digitizers.Finger X/Y ranges. 2772261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires * Let's just ignore this input. */ 2782261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires if (field->physical == HID_DG_STYLUS) 2792261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires return -1; 2802261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires 2815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid & HID_USAGE_PAGE) { 2825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 2835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_UP_GENDESK: 2845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 2855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_X: 2865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 2875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_POSITION_X); 2885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_POSITION_X, field, 2895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_move); 2905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 2915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_X, field, cls->sn_move); 292b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 293b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 294b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 295b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 2965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 2975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_Y: 2985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 2995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_POSITION_Y); 3005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_POSITION_Y, field, 3015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_move); 3025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 3035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_Y, field, cls->sn_move); 304b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 305b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 306b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 307b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 3115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_UP_DIGITIZER: 3135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 3145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_INRANGE: 315b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 316b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 317b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 318b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONFIDENCE: 321b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 322b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 323b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 324b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPSWITCH: 3275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); 3285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_set_capability(hi->input, EV_KEY, BTN_TOUCH); 329b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 330b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 331b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 332b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTID: 33550bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires if (!td->maxcontacts) 33650bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires td->maxcontacts = MT_DEFAULT_MAXCONTACT; 3379498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires input_mt_init_slots(hi->input, td->maxcontacts); 3385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->last_slot_field = usage->hid; 3392955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires td->last_field_index = field->index; 340b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_mt_collection = usage->collection_index; 3415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_WIDTH: 3435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_TOUCH_MAJOR); 345f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field, 346f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires cls->sn_width); 347b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 348b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 349b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 350b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_HEIGHT: 3535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_TOUCH_MINOR); 355f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires set_abs(hi->input, ABS_MT_TOUCH_MINOR, field, 356f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires cls->sn_height); 3571e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires input_set_abs_params(hi->input, 3581e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires ABS_MT_ORIENTATION, 0, 1, 0, 0); 359b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 360b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 361b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 362b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPPRESSURE: 3655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_map_usage(hi, usage, bit, max, 3665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires EV_ABS, ABS_MT_PRESSURE); 3675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_MT_PRESSURE, field, 3685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_pressure); 3695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* touchscreen emulation */ 3705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_abs(hi->input, ABS_PRESSURE, field, 3715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires cls->sn_pressure); 372b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) { 373b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_slot_field = usage->hid; 374b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 375b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires } 3765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTCOUNT: 378b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) 379b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 3805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 3815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTMAX: 3825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we don't set td->last_slot_field as contactcount and 3835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * contact max are global to the report */ 384b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires if (td->last_mt_collection == usage->collection_index) 385b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_field_index = field->index; 3865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 3875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* let hid-input decide for the others */ 3895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 3905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case 0xff000000: 3925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we do not want to map these: no input-oriented meaning */ 3935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 3945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 3955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 3975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 3985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 3995519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi, 4005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_field *field, struct hid_usage *usage, 4015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires unsigned long **bit, int *max) 4025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (usage->type == EV_KEY || usage->type == EV_ABS) 4045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires set_bit(usage->type, hi->input->evbit); 4055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -1; 4075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4095519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_compute_slot(struct mt_device *td) 4105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 411eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 quirks = td->mtclass.quirks; 4125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4132d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTID) 4142d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return td->curdata.contactid; 4155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4162d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_CYPRESS) 417a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires return cypress_compute_slot(td); 418a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 4192d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER) 4202d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires return td->num_received; 4215572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires 4224a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE) 4234a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires return td->curdata.contactid - 1; 4244a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires 4255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return find_slot_from_contactid(td); 4265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 4295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole contact has been processed, 4305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can assign it to a slot and store the data there 4315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 4325519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_complete_slot(struct mt_device *td) 4335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4342d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curdata.seen_in_this_frame = true; 4355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->curvalid) { 4365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int slotnum = mt_compute_slot(td); 4375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4389498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (slotnum >= 0 && slotnum < td->maxcontacts) 4392d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->slots[slotnum] = td->curdata; 4405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->num_received++; 4425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* 4465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole packet has been received and processed, 4475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can decide what to send to the input layer. 4485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 4495519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_emit_event(struct mt_device *td, struct input_dev *input) 4505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires int i; 4525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4539498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires for (i = 0; i < td->maxcontacts; ++i) { 4545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_slot *s = &(td->slots[i]); 455eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) && 4565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires !s->seen_in_this_frame) { 4575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->touch_state = false; 4585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_slot(input, i); 4615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_report_slot_state(input, MT_TOOL_FINGER, 4625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->touch_state); 4632d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (s->touch_state) { 464f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* this finger is on the screen */ 465f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int wide = (s->w > s->h); 466f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* divided by two to match visual scale of touch */ 467f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int major = max(s->w, s->h) >> 1; 468f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires int minor = min(s->w, s->h) >> 1; 469f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires 4702d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x); 4712d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y); 472f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); 4732d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p); 474f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); 475f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); 4762d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 4775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires s->seen_in_this_frame = false; 4785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 4805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_mt_report_pointer_emulation(input, true); 4825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires input_sync(input); 4835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->num_received = 0; 4845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 4855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4885519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_event(struct hid_device *hid, struct hid_field *field, 4895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_usage *usage, __s32 value) 4905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 4915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hid); 492eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires __s32 quirks = td->mtclass.quirks; 4935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 4949498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (hid->claimed & HID_CLAIMED_INPUT && td->slots) { 4955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires switch (usage->hid) { 4965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_INRANGE: 497a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty if (quirks & MT_QUIRK_ALWAYS_VALID) 498a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty td->curvalid = true; 499a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty else if (quirks & MT_QUIRK_VALID_IS_INRANGE) 5002d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPSWITCH: 5032d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) 5042d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.touch_state = value; 5065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONFIDENCE: 5082d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE) 5092d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->curvalid = value; 5105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTID: 5125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.contactid = value; 5135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_TIPPRESSURE: 5155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.p = value; 5165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_X: 5185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.x = value; 5195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_GD_Y: 5215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.y = value; 5225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_WIDTH: 5245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.w = value; 5255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_HEIGHT: 5275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->curdata.h = value; 5285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires case HID_DG_CONTACTCOUNT: 5305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* 5312d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires * Includes multi-packet support where subsequent 5322d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires * packets are sent with zero contactcount. 5335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */ 5345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (value) 5352d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires td->num_expected = value; 5365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires break; 5375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires default: 5395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* fallback to the generic hidinput handling */ 5405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 5415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 5425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 543f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg if (usage->hid == td->last_slot_field) { 5442d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mt_complete_slot(td); 545f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg } 5462d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires 5472d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (field->index == td->last_field_index 5482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires && td->num_received >= td->num_expected) 5492d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mt_emit_event(td, field->hidinput->input); 5505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5512d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* we have handled the hidinput part, now remains hiddev */ 5545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event) 5555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid->hiddev_hid_event(hid, field, usage, value); 5565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 1; 5585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 5595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5605519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_set_input_mode(struct hid_device *hdev) 5615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 5625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 5635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_report *r; 5645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct hid_report_enum *re; 5655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (td->inputmode < 0) 5675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return; 5685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires re = &(hdev->report_enum[HID_FEATURE_REPORT]); 5705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires r = re->report_id_hash[td->inputmode]; 5715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (r) { 5725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires r->field[0]->value[0] = 0x02; 5735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires usbhid_submit_report(hdev, r, USB_DIR_OUT); 5745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 5755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 5765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5775519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) 5785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 5792d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires int ret, i; 5805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td; 5812d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */ 5822d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires 5832d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires for (i = 0; mt_classes[i].name ; i++) { 5842d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (id->driver_data == mt_classes[i].name) { 5852d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires mtclass = &(mt_classes[i]); 5862d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires break; 5872d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5882d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires } 5895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 590d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg /* This allows the driver to correctly support devices 591d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg * that emit events over several HID messages. 592d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg */ 593d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; 5945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 5959498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td = kzalloc(sizeof(struct mt_device), GFP_KERNEL); 5965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (!td) { 5975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires dev_err(&hdev->dev, "cannot allocate multitouch data\n"); 5985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return -ENOMEM; 5995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires } 600eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires td->mtclass = *mtclass; 6015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires td->inputmode = -1; 602b84bd27fe70206f9253c395958134e4e4b7e55f0Benjamin Tissoires td->last_mt_collection = -1; 6035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_set_drvdata(hdev, td); 6045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires ret = hid_parse(hdev); 6065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires if (ret != 0) 6075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires goto fail; 6085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 6102d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires if (ret) 6115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires goto fail; 6125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6139498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), 6149498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires GFP_KERNEL); 6159498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires if (!td->slots) { 6169498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires dev_err(&hdev->dev, "cannot allocate multitouch slots\n"); 6179498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires hid_hw_stop(hdev); 6189498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires ret = -ENOMEM; 6199498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires goto fail; 6209498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires } 6219498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires 622eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group); 623eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires 6245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires mt_set_input_mode(hdev); 6255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 6275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6285519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresfail: 6295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires kfree(td); 6305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return ret; 6315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM 6345519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_reset_resume(struct hid_device *hdev) 6355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 6365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires mt_set_input_mode(hdev); 6375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return 0; 6385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif 6405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6415519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_remove(struct hid_device *hdev) 6425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 6435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires struct mt_device *td = hid_get_drvdata(hdev); 644eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group); 6455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_hw_stop(hdev); 6469498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires kfree(td->slots); 6475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires kfree(td); 6485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_set_drvdata(hdev, NULL); 6495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 6505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 6515519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_device_id mt_devices[] = { 6525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 653f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires /* 3M panels */ 654f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires { .driver_data = MT_CLS_3M, 655f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_3M, 656f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires USB_DEVICE_ID_3M1968) }, 657f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires { .driver_data = MT_CLS_3M, 658f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_3M, 659f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires USB_DEVICE_ID_3M2256) }, 660f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires 661e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires /* ActionStar panels */ 662e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 663e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, 664e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires USB_DEVICE_ID_ACTIONSTAR_1011) }, 665e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires 666a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires /* Cando panels */ 667a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 668a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 669a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, 670a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 671a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 672a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) }, 673a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 674a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 675a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, 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_15_6) }, 679a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires 680942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang /* Chunghwa Telecom touch panels */ 681942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang { .driver_data = MT_CLS_DEFAULT, 682942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, 683942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, 684942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang 68579603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires /* CVTouch panels */ 68679603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 68779603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, 68879603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires USB_DEVICE_ID_CVTOUCH_SCREEN) }, 68979603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires 690a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires /* Cypress panel */ 691a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires { .driver_data = MT_CLS_CYPRESS, 692a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, 693a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires USB_DEVICE_ID_CYPRESS_TRUETOUCH) }, 694a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires 69522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* eGalax devices (resistive) */ 696e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 69722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 698e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) }, 699e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 70022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 701e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) }, 70222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 70322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires /* eGalax devices (capacitive) */ 704e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 70522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 706e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) }, 707e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 70822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 709e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) }, 710e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 71122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 712e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) }, 713e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires { .driver_data = MT_CLS_EGALAX, 7141fd8f047490dd0ec4e4db710fcbc1bd4798d944cChris Bagwell HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 71566f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) }, 71666f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires { .driver_data = MT_CLS_EGALAX, 71766f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 718bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) }, 7191b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires { .driver_data = MT_CLS_EGALAX_SERIAL, 720bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut HID_USB_DEVICE(USB_VENDOR_ID_DWAV, 721e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, 72222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires 723c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires /* Elo TouchSystems IntelliTouch Plus panel */ 724c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires { .driver_data = MT_CLS_DUAL_NSMU_CONTACTID, 725c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ELO, 726c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires USB_DEVICE_ID_ELO_TS2515) }, 727c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires 7285572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires /* GeneralTouch panel */ 7291e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER, 7305572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 7315572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) }, 7325572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires 733ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires /* GoodTouch panels */ 734ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 735ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, 736ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires USB_DEVICE_ID_GOODTOUCH_000f) }, 737ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires 738a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty /* Ideacom panel */ 739a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty { .driver_data = MT_CLS_SERIAL, 740a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, 741a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty USB_DEVICE_ID_IDEACOM_IDC6650) }, 742a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty 7434e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang /* Ilitek dual touch panel */ 7444e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang { .driver_data = MT_CLS_DEFAULT, 7454e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, 7464e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang USB_DEVICE_ID_ILITEK_MULTITOUCH) }, 7474e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang 7484dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires /* IRTOUCH panels */ 7494dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 7504dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, 7514dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, 7524dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires 753c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown /* LG Display panels */ 754c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown { .driver_data = MT_CLS_DEFAULT, 755c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown HID_USB_DEVICE(USB_VENDOR_ID_LG, 756c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown USB_DEVICE_ID_LG_MULTITOUCH) }, 757c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown 758df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires /* Lumio panels */ 759df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 760df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 761df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires USB_DEVICE_ID_CRYSTALTOUCH) }, 762c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 763c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 764c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, 765df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires 7664a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires /* MosArt panels */ 7674a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7684a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ASUS, 7694a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_ASUS_T91MT)}, 7704a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7714a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_ASUS, 7724a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, 7734a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 7744a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, 7754a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) }, 7764a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires 7776ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung /* PenMount panels */ 7786ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung { .driver_data = MT_CLS_CONFIDENCE, 7796ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, 7806ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung USB_DEVICE_ID_PENMOUNT_PCI) }, 7816ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung 7825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires /* PixCir-based panels */ 7831e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 7845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_HANVON, 7855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires USB_DEVICE_ID_HANVON_MULTITOUCH) }, 7861e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires { .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID, 7875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_CANDO, 7885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) }, 7895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 7905e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires /* Quanta-based panels */ 7915e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 7925e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 7935e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 7945e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 7955e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 7965e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) }, 7975e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID, 7985e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, 7995e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) }, 8005e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires 801043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires /* Stantum panels */ 802bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 803043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, 804043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP)}, 805bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 80685a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, 807043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP_STM)}, 808bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires { .driver_data = MT_CLS_CONFIDENCE, 80985a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, 810043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires USB_DEVICE_ID_MTP_SITRONIX)}, 811043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires 8125e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires /* Touch International panels */ 8135e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 8145e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, 8155e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) }, 8165e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires 817617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires /* Unitec panels */ 818617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 819617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 820617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, 821617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires { .driver_data = MT_CLS_DEFAULT, 822617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 823617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 824bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien /* XAT */ 825bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien { .driver_data = MT_CLS_DEFAULT, 826bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien HID_USB_DEVICE(USB_VENDOR_ID_XAT, 827bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien USB_DEVICE_ID_XAT_CSR) }, 828617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires 8295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { } 8305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8315519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DEVICE_TABLE(hid, mt_devices); 8325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8335519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_usage_id mt_grabbed_usages[] = { 8345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { HID_ANY_ID, HID_ANY_ID, HID_ANY_ID }, 8355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1} 8365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8385519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic struct hid_driver mt_driver = { 8395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .name = "hid-multitouch", 8405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .id_table = mt_devices, 8415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .probe = mt_probe, 8425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .remove = mt_remove, 8435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .input_mapping = mt_input_mapping, 8445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .input_mapped = mt_input_mapped, 8455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .feature_mapping = mt_feature_mapping, 8465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .usage_table = mt_grabbed_usages, 8475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .event = mt_event, 8485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM 8495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires .reset_resume = mt_reset_resume, 8505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif 8515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}; 8525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8535519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int __init mt_init(void) 8545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 8555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires return hid_register_driver(&mt_driver); 8565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 8575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8585519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void __exit mt_exit(void) 8595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{ 8605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires hid_unregister_driver(&mt_driver); 8615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires} 8625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires 8635519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_init(mt_init); 8645519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_exit(mt_exit); 865