hid-multitouch.c revision 942fd4225f72826b31d893582b6ae7e172bb3202
15519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
25519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *  HID driver for multitouch panels
35519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *
45519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *  Copyright (c) 2010-2011 Stephane Chatty <chatty@enac.fr>
55519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *  Copyright (c) 2010-2011 Benjamin Tissoires <benjamin.tissoires@gmail.com>
65519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *  Copyright (c) 2010-2011 Ecole Nationale de l'Aviation Civile, France
75519cab477b61326963c8d523520db0342862b63Benjamin Tissoires *
84875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *  This code is partly based on hid-egalax.c:
94875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *
104875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *  Copyright (c) 2010 Stephane Chatty <chatty@enac.fr>
114875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *  Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
124875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *  Copyright (c) 2010 Canonical, Ltd.
134875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber *
14f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *  This code is partly based on hid-3m-pct.c:
15f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *
16f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
17f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *  Copyright (c) 2010      Henrik Rydberg <rydberg@euromail.se>
18f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *  Copyright (c) 2010      Canonical, Ltd.
19f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires *
205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * This program is free software; you can redistribute it and/or modify it
245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * under the terms of the GNU General Public License as published by the Free
255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * Software Foundation; either version 2 of the License, or (at your option)
265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * any later version.
275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/device.h>
305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/hid.h>
315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/module.h>
325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/slab.h>
335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/usb.h>
345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include <linux/input/mt.h>
355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include "usbhid/usbhid.h"
365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
385519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
39ef2fafb3e233ca9cb390fc3c1461b7f3859998fcBenjamin TissoiresMODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
405519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DESCRIPTION("HID multitouch panels");
415519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_LICENSE("GPL");
425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#include "hid-ids.h"
445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* quirks to control the device */
465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#define MT_QUIRK_NOT_SEEN_MEANS_UP	(1 << 0)
475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#define MT_QUIRK_SLOT_IS_CONTACTID	(1 << 1)
482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires#define MT_QUIRK_CYPRESS		(1 << 2)
495572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires#define MT_QUIRK_SLOT_IS_CONTACTNUMBER	(1 << 3)
502d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires#define MT_QUIRK_VALID_IS_INRANGE	(1 << 4)
512d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires#define MT_QUIRK_VALID_IS_CONFIDENCE	(1 << 5)
524875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber#define MT_QUIRK_EGALAX_XYZ_FIXUP	(1 << 6)
534a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	(1 << 7)
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
625519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_device {
635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_slot curdata;	/* placeholder of incoming data */
645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_class *mtclass;	/* our mt device class */
655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	unsigned last_field_index;	/* last field index of the report */
665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	unsigned last_slot_field;	/* the last field of a slot */
675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__u8 num_received;	/* how many contacts we received */
695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__u8 num_expected;	/* expected last contact index */
709498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	__u8 maxcontacts;
715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	bool curvalid;		/* is the current contact valid? */
729498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	struct mt_slot *slots;
735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
755519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_class {
762d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	__s32 name;	/* MT_CLS */
775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__s32 quirks;
785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__s32 sn_move;	/* Signal/noise ratio for move events */
79f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	__s32 sn_width;	/* Signal/noise ratio for width events */
80f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	__s32 sn_height;	/* Signal/noise ratio for height events */
815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	__u8 maxcontacts;
835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/* classes of device behavior */
8622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DEFAULT				0x0001
8722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
8822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CONFIDENCE			0x0002
8922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CONFIDENCE_MINUS_ONE		0x0003
9022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTID		0x0004
9122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER	0x0005
9222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_DUAL_NSMU_CONTACTID		0x0006
9322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
9422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires/* vendor specific classes */
9522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_3M				0x0101
9622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_CYPRESS				0x0102
9722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires#define MT_CLS_EGALAX				0x0103
985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
999498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires#define MT_DEFAULT_MAXCONTACT	10
1009498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
1015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
1025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * these device-dependent functions determine what slot corresponds
1035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * to a valid contact that was just read.
1045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
1055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
106a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoiresstatic int cypress_compute_slot(struct mt_device *td)
107a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires{
108a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	if (td->curdata.contactid != 0 || td->num_received == 0)
109a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return td->curdata.contactid;
110a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	else
111a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return -1;
112a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires}
113a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
1145519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int find_slot_from_contactid(struct mt_device *td)
1155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
1165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int i;
1179498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
1185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		if (td->slots[i].contactid == td->curdata.contactid &&
1195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->slots[i].touch_state)
1205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return i;
1215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
1229498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
1235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		if (!td->slots[i].seen_in_this_frame &&
1245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			!td->slots[i].touch_state)
1255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return i;
1265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
1275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* should not occurs. If this happens that means
1285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 * that the device sent more touches that it says
1295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 * in the report descriptor. It is ignored then. */
1302d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	return -1;
1315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
1325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
1335519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstruct mt_class mt_classes[] = {
1342d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ .name = MT_CLS_DEFAULT,
1359498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
13622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_CONFIDENCE,
13722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
13822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_CONFIDENCE_MINUS_ONE,
13922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
14022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
1411e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .name = MT_CLS_DUAL_INRANGE_CONTACTID,
1422d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_INRANGE |
1432d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
1442d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 2 },
1451e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .name = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
1462d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_INRANGE |
1472d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTNUMBER,
1482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 2 },
14922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_DUAL_NSMU_CONTACTID,
15022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
15122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
15222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.maxcontacts = 2 },
15322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
15422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/*
15522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	 * vendor specific classes
15622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	 */
15722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{ .name = MT_CLS_3M,
15822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
15922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			MT_QUIRK_SLOT_IS_CONTACTID,
16022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_move = 2048,
16122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_width = 128,
16222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		.sn_height = 128 },
1632d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ .name = MT_CLS_CYPRESS,
1642d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
1652d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			MT_QUIRK_CYPRESS,
1662d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		.maxcontacts = 10 },
1674875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	{ .name = MT_CLS_EGALAX,
1684875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
1694875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber			MT_QUIRK_VALID_IS_INRANGE |
1704875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber			MT_QUIRK_EGALAX_XYZ_FIXUP,
1714875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.maxcontacts = 2,
1724875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_move = 4096,
1734875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber		.sn_pressure = 32,
1744875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	},
175043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires
1762d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	{ }
1775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
1785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
179f635bd11c8d332d917fb9a4cad3071b2357d5b2aHenrik Rydbergstatic void mt_feature_mapping(struct hid_device *hdev,
1805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage)
1815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
1829498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
1839498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
1849498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	switch (usage->hid) {
1859498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	case HID_DG_INPUTMODE:
1865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		td->inputmode = field->report->id;
1879498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		break;
1889498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	case HID_DG_CONTACTMAX:
1899498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		td->maxcontacts = field->value[0];
1909498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		if (td->mtclass->maxcontacts)
1919498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires			/* check if the maxcontacts is given by the class */
1929498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires			td->maxcontacts = td->mtclass->maxcontacts;
1939498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
1949498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		break;
1955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
1965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
1975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
1985519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void set_abs(struct input_dev *input, unsigned int code,
1995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, int snratio)
2005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
2015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fmin = field->logical_minimum;
2025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fmax = field->logical_maximum;
2035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int fuzz = snratio ? (fmax - fmin) / snratio : 0;
2045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
2055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
2065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
2075519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage,
2095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		unsigned long **bit, int *max)
2105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
2115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
2125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_class *cls = td->mtclass;
2134875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber	__s32 quirks = cls->quirks;
2144875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber
2155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	switch (usage->hid & HID_USAGE_PAGE) {
2165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
2175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case HID_UP_GENDESK:
2185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
2195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_X:
2204875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
2214875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber				field->logical_maximum = 32760;
2225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
2235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_POSITION_X);
2245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_POSITION_X, field,
2255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_move);
2265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
2275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_X, field, cls->sn_move);
2285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2292955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_Y:
2324875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
2334875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber				field->logical_maximum = 32760;
2345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
2355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_POSITION_Y);
2365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_POSITION_Y, field,
2375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_move);
2385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
2395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_Y, field, cls->sn_move);
2405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2412955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
2445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return 0;
2455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
2465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case HID_UP_DIGITIZER:
2475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
2485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_INRANGE:
2495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2502955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONFIDENCE:
2535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2542955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPSWITCH:
2575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
2585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
2595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2602955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTID:
2639498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires			input_mt_init_slots(hi->input, td->maxcontacts);
2645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2652955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_WIDTH:
2685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
2695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_TOUCH_MAJOR);
270f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
271f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires				cls->sn_width);
2725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2732955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_HEIGHT:
2765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
2775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_TOUCH_MINOR);
278f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
279f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires				cls->sn_height);
2801e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires			input_set_abs_params(hi->input,
2811e648a13720ef5de51f132501acf3e443d1a36d4Benjamin Tissoires					ABS_MT_ORIENTATION, 0, 1, 0, 0);
2825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2832955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPPRESSURE:
2864875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
2874875ac114d8bce99838a9b0ee7c3f5469cc6352eRichard Nauber				field->logical_minimum = 0;
2885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			hid_map_usage(hi, usage, bit, max,
2895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires					EV_ABS, ABS_MT_PRESSURE);
2905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_MT_PRESSURE, field,
2915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_pressure);
2925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* touchscreen emulation */
2935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			set_abs(hi->input, ABS_PRESSURE, field,
2945519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				cls->sn_pressure);
2955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->last_slot_field = usage->hid;
2962955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
2975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
2985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTCOUNT:
2992955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
3005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 1;
3015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTMAX:
3025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* we don't set td->last_slot_field as contactcount and
3035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			 * contact max are global to the report */
3042955caed8b9865c1f04fcde6bd7103d5d5ec9415Benjamin Tissoires			td->last_field_index = field->index;
3055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return -1;
3065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
3075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		/* let hid-input decide for the others */
3085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return 0;
3095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	case 0xff000000:
3115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		/* we do not want to map these: no input-oriented meaning */
3125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return -1;
3135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
3145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
3165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
3175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3185519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
3195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct hid_field *field, struct hid_usage *usage,
3205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		unsigned long **bit, int *max)
3215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
3225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (usage->type == EV_KEY || usage->type == EV_ABS)
3235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		set_bit(usage->type, hi->input->evbit);
3245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return -1;
3265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
3275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3285519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_compute_slot(struct mt_device *td)
3295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
3302d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	__s32 quirks = td->mtclass->quirks;
3315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3322d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID)
3332d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		return td->curdata.contactid;
3345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3352d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_CYPRESS)
336a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		return cypress_compute_slot(td);
337a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
3382d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
3392d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		return td->num_received;
3405572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires
3414a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
3424a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		return td->curdata.contactid - 1;
3434a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires
3445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return find_slot_from_contactid(td);
3455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
3465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
3485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole contact has been processed,
3495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can assign it to a slot and store the data there
3505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
3515519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_complete_slot(struct mt_device *td)
3525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
3532d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	td->curdata.seen_in_this_frame = true;
3545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (td->curvalid) {
3555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		int slotnum = mt_compute_slot(td);
3565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3579498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		if (slotnum >= 0 && slotnum < td->maxcontacts)
3582d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			td->slots[slotnum] = td->curdata;
3595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
3605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->num_received++;
3615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
3625519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires/*
3655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * this function is called when a whole packet has been received and processed,
3665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires * so that it can decide what to send to the input layer.
3675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires */
3685519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_emit_event(struct mt_device *td, struct input_dev *input)
3695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
3705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	int i;
3715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3729498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	for (i = 0; i < td->maxcontacts; ++i) {
3735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		struct mt_slot *s = &(td->slots[i]);
3745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
3755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			!s->seen_in_this_frame) {
3765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			s->touch_state = false;
3775519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
3785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		input_mt_slot(input, i);
3805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		input_mt_report_slot_state(input, MT_TOOL_FINGER,
3815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			s->touch_state);
3822d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		if (s->touch_state) {
383f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			/* this finger is on the screen */
384f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int wide = (s->w > s->h);
385f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			/* divided by two to match visual scale of touch */
386f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int major = max(s->w, s->h) >> 1;
387f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			int minor = min(s->w, s->h) >> 1;
388f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires
3892d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
3902d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
391f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
3922d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
393f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
394f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
3952d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		}
3965519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		s->seen_in_this_frame = false;
3975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
3985519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
3995519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4005519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_mt_report_pointer_emulation(input, true);
4015519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	input_sync(input);
4025519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->num_received = 0;
4035519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4045519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4055519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4075519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_event(struct hid_device *hid, struct hid_field *field,
4085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires				struct hid_usage *usage, __s32 value)
4095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
4105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hid);
4112d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	__s32 quirks = td->mtclass->quirks;
4125519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4139498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
4145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		switch (usage->hid) {
4155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_INRANGE:
4162d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			if (quirks & MT_QUIRK_VALID_IS_INRANGE)
4172d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
4185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPSWITCH:
4202d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			if (quirks & MT_QUIRK_NOT_SEEN_MEANS_UP)
4212d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
4225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.touch_state = value;
4235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONFIDENCE:
4252d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
4262d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->curvalid = value;
4275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTID:
4295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.contactid = value;
4305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_TIPPRESSURE:
4325519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.p = value;
4335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_X:
4355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.x = value;
4365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4375519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_GD_Y:
4385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.y = value;
4395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_WIDTH:
4415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.w = value;
4425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_HEIGHT:
4445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			td->curdata.h = value;
4455519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		case HID_DG_CONTACTCOUNT:
4475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/*
4482d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			 * Includes multi-packet support where subsequent
4492d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			 * packets are sent with zero contactcount.
4505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			 */
4515519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			if (value)
4522d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires				td->num_expected = value;
4535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			break;
4545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		default:
4565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			/* fallback to the generic hidinput handling */
4575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			return 0;
4585519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		}
4595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
460f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg		if (usage->hid == td->last_slot_field) {
4612d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			mt_complete_slot(td);
462f153fc3990d4ad2709a52d7150e2c04363afb1fbHenrik Rydberg		}
4632d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires
4642d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		if (field->index == td->last_field_index
4652d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			&& td->num_received >= td->num_expected)
4662d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			mt_emit_event(td, field->hidinput->input);
4675519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4682d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	}
4695519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4705519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* we have handled the hidinput part, now remains hiddev */
4715519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (hid->claimed & HID_CLAIMED_HIDDEV && hid->hiddev_hid_event)
4725519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		hid->hiddev_hid_event(hid, field, usage, value);
4735519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4745519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 1;
4755519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4775519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_set_input_mode(struct hid_device *hdev)
4785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
4795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
4805519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct hid_report *r;
4815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct hid_report_enum *re;
4825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (td->inputmode < 0)
4845519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return;
4855519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4865519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	re = &(hdev->report_enum[HID_FEATURE_REPORT]);
4875519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	r = re->report_id_hash[td->inputmode];
4885519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (r) {
4895519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		r->field[0]->value[0] = 0x02;
4905519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		usbhid_submit_report(hdev, r, USB_DIR_OUT);
4915519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
4925519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
4935519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
4945519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
4955519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
4962d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	int ret, i;
4975519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td;
4982d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	struct mt_class *mtclass = mt_classes; /* MT_CLS_DEFAULT */
4992d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires
5002d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	for (i = 0; mt_classes[i].name ; i++) {
5012d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		if (id->driver_data == mt_classes[i].name) {
5022d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			mtclass = &(mt_classes[i]);
5032d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires			break;
5042d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires		}
5052d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	}
5065519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5075519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* This allows the driver to correctly support devices
5085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 * that emit events over several HID messages.
5095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	 */
5105519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
5115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5129498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
5135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (!td) {
5145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		dev_err(&hdev->dev, "cannot allocate multitouch data\n");
5155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		return -ENOMEM;
5165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	}
5175519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->mtclass = mtclass;
5185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	td->inputmode = -1;
5195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_set_drvdata(hdev, td);
5205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	ret = hid_parse(hdev);
5225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	if (ret != 0)
5235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		goto fail;
5245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
5262d93666e70662cfcf1927e1a858685f5b38d5d65Benjamin Tissoires	if (ret)
5275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		goto fail;
5285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5299498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	if (!td->maxcontacts)
5309498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		td->maxcontacts = MT_DEFAULT_MAXCONTACT;
5319498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
5329498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
5339498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires				GFP_KERNEL);
5349498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	if (!td->slots) {
5359498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
5369498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		hid_hw_stop(hdev);
5379498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		ret = -ENOMEM;
5389498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires		goto fail;
5399498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	}
5409498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires
5415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	mt_set_input_mode(hdev);
5425519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5435519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
5445519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5455519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresfail:
5465519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	kfree(td);
5475519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return ret;
5485519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
5495519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5505519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM
5515519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int mt_reset_resume(struct hid_device *hdev)
5525519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
5535519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	mt_set_input_mode(hdev);
5545519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return 0;
5555519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
5565519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif
5575519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5585519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void mt_remove(struct hid_device *hdev)
5595519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
5605519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	struct mt_device *td = hid_get_drvdata(hdev);
5615519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_hw_stop(hdev);
5629498f954a4ec389806333041a1018909c6fe0518Benjamin Tissoires	kfree(td->slots);
5635519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	kfree(td);
5645519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_set_drvdata(hdev, NULL);
5655519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
5665519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
5675519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_device_id mt_devices[] = {
5685519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
569f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	/* 3M panels */
570f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	{ .driver_data = MT_CLS_3M,
571f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_3M,
572f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			USB_DEVICE_ID_3M1968) },
573f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires	{ .driver_data = MT_CLS_3M,
574f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_3M,
575f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires			USB_DEVICE_ID_3M2256) },
576f786bba4499cf3de20da345ce090457ebcef03b0Benjamin Tissoires
577e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires	/* ActionStar panels */
578e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
579e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
580e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires			USB_DEVICE_ID_ACTIONSTAR_1011) },
581e6aac3427ef03f61e7478514d0648b58359d05d1Benjamin Tissoires
582a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	/* Cando panels */
583a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
584a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
585a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
586a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
587a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
588a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
589a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
590a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
591a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
592a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
593a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
594a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires			USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
595a841b62c5d5f75ce3676fde755696d30cc8de99aBenjamin Tissoires
596942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang	/* Chunghwa Telecom touch panels */
597942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang	{  .driver_data = MT_CLS_DEFAULT,
598942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang		HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
599942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
600942fd4225f72826b31d893582b6ae7e172bb3202Austin Zhang
60179603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires	/* CVTouch panels */
60279603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
60379603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
60479603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires			USB_DEVICE_ID_CVTOUCH_SCREEN) },
60579603dc9a8223856cf3194dcabad32b9828c7be9Benjamin Tissoires
606a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	/* Cypress panel */
607a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires	{ .driver_data = MT_CLS_CYPRESS,
608a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
609a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires			USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
610a3b5e577d96bfccbc41ebf4df784e3a153072273Benjamin Tissoires
61122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/* eGalax devices (resistive) */
61222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{  .driver_data = MT_CLS_EGALAX,
61322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
61422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
61522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{  .driver_data = MT_CLS_EGALAX,
61622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
61722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
61822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
61922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	/* eGalax devices (capacitive) */
62022408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{  .driver_data = MT_CLS_EGALAX,
62122408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
62222408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
62322408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{  .driver_data = MT_CLS_EGALAX,
62422408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
62522408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
62622408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires	{  .driver_data = MT_CLS_EGALAX,
62722408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
62822408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
62922408283bca57780bdd53da5a6e4474b71b94430Benjamin Tissoires
630c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires	/* Elo TouchSystems IntelliTouch Plus panel */
631c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
632c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ELO,
633c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires			USB_DEVICE_ID_ELO_TS2515) },
634c04abeeff9d76a703cac1e6d312853b0fc8136f5Benjamin Tissoires
6355572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires	/* GeneralTouch panel */
6361e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
6375572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
6385572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires			USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
6395572da08a784621f2ab4fdc8dc65471261871795Benjamin Tissoires
640ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires	/* GoodTouch panels */
641ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
642ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
643ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires			USB_DEVICE_ID_GOODTOUCH_000f) },
644ee0fbd149182d91e3b9df7b306eb03cd1f1dd4a1Benjamin Tissoires
6454e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang	/* Ilitek dual touch panel */
6464e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang	{  .driver_data = MT_CLS_DEFAULT,
6474e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang		HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
6484e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang			USB_DEVICE_ID_ILITEK_MULTITOUCH) },
6494e61f0d75aa86c9e59451f6bcffcdceb355b4fc4Austin Zhang
6504dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires	/* IRTOUCH panels */
6514dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
6524dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
6534dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires			USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
6544dfcced8a1f42248f9e7a461485f6aa5f66d2105Benjamin Tissoires
655df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires	/* Lumio panels */
656df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
657df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
658df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires			USB_DEVICE_ID_CRYSTALTOUCH) },
659df167c4a0d68a9dbde044a39a77f255ac666f93eBenjamin Tissoires
6604a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	/* MosArt panels */
6614a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
6624a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
6634a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_ASUS_T91MT)},
6644a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
6654a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
6664a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
6674a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
6684a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
6694a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires			USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
6704a6ee685fbcba4a440cf86f41557752ba81e2ccfBenjamin Tissoires
6716ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung	/* PenMount panels */
6726ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung	{ .driver_data = MT_CLS_CONFIDENCE,
6736ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung		HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
6746ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung			USB_DEVICE_ID_PENMOUNT_PCI) },
6756ab3a9a63fc16b04f7de48eb0190d516dd7574dfJohn Sung
6765519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	/* PixCir-based panels */
6771e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
6785519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
6795519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			USB_DEVICE_ID_HANVON_MULTITOUCH) },
6801e9cf35b995610e7ba2934d3dc92e3a03fa361a1Benjamin Tissoires	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
6815519cab477b61326963c8d523520db0342862b63Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
6825519cab477b61326963c8d523520db0342862b63Benjamin Tissoires			USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
6835519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
684043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires	/* Stantum panels */
685bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
686043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
687043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP)},
688bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
689043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
690043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP_STM)},
691bf5af9b5bba2453ff46f241e8f2e139ca79302e7Benjamin Tissoires	{ .driver_data = MT_CLS_CONFIDENCE,
692043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
693043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires			USB_DEVICE_ID_MTP_SITRONIX)},
694043b403aede4a528ed99ceaf050f567f1283a23eBenjamin Tissoires
6955e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires	/* Touch International panels */
6965e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
6975e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
6985e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires			USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
6995e74e56da03f581482c104628951eeb1455848eaBenjamin Tissoires
700617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	/* Unitec panels */
701617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
702617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
703617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires			USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
704617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires	{ .driver_data = MT_CLS_DEFAULT,
705617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
706617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires			USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
707617b64f97708be26a061e6c8178ad46b4c49d031Benjamin Tissoires
7085519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ }
7095519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
7105519cab477b61326963c8d523520db0342862b63Benjamin TissoiresMODULE_DEVICE_TABLE(hid, mt_devices);
7115519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7125519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic const struct hid_usage_id mt_grabbed_usages[] = {
7135519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ HID_ANY_ID, HID_ANY_ID, HID_ANY_ID },
7145519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	{ HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
7155519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
7165519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7175519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic struct hid_driver mt_driver = {
7185519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.name = "hid-multitouch",
7195519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.id_table = mt_devices,
7205519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.probe = mt_probe,
7215519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.remove = mt_remove,
7225519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.input_mapping = mt_input_mapping,
7235519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.input_mapped = mt_input_mapped,
7245519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.feature_mapping = mt_feature_mapping,
7255519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.usage_table = mt_grabbed_usages,
7265519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.event = mt_event,
7275519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#ifdef CONFIG_PM
7285519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	.reset_resume = mt_reset_resume,
7295519cab477b61326963c8d523520db0342862b63Benjamin Tissoires#endif
7305519cab477b61326963c8d523520db0342862b63Benjamin Tissoires};
7315519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7325519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic int __init mt_init(void)
7335519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
7345519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	return hid_register_driver(&mt_driver);
7355519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
7365519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7375519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresstatic void __exit mt_exit(void)
7385519cab477b61326963c8d523520db0342862b63Benjamin Tissoires{
7395519cab477b61326963c8d523520db0342862b63Benjamin Tissoires	hid_unregister_driver(&mt_driver);
7405519cab477b61326963c8d523520db0342862b63Benjamin Tissoires}
7415519cab477b61326963c8d523520db0342862b63Benjamin Tissoires
7425519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_init(mt_init);
7435519cab477b61326963c8d523520db0342862b63Benjamin Tissoiresmodule_exit(mt_exit);
744