15519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
25519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *  HID driver for multitouch panels
35519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *
4c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires *  Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
5c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires *  Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
6c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires *  Copyright (c) 2010-2012 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;
70c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	bool is_indirect;	/* true for touchpads */
71eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires};
72eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
73099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoiresstruct mt_fields {
74099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	unsigned usages[HID_MAX_FIELDS];
75099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	unsigned int length;
76099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires};
77099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
785519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_device {
795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_slot curdata;	/* placeholder of incoming data */
80eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct mt_class mtclass;	/* our mt device class */
81099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	struct mt_fields *fields;	/* temporary placeholder for storing the
82099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires					   multitouch fields */
835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	unsigned last_field_index;	/* last field index of the report */
845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	unsigned last_slot_field;	/* the last field of a slot */
855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
8631ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	__s8 maxcontact_report_id;	/* Maximum Contact Number HID feature,
8731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires				   -1 if non-existent */
885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__u8 num_received;	/* how many contacts we received */
895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__u8 num_expected;	/* expected last contact index */
909498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	__u8 maxcontacts;
919e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires	__u8 touches_by_report;	/* how many touches are present in one report:
929e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires				* 1 means we should use a serial protocol
939e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires				* > 1 means hybrid (multitouch) protocol */
945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	bool curvalid;		/* is the current contact valid? */
959498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	struct mt_slot *slots;
965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* classes of device behavior */
9922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DEFAULT				0x0001
10022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
101a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_CLS_SERIAL				0x0002
102a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty#define MT_CLS_CONFIDENCE			0x0003
1035e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_CONFIDENCE_CONTACT_ID		0x0004
1045e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_CONFIDENCE_MINUS_ONE		0x0005
1055e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTID		0x0006
1065e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER	0x0007
1075e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires#define MT_CLS_DUAL_NSMU_CONTACTID		0x0008
108b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian#define MT_CLS_INRANGE_CONTACTNUMBER		0x0009
10922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
11022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires/* vendor specific classes */
11122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_3M				0x0101
11222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CYPRESS				0x0102
11322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_EGALAX				0x0103
1141b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires#define MT_CLS_EGALAX_SERIAL			0x0104
115847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires#define MT_CLS_TOPSEED				0x0105
1162258e863b451be319d374f89688000ab858b13c3Denis Kovalev#define MT_CLS_PANASONIC			0x0106
1175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
1189498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires#define MT_DEFAULT_MAXCONTACT	10
1199498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
1205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
1215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * these device-dependent functions determine what slot corresponds
1225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * to a valid contact that was just read.
1235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
1245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
125a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoiresstatic int cypress_compute_slot(struct mt_device *td)
126a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires{
127a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	if (td->curdata.contactid != 0 || td->num_received == 0)
128a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return td->curdata.contactid;
129a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	else
130a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return -1;
131a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires}
132a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
1335519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int find_slot_from_contactid(struct mt_device *td)
1345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
1355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int i;
1369498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
1375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		if (td->slots[i].contactid == td->curdata.contactid &&
1385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->slots[i].touch_state)
1395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return i;
1405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
1419498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
1425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		if (!td->slots[i].seen_in_this_frame &&
1435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			!td->slots[i].touch_state)
1445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return i;
1455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
1465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* should not occurs. If this happens that means
1475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 * that the device sent more touches that it says
1485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 * in the report descriptor. It is ignored then. */
1492d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	return -1;
1505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
1515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
152b3c21d2cadd568d31db72f37c52bd1d501d1be13Jiri Kosinastatic struct mt_class mt_classes[] = {
1532d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ .name = MT_CLS_DEFAULT,
1549498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
155a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty	{ .name = MT_CLS_SERIAL,
156a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty		.quirks = MT_QUIRK_ALWAYS_VALID},
15722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_CONFIDENCE,
15822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
1595e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires	{ .name = MT_CLS_CONFIDENCE_CONTACT_ID,
1605e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
1615e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID },
16222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_CONFIDENCE_MINUS_ONE,
16322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
16422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
1651e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .name = MT_CLS_DUAL_INRANGE_CONTACTID,
1662d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_INRANGE |
1672d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
1682d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 2 },
1691e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
1702d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_INRANGE |
1712d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTNUMBER,
1722d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 2 },
17322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_DUAL_NSMU_CONTACTID,
17422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
17522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
17622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.maxcontacts = 2 },
177b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian	{ .name = MT_CLS_INRANGE_CONTACTNUMBER,
178b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian		.quirks = MT_QUIRK_VALID_IS_INRANGE |
179b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian			MT_QUIRK_SLOT_IS_CONTACTNUMBER },
18022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
18122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/*
18222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	 * vendor specific classes
18322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	 */
18422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_3M,
18522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
18622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
18722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_move = 2048,
18822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_width = 128,
18922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_height = 128 },
1902d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ .name = MT_CLS_CYPRESS,
1912d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
1922d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_CYPRESS,
1932d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 10 },
1944875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	{ .name = MT_CLS_EGALAX,
1954875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
1962261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires			MT_QUIRK_VALID_IS_INRANGE,
1974875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_move = 4096,
1984875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_pressure = 32,
1994875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	},
2001b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires	{ .name = MT_CLS_EGALAX_SERIAL,
2011b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
2021b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires			MT_QUIRK_ALWAYS_VALID,
2034875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_move = 4096,
2044875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_pressure = 32,
2054875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	},
206847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires	{ .name = MT_CLS_TOPSEED,
207847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires		.quirks = MT_QUIRK_ALWAYS_VALID,
208847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires		.is_indirect = true,
209847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires		.maxcontacts = 2,
210847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires	},
2112258e863b451be319d374f89688000ab858b13c3Denis Kovalev	{ .name = MT_CLS_PANASONIC,
2122258e863b451be319d374f89688000ab858b13c3Denis Kovalev		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
2132258e863b451be319d374f89688000ab858b13c3Denis Kovalev		.maxcontacts = 4 },
214043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires
2152d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ }
2165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
2175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
218eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_show_quirks(struct device *dev,
219eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires			   struct device_attribute *attr,
220eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires			   char *buf)
221eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{
222eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
223eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
224eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
225eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	return sprintf(buf, "%u\n", td->mtclass.quirks);
226eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}
227eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
228eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic ssize_t mt_set_quirks(struct device *dev,
229eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires			  struct device_attribute *attr,
230eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires			  const char *buf, size_t count)
231eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires{
232eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
233eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
234eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
235eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	unsigned long val;
236eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
237eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	if (kstrtoul(buf, 0, &val))
238eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires		return -EINVAL;
239eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
240eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	td->mtclass.quirks = val;
241eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
242eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	return count;
243eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires}
244eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
245eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic DEVICE_ATTR(quirks, S_IWUSR | S_IRUGO, mt_show_quirks, mt_set_quirks);
246eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
247eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute *sysfs_attrs[] = {
248eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	&dev_attr_quirks.attr,
249eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	NULL
250eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires};
251eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
252eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoiresstatic struct attribute_group mt_attribute_group = {
253eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	.attrs = sysfs_attrs
254eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires};
255eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
256f635bd11c8d332d917fb9a4cad3071b2357d5b2aHenrik Rydbergstatic void mt_feature_mapping(struct hid_device *hdev,
2575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage)
2585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
2599498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
2609498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
2619498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	switch (usage->hid) {
2629498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	case HID_DG_INPUTMODE:
2635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		td->inputmode = field->report->id;
2649498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		break;
2659498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	case HID_DG_CONTACTMAX:
26631ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		td->maxcontact_report_id = field->report->id;
2679498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		td->maxcontacts = field->value[0];
268eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires		if (td->mtclass.maxcontacts)
2699498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires			/* check if the maxcontacts is given by the class */
270eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires			td->maxcontacts = td->mtclass.maxcontacts;
2719498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
2729498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		break;
2735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
2745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
2755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
2765519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void set_abs(struct input_dev *input, unsigned int code,
2775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, int snratio)
2785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
2795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fmin = field->logical_minimum;
2805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fmax = field->logical_maximum;
2815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fuzz = snratio ? (fmax - fmin) / snratio : 0;
2825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
2835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
2845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
285099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoiresstatic void mt_store_field(struct hid_usage *usage, struct mt_device *td,
286ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires		struct hid_input *hi)
287ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires{
288099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	struct mt_fields *f = td->fields;
289099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
290099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	if (f->length >= HID_MAX_FIELDS)
291099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		return;
292099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
293099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	f->usages[f->length++] = usage->hid;
294ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires}
295ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires
2965519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage,
2985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		unsigned long **bit, int *max)
2995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
3005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
301eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	struct mt_class *cls = &td->mtclass;
302c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	int code;
3034875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber
304658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown	/* Only map fields from TouchScreen or TouchPad collections.
3052258e863b451be319d374f89688000ab858b13c3Denis Kovalev	* We need to ignore fields that belong to other collections
3062258e863b451be319d374f89688000ab858b13c3Denis Kovalev	* such as Mouse that might have the same GenericDesktop usages. */
307658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown	if (field->application == HID_DG_TOUCHSCREEN)
308658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown		set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
309c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	else if (field->application != HID_DG_TOUCHPAD)
310658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown		return 0;
311658d4aed59b36f877edc668cc27b188a33e643e5Jeff Brown
312c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	/* In case of an indirect device (touchpad), we need to add
313c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	 * specific BTN_TOOL_* to be handled by the synaptics xorg
314c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	 * driver.
315c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	 * We also consider that touchscreens providing buttons are touchpads.
316c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	 */
317c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	if (field->application == HID_DG_TOUCHPAD ||
318c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	    (usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON ||
319c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	    cls->is_indirect) {
320c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
321c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		set_bit(BTN_TOOL_FINGER, hi->input->keybit);
322c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		set_bit(BTN_TOOL_DOUBLETAP, hi->input->keybit);
323c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		set_bit(BTN_TOOL_TRIPLETAP, hi->input->keybit);
324c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		set_bit(BTN_TOOL_QUADTAP, hi->input->keybit);
325c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	}
326c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires
3272261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires	/* eGalax devices provide a Digitizer.Stylus input which overrides
3282261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires	 * the correct Digitizers.Finger X/Y ranges.
3292261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires	 * Let's just ignore this input. */
3302261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires	if (field->physical == HID_DG_STYLUS)
3312261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires		return -1;
3322261bb9ff0dc38e1d5f35af08f75ec3b37ba6335Benjamin Tissoires
33373f1329d135147aacf26013f64a4c30145bc0520Jeff Brown	/* Only map fields from TouchScreen or TouchPad collections.
33473f1329d135147aacf26013f64a4c30145bc0520Jeff Brown         * We need to ignore fields that belong to other collections
33573f1329d135147aacf26013f64a4c30145bc0520Jeff Brown         * such as Mouse that might have the same GenericDesktop usages. */
33673f1329d135147aacf26013f64a4c30145bc0520Jeff Brown	if (field->application == HID_DG_TOUCHSCREEN)
33773f1329d135147aacf26013f64a4c30145bc0520Jeff Brown		set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
33873f1329d135147aacf26013f64a4c30145bc0520Jeff Brown	else if (field->application == HID_DG_TOUCHPAD)
33973f1329d135147aacf26013f64a4c30145bc0520Jeff Brown		set_bit(INPUT_PROP_POINTER, hi->input->propbit);
34073f1329d135147aacf26013f64a4c30145bc0520Jeff Brown	else
34173f1329d135147aacf26013f64a4c30145bc0520Jeff Brown		return 0;
34273f1329d135147aacf26013f64a4c30145bc0520Jeff Brown
3435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	switch (usage->hid & HID_USAGE_PAGE) {
3445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case HID_UP_GENDESK:
3465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
3475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_X:
3485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
3495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_POSITION_X);
3505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_POSITION_X, field,
3515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_move);
3525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
3535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_X, field, cls->sn_move);
354099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
355ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
3565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_Y:
3585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
3595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_POSITION_Y);
3605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_POSITION_Y, field,
3615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_move);
3625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
3635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_Y, field, cls->sn_move);
364099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
365ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
3665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
3685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return 0;
3695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case HID_UP_DIGITIZER:
3715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
3725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_INRANGE:
373099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
374ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
3755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONFIDENCE:
377099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
378ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
3795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPSWITCH:
3815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
3825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
383099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
384ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
3855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTID:
38750bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires			if (!td->maxcontacts)
38850bc03ab5c7529fdfe4e01621efca7d26439ea00Benjamin Tissoires				td->maxcontacts = MT_DEFAULT_MAXCONTACT;
3899498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires			input_mt_init_slots(hi->input, td->maxcontacts);
390099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
3912955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
3929e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires			td->touches_by_report++;
3935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_WIDTH:
3955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
3965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_TOUCH_MAJOR);
397f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
398f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires				cls->sn_width);
399099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
400ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
4015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
4025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_HEIGHT:
4035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
4045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_TOUCH_MINOR);
405f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
406f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires				cls->sn_height);
4071e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires			input_set_abs_params(hi->input,
4081e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires					ABS_MT_ORIENTATION, 0, 1, 0, 0);
409099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
410ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
4115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
4125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPPRESSURE:
4135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
4145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_PRESSURE);
4155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_PRESSURE, field,
4165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_pressure);
4175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
4185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_PRESSURE, field,
4195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_pressure);
420099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires			mt_store_field(usage, td, hi);
421ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
4225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
4235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTCOUNT:
424ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
4255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
4265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTMAX:
4275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* we don't set td->last_slot_field as contactcount and
4285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			 * contact max are global to the report */
429ed9d5c96147b3bed6178252e8e04b27b7d32edd0Benjamin Tissoires			td->last_field_index = field->index;
4305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return -1;
4315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
432c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		case HID_DG_TOUCH:
433c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires			/* Legacy devices use TIPSWITCH and not TOUCH.
434c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires			 * Let's just ignore this field. */
435c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires			return -1;
4365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		/* let hid-input decide for the others */
4375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return 0;
4385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
439c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires	case HID_UP_BUTTON:
440c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		code = BTN_MOUSE + ((usage->hid - 1) & HID_USAGE);
441c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		hid_map_usage(hi, usage, bit, max, EV_KEY, code);
442c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		input_set_capability(hi->input, EV_KEY, code);
443c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		return 1;
444c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires
4455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case 0xff000000:
4465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		/* we do not want to map these: no input-oriented meaning */
4475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return -1;
4485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
4495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
4515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4535519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
4545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage,
4555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		unsigned long **bit, int *max)
4565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
4575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (usage->type == EV_KEY || usage->type == EV_ABS)
4585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		set_bit(usage->type, hi->input->evbit);
4595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return -1;
4615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4635519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_compute_slot(struct mt_device *td)
4645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
465eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	__s32 quirks = td->mtclass.quirks;
4665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4672d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
4682d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		return td->curdata.contactid;
4695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4702d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_CYPRESS)
471a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return cypress_compute_slot(td);
472a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
4732d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
4742d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		return td->num_received;
4755572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires
4764a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
4774a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		return td->curdata.contactid - 1;
4784a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires
4795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return find_slot_from_contactid(td);
4805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
4835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole contact has been processed,
4845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can assign it to a slot and store the data there
4855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
4865519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_complete_slot(struct mt_device *td)
4875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
4882d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	td->curdata.seen_in_this_frame = true;
4895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (td->curvalid) {
4905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		int slotnum = mt_compute_slot(td);
4915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4929498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		if (slotnum >= 0 && slotnum < td->maxcontacts)
4932d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			td->slots[slotnum] = td->curdata;
4945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
4955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->num_received++;
4965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
5005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole packet has been received and processed,
5015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can decide what to send to the input layer.
5025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
5035519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_emit_event(struct mt_device *td, struct input_dev *input)
5045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
5055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int i;
5065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5079498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
5085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct mt_slot *s = &(td->slots[i]);
509eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires		if ((td->mtclass.quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
5105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			!s->seen_in_this_frame) {
5115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			s->touch_state = false;
5125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
5135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		input_mt_slot(input, i);
5155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		input_mt_report_slot_state(input, MT_TOOL_FINGER,
5165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			s->touch_state);
5172d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		if (s->touch_state) {
518f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			/* this finger is on the screen */
519f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int wide = (s->w > s->h);
520f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			/* divided by two to match visual scale of touch */
521f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int major = max(s->w, s->h) >> 1;
522f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int minor = min(s->w, s->h) >> 1;
523f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires
5242d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
5252d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
526f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
5272d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
528f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
529f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
5302d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		}
5315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		s->seen_in_this_frame = false;
5325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
5345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_mt_report_pointer_emulation(input, true);
5365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_sync(input);
5375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->num_received = 0;
5385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
5395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5425519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_event(struct hid_device *hid, struct hid_field *field,
5435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				struct hid_usage *usage, __s32 value)
5445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
5455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hid);
546eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	__s32 quirks = td->mtclass.quirks;
5475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5489498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
5495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
5505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_INRANGE:
551a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty			if (quirks & MT_QUIRK_ALWAYS_VALID)
552a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty				td->curvalid = true;
553a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty			else if (quirks & MT_QUIRK_VALID_IS_INRANGE)
5542d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
5555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPSWITCH:
5572d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
5582d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
5595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.touch_state = value;
5605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONFIDENCE:
5622d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
5632d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
5645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTID:
5665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.contactid = value;
5675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPPRESSURE:
5695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.p = value;
5705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_X:
5725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.x = value;
5735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_Y:
5755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.y = value;
5765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_WIDTH:
5785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.w = value;
5795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_HEIGHT:
5815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.h = value;
5825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
5835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTCOUNT:
5845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/*
5852d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			 * Includes multi-packet support where subsequent
5862d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			 * packets are sent with zero contactcount.
5875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			 */
5885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			if (value)
5892d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->num_expected = value;
5905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
591c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires		case HID_DG_TOUCH:
592c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires			/* do nothing */
593c2ef8f21ea8f7c34dfa0b569fdee431348205955Benjamin Tissoires			break;
5945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		default:
5965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* fallback to the generic hidinput handling */
5975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 0;
5985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
5995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6002258e863b451be319d374f89688000ab858b13c3Denis Kovalev		if (usage->hid == td->last_slot_field)
6012d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			mt_complete_slot(td);
6022d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires
6032d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		if (field->index == td->last_field_index
6042d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			&& td->num_received >= td->num_expected)
6052d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			mt_emit_event(td, field->hidinput->input);
6065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6072d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	}
6085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* we have handled the hidinput part, now remains hiddev */
6105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
6115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		hid->hiddev_hid_event(hid, field, usage, value);
6125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 1;
6145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
6155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6165519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_set_input_mode(struct hid_device *hdev)
6175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
6185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
6195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct hid_report *r;
6205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct hid_report_enum *re;
6215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (td->inputmode < 0)
6235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return;
6245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	re = &(hdev->report_enum[HID_FEATURE_REPORT]);
6265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	r = re->report_id_hash[td->inputmode];
6275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (r) {
6285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		r->field[0]->value[0] = 0x02;
6295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		usbhid_submit_report(hdev, r, USB_DIR_OUT);
6305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
6315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
6325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
63331ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoiresstatic void mt_set_maxcontacts(struct hid_device *hdev)
63431ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires{
63531ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
63631ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	struct hid_report *r;
63731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	struct hid_report_enum *re;
63831ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	int fieldmax, max;
63931ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires
64031ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	if (td->maxcontact_report_id < 0)
64131ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		return;
64231ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires
64331ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	if (!td->mtclass.maxcontacts)
64431ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		return;
64531ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires
64631ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	re = &hdev->report_enum[HID_FEATURE_REPORT];
64731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	r = re->report_id_hash[td->maxcontact_report_id];
64831ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	if (r) {
64931ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		max = td->mtclass.maxcontacts;
65031ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		fieldmax = r->field[0]->logical_maximum;
65131ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		max = min(fieldmax, max);
65231ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		if (r->field[0]->value[0] != max) {
65331ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires			r->field[0]->value[0] = max;
65431ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires			usbhid_submit_report(hdev, r, USB_DIR_OUT);
65531ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires		}
65631ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	}
65731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires}
65831ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires
659099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoiresstatic void mt_post_parse(struct mt_device *td)
660099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires{
661099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	struct mt_fields *f = td->fields;
662099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
663099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	if (td->touches_by_report > 0) {
664099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		int field_count_per_touch = f->length / td->touches_by_report;
665099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		td->last_slot_field = f->usages[field_count_per_touch - 1];
666099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	}
667099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires}
668099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
6695519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
6705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
6712d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	int ret, i;
6725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td;
6732d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
6742d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires
6758d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires	if (id) {
6768d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires		for (i = 0; mt_classes[i].name ; i++) {
6778d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires			if (id->driver_data == mt_classes[i].name) {
6788d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires				mtclass = &(mt_classes[i]);
6798d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires				break;
6808d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires			}
6812d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		}
6822d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	}
6835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
684d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg	/* This allows the driver to correctly support devices
685d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg	 * that emit events over several HID messages.
686d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg	 */
687d682bd7f38b73e5dff0b5584c8ec301ccf76e4dbHenrik Rydberg	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
6888d179a9ef25a64b451e2bbd46f6a6c16c6a72eb1Benjamin Tissoires	hdev->quirks &= ~HID_QUIRK_MULTITOUCH;
6895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
6909498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
6915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (!td) {
6925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		dev_err(&hdev->dev, "cannot allocate multitouch data\n");
6935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return -ENOMEM;
6945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
695eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	td->mtclass = *mtclass;
6965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->inputmode = -1;
69731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	td->maxcontact_report_id = -1;
6985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_set_drvdata(hdev, td);
6995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
700099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	td->fields = kzalloc(sizeof(struct mt_fields), GFP_KERNEL);
701099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	if (!td->fields) {
702099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		dev_err(&hdev->dev, "cannot allocate multitouch fields data\n");
703099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		ret = -ENOMEM;
704099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires		goto fail;
705099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	}
706099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
7075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	ret = hid_parse(hdev);
7085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (ret != 0)
7095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		goto fail;
7105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
7122d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (ret)
7135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		goto fail;
7145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
715099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	mt_post_parse(td);
716099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
7179e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires	if (!id && td->touches_by_report == 1) {
7189e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		/* the device has been sent by hid-generic */
7199e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		mtclass = &td->mtclass;
7209e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		mtclass->quirks |= MT_QUIRK_ALWAYS_VALID;
7219e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		mtclass->quirks &= ~MT_QUIRK_NOT_SEEN_MEANS_UP;
7229e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		mtclass->quirks &= ~MT_QUIRK_VALID_IS_INRANGE;
7239e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires		mtclass->quirks &= ~MT_QUIRK_VALID_IS_CONFIDENCE;
7249e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires	}
7259e87f22ac6353b50425c5da412fe2418a48e25a3Benjamin Tissoires
7269498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
7279498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires				GFP_KERNEL);
7289498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	if (!td->slots) {
7299498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
7309498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		hid_hw_stop(hdev);
7319498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		ret = -ENOMEM;
7329498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		goto fail;
7339498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	}
7349498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
735eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	ret = sysfs_create_group(&hdev->dev.kobj, &mt_attribute_group);
736eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires
73731ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	mt_set_maxcontacts(hdev);
7385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	mt_set_input_mode(hdev);
7395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
740099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	kfree(td->fields);
741099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	td->fields = NULL;
742099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires
7435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
7445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7455519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresfail:
746099fddaa7a49187a9405cb05c6373814884dfcffBenjamin Tissoires	kfree(td->fields);
7475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	kfree(td);
7485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return ret;
7495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
7505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM
7525519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_reset_resume(struct hid_device *hdev)
7535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
75431ae9bddb935c74b51ead08d54948e5bea0f0344Benjamin Tissoires	mt_set_maxcontacts(hdev);
7555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	mt_set_input_mode(hdev);
7565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
7575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
7585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif
7595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7605519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_remove(struct hid_device *hdev)
7615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
7625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
763eec29e3dab483a5d9a742a6fa68db1ec1f0f7504Benjamin Tissoires	sysfs_remove_group(&hdev->dev.kobj, &mt_attribute_group);
7645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_hw_stop(hdev);
7659498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	kfree(td->slots);
7665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	kfree(td);
7675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_set_drvdata(hdev, NULL);
7685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
7695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7705519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_device_id mt_devices[] = {
7715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
772f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	/* 3M panels */
773f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	{ .driver_data = MT_CLS_3M,
774f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_3M,
775f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			USB_DEVICE_ID_3M1968) },
776f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	{ .driver_data = MT_CLS_3M,
777f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_3M,
778f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			USB_DEVICE_ID_3M2256) },
779c4fad877cd0efb51d8180ae2eaa791c99c92051cBenjamin Tissoires	{ .driver_data = MT_CLS_3M,
780c4fad877cd0efb51d8180ae2eaa791c99c92051cBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_3M,
781c4fad877cd0efb51d8180ae2eaa791c99c92051cBenjamin Tissoires			USB_DEVICE_ID_3M3266) },
782f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires
783e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires	/* ActionStar panels */
784e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
785e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
786e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires			USB_DEVICE_ID_ACTIONSTAR_1011) },
787e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires
788b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires	/* Atmel panels */
789b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires	{ .driver_data = MT_CLS_SERIAL,
790b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
791b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires			USB_DEVICE_ID_ATMEL_MULTITOUCH) },
792841cb1570d2c9eed4496ac9ce53c4fd4ae66ebfcBenjamin Tissoires	{ .driver_data = MT_CLS_SERIAL,
793841cb1570d2c9eed4496ac9ce53c4fd4ae66ebfcBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ATMEL,
794841cb1570d2c9eed4496ac9ce53c4fd4ae66ebfcBenjamin Tissoires			USB_DEVICE_ID_ATMEL_MXT_DIGITIZER) },
795b105712469d957cf1ab223c1ea72b7ba88edb926Benjamin Tissoires
796a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	/* Cando panels */
797a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
798a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
799a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
800a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
801a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
802a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
803a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
804a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
805a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
806a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
807a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
808a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
809a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires
810942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang	/* Chunghwa Telecom touch panels */
811942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang	{  .driver_data = MT_CLS_DEFAULT,
812942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang		HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
813942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
814942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang
81579603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires	/* CVTouch panels */
81679603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
81779603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
81879603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires			USB_DEVICE_ID_CVTOUCH_SCREEN) },
81979603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires
820a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	/* Cypress panel */
821a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	{ .driver_data = MT_CLS_CYPRESS,
822a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
823a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires			USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
824a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
82522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/* eGalax devices (resistive) */
826e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
82722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
828e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480D) },
829e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
83022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
831e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_480E) },
83222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
83322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/* eGalax devices (capacitive) */
834e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
83522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
836e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_720C) },
837fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
838fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
839fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7207) },
840fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
841fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
842fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_725E) },
843fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
844fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
845fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7224) },
8462ce09df47b67f16367272f63f85f4cc991e6009aBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
8472ce09df47b67f16367272f63f85f4cc991e6009aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
8482ce09df47b67f16367272f63f85f4cc991e6009aBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_722A) },
849e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
85022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
851e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_726B) },
852fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
853fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
854fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7262) },
855e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
85622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
857e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72A1) },
858fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
859fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
860fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72AA) },
861e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
8621fd8f047490dd0ec4e4db710fcbc1bd4798d944cChris Bagwell		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
86366f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_72FA) },
86466f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX,
86566f06127f34ad6e8a1b24a2c03144b694d19f99fBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
866bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7302) },
8671b723e8dc81b23141bfb8991e002073b17fd0199Benjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
868bb9ff21072043634f147c05ac65dbf8185d4af6dMarek Vasut		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
869fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349) },
870fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires	{ .driver_data = MT_CLS_EGALAX_SERIAL,
871fd1d152583e6ce02b47cb7315295ab58014aa26dBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
872e36f690b37945e0a9bb1554e1546eeec93f7d1f6Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) },
87322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
874c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires	/* Elo TouchSystems IntelliTouch Plus panel */
875c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
876c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ELO,
877c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires			USB_DEVICE_ID_ELO_TS2515) },
878c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires
8795572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires	/* GeneralTouch panel */
8801e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
8815572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
8825572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires			USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
8835572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires
8844d5df5d11e8027c11c1079205757527cbaade62dAndreas Nielsen	/* Gametel game controller */
8854d5df5d11e8027c11c1079205757527cbaade62dAndreas Nielsen	{ .driver_data = MT_CLS_DEFAULT,
8864d5df5d11e8027c11c1079205757527cbaade62dAndreas Nielsen		HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_FRUCTEL,
8874d5df5d11e8027c11c1079205757527cbaade62dAndreas Nielsen			USB_DEVICE_ID_GAMETEL_MT_MODE) },
8884d5df5d11e8027c11c1079205757527cbaade62dAndreas Nielsen
889ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires	/* GoodTouch panels */
890ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
891ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
892ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires			USB_DEVICE_ID_GOODTOUCH_000f) },
893ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires
894545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires	/* Hanvon panels */
895545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
896545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT,
897545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires			USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) },
898545803651da8dde248eeb8ce3ed1e547e9e4ac0aBenjamin Tissoires
899a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty	/* Ideacom panel */
900a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty	{ .driver_data = MT_CLS_SERIAL,
901a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty		HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
902a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty			USB_DEVICE_ID_IDEACOM_IDC6650) },
90371078b0deba8420e00b0c5e39ea359dbcaa11114Benjamin Tissoires	{ .driver_data = MT_CLS_SERIAL,
90471078b0deba8420e00b0c5e39ea359dbcaa11114Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM,
90571078b0deba8420e00b0c5e39ea359dbcaa11114Benjamin Tissoires			USB_DEVICE_ID_IDEACOM_IDC6651) },
906a062cc5a76fa1d12f0821e56e3746cad2dc2fc65Stephane Chatty
9074e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang	/* Ilitek dual touch panel */
9084e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang	{  .driver_data = MT_CLS_DEFAULT,
9094e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang		HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
9104e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang			USB_DEVICE_ID_ILITEK_MULTITOUCH) },
9114e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang
9124dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires	/* IRTOUCH panels */
9134dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
9144dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
9154dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires			USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
9164dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires
917c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown	/* LG Display panels */
918c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown	{ .driver_data = MT_CLS_DEFAULT,
919c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown		HID_USB_DEVICE(USB_VENDOR_ID_LG,
920c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown			USB_DEVICE_ID_LG_MULTITOUCH) },
921c50bb1a4005630f47b5da26336f74a485033a515Jeff Brown
922df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires	/* Lumio panels */
923df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
924df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
925df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires			USB_DEVICE_ID_CRYSTALTOUCH) },
926c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
927c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
928c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0Benjamin Tissoires			USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
929df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires
9304a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	/* MosArt panels */
9314a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
9324a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
9334a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_ASUS_T91MT)},
9344a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
9354a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
9364a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
9374a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
9384a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
9394a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
9404a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires
9412258e863b451be319d374f89688000ab858b13c3Denis Kovalev	/* Panasonic panels */
9422258e863b451be319d374f89688000ab858b13c3Denis Kovalev	{ .driver_data = MT_CLS_PANASONIC,
9432258e863b451be319d374f89688000ab858b13c3Denis Kovalev		HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
9442258e863b451be319d374f89688000ab858b13c3Denis Kovalev			USB_DEVICE_ID_PANABOARD_UBT780) },
9452258e863b451be319d374f89688000ab858b13c3Denis Kovalev	{ .driver_data = MT_CLS_PANASONIC,
9462258e863b451be319d374f89688000ab858b13c3Denis Kovalev		HID_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
9472258e863b451be319d374f89688000ab858b13c3Denis Kovalev			USB_DEVICE_ID_PANABOARD_UBT880) },
9482258e863b451be319d374f89688000ab858b13c3Denis Kovalev
9496ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung	/* PenMount panels */
9506ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung	{ .driver_data = MT_CLS_CONFIDENCE,
9516ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung		HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
9526ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung			USB_DEVICE_ID_PENMOUNT_PCI) },
9536ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung
954b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian	/* PixArt optical touch screen */
955b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
956b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian		HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
957b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN) },
958b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
959b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian		HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
960b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1) },
961b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian	{ .driver_data = MT_CLS_INRANGE_CONTACTNUMBER,
962b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian		HID_USB_DEVICE(USB_VENDOR_ID_PIXART,
963b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian			USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN2) },
964b7ea95ff9baab144dacdc30d752307938c5ab6bfAaron Tian
9655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* PixCir-based panels */
9661e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
9675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
9685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			USB_DEVICE_ID_HANVON_MULTITOUCH) },
9691e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
9705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
9715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
9725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
9735e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires	/* Quanta-based panels */
9745e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
9755e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
9765e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
9775e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
9785e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
9795e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001) },
9805e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_CONTACT_ID,
9815e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_QUANTA,
9825e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires			USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) },
9835e7ea11f603a0aeb77fd1bff0b242931ffe139deBenjamin Tissoires
984043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires	/* Stantum panels */
985bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
986043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
987043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP)},
988bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
98985a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
990043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP_STM)},
991bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
99285a600825b425d52e466c6093dcdfeba85eb0044Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
993043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP_SITRONIX)},
994043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires
995847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires	/* TopSeed panels */
996847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires	{ .driver_data = MT_CLS_TOPSEED,
997847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2,
998847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires			USB_DEVICE_ID_TOPSEED2_PERIPAD_701) },
999847672cd141c07db3d5fc1442b4c3e8a702488dfBenjamin Tissoires
10005e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires	/* Touch International panels */
10015e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
10025e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
10035e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires			USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
10045e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires
1005617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	/* Unitec panels */
1006617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
1007617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
1008617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires			USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
1009617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
1010617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
1011617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires			USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
1012bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien	/* XAT */
1013bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien	{ .driver_data = MT_CLS_DEFAULT,
1014bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien		HID_USB_DEVICE(USB_VENDOR_ID_XAT,
1015bc8a2a9b4e5c418bebaa6bb812982b7ecd298821ice chien			USB_DEVICE_ID_XAT_CSR) },
1016617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires
101711576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	/* Xiroku */
101811576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
101911576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
102011576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_SPX) },
102111576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
102211576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
102311576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_MPX) },
102411576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
102511576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
102611576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_CSR) },
102711576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
102811576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
102911576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_SPX1) },
103011576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
103111576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
103211576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_MPX1) },
103311576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
103411576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
103511576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_CSR1) },
103611576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
103711576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
103811576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_SPX2) },
103911576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
104011576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
104111576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_MPX2) },
104211576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa	{ .driver_data = MT_CLS_DEFAULT,
104311576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa		HID_USB_DEVICE(USB_VENDOR_ID_XIROKU,
104411576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa			USB_DEVICE_ID_XIROKU_CSR2) },
104511576c6114c3b6505aea2e0c988bedb856a0e20cMasatoshi Hoshikawa
10465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ }
10475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
10485519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DEVICE_TABLE(hid, mt_devices);
10495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
10505519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_usage_id mt_grabbed_usages[] = {
10515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
10525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
10535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
10545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
10555519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic struct hid_driver mt_driver = {
10565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.name = "hid-multitouch",
10575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.id_table = mt_devices,
10585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.probe = mt_probe,
10595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.remove = mt_remove,
10605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.input_mapping = mt_input_mapping,
10615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.input_mapped = mt_input_mapped,
10625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.feature_mapping = mt_feature_mapping,
10635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.usage_table = mt_grabbed_usages,
10645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.event = mt_event,
10655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM
10665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.reset_resume = mt_reset_resume,
10675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif
10685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
10695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
10705519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int __init mt_init(void)
10715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
10725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return hid_register_driver(&mt_driver);
10735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
10745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
10755519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void __exit mt_exit(void)
10765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
10775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_unregister_driver(&mt_driver);
10785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
10795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
10805519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_init(mt_init);
10815519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_exit(mt_exit);
1082