Blame view

drivers/hid/wacom_wac.c 115 KB
3bea733ab   Ping Cheng   USB: wacom tablet...
1
  /*
4104d13fe   Dmitry Torokhov   Input: move USB t...
2
   * drivers/input/tablet/wacom_wac.c
3bea733ab   Ping Cheng   USB: wacom tablet...
3
   *
ee54500d7   Ping Cheng   Input: wacom - ad...
4
   *  USB Wacom tablet support - Wacom specific code
3bea733ab   Ping Cheng   USB: wacom tablet...
5
6
7
8
9
10
11
12
13
   *
   */
  
  /*
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   */
51269fe86   Dmitry Torokhov   Input: wacom - do...
14

3bea733ab   Ping Cheng   USB: wacom tablet...
15
  #include "wacom_wac.h"
51269fe86   Dmitry Torokhov   Input: wacom - do...
16
  #include "wacom.h"
47c78e891   Henrik Rydberg   input: mt: Break ...
17
  #include <linux/input/mt.h>
3bea733ab   Ping Cheng   USB: wacom tablet...
18

e35fb8c1d   Ping Cheng   Input: wacom - re...
19
20
21
22
23
24
25
  /* resolution for penabled devices */
  #define WACOM_PL_RES		20
  #define WACOM_PENPRTN_RES	40
  #define WACOM_VOLITO_RES	50
  #define WACOM_GRAPHIRE_RES	80
  #define WACOM_INTUOS_RES	100
  #define WACOM_INTUOS3_RES	200
fa7703402   Ping Cheng   HID: wacom: add d...
26
27
28
  /* Newer Cintiq and DTU have an offset between tablet and screen areas */
  #define WACOM_DTU_OFFSET	200
  #define WACOM_CINTIQ_OFFSET	400
387142bb8   Benjamin Tissoires   Input: wacom - ha...
29
30
  /*
   * Scale factor relating reported contact size to logical contact area.
4e9049549   Jason Gerecke   Input: wacom - re...
31
32
33
   * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo
   */
  #define WACOM_CONTACT_AREA_SCALE 2607
1924e05e6   Ping Cheng   HID: wacom - add ...
34
35
36
  static bool touch_arbitration = 1;
  module_param(touch_arbitration, bool, 0644);
  MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)");
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
37
38
  static void wacom_report_numbered_buttons(struct input_dev *input_dev,
  				int button_count, int mask);
387142bb8   Benjamin Tissoires   Input: wacom - ha...
39
40
41
42
43
  /*
   * Percent of battery capacity for Graphire.
   * 8th value means AC online and show 100% capacity.
   */
  static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
44
45
46
47
  /*
   * Percent of battery capacity for Intuos4 WL, AC has a separate bit.
   */
  static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };
59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  static void __wacom_notify_battery(struct wacom_battery *battery,
  				   int bat_capacity, bool bat_charging,
  				   bool bat_connected, bool ps_connected)
  {
  	bool changed = battery->battery_capacity != bat_capacity  ||
  		       battery->bat_charging     != bat_charging  ||
  		       battery->bat_connected    != bat_connected ||
  		       battery->ps_connected     != ps_connected;
  
  	if (changed) {
  		battery->battery_capacity = bat_capacity;
  		battery->bat_charging = bat_charging;
  		battery->bat_connected = bat_connected;
  		battery->ps_connected = ps_connected;
  
  		if (battery->battery)
  			power_supply_changed(battery->battery);
  	}
  }
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
67
  static void wacom_notify_battery(struct wacom_wac *wacom_wac,
71fa641eb   Jason Gerecke   HID: wacom: Add b...
68
69
  	int bat_capacity, bool bat_charging, bool bat_connected,
  	bool ps_connected)
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
70
71
  {
  	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
72

59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
73
74
  	__wacom_notify_battery(&wacom->battery, bat_capacity, bat_charging,
  			       bat_connected, ps_connected);
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
75
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
76
  static int wacom_penpartner_irq(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
77
78
  {
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
79
  	struct input_dev *input = wacom->pen_input;
3bea733ab   Ping Cheng   USB: wacom tablet...
80
81
  
  	switch (data[0]) {
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
82
83
84
85
  	case 1:
  		if (data[5] & 0x80) {
  			wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  			wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
86
87
  			input_report_key(input, wacom->tool[0], 1);
  			input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
252f77698   Dmitry Torokhov   Input: wacom - us...
88
89
  			input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
  			input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
90
91
92
  			input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
  			input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127));
  			input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
93
  		} else {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
94
95
96
97
  			input_report_key(input, wacom->tool[0], 0);
  			input_report_abs(input, ABS_MISC, 0); /* report tool id */
  			input_report_abs(input, ABS_PRESSURE, -1);
  			input_report_key(input, BTN_TOUCH, 0);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
98
99
  		}
  		break;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
100

73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
101
  	case 2:
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
102
103
  		input_report_key(input, BTN_TOOL_PEN, 1);
  		input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
252f77698   Dmitry Torokhov   Input: wacom - us...
104
105
  		input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
  		input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
106
107
108
  		input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);
  		input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));
  		input_report_key(input, BTN_STYLUS, (data[5] & 0x40));
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
109
  		break;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
110

73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
111
  	default:
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
112
113
114
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d
  ", __func__, data[0]);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
115
  		return 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
116
          }
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
117

3bea733ab   Ping Cheng   USB: wacom tablet...
118
119
  	return 1;
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
120
  static int wacom_pl_irq(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
121
  {
e33da8a54   Jason Childs   Input: wacom - us...
122
  	struct wacom_features *features = &wacom->features;
3bea733ab   Ping Cheng   USB: wacom tablet...
123
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
124
  	struct input_dev *input = wacom->pen_input;
e34b9d2f4   Ping Cheng   Input: wacom - cl...
125
  	int prox, pressure;
3bea733ab   Ping Cheng   USB: wacom tablet...
126

cad747008   Ping Cheng   Input: wacom - ad...
127
  	if (data[0] != WACOM_REPORT_PENABLED) {
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
128
129
130
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d
  ", __func__, data[0]);
3bea733ab   Ping Cheng   USB: wacom tablet...
131
132
133
134
  		return 0;
  	}
  
  	prox = data[1] & 0x40;
025bcc154   Jason Gerecke   HID: wacom: Simpl...
135
136
137
138
  	if (!wacom->id[0]) {
  		if ((data[0] & 0x10) || (data[4] & 0x20)) {
  			wacom->tool[0] = BTN_TOOL_RUBBER;
  			wacom->id[0] = ERASER_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
139
  		}
025bcc154   Jason Gerecke   HID: wacom: Simpl...
140
141
  		else {
  			wacom->tool[0] = BTN_TOOL_PEN;
e34b9d2f4   Ping Cheng   Input: wacom - cl...
142
  			wacom->id[0] = STYLUS_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
143
  		}
3bea733ab   Ping Cheng   USB: wacom tablet...
144
  	}
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
145

025bcc154   Jason Gerecke   HID: wacom: Simpl...
146
147
148
149
150
151
152
153
154
155
  	/* If the eraser is in prox, STYLUS2 is always set. If we
  	 * mis-detected the type and notice that STYLUS2 isn't set
  	 * then force the eraser out of prox and let the pen in.
  	 */
  	if (wacom->tool[0] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
  		input_report_key(input, BTN_TOOL_RUBBER, 0);
  		input_report_abs(input, ABS_MISC, 0);
  		input_sync(input);
  		wacom->tool[0] = BTN_TOOL_PEN;
  		wacom->id[0] = STYLUS_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
156
  	}
e6bd71215   Jason Gerecke   HID: wacom: Fix p...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  	if (prox) {
  		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
  		if (features->pressure_max > 255)
  			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
  		pressure += (features->pressure_max + 1) / 2;
  
  		input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));
  		input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));
  		input_report_abs(input, ABS_PRESSURE, pressure);
  
  		input_report_key(input, BTN_TOUCH, data[4] & 0x08);
  		input_report_key(input, BTN_STYLUS, data[4] & 0x10);
  		/* Only allow the stylus2 button to be reported for the pen tool. */
  		input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20));
  	}
025bcc154   Jason Gerecke   HID: wacom: Simpl...
172
173
174
175
176
  
  	if (!prox)
  		wacom->id[0] = 0;
  	input_report_key(input, wacom->tool[0], prox);
  	input_report_abs(input, ABS_MISC, wacom->id[0]);
3bea733ab   Ping Cheng   USB: wacom tablet...
177
178
  	return 1;
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
179
  static int wacom_ptu_irq(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
180
181
  {
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
182
  	struct input_dev *input = wacom->pen_input;
3bea733ab   Ping Cheng   USB: wacom tablet...
183

cad747008   Ping Cheng   Input: wacom - ad...
184
  	if (data[0] != WACOM_REPORT_PENABLED) {
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
185
186
187
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d
  ", __func__, data[0]);
3bea733ab   Ping Cheng   USB: wacom tablet...
188
189
  		return 0;
  	}
3bea733ab   Ping Cheng   USB: wacom tablet...
190
  	if (data[1] & 0x04) {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
191
192
  		input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20);
  		input_report_key(input, BTN_TOUCH, data[1] & 0x08);
e34b9d2f4   Ping Cheng   Input: wacom - cl...
193
  		wacom->id[0] = ERASER_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
194
  	} else {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
195
196
  		input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20);
  		input_report_key(input, BTN_TOUCH, data[1] & 0x01);
e34b9d2f4   Ping Cheng   Input: wacom - cl...
197
  		wacom->id[0] = STYLUS_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
198
  	}
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
199
  	input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
252f77698   Dmitry Torokhov   Input: wacom - us...
200
201
202
  	input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
  	input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
  	input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6]));
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
203
204
  	input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  	input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
3bea733ab   Ping Cheng   USB: wacom tablet...
205
206
  	return 1;
  }
c8f2edc56   Ping Cheng   Input: wacom - ad...
207
208
  static int wacom_dtu_irq(struct wacom_wac *wacom)
  {
74b634178   Jason Gerecke   Input: wacom - re...
209
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
210
  	struct input_dev *input = wacom->pen_input;
74b634178   Jason Gerecke   Input: wacom - re...
211
  	int prox = data[1] & 0x20;
c8f2edc56   Ping Cheng   Input: wacom - ad...
212

eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
213
214
  	dev_dbg(input->dev.parent,
  		"%s: received report #%d", __func__, data[0]);
c8f2edc56   Ping Cheng   Input: wacom - ad...
215
216
217
218
219
220
221
222
223
224
225
226
227
  
  	if (prox) {
  		/* Going into proximity select tool */
  		wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  		if (wacom->tool[0] == BTN_TOOL_PEN)
  			wacom->id[0] = STYLUS_DEVICE_ID;
  		else
  			wacom->id[0] = ERASER_DEVICE_ID;
  	}
  	input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  	input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
  	input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
  	input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
74b634178   Jason Gerecke   Input: wacom - re...
228
  	input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]);
c8f2edc56   Ping Cheng   Input: wacom - ad...
229
230
231
232
233
234
235
  	input_report_key(input, BTN_TOUCH, data[1] & 0x05);
  	if (!prox) /* out-prox */
  		wacom->id[0] = 0;
  	input_report_key(input, wacom->tool[0], prox);
  	input_report_abs(input, ABS_MISC, wacom->id[0]);
  	return 1;
  }
497ab1f29   Ping Cheng   Input: wacom - ad...
236
237
238
  static int wacom_dtus_irq(struct wacom_wac *wacom)
  {
  	char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
239
  	struct input_dev *input = wacom->pen_input;
497ab1f29   Ping Cheng   Input: wacom - ad...
240
241
242
243
244
245
246
  	unsigned short prox, pressure = 0;
  
  	if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d", __func__, data[0]);
  		return 0;
  	} else if (data[0] == WACOM_REPORT_DTUSPAD) {
422b0314b   Benjamin Tissoires   Input: wacom - sp...
247
  		input = wacom->pad_input;
497ab1f29   Ping Cheng   Input: wacom - ad...
248
249
250
251
252
253
  		input_report_key(input, BTN_0, (data[1] & 0x01));
  		input_report_key(input, BTN_1, (data[1] & 0x02));
  		input_report_key(input, BTN_2, (data[1] & 0x04));
  		input_report_key(input, BTN_3, (data[1] & 0x08));
  		input_report_abs(input, ABS_MISC,
  				 data[1] & 0x0f ? PAD_DEVICE_ID : 0);
497ab1f29   Ping Cheng   Input: wacom - ad...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  		return 1;
  	} else {
  		prox = data[1] & 0x80;
  		if (prox) {
  			switch ((data[1] >> 3) & 3) {
  			case 1: /* Rubber */
  				wacom->tool[0] = BTN_TOOL_RUBBER;
  				wacom->id[0] = ERASER_DEVICE_ID;
  				break;
  
  			case 2: /* Pen */
  				wacom->tool[0] = BTN_TOOL_PEN;
  				wacom->id[0] = STYLUS_DEVICE_ID;
  				break;
  			}
  		}
  
  		input_report_key(input, BTN_STYLUS, data[1] & 0x20);
  		input_report_key(input, BTN_STYLUS2, data[1] & 0x40);
  		input_report_abs(input, ABS_X, get_unaligned_be16(&data[3]));
  		input_report_abs(input, ABS_Y, get_unaligned_be16(&data[5]));
  		pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff);
  		input_report_abs(input, ABS_PRESSURE, pressure);
  		input_report_key(input, BTN_TOUCH, pressure > 10);
  
  		if (!prox) /* out-prox */
  			wacom->id[0] = 0;
  		input_report_key(input, wacom->tool[0], prox);
  		input_report_abs(input, ABS_MISC, wacom->id[0]);
497ab1f29   Ping Cheng   Input: wacom - ad...
283
284
285
  		return 1;
  	}
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
286
  static int wacom_graphire_irq(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
287
  {
e33da8a54   Jason Childs   Input: wacom - us...
288
  	struct wacom_features *features = &wacom->features;
3bea733ab   Ping Cheng   USB: wacom tablet...
289
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
290
  	struct input_dev *input = wacom->pen_input;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
291
  	struct input_dev *pad_input = wacom->pad_input;
387142bb8   Benjamin Tissoires   Input: wacom - ha...
292
  	int battery_capacity, ps_connected;
252f77698   Dmitry Torokhov   Input: wacom - us...
293
  	int prox;
3b57ca0f8   Ping Cheng   Input: wacom - me...
294
295
  	int rw = 0;
  	int retval = 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
296

387142bb8   Benjamin Tissoires   Input: wacom - ha...
297
298
299
300
301
302
303
304
305
  	if (features->type == GRAPHIRE_BT) {
  		if (data[0] != WACOM_REPORT_PENABLED_BT) {
  			dev_dbg(input->dev.parent,
  				"%s: received unknown report #%d
  ", __func__,
  				data[0]);
  			goto exit;
  		}
  	} else if (data[0] != WACOM_REPORT_PENABLED) {
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
306
307
308
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d
  ", __func__, data[0]);
3b57ca0f8   Ping Cheng   Input: wacom - me...
309
  		goto exit;
3bea733ab   Ping Cheng   USB: wacom tablet...
310
  	}
3b57ca0f8   Ping Cheng   Input: wacom - me...
311
312
313
314
  	prox = data[1] & 0x80;
  	if (prox || wacom->id[0]) {
  		if (prox) {
  			switch ((data[1] >> 5) & 3) {
3bea733ab   Ping Cheng   USB: wacom tablet...
315
316
317
  
  			case 0:	/* Pen */
  				wacom->tool[0] = BTN_TOOL_PEN;
e34b9d2f4   Ping Cheng   Input: wacom - cl...
318
  				wacom->id[0] = STYLUS_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
319
320
321
322
  				break;
  
  			case 1: /* Rubber */
  				wacom->tool[0] = BTN_TOOL_RUBBER;
e34b9d2f4   Ping Cheng   Input: wacom - cl...
323
  				wacom->id[0] = ERASER_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
324
325
326
  				break;
  
  			case 2: /* Mouse with wheel */
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
327
  				input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
3bea733ab   Ping Cheng   USB: wacom tablet...
328
329
330
331
  				/* fall through */
  
  			case 3: /* Mouse without wheel */
  				wacom->tool[0] = BTN_TOOL_MOUSE;
e34b9d2f4   Ping Cheng   Input: wacom - cl...
332
  				wacom->id[0] = CURSOR_DEVICE_ID;
3bea733ab   Ping Cheng   USB: wacom tablet...
333
  				break;
3b57ca0f8   Ping Cheng   Input: wacom - me...
334
  			}
3bea733ab   Ping Cheng   USB: wacom tablet...
335
  		}
252f77698   Dmitry Torokhov   Input: wacom - us...
336
337
  		input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
  		input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
3bea733ab   Ping Cheng   USB: wacom tablet...
338
  		if (wacom->tool[0] != BTN_TOOL_MOUSE) {
387142bb8   Benjamin Tissoires   Input: wacom - ha...
339
340
341
342
343
344
  			if (features->type == GRAPHIRE_BT)
  				input_report_abs(input, ABS_PRESSURE, data[6] |
  					(((__u16) (data[1] & 0x08)) << 5));
  			else
  				input_report_abs(input, ABS_PRESSURE, data[6] |
  					((data[7] & 0x03) << 8));
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
345
346
347
  			input_report_key(input, BTN_TOUCH, data[1] & 0x01);
  			input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  			input_report_key(input, BTN_STYLUS2, data[1] & 0x04);
afb567e3f   Dmitry Torokhov   Revert "Input: wa...
348
  		} else {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
349
350
  			input_report_key(input, BTN_LEFT, data[1] & 0x01);
  			input_report_key(input, BTN_RIGHT, data[1] & 0x02);
3b57ca0f8   Ping Cheng   Input: wacom - me...
351
352
  			if (features->type == WACOM_G4 ||
  					features->type == WACOM_MO) {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
353
  				input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);
d9f66c1a4   Mike Auty   Input: wacom - fi...
354
  				rw = (data[7] & 0x04) - (data[7] & 0x03);
387142bb8   Benjamin Tissoires   Input: wacom - ha...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  			} else if (features->type == GRAPHIRE_BT) {
  				/* Compute distance between mouse and tablet */
  				rw = 44 - (data[6] >> 2);
  				rw = clamp_val(rw, 0, 31);
  				input_report_abs(input, ABS_DISTANCE, rw);
  				if (((data[1] >> 5) & 3) == 2) {
  					/* Mouse with wheel */
  					input_report_key(input, BTN_MIDDLE,
  							data[1] & 0x04);
  					rw = (data[6] & 0x01) ? -1 :
  						(data[6] & 0x02) ? 1 : 0;
  				} else {
  					rw = 0;
  				}
3b57ca0f8   Ping Cheng   Input: wacom - me...
369
  			} else {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
370
  				input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);
d9f66c1a4   Mike Auty   Input: wacom - fi...
371
  				rw = -(signed char)data[6];
3b57ca0f8   Ping Cheng   Input: wacom - me...
372
  			}
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
373
  			input_report_rel(input, REL_WHEEL, rw);
afb567e3f   Dmitry Torokhov   Revert "Input: wa...
374
  		}
3b57ca0f8   Ping Cheng   Input: wacom - me...
375
376
377
  
  		if (!prox)
  			wacom->id[0] = 0;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
378
379
380
  		input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
  		input_report_key(input, wacom->tool[0], prox);
  		input_sync(input); /* sync last event */
80d4e8e98   Ping Cheng   USB: Wacom driver...
381
  	}
3bea733ab   Ping Cheng   USB: wacom tablet...
382
383
  
  	/* send pad data */
e33da8a54   Jason Childs   Input: wacom - us...
384
  	switch (features->type) {
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
385
  	case WACOM_G4:
3b57ca0f8   Ping Cheng   Input: wacom - me...
386
387
  		prox = data[7] & 0xf8;
  		if (prox || wacom->id[1]) {
e34b9d2f4   Ping Cheng   Input: wacom - cl...
388
  			wacom->id[1] = PAD_DEVICE_ID;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
389
390
  			input_report_key(pad_input, BTN_BACK, (data[7] & 0x40));
  			input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80));
3bea733ab   Ping Cheng   USB: wacom tablet...
391
  			rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
3813810c7   Benjamin Tissoires   Input: wacom - sp...
392
  			input_report_rel(pad_input, REL_WHEEL, rw);
3b57ca0f8   Ping Cheng   Input: wacom - me...
393
394
  			if (!prox)
  				wacom->id[1] = 0;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
395
  			input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
ab687b18a   Ping Cheng   Input: wacom - st...
396
  			retval = 1;
3bea733ab   Ping Cheng   USB: wacom tablet...
397
  		}
7ecfbfd3d   Ping Cheng   Input: wacom - ad...
398
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
399
400
  
  	case WACOM_MO:
3b57ca0f8   Ping Cheng   Input: wacom - me...
401
402
  		prox = (data[7] & 0xf8) || data[8];
  		if (prox || wacom->id[1]) {
e34b9d2f4   Ping Cheng   Input: wacom - cl...
403
  			wacom->id[1] = PAD_DEVICE_ID;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
404
405
406
407
408
  			input_report_key(pad_input, BTN_BACK, (data[7] & 0x08));
  			input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20));
  			input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x10));
  			input_report_key(pad_input, BTN_RIGHT, (data[7] & 0x40));
  			input_report_abs(pad_input, ABS_WHEEL, (data[8] & 0x7f));
3b57ca0f8   Ping Cheng   Input: wacom - me...
409
410
  			if (!prox)
  				wacom->id[1] = 0;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
411
  			input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
844600145   Ping Cheng   Input: wacom - cl...
412
  			retval = 1;
7ecfbfd3d   Ping Cheng   Input: wacom - ad...
413
414
  		}
  		break;
387142bb8   Benjamin Tissoires   Input: wacom - ha...
415
416
417
418
419
420
  	case GRAPHIRE_BT:
  		prox = data[7] & 0x03;
  		if (prox || wacom->id[1]) {
  			wacom->id[1] = PAD_DEVICE_ID;
  			input_report_key(pad_input, BTN_0, (data[7] & 0x02));
  			input_report_key(pad_input, BTN_1, (data[7] & 0x01));
3b57ca0f8   Ping Cheng   Input: wacom - me...
421
422
  			if (!prox)
  				wacom->id[1] = 0;
387142bb8   Benjamin Tissoires   Input: wacom - ha...
423
  			input_report_abs(pad_input, ABS_MISC, wacom->id[1]);
844600145   Ping Cheng   Input: wacom - cl...
424
  			retval = 1;
7ecfbfd3d   Ping Cheng   Input: wacom - ad...
425
426
  		}
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
427
  	}
387142bb8   Benjamin Tissoires   Input: wacom - ha...
428
429
430
431
432
433
  
  	/* Store current battery capacity and power supply state */
  	if (features->type == GRAPHIRE_BT) {
  		rw = (data[7] >> 2 & 0x07);
  		battery_capacity = batcap_gr[rw];
  		ps_connected = rw == 7;
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
434
  		wacom_notify_battery(wacom, battery_capacity, ps_connected,
71fa641eb   Jason Gerecke   HID: wacom: Add b...
435
  				     1, ps_connected);
3bea733ab   Ping Cheng   USB: wacom tablet...
436
  	}
3b57ca0f8   Ping Cheng   Input: wacom - me...
437
438
  exit:
  	return retval;
3bea733ab   Ping Cheng   USB: wacom tablet...
439
  }
5fcad1673   Benjamin Tissoires   HID: wacom: ask f...
440
441
442
  static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac)
  {
  	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
0bbfe28ad   Jason Gerecke   HID: wacom: Use c...
443
  	struct wacom_features *features = &wacom_wac->features;
5fcad1673   Benjamin Tissoires   HID: wacom: ask f...
444
445
446
447
  	struct hid_report *r;
  	struct hid_report_enum *re;
  
  	re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]);
0bbfe28ad   Jason Gerecke   HID: wacom: Use c...
448
449
450
451
  	if (features->type == INTUOSHT2)
  		r = re->report_id_hash[WACOM_REPORT_INTUOSHT2_ID];
  	else
  		r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1];
5fcad1673   Benjamin Tissoires   HID: wacom: ask f...
452
453
454
455
  	if (r) {
  		hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT);
  	}
  }
fb013a01d   Jason Gerecke   HID: wacom: Move ...
456
457
458
459
460
  static int wacom_intuos_pad(struct wacom_wac *wacom)
  {
  	struct wacom_features *features = &wacom->features;
  	unsigned char *data = wacom->data;
  	struct input_dev *input = wacom->pad_input;
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
461
462
463
464
465
466
  	int i;
  	int buttons = 0, nbuttons = features->numbered_buttons;
  	int keys = 0, nkeys = 0;
  	int ring1 = 0, ring2 = 0;
  	int strip1 = 0, strip2 = 0;
  	bool prox = false;
fb013a01d   Jason Gerecke   HID: wacom: Move ...
467
468
469
470
471
472
473
  
  	/* pad packets. Works as a second tool and is always in prox */
  	if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
  	      data[0] == WACOM_REPORT_CINTIQPAD))
  		return 0;
  
  	if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
474
475
  		buttons = (data[3] << 1) | (data[2] & 0x01);
  		ring1 = data[1];
fb013a01d   Jason Gerecke   HID: wacom: Move ...
476
  	} else if (features->type == DTK) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
477
  		buttons = data[6];
fb013a01d   Jason Gerecke   HID: wacom: Move ...
478
  	} else if (features->type == WACOM_13HD) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
479
  		buttons = (data[4] << 1) | (data[3] & 0x01);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
480
  	} else if (features->type == WACOM_24HD) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
481
482
483
  		buttons = (data[8] << 8) | data[6];
  		ring1 = data[1];
  		ring2 = data[2];
fb013a01d   Jason Gerecke   HID: wacom: Move ...
484
485
486
487
488
489
490
491
  
  		/*
  		 * Three "buttons" are available on the 24HD which are
  		 * physically implemented as a touchstrip. Each button
  		 * is approximately 3 bits wide with a 2 bit spacing.
  		 * The raw touchstrip bits are stored at:
  		 *    ((data[3] & 0x1f) << 8) | data[4])
  		 */
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
492
493
494
495
  		nkeys = 3;
  		keys = ((data[3] & 0x1C) ? 1<<2 : 0) |
  		       ((data[4] & 0xE0) ? 1<<1 : 0) |
  		       ((data[4] & 0x07) ? 1<<0 : 0);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
496
  	} else if (features->type == WACOM_27QHD) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
497
498
  		nkeys = 3;
  		keys = data[2] & 0x07;
fb013a01d   Jason Gerecke   HID: wacom: Move ...
499
500
501
502
  
  		input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
  		input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
  		input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
fb013a01d   Jason Gerecke   HID: wacom: Move ...
503
504
505
506
507
  	} else if (features->type == CINTIQ_HYBRID) {
  		/*
  		 * Do not send hardware buttons under Android. They
  		 * are already sent to the system through GPIO (and
  		 * have different meaning).
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
508
509
510
511
512
513
  		 *
  		 * d-pad right  -> data[4] & 0x10
  		 * d-pad up     -> data[4] & 0x20
  		 * d-pad left   -> data[4] & 0x40
  		 * d-pad down   -> data[4] & 0x80
  		 * d-pad center -> data[3] & 0x01
fb013a01d   Jason Gerecke   HID: wacom: Move ...
514
  		 */
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
515
  		buttons = (data[4] << 1) | (data[3] & 0x01);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
516
  	} else if (features->type == CINTIQ_COMPANION_2) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
517
518
519
520
521
522
  		/* d-pad right  -> data[4] & 0x10
  		 * d-pad up     -> data[4] & 0x20
  		 * d-pad left   -> data[4] & 0x40
  		 * d-pad down   -> data[4] & 0x80
  		 * d-pad center -> data[3] & 0x01
  		 */
0402b6b77   Jason Gerecke   HID: wacom: Fix p...
523
  		buttons = ((data[2] >> 4) << 7) |
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
524
525
526
  		          ((data[1] & 0x04) << 6) |
  		          ((data[2] & 0x0F) << 2) |
  		          (data[1] & 0x03);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
527
  	} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
fb013a01d   Jason Gerecke   HID: wacom: Move ...
528
529
530
531
  		/*
  		 * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
  		 * addition to the mechanical switch. Switch data is
  		 * stored in data[4], capacitive data in data[5].
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
532
533
  		 *
  		 * Touch ring mode switch (data[3]) has no capacitive sensor
fb013a01d   Jason Gerecke   HID: wacom: Move ...
534
  		 */
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
535
536
  		buttons = (data[4] << 1) | (data[3] & 0x01);
  		ring1 = data[2];
fb013a01d   Jason Gerecke   HID: wacom: Move ...
537
538
  	} else {
  		if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
539
540
  			buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) |
  			          (data[6] << 1) | (data[5] & 0x01);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
541
542
  
  			if (features->type == WACOM_22HD) {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
543
544
  				nkeys = 3;
  				keys = data[9] & 0x07;
fb013a01d   Jason Gerecke   HID: wacom: Move ...
545
546
  			}
  		} else {
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
547
548
549
550
  			buttons = ((data[6] & 0x10) << 10) |
  			          ((data[5] & 0x10) << 9)  |
  			          ((data[6] & 0x0F) << 4)  |
  			          (data[5] & 0x0F);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
551
  		}
f73d08d07   Jason Gerecke   HID: wacom: Limit...
552
553
  		strip1 = ((data[1] & 0x1f) << 8) | data[2];
  		strip2 = ((data[3] & 0x1f) << 8) | data[4];
fb013a01d   Jason Gerecke   HID: wacom: Move ...
554
  	}
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
555

8f9cfdd35   Dan Carpenter   HID: wacom: bitwi...
556
557
  	prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) |
  	       (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2;
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
558
559
560
561
562
563
564
  
  	wacom_report_numbered_buttons(input, nbuttons, buttons);
  
  	for (i = 0; i < nkeys; i++)
  		input_report_key(input, KEY_PROG1 + i, keys & (1 << i));
  
  	input_report_abs(input, ABS_RX, strip1);
03a0dc546   Jason Gerecke   HID: wacom: Repor...
565
  	input_report_abs(input, ABS_RY, strip2);
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
566

aaae03e4f   Jason Gerecke   HID: wacom: Fix t...
567
568
  	input_report_abs(input, ABS_WHEEL,    (ring1 & 0x80) ? (ring1 & 0x7f) : 0);
  	input_report_abs(input, ABS_THROTTLE, (ring2 & 0x80) ? (ring2 & 0x7f) : 0);
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
569
570
571
572
573
  
  	input_report_key(input, wacom->tool[1], prox ? 1 : 0);
  	input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);
  
  	input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
fb013a01d   Jason Gerecke   HID: wacom: Move ...
574
575
  	return 1;
  }
7e129783b   Benjamin Tissoires   HID: wacom: break...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
  static int wacom_intuos_get_tool_type(int tool_id)
  {
  	int tool_type;
  
  	switch (tool_id) {
  	case 0x812: /* Inking pen */
  	case 0x801: /* Intuos3 Inking pen */
  	case 0x120802: /* Intuos4/5 Inking Pen */
  	case 0x012:
  		tool_type = BTN_TOOL_PENCIL;
  		break;
  
  	case 0x822: /* Pen */
  	case 0x842:
  	case 0x852:
  	case 0x823: /* Intuos3 Grip Pen */
  	case 0x813: /* Intuos3 Classic Pen */
  	case 0x885: /* Intuos3 Marker Pen */
  	case 0x802: /* Intuos4/5 13HD/24HD General Pen */
  	case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
  	case 0x8e2: /* IntuosHT2 pen */
  	case 0x022:
  	case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
  	case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */
  	case 0x160802: /* Cintiq 13HD Pro Pen */
  	case 0x180802: /* DTH2242 Pen */
  	case 0x100802: /* Intuos4/5 13HD/24HD General Pen */
  		tool_type = BTN_TOOL_PEN;
  		break;
  
  	case 0x832: /* Stroke pen */
  	case 0x032:
  		tool_type = BTN_TOOL_BRUSH;
  		break;
  
  	case 0x007: /* Mouse 4D and 2D */
  	case 0x09c:
  	case 0x094:
  	case 0x017: /* Intuos3 2D Mouse */
  	case 0x806: /* Intuos4 Mouse */
  		tool_type = BTN_TOOL_MOUSE;
  		break;
  
  	case 0x096: /* Lens cursor */
  	case 0x097: /* Intuos3 Lens cursor */
  	case 0x006: /* Intuos4 Lens cursor */
  		tool_type = BTN_TOOL_LENS;
  		break;
  
  	case 0x82a: /* Eraser */
  	case 0x85a:
  	case 0x91a:
  	case 0xd1a:
  	case 0x0fa:
  	case 0x82b: /* Intuos3 Grip Pen Eraser */
  	case 0x81b: /* Intuos3 Classic Pen Eraser */
  	case 0x91b: /* Intuos3 Airbrush Eraser */
  	case 0x80c: /* Intuos4/5 13HD/24HD Marker Pen Eraser */
  	case 0x80a: /* Intuos4/5 13HD/24HD General Pen Eraser */
  	case 0x90a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
  	case 0x14080a: /* Intuos4/5 13HD/24HD Classic Pen Eraser */
  	case 0x10090a: /* Intuos4/5 13HD/24HD Airbrush Eraser */
  	case 0x10080c: /* Intuos4/5 13HD/24HD Art Pen Eraser */
  	case 0x16080a: /* Cintiq 13HD Pro Pen Eraser */
  	case 0x18080a: /* DTH2242 Eraser */
  	case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */
  		tool_type = BTN_TOOL_RUBBER;
  		break;
  
  	case 0xd12:
  	case 0x912:
  	case 0x112:
  	case 0x913: /* Intuos3 Airbrush */
  	case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
  	case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
  		tool_type = BTN_TOOL_AIRBRUSH;
  		break;
  
  	default: /* Unknown tool */
  		tool_type = BTN_TOOL_PEN;
  		break;
  	}
  	return tool_type;
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
660
  static int wacom_intuos_inout(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
661
  {
e33da8a54   Jason Childs   Input: wacom - us...
662
  	struct wacom_features *features = &wacom->features;
3bea733ab   Ping Cheng   USB: wacom tablet...
663
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
664
  	struct input_dev *input = wacom->pen_input;
4750f5fe2   Ping Cheng   HID: wacom - make...
665
  	int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
666

4750f5fe2   Ping Cheng   HID: wacom - make...
667
668
669
670
  	if (!(((data[1] & 0xfc) == 0xc0) ||  /* in prox */
  	    ((data[1] & 0xfe) == 0x20) ||    /* in range */
  	    ((data[1] & 0xfe) == 0x80)))     /* out prox */
  		return 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
671
672
673
674
675
676
677
  
  	/* Enter report */
  	if ((data[1] & 0xfc) == 0xc0) {
  		/* serial number of the tool */
  		wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
  			(data[4] << 20) + (data[5] << 12) +
  			(data[6] << 4) + (data[7] >> 4);
493630b20   Ping Cheng   Input: wacom - fi...
678
679
  		wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |
  			((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
680

7e129783b   Benjamin Tissoires   HID: wacom: break...
681
  		wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]);
eff6ca979   Ping Cheng   HID: wacom: add m...
682
  		wacom->shared->stylus_in_proximity = true;
3bea733ab   Ping Cheng   USB: wacom tablet...
683
684
  		return 1;
  	}
c1b03f551   Ping Cheng   HID: wacom - Clea...
685
686
  	/* in Range */
  	if ((data[1] & 0xfe) == 0x20) {
526d6e7b5   Ping Cheng   HID: wacom - Add ...
687
688
  		if (features->type != INTUOSHT2)
  			wacom->shared->stylus_in_proximity = true;
486b908d4   Ping Cheng   HID: wacom: do no...
689

c1b03f551   Ping Cheng   HID: wacom - Clea...
690
691
692
693
694
695
696
697
  		/* in Range while exiting */
  		if (wacom->reporting_data) {
  			input_report_key(input, BTN_TOUCH, 0);
  			input_report_abs(input, ABS_PRESSURE, 0);
  			input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);
  			return 2;
  		}
  		return 1;
4eb1830b4   Jason Gerecke   Input: wacom - se...
698
  	}
3bea733ab   Ping Cheng   USB: wacom tablet...
699
700
  	/* Exit report */
  	if ((data[1] & 0xfe) == 0x80) {
f3586d2f8   Ping Cheng   HID: wacom: remov...
701
  		wacom->shared->stylus_in_proximity = false;
b3bd7ef39   Ping Cheng   HID: wacom: pepor...
702
  		wacom->reporting_data = false;
ae584ca47   Jason Gerecke   Input: wacom - ad...
703

373a5356d   Ping Cheng   HID: wacom: proce...
704
705
706
  		/* don't report exit if we don't know the ID */
  		if (!wacom->id[idx])
  			return 1;
6f660f12d   Ping Cheng   Input: wacom - ad...
707
708
709
710
  		/*
  		 * Reset all states otherwise we lose the initial states
  		 * when in-prox next time
  		 */
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
711
712
713
714
715
  		input_report_abs(input, ABS_X, 0);
  		input_report_abs(input, ABS_Y, 0);
  		input_report_abs(input, ABS_DISTANCE, 0);
  		input_report_abs(input, ABS_TILT_X, 0);
  		input_report_abs(input, ABS_TILT_Y, 0);
80d4e8e98   Ping Cheng   USB: Wacom driver...
716
  		if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
717
718
719
720
721
722
723
  			input_report_key(input, BTN_LEFT, 0);
  			input_report_key(input, BTN_MIDDLE, 0);
  			input_report_key(input, BTN_RIGHT, 0);
  			input_report_key(input, BTN_SIDE, 0);
  			input_report_key(input, BTN_EXTRA, 0);
  			input_report_abs(input, ABS_THROTTLE, 0);
  			input_report_abs(input, ABS_RZ, 0);
7ecfbfd3d   Ping Cheng   Input: wacom - ad...
724
  		} else {
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
725
726
727
728
729
  			input_report_abs(input, ABS_PRESSURE, 0);
  			input_report_key(input, BTN_STYLUS, 0);
  			input_report_key(input, BTN_STYLUS2, 0);
  			input_report_key(input, BTN_TOUCH, 0);
  			input_report_abs(input, ABS_WHEEL, 0);
e33da8a54   Jason Childs   Input: wacom - us...
730
  			if (features->type >= INTUOS3S)
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
731
  				input_report_abs(input, ABS_Z, 0);
8d32e3ae5   Ping Cheng   USB: Wacom driver...
732
  		}
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
733
734
735
  		input_report_key(input, wacom->tool[idx], 0);
  		input_report_abs(input, ABS_MISC, 0); /* reset tool id */
  		input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
6f660f12d   Ping Cheng   Input: wacom - ad...
736
  		wacom->id[idx] = 0;
80d4e8e98   Ping Cheng   USB: Wacom driver...
737
  		return 2;
3bea733ab   Ping Cheng   USB: wacom tablet...
738
  	}
373a5356d   Ping Cheng   HID: wacom: proce...
739

3bea733ab   Ping Cheng   USB: wacom tablet...
740
741
  	return 0;
  }
72b236d60   Aaron Skomra   HID: wacom: Add s...
742
743
744
  static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
  {
  	unsigned char *data = wacom_wac->data;
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
745
  	struct input_dev *input;
72b236d60   Aaron Skomra   HID: wacom: Add s...
746
  	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
747
  	struct wacom_remote *remote = wacom->remote;
72b236d60   Aaron Skomra   HID: wacom: Add s...
748
749
  	int bat_charging, bat_percent, touch_ring_mode;
  	__u32 serial;
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
750
751
  	int i, index = -1;
  	unsigned long flags;
72b236d60   Aaron Skomra   HID: wacom: Add s...
752
753
  
  	if (data[0] != WACOM_REPORT_REMOTE) {
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
754
755
  		hid_dbg(wacom->hdev, "%s: received unknown report #%d",
  			__func__, data[0]);
72b236d60   Aaron Skomra   HID: wacom: Add s...
756
757
758
759
760
  		return 0;
  	}
  
  	serial = data[3] + (data[4] << 8) + (data[5] << 16);
  	wacom_wac->id[0] = PAD_DEVICE_ID;
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
761
762
763
764
765
766
767
768
769
770
771
772
773
  	spin_lock_irqsave(&remote->remote_lock, flags);
  
  	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
  		if (remote->remotes[i].serial == serial) {
  			index = i;
  			break;
  		}
  	}
  
  	if (index < 0 || !remote->remotes[index].registered)
  		goto out;
  
  	input = remote->remotes[index].input;
72b236d60   Aaron Skomra   HID: wacom: Add s...
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
  	input_report_key(input, BTN_0, (data[9] & 0x01));
  	input_report_key(input, BTN_1, (data[9] & 0x02));
  	input_report_key(input, BTN_2, (data[9] & 0x04));
  	input_report_key(input, BTN_3, (data[9] & 0x08));
  	input_report_key(input, BTN_4, (data[9] & 0x10));
  	input_report_key(input, BTN_5, (data[9] & 0x20));
  	input_report_key(input, BTN_6, (data[9] & 0x40));
  	input_report_key(input, BTN_7, (data[9] & 0x80));
  
  	input_report_key(input, BTN_8, (data[10] & 0x01));
  	input_report_key(input, BTN_9, (data[10] & 0x02));
  	input_report_key(input, BTN_A, (data[10] & 0x04));
  	input_report_key(input, BTN_B, (data[10] & 0x08));
  	input_report_key(input, BTN_C, (data[10] & 0x10));
  	input_report_key(input, BTN_X, (data[10] & 0x20));
  	input_report_key(input, BTN_Y, (data[10] & 0x40));
  	input_report_key(input, BTN_Z, (data[10] & 0x80));
  
  	input_report_key(input, BTN_BASE, (data[11] & 0x01));
  	input_report_key(input, BTN_BASE2, (data[11] & 0x02));
  
  	if (data[12] & 0x80)
  		input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f));
  	else
  		input_report_abs(input, ABS_WHEEL, 0);
  
  	bat_percent = data[7] & 0x7f;
  	bat_charging = !!(data[7] & 0x80);
  
  	if (data[9] | data[10] | (data[11] & 0x03) | data[12])
  		input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
  	else
  		input_report_abs(input, ABS_MISC, 0);
  
  	input_event(input, EV_MSC, MSC_SERIAL, serial);
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
809
  	input_sync(input);
72b236d60   Aaron Skomra   HID: wacom: Add s...
810
811
812
813
  	/*Which mode select (LED light) is currently on?*/
  	touch_ring_mode = (data[11] & 0xC0) >> 6;
  
  	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
e7749f6e5   Benjamin Tissoires   HID: wacom: EKR: ...
814
  		if (remote->remotes[i].serial == serial)
a50aac719   Benjamin Tissoires   HID: wacom: leds:...
815
  			wacom->led.groups[i].select = touch_ring_mode;
72b236d60   Aaron Skomra   HID: wacom: Add s...
816
  	}
59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
817
818
  	__wacom_notify_battery(&remote->remotes[index].battery, bat_percent,
  				bat_charging, 1, bat_charging);
72b236d60   Aaron Skomra   HID: wacom: Add s...
819

7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
820
821
822
  out:
  	spin_unlock_irqrestore(&remote->remote_lock, flags);
  	return 0;
72b236d60   Aaron Skomra   HID: wacom: Add s...
823
  }
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
824
  static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
72b236d60   Aaron Skomra   HID: wacom: Add s...
825
826
827
  {
  	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
  	unsigned char *data = wacom_wac->data;
83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
828
  	struct wacom_remote *remote = wacom->remote;
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
829
830
831
  	struct wacom_remote_data remote_data;
  	unsigned long flags;
  	int i, ret;
72b236d60   Aaron Skomra   HID: wacom: Add s...
832
833
  
  	if (data[0] != WACOM_REPORT_DEVICE_LIST)
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
834
835
836
  		return;
  
  	memset(&remote_data, 0, sizeof(struct wacom_remote_data));
72b236d60   Aaron Skomra   HID: wacom: Add s...
837
838
839
840
841
  
  	for (i = 0; i < WACOM_MAX_REMOTES; i++) {
  		int j = i * 6;
  		int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4];
  		bool connected = data[j+2];
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
842
843
844
  		remote_data.remote[i].serial = serial;
  		remote_data.remote[i].connected = connected;
  	}
72b236d60   Aaron Skomra   HID: wacom: Add s...
845

83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
846
  	spin_lock_irqsave(&remote->remote_lock, flags);
72b236d60   Aaron Skomra   HID: wacom: Add s...
847

83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
848
  	ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data));
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
849
  	if (ret != sizeof(remote_data)) {
83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
850
  		spin_unlock_irqrestore(&remote->remote_lock, flags);
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
851
852
853
  		hid_err(wacom->hdev, "Can't queue Remote status event.
  ");
  		return;
72b236d60   Aaron Skomra   HID: wacom: Add s...
854
  	}
72b236d60   Aaron Skomra   HID: wacom: Add s...
855

83e6b40e2   Benjamin Tissoires   HID: wacom: EKR: ...
856
  	spin_unlock_irqrestore(&remote->remote_lock, flags);
72b236d60   Aaron Skomra   HID: wacom: Add s...
857

e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
858
  	wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE);
72b236d60   Aaron Skomra   HID: wacom: Add s...
859
  }
72b236d60   Aaron Skomra   HID: wacom: Add s...
860

1924e05e6   Ping Cheng   HID: wacom - add ...
861
862
863
864
  static inline bool report_touch_events(struct wacom_wac *wacom)
  {
  	return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1);
  }
72b236d60   Aaron Skomra   HID: wacom: Add s...
865

1924e05e6   Ping Cheng   HID: wacom - add ...
866
867
868
  static inline bool delay_pen_events(struct wacom_wac *wacom)
  {
  	return (wacom->shared->touch_down && touch_arbitration);
72b236d60   Aaron Skomra   HID: wacom: Add s...
869
  }
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
870
  static int wacom_intuos_general(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
871
  {
e33da8a54   Jason Childs   Input: wacom - us...
872
  	struct wacom_features *features = &wacom->features;
3bea733ab   Ping Cheng   USB: wacom tablet...
873
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
874
  	struct input_dev *input = wacom->pen_input;
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
875
  	int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
a8a09c859   Jason Gerecke   HID: wacom: Repla...
876
  	unsigned char type = (data[1] >> 1) & 0x0F;
5f33f430e   Jason Gerecke   HID: wacom: Clean...
877
  	unsigned int x, y, distance, t;
3bea733ab   Ping Cheng   USB: wacom tablet...
878

16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
879
880
881
  	if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ &&
  		data[0] != WACOM_REPORT_INTUOS_PEN)
  		return 0;
1924e05e6   Ping Cheng   HID: wacom - add ...
882
  	if (delay_pen_events(wacom))
c1b03f551   Ping Cheng   HID: wacom - Clea...
883
  		return 1;
599b08209   Ping Cheng   HID: wacom - requ...
884
885
886
887
888
889
  	/* don't report events if we don't know the tool ID */
  	if (!wacom->id[idx]) {
  		/* but reschedule a read of the current tool */
  		wacom_intuos_schedule_prox_event(wacom);
  		return 1;
  	}
4750f5fe2   Ping Cheng   HID: wacom - make...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  	/*
  	 * don't report events for invalid data
  	 */
  	/* older I4 styli don't work with new Cintiqs */
  	if ((!((wacom->id[idx] >> 20) & 0x01) &&
  			(features->type == WACOM_21UX2)) ||
  	    /* Only large Intuos support Lense Cursor */
  	    (wacom->tool[idx] == BTN_TOOL_LENS &&
  		(features->type == INTUOS3 ||
  		 features->type == INTUOS3S ||
  		 features->type == INTUOS4 ||
  		 features->type == INTUOS4S ||
  		 features->type == INTUOS5 ||
  		 features->type == INTUOS5S ||
  		 features->type == INTUOSPM ||
  		 features->type == INTUOSPS)) ||
  	   /* Cintiq doesn't send data when RDY bit isn't set */
  	   (features->type == CINTIQ && !(data[1] & 0x40)))
  		return 1;
5f33f430e   Jason Gerecke   HID: wacom: Clean...
909
910
911
912
913
914
915
  	x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1);
  	y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1);
  	distance = data[9] >> 2;
  	if (features->type < INTUOS3S) {
  		x >>= 1;
  		y >>= 1;
  		distance >>= 1;
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
916
  	}
5f33f430e   Jason Gerecke   HID: wacom: Clean...
917
918
919
  	input_report_abs(input, ABS_X, x);
  	input_report_abs(input, ABS_Y, y);
  	input_report_abs(input, ABS_DISTANCE, distance);
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
920

a8a09c859   Jason Gerecke   HID: wacom: Repla...
921
922
923
924
925
926
  	switch (type) {
  	case 0x00:
  	case 0x01:
  	case 0x02:
  	case 0x03:
  		/* general pen packet */
5f33f430e   Jason Gerecke   HID: wacom: Clean...
927
928
929
  		t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1);
  		if (features->pressure_max < 2047)
  			t >>= 1;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
930
  		input_report_abs(input, ABS_PRESSURE, t);
eda01dab5   Ping Cheng   HID: wacom: Add f...
931
932
  		if (features->type != INTUOSHT2) {
  		    input_report_abs(input, ABS_TILT_X,
ec5fc1c1b   Jason Gerecke   HID: wacom: Repor...
933
  				 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
eda01dab5   Ping Cheng   HID: wacom: Add f...
934
935
  		    input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
  		}
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
936
937
938
  		input_report_key(input, BTN_STYLUS, data[1] & 2);
  		input_report_key(input, BTN_STYLUS2, data[1] & 4);
  		input_report_key(input, BTN_TOUCH, t > 10);
a8a09c859   Jason Gerecke   HID: wacom: Repla...
939
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
940

a8a09c859   Jason Gerecke   HID: wacom: Repla...
941
  	case 0x0a:
a8a09c859   Jason Gerecke   HID: wacom: Repla...
942
  		/* airbrush second packet */
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
943
  		input_report_abs(input, ABS_WHEEL,
3bea733ab   Ping Cheng   USB: wacom tablet...
944
  				(data[6] << 2) | ((data[7] >> 6) & 3));
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
945
  		input_report_abs(input, ABS_TILT_X,
ec5fc1c1b   Jason Gerecke   HID: wacom: Repor...
946
947
  				 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
  		input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
a8a09c859   Jason Gerecke   HID: wacom: Repla...
948
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
949

a8a09c859   Jason Gerecke   HID: wacom: Repla...
950
  	case 0x05:
a8a09c859   Jason Gerecke   HID: wacom: Repla...
951
952
953
954
955
956
957
958
  		/* Rotation packet */
  		if (features->type >= INTUOS3S) {
  			/* I3 marker pen rotation */
  			t = (data[6] << 3) | ((data[7] >> 5) & 7);
  			t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
  				((t-1) / 2 + 450)) : (450 - t / 2) ;
  			input_report_abs(input, ABS_Z, t);
  		} else {
571f572f9   Jason Gerecke   HID: wacom: Furth...
959
  			/* 4D mouse 2nd packet */
a8a09c859   Jason Gerecke   HID: wacom: Repla...
960
961
962
963
964
  			t = (data[6] << 3) | ((data[7] >> 5) & 7);
  			input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
  				((t - 1) / 2) : -t / 2);
  		}
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
965

a8a09c859   Jason Gerecke   HID: wacom: Repla...
966
  	case 0x04:
571f572f9   Jason Gerecke   HID: wacom: Furth...
967
968
969
970
971
972
973
974
975
976
  		/* 4D mouse 1st packet */
  		input_report_key(input, BTN_LEFT,   data[8] & 0x01);
  		input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
  		input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
  
  		input_report_key(input, BTN_SIDE,   data[8] & 0x20);
  		input_report_key(input, BTN_EXTRA,  data[8] & 0x10);
  		t = (data[6] << 2) | ((data[7] >> 6) & 3);
  		input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
  		break;
a8a09c859   Jason Gerecke   HID: wacom: Repla...
977
  	case 0x06:
571f572f9   Jason Gerecke   HID: wacom: Furth...
978
979
980
981
982
983
984
985
  		/* I4 mouse */
  		input_report_key(input, BTN_LEFT,   data[6] & 0x01);
  		input_report_key(input, BTN_MIDDLE, data[6] & 0x02);
  		input_report_key(input, BTN_RIGHT,  data[6] & 0x04);
  		input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)
  				 - ((data[7] & 0x40) >> 6));
  		input_report_key(input, BTN_SIDE,   data[6] & 0x08);
  		input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
3bea733ab   Ping Cheng   USB: wacom tablet...
986

571f572f9   Jason Gerecke   HID: wacom: Furth...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
  		input_report_abs(input, ABS_TILT_X,
  			(((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
  		input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
  		break;
  
  	case 0x08:
  		if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
  			/* 2D mouse packet */
  			input_report_key(input, BTN_LEFT,   data[8] & 0x04);
  			input_report_key(input, BTN_MIDDLE, data[8] & 0x08);
  			input_report_key(input, BTN_RIGHT,  data[8] & 0x10);
  			input_report_rel(input, REL_WHEEL, (data[8] & 0x01)
  					 - ((data[8] & 0x02) >> 1));
  
  			/* I3 2D mouse side buttons */
  			if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
  				input_report_key(input, BTN_SIDE,   data[8] & 0x40);
  				input_report_key(input, BTN_EXTRA,  data[8] & 0x20);
3bea733ab   Ping Cheng   USB: wacom tablet...
1005
  			}
a8a09c859   Jason Gerecke   HID: wacom: Repla...
1006
  		}
571f572f9   Jason Gerecke   HID: wacom: Furth...
1007
  		else if (wacom->tool[idx] == BTN_TOOL_LENS) {
3bea733ab   Ping Cheng   USB: wacom tablet...
1008
  			/* Lens cursor packets */
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
1009
1010
1011
1012
1013
  			input_report_key(input, BTN_LEFT,   data[8] & 0x01);
  			input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
  			input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
  			input_report_key(input, BTN_SIDE,   data[8] & 0x10);
  			input_report_key(input, BTN_EXTRA,  data[8] & 0x08);
3bea733ab   Ping Cheng   USB: wacom tablet...
1014
  		}
a8a09c859   Jason Gerecke   HID: wacom: Repla...
1015
  		break;
571f572f9   Jason Gerecke   HID: wacom: Furth...
1016
  	case 0x07:
a8a09c859   Jason Gerecke   HID: wacom: Repla...
1017
  	case 0x09:
571f572f9   Jason Gerecke   HID: wacom: Furth...
1018
  	case 0x0b:
a8a09c859   Jason Gerecke   HID: wacom: Repla...
1019
1020
1021
1022
1023
1024
  	case 0x0c:
  	case 0x0d:
  	case 0x0e:
  	case 0x0f:
  		/* unhandled */
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
1025
  	}
3bea733ab   Ping Cheng   USB: wacom tablet...
1026

8da23fc11   Dmitry Torokhov   Input: wacom - ge...
1027
1028
1029
  	input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
  	input_report_key(input, wacom->tool[idx], 1);
  	input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
b3bd7ef39   Ping Cheng   HID: wacom: pepor...
1030
  	wacom->reporting_data = true;
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1031
  	return 2;
3bea733ab   Ping Cheng   USB: wacom tablet...
1032
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
1033
  static int wacom_intuos_irq(struct wacom_wac *wacom)
3bea733ab   Ping Cheng   USB: wacom tablet...
1034
1035
  {
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1036
  	struct input_dev *input = wacom->pen_input;
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1037
  	int result;
3bea733ab   Ping Cheng   USB: wacom tablet...
1038

eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
1039
  	if (data[0] != WACOM_REPORT_PENABLED &&
061099936   Jason Gerecke   HID: wacom: Renam...
1040
1041
  	    data[0] != WACOM_REPORT_INTUOS_ID1 &&
  	    data[0] != WACOM_REPORT_INTUOS_ID2 &&
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
1042
  	    data[0] != WACOM_REPORT_INTUOSPAD &&
eda01dab5   Ping Cheng   HID: wacom: Add f...
1043
  	    data[0] != WACOM_REPORT_INTUOS_PEN &&
500d4160a   Ping Cheng   HID: wacom: add s...
1044
1045
  	    data[0] != WACOM_REPORT_CINTIQ &&
  	    data[0] != WACOM_REPORT_CINTIQPAD &&
eb71d1bb2   Dmitry Torokhov   Input: wacom - us...
1046
1047
1048
1049
  	    data[0] != WACOM_REPORT_INTUOS5PAD) {
  		dev_dbg(input->dev.parent,
  			"%s: received unknown report #%d
  ", __func__, data[0]);
3bea733ab   Ping Cheng   USB: wacom tablet...
1050
1051
                  return 0;
  	}
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1052
1053
1054
1055
  	/* process pad events */
  	result = wacom_intuos_pad(wacom);
  	if (result)
  		return result;
3bea733ab   Ping Cheng   USB: wacom tablet...
1056
1057
  
  	/* process in/out prox events */
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
1058
  	result = wacom_intuos_inout(wacom);
3bea733ab   Ping Cheng   USB: wacom tablet...
1059
  	if (result)
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1060
  		return result - 1;
3bea733ab   Ping Cheng   USB: wacom tablet...
1061
1062
  
  	/* process general packets */
16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1063
1064
1065
  	result = wacom_intuos_general(wacom);
  	if (result)
  		return result - 1;
3bea733ab   Ping Cheng   USB: wacom tablet...
1066

16e0a6a0d   Jason Gerecke   HID: wacom: Centr...
1067
  	return 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
1068
  }
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1069
1070
1071
1072
1073
1074
1075
  static int int_dist(int x1, int y1, int x2, int y2)
  {
  	int x = x2 - x1;
  	int y = y2 - y1;
  
  	return int_sqrt(x*x + y*y);
  }
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
1076
1077
1078
1079
1080
  static void wacom_intuos_bt_process_data(struct wacom_wac *wacom,
  		unsigned char *data)
  {
  	memcpy(wacom->data, data, 10);
  	wacom_intuos_irq(wacom);
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1081
  	input_sync(wacom->pen_input);
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
  	if (wacom->pad_input)
  		input_sync(wacom->pad_input);
  }
  
  static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)
  {
  	unsigned char data[WACOM_PKGLEN_MAX];
  	int i = 1;
  	unsigned power_raw, battery_capacity, bat_charging, ps_connected;
  
  	memcpy(data, wacom->data, len);
  
  	switch (data[0]) {
  	case 0x04:
  		wacom_intuos_bt_process_data(wacom, data + i);
  		i += 10;
  		/* fall through */
  	case 0x03:
  		wacom_intuos_bt_process_data(wacom, data + i);
  		i += 10;
  		wacom_intuos_bt_process_data(wacom, data + i);
  		i += 10;
  		power_raw = data[i];
  		bat_charging = (power_raw & 0x08) ? 1 : 0;
  		ps_connected = (power_raw & 0x10) ? 1 : 0;
  		battery_capacity = batcap_i4[power_raw & 0x07];
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
1108
  		wacom_notify_battery(wacom, battery_capacity, bat_charging,
71fa641eb   Jason Gerecke   HID: wacom: Add b...
1109
  				     battery_capacity || bat_charging,
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
1110
  				     ps_connected);
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
1111
1112
  		break;
  	default:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1113
  		dev_dbg(wacom->pen_input->dev.parent,
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
1114
1115
1116
1117
1118
1119
1120
  				"Unknown report: %d,%d size:%zu
  ",
  				data[0], data[1], len);
  		return 0;
  	}
  	return 0;
  }
7d059ed01   Ping Cheng   HID: wacom: use w...
1121
1122
  static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1123
  	struct input_dev *input = wacom->touch_input;
7d059ed01   Ping Cheng   HID: wacom: use w...
1124
1125
1126
  	unsigned touch_max = wacom->features.touch_max;
  	int count = 0;
  	int i;
26ba61f87   Ping Cheng   HID: wacom: fix a...
1127
1128
  	if (!touch_max)
  		return 0;
71b5c4766   Jason Gerecke   HID: wacom: Simpl...
1129
1130
  	if (touch_max == 1)
  		return test_bit(BTN_TOUCH, input->key) &&
1924e05e6   Ping Cheng   HID: wacom - add ...
1131
  			report_touch_events(wacom);
7d059ed01   Ping Cheng   HID: wacom: use w...
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
  
  	for (i = 0; i < input->mt->num_slots; i++) {
  		struct input_mt_slot *ps = &input->mt->slots[i];
  		int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
  		if (id >= 0)
  			count++;
  	}
  
  	return count;
  }
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1142
1143
  static int wacom_24hdt_irq(struct wacom_wac *wacom)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1144
  	struct input_dev *input = wacom->touch_input;
74b634178   Jason Gerecke   Input: wacom - re...
1145
  	unsigned char *data = wacom->data;
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1146
  	int i;
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1147
  	int current_num_contacts = data[61];
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1148
  	int contacts_to_send = 0;
500d4160a   Ping Cheng   HID: wacom: add s...
1149
1150
1151
1152
1153
1154
1155
1156
1157
  	int num_contacts_left = 4; /* maximum contacts per packet */
  	int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
  	int y_offset = 2;
  
  	if (wacom->features.type == WACOM_27QHDT) {
  		current_num_contacts = data[63];
  		num_contacts_left = 10;
  		byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET;
  		y_offset = 0;
500d4160a   Ping Cheng   HID: wacom: add s...
1158
  	}
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1159
1160
1161
1162
1163
  
  	/*
  	 * First packet resets the counter since only the first
  	 * packet in series will have non-zero current_num_contacts.
  	 */
7d059ed01   Ping Cheng   HID: wacom: use w...
1164
  	if (current_num_contacts)
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1165
  		wacom->num_contacts_left = current_num_contacts;
500d4160a   Ping Cheng   HID: wacom: add s...
1166
  	contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1167
1168
  
  	for (i = 0; i < contacts_to_send; i++) {
500d4160a   Ping Cheng   HID: wacom: add s...
1169
  		int offset = (byte_per_packet * i) + 1;
1924e05e6   Ping Cheng   HID: wacom - add ...
1170
  		bool touch = (data[offset] & 0x1) && report_touch_events(wacom);
02295e68c   Ping Cheng   Input: wacom - us...
1171
  		int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1172
1173
1174
1175
1176
1177
1178
  
  		if (slot < 0)
  			continue;
  		input_mt_slot(input, slot);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
  
  		if (touch) {
edc8e20af   Jason Gerecke   Input: wacom - us...
1179
  			int t_x = get_unaligned_le16(&data[offset + 2]);
500d4160a   Ping Cheng   HID: wacom: add s...
1180
  			int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]);
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1181
1182
1183
  
  			input_report_abs(input, ABS_MT_POSITION_X, t_x);
  			input_report_abs(input, ABS_MT_POSITION_Y, t_y);
500d4160a   Ping Cheng   HID: wacom: add s...
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
  
  			if (wacom->features.type != WACOM_27QHDT) {
  				int c_x = get_unaligned_le16(&data[offset + 4]);
  				int c_y = get_unaligned_le16(&data[offset + 8]);
  				int w = get_unaligned_le16(&data[offset + 10]);
  				int h = get_unaligned_le16(&data[offset + 12]);
  
  				input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));
  				input_report_abs(input, ABS_MT_WIDTH_MAJOR,
  						 min(w, h) + int_dist(t_x, t_y, c_x, c_y));
  				input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));
  				input_report_abs(input, ABS_MT_ORIENTATION, w > h);
  			}
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1197
  		}
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1198
  	}
9a1c00129   Benjamin Tissoires   HID: wacom: do no...
1199
  	input_mt_sync_frame(input);
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1200
1201
  
  	wacom->num_contacts_left -= contacts_to_send;
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1202
  	if (wacom->num_contacts_left <= 0) {
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1203
  		wacom->num_contacts_left = 0;
7d059ed01   Ping Cheng   HID: wacom: use w...
1204
  		wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1205
  	}
b1e4279e4   Jason Gerecke   Input: wacom - ad...
1206
1207
  	return 1;
  }
1963518b9   Ping Cheng   Input: wacom - ad...
1208
1209
  static int wacom_mt_touch(struct wacom_wac *wacom)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1210
  	struct input_dev *input = wacom->touch_input;
74b634178   Jason Gerecke   Input: wacom - re...
1211
  	unsigned char *data = wacom->data;
1963518b9   Ping Cheng   Input: wacom - ad...
1212
1213
1214
  	int i;
  	int current_num_contacts = data[2];
  	int contacts_to_send = 0;
6afdc289c   Ping Cheng   Input: wacom - ad...
1215
1216
1217
  	int x_offset = 0;
  
  	/* MTTPC does not support Height and Width */
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
1218
  	if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)
6afdc289c   Ping Cheng   Input: wacom - ad...
1219
  		x_offset = -4;
1963518b9   Ping Cheng   Input: wacom - ad...
1220
1221
1222
1223
1224
  
  	/*
  	 * First packet resets the counter since only the first
  	 * packet in series will have non-zero current_num_contacts.
  	 */
7d059ed01   Ping Cheng   HID: wacom: use w...
1225
  	if (current_num_contacts)
1963518b9   Ping Cheng   Input: wacom - ad...
1226
1227
1228
1229
1230
1231
  		wacom->num_contacts_left = current_num_contacts;
  
  	/* There are at most 5 contacts per packet */
  	contacts_to_send = min(5, wacom->num_contacts_left);
  
  	for (i = 0; i < contacts_to_send; i++) {
6afdc289c   Ping Cheng   Input: wacom - ad...
1232
  		int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
1924e05e6   Ping Cheng   HID: wacom - add ...
1233
  		bool touch = (data[offset] & 0x1) && report_touch_events(wacom);
edc8e20af   Jason Gerecke   Input: wacom - us...
1234
  		int id = get_unaligned_le16(&data[offset + 1]);
02295e68c   Ping Cheng   Input: wacom - us...
1235
  		int slot = input_mt_get_slot_by_key(input, id);
1963518b9   Ping Cheng   Input: wacom - ad...
1236
1237
1238
1239
1240
1241
1242
  
  		if (slot < 0)
  			continue;
  
  		input_mt_slot(input, slot);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
  		if (touch) {
edc8e20af   Jason Gerecke   Input: wacom - us...
1243
1244
  			int x = get_unaligned_le16(&data[offset + x_offset + 7]);
  			int y = get_unaligned_le16(&data[offset + x_offset + 9]);
1963518b9   Ping Cheng   Input: wacom - ad...
1245
1246
1247
  			input_report_abs(input, ABS_MT_POSITION_X, x);
  			input_report_abs(input, ABS_MT_POSITION_Y, y);
  		}
1963518b9   Ping Cheng   Input: wacom - ad...
1248
  	}
9a1c00129   Benjamin Tissoires   HID: wacom: do no...
1249
  	input_mt_sync_frame(input);
1963518b9   Ping Cheng   Input: wacom - ad...
1250
1251
  
  	wacom->num_contacts_left -= contacts_to_send;
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1252
  	if (wacom->num_contacts_left <= 0) {
1963518b9   Ping Cheng   Input: wacom - ad...
1253
  		wacom->num_contacts_left = 0;
7d059ed01   Ping Cheng   HID: wacom: use w...
1254
  		wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1255
  	}
1963518b9   Ping Cheng   Input: wacom - ad...
1256
1257
  	return 1;
  }
84eb5aa6c   Ping Cheng   Input: wacom - su...
1258
1259
  static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1260
  	struct input_dev *input = wacom->touch_input;
84eb5aa6c   Ping Cheng   Input: wacom - su...
1261
  	unsigned char *data = wacom->data;
84eb5aa6c   Ping Cheng   Input: wacom - su...
1262
1263
1264
1265
  	int i;
  
  	for (i = 0; i < 2; i++) {
  		int p = data[1] & (1 << i);
1924e05e6   Ping Cheng   HID: wacom - add ...
1266
  		bool touch = p && report_touch_events(wacom);
84eb5aa6c   Ping Cheng   Input: wacom - su...
1267
1268
1269
1270
1271
1272
1273
1274
1275
  
  		input_mt_slot(input, i);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
  		if (touch) {
  			int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff;
  			int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff;
  
  			input_report_abs(input, ABS_MT_POSITION_X, x);
  			input_report_abs(input, ABS_MT_POSITION_Y, y);
84eb5aa6c   Ping Cheng   Input: wacom - su...
1276
1277
  		}
  	}
9a1c00129   Benjamin Tissoires   HID: wacom: do no...
1278
  	input_mt_sync_frame(input);
84eb5aa6c   Ping Cheng   Input: wacom - su...
1279
1280
  
  	/* keep touch state for pen event */
7d059ed01   Ping Cheng   HID: wacom: use w...
1281
  	wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
84eb5aa6c   Ping Cheng   Input: wacom - su...
1282

84eb5aa6c   Ping Cheng   Input: wacom - su...
1283
1284
  	return 1;
  }
a43c7c538   Ping Cheng   Input: wacom - su...
1285
  static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
ec67bbedc   Ping Cheng   Input: wacom - ad...
1286
  {
74b634178   Jason Gerecke   Input: wacom - re...
1287
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1288
  	struct input_dev *input = wacom->touch_input;
1924e05e6   Ping Cheng   HID: wacom - add ...
1289
  	bool prox = report_touch_events(wacom);
a43c7c538   Ping Cheng   Input: wacom - su...
1290
  	int x = 0, y = 0;
ec67bbedc   Ping Cheng   Input: wacom - ad...
1291

1963518b9   Ping Cheng   Input: wacom - ad...
1292
1293
  	if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
  		return 0;
e0d41fd43   Ping Cheng   HID: wacom: rely ...
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
  	if (len == WACOM_PKGLEN_TPC1FG) {
  		prox = prox && (data[0] & 0x01);
  		x = get_unaligned_le16(&data[1]);
  		y = get_unaligned_le16(&data[3]);
  	} else if (len == WACOM_PKGLEN_TPC1FG_B) {
  		prox = prox && (data[2] & 0x01);
  		x = get_unaligned_le16(&data[3]);
  		y = get_unaligned_le16(&data[5]);
  	} else {
  		prox = prox && (data[1] & 0x01);
  		x = le16_to_cpup((__le16 *)&data[2]);
  		y = le16_to_cpup((__le16 *)&data[4]);
  	}
ec67bbedc   Ping Cheng   Input: wacom - ad...
1307

a43c7c538   Ping Cheng   Input: wacom - su...
1308
1309
1310
1311
1312
  	if (prox) {
  		input_report_abs(input, ABS_X, x);
  		input_report_abs(input, ABS_Y, y);
  	}
  	input_report_key(input, BTN_TOUCH, prox);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
1313

a43c7c538   Ping Cheng   Input: wacom - su...
1314
1315
  	/* keep touch state for pen events */
  	wacom->shared->touch_down = prox;
ec67bbedc   Ping Cheng   Input: wacom - ad...
1316

a43c7c538   Ping Cheng   Input: wacom - su...
1317
  	return 1;
ec67bbedc   Ping Cheng   Input: wacom - ad...
1318
  }
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1319
  static int wacom_tpc_pen(struct wacom_wac *wacom)
545f4e99d   Ping Cheng   Input: wacom - ad...
1320
  {
74b634178   Jason Gerecke   Input: wacom - re...
1321
  	unsigned char *data = wacom->data;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1322
  	struct input_dev *input = wacom->pen_input;
a43c7c538   Ping Cheng   Input: wacom - su...
1323
  	bool prox = data[1] & 0x20;
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1324

a43c7c538   Ping Cheng   Input: wacom - su...
1325
  	if (!wacom->shared->stylus_in_proximity) /* first in prox */
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1326
1327
  		/* Going into proximity select tool */
  		wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1328

a43c7c538   Ping Cheng   Input: wacom - su...
1329
1330
  	/* keep pen state for touch events */
  	wacom->shared->stylus_in_proximity = prox;
1924e05e6   Ping Cheng   HID: wacom - add ...
1331
1332
1333
1334
  	/* send pen events only when touch is up or forced out
  	 * or touch arbitration is off
  	 */
  	if (!delay_pen_events(wacom)) {
a43c7c538   Ping Cheng   Input: wacom - su...
1335
1336
1337
1338
  		input_report_key(input, BTN_STYLUS, data[1] & 0x02);
  		input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
  		input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
  		input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
0b335cad7   Jason Gerecke   Input: wacom - su...
1339
  		input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x07) << 8) | data[6]);
a43c7c538   Ping Cheng   Input: wacom - su...
1340
1341
1342
  		input_report_key(input, BTN_TOUCH, data[1] & 0x05);
  		input_report_key(input, wacom->tool[0], prox);
  		return 1;
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1343
  	}
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1344

a43c7c538   Ping Cheng   Input: wacom - su...
1345
  	return 0;
8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1346
1347
1348
1349
  }
  
  static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
  {
74b634178   Jason Gerecke   Input: wacom - re...
1350
  	unsigned char *data = wacom->data;
545f4e99d   Ping Cheng   Input: wacom - ad...
1351

2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1352
1353
1354
1355
1356
1357
1358
1359
  	if (wacom->pen_input)
  		dev_dbg(wacom->pen_input->dev.parent,
  			"%s: received report #%d
  ", __func__, data[0]);
  	else if (wacom->touch_input)
  		dev_dbg(wacom->touch_input->dev.parent,
  			"%s: received report #%d
  ", __func__, data[0]);
545f4e99d   Ping Cheng   Input: wacom - ad...
1360

31175a834   Ping Cheng   Input: wacom - us...
1361
1362
  	switch (len) {
  	case WACOM_PKGLEN_TPC1FG:
1963518b9   Ping Cheng   Input: wacom - ad...
1363
  		return wacom_tpc_single_touch(wacom, len);
31175a834   Ping Cheng   Input: wacom - us...
1364
1365
  
  	case WACOM_PKGLEN_TPC2FG:
1963518b9   Ping Cheng   Input: wacom - ad...
1366
  		return wacom_tpc_mt_touch(wacom);
31175a834   Ping Cheng   Input: wacom - us...
1367

d51ddb2bf   Jason Gerecke   Input: wacom - ad...
1368
1369
  	case WACOM_PKGLEN_PENABLED:
  		return wacom_tpc_pen(wacom);
31175a834   Ping Cheng   Input: wacom - us...
1370
1371
1372
1373
1374
  	default:
  		switch (data[0]) {
  		case WACOM_REPORT_TPC1FG:
  		case WACOM_REPORT_TPCHID:
  		case WACOM_REPORT_TPCST:
ac173837c   Ping Cheng   Input: wacom - ad...
1375
  		case WACOM_REPORT_TPC1FGE:
31175a834   Ping Cheng   Input: wacom - us...
1376
  			return wacom_tpc_single_touch(wacom, len);
1963518b9   Ping Cheng   Input: wacom - ad...
1377
  		case WACOM_REPORT_TPCMT:
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
1378
  		case WACOM_REPORT_TPCMT2:
1963518b9   Ping Cheng   Input: wacom - ad...
1379
  			return wacom_mt_touch(wacom);
31175a834   Ping Cheng   Input: wacom - us...
1380
1381
1382
1383
  		case WACOM_REPORT_PENABLED:
  			return wacom_tpc_pen(wacom);
  		}
  	}
4492effff   Ping Cheng   Input: wacom - sh...
1384

8aa9a9ac8   Ping Cheng   Input: wacom - pr...
1385
  	return 0;
545f4e99d   Ping Cheng   Input: wacom - ad...
1386
  }
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1387
  static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1388
1389
  		struct hid_field *field, __u8 type, __u16 code, int fuzz)
  {
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
  	int fmin = field->logical_minimum;
  	int fmax = field->logical_maximum;
  
  	usage->type = type;
  	usage->code = code;
  
  	set_bit(type, input->evbit);
  
  	switch (type) {
  	case EV_ABS:
  		input_set_abs_params(input, code, fmin, fmax, fuzz, 0);
  		input_abs_set_res(input, code,
  				  hidinput_calc_abs_res(field, code));
  		break;
  	case EV_KEY:
  		input_set_capability(input, EV_KEY, code);
  		break;
  	case EV_MSC:
  		input_set_capability(input, EV_MSC, code);
  		break;
  	}
  }
  
  static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
  		struct hid_field *field, struct hid_usage *usage)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1417
1418
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
  	struct input_dev *input = wacom_wac->pen_input;
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1419
1420
1421
  
  	switch (usage->hid) {
  	case HID_GD_X:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1422
  		wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1423
1424
  		break;
  	case HID_GD_Y:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1425
  		wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1426
1427
  		break;
  	case HID_DG_TIPPRESSURE:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1428
  		wacom_map_usage(input, usage, field, EV_ABS, ABS_PRESSURE, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1429
1430
  		break;
  	case HID_DG_INRANGE:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1431
  		wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1432
1433
  		break;
  	case HID_DG_INVERT:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1434
  		wacom_map_usage(input, usage, field, EV_KEY,
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1435
1436
1437
1438
  				BTN_TOOL_RUBBER, 0);
  		break;
  	case HID_DG_ERASER:
  	case HID_DG_TIPSWITCH:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1439
  		wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1440
1441
  		break;
  	case HID_DG_BARRELSWITCH:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1442
  		wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1443
1444
  		break;
  	case HID_DG_BARRELSWITCH2:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1445
  		wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS2, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1446
1447
  		break;
  	case HID_DG_TOOLSERIALNUMBER:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1448
  		wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1449
1450
1451
1452
1453
1454
1455
1456
1457
  		break;
  	}
  }
  
  static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,
  		struct hid_usage *usage, __s32 value)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1458
  	struct input_dev *input = wacom_wac->pen_input;
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
  
  	/* checking which Tool / tip switch to send */
  	switch (usage->hid) {
  	case HID_DG_INRANGE:
  		wacom_wac->hid_data.inrange_state = value;
  		return 0;
  	case HID_DG_INVERT:
  		wacom_wac->hid_data.invert_state = value;
  		return 0;
  	case HID_DG_ERASER:
  	case HID_DG_TIPSWITCH:
  		wacom_wac->hid_data.tipswitch |= value;
  		return 0;
  	}
1924e05e6   Ping Cheng   HID: wacom - add ...
1473
1474
1475
1476
  	/* send pen events only when touch is up or forced out
  	 * or touch arbitration is off
  	 */
  	if (!usage->type || delay_pen_events(wacom_wac))
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1477
1478
1479
1480
1481
1482
  		return 0;
  
  	input_event(input, usage->type, usage->code, value);
  
  	return 0;
  }
06324e0cb   Jason Gerecke   HID: wacom: Perfo...
1483
1484
1485
1486
1487
  static void wacom_wac_pen_pre_report(struct hid_device *hdev,
  		struct hid_report *report)
  {
  	return;
  }
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1488
1489
1490
1491
1492
  static void wacom_wac_pen_report(struct hid_device *hdev,
  		struct hid_report *report)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1493
  	struct input_dev *input = wacom_wac->pen_input;
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1494
1495
1496
1497
1498
1499
1500
1501
1502
  	bool prox = wacom_wac->hid_data.inrange_state;
  
  	if (!wacom_wac->shared->stylus_in_proximity) /* first in prox */
  		/* Going into proximity select tool */
  		wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ?
  						BTN_TOOL_RUBBER : BTN_TOOL_PEN;
  
  	/* keep pen state for touch events */
  	wacom_wac->shared->stylus_in_proximity = prox;
1924e05e6   Ping Cheng   HID: wacom - add ...
1503
  	if (!delay_pen_events(wacom_wac)) {
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1504
1505
1506
1507
1508
1509
1510
1511
1512
  		input_report_key(input, BTN_TOUCH,
  				wacom_wac->hid_data.tipswitch);
  		input_report_key(input, wacom_wac->tool[0], prox);
  
  		wacom_wac->hid_data.tipswitch = false;
  
  		input_sync(input);
  	}
  }
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1513
1514
1515
1516
1517
  static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
  		struct hid_field *field, struct hid_usage *usage)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1518
  	struct input_dev *input = wacom_wac->touch_input;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1519
1520
1521
1522
1523
  	unsigned touch_max = wacom_wac->features.touch_max;
  
  	switch (usage->hid) {
  	case HID_GD_X:
  		if (touch_max == 1)
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1524
  			wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1525
  		else
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1526
  			wacom_map_usage(input, usage, field, EV_ABS,
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1527
1528
1529
1530
  					ABS_MT_POSITION_X, 4);
  		break;
  	case HID_GD_Y:
  		if (touch_max == 1)
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1531
  			wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1532
  		else
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1533
  			wacom_map_usage(input, usage, field, EV_ABS,
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1534
1535
  					ABS_MT_POSITION_Y, 4);
  		break;
488abb5c7   Jason Gerecke   HID: wacom: Repor...
1536
1537
  	case HID_DG_WIDTH:
  	case HID_DG_HEIGHT:
488abb5c7   Jason Gerecke   HID: wacom: Repor...
1538
1539
1540
1541
  		wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MAJOR, 0);
  		wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MINOR, 0);
  		input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);
  		break;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1542
  	case HID_DG_TIPSWITCH:
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1543
  		wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1544
  		break;
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1545
  	case HID_DG_CONTACTCOUNT:
499522c8c   Jason Gerecke   HID: wacom: Tie c...
1546
  		wacom_wac->hid_data.cc_report = field->report->id;
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1547
1548
1549
  		wacom_wac->hid_data.cc_index = field->index;
  		wacom_wac->hid_data.cc_value_index = usage->usage_index;
  		break;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1550
1551
  	}
  }
601a22f37   Jason Gerecke   HID: wacom: Repor...
1552
1553
1554
1555
1556
1557
  static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
  		struct input_dev *input)
  {
  	struct hid_data *hid_data = &wacom_wac->hid_data;
  	bool mt = wacom_wac->features.touch_max > 1;
  	bool prox = hid_data->tipswitch &&
1924e05e6   Ping Cheng   HID: wacom - add ...
1558
  		    report_touch_events(wacom_wac);
601a22f37   Jason Gerecke   HID: wacom: Repor...
1559

1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1560
1561
1562
  	wacom_wac->hid_data.num_received++;
  	if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected)
  		return;
601a22f37   Jason Gerecke   HID: wacom: Repor...
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
  	if (mt) {
  		int slot;
  
  		slot = input_mt_get_slot_by_key(input, hid_data->id);
  		input_mt_slot(input, slot);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, prox);
  	}
  	else {
  		input_report_key(input, BTN_TOUCH, prox);
  	}
  
  	if (prox) {
  		input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X,
  				 hid_data->x);
  		input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y,
  				 hid_data->y);
488abb5c7   Jason Gerecke   HID: wacom: Repor...
1579
1580
1581
1582
1583
1584
1585
  
  		if (test_bit(ABS_MT_TOUCH_MAJOR, input->absbit)) {
  			input_report_abs(input, ABS_MT_TOUCH_MAJOR, max(hid_data->width, hid_data->height));
  			input_report_abs(input, ABS_MT_TOUCH_MINOR, min(hid_data->width, hid_data->height));
  			if (hid_data->width != hid_data->height)
  				input_report_abs(input, ABS_MT_ORIENTATION, hid_data->width <= hid_data->height ? 0 : 1);
  		}
601a22f37   Jason Gerecke   HID: wacom: Repor...
1586
1587
  	}
  }
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
  static int wacom_wac_finger_event(struct hid_device *hdev,
  		struct hid_field *field, struct hid_usage *usage, __s32 value)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
  
  	switch (usage->hid) {
  	case HID_GD_X:
  		wacom_wac->hid_data.x = value;
  		break;
  	case HID_GD_Y:
  		wacom_wac->hid_data.y = value;
  		break;
488abb5c7   Jason Gerecke   HID: wacom: Repor...
1601
1602
1603
1604
1605
1606
  	case HID_DG_WIDTH:
  		wacom_wac->hid_data.width = value;
  		break;
  	case HID_DG_HEIGHT:
  		wacom_wac->hid_data.height = value;
  		break;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1607
1608
1609
1610
1611
1612
1613
  	case HID_DG_CONTACTID:
  		wacom_wac->hid_data.id = value;
  		break;
  	case HID_DG_TIPSWITCH:
  		wacom_wac->hid_data.tipswitch = value;
  		break;
  	}
601a22f37   Jason Gerecke   HID: wacom: Repor...
1614
  	if (usage->usage_index + 1 == field->report_count) {
003f50ab6   Jason Gerecke   HID: wacom: Updat...
1615
  		if (usage->hid == wacom_wac->hid_data.last_slot_field)
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1616
  			wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
601a22f37   Jason Gerecke   HID: wacom: Repor...
1617
  	}
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1618
1619
  	return 0;
  }
06324e0cb   Jason Gerecke   HID: wacom: Perfo...
1620
1621
1622
  static void wacom_wac_finger_pre_report(struct hid_device *hdev,
  		struct hid_report *report)
  {
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1623
1624
1625
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
  	struct hid_data* hid_data = &wacom_wac->hid_data;
003f50ab6   Jason Gerecke   HID: wacom: Updat...
1626
  	int i;
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1627

003f50ab6   Jason Gerecke   HID: wacom: Updat...
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
  	for (i = 0; i < report->maxfield; i++) {
  		struct hid_field *field = report->field[i];
  		int j;
  
  		for (j = 0; j < field->maxusage; j++) {
  			struct hid_usage *usage = &field->usage[j];
  
  			switch (usage->hid) {
  			case HID_GD_X:
  			case HID_GD_Y:
  			case HID_DG_WIDTH:
  			case HID_DG_HEIGHT:
  			case HID_DG_CONTACTID:
  			case HID_DG_INRANGE:
  			case HID_DG_INVERT:
  			case HID_DG_TIPSWITCH:
  				hid_data->last_slot_field = usage->hid;
  				break;
  			case HID_DG_CONTACTCOUNT:
  				hid_data->cc_report = report->id;
  				hid_data->cc_index = i;
  				hid_data->cc_value_index = j;
  				break;
499522c8c   Jason Gerecke   HID: wacom: Tie c...
1651
1652
1653
  			}
  		}
  	}
003f50ab6   Jason Gerecke   HID: wacom: Updat...
1654

df7079380   Jason Gerecke   HID: wacom: Expec...
1655
1656
  	if (hid_data->cc_report != 0 &&
  	    hid_data->cc_index >= 0) {
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1657
1658
1659
1660
1661
1662
1663
1664
  		struct hid_field *field = report->field[hid_data->cc_index];
  		int value = field->value[hid_data->cc_value_index];
  		if (value)
  			hid_data->num_expected = value;
  	}
  	else {
  		hid_data->num_expected = wacom_wac->features.touch_max;
  	}
06324e0cb   Jason Gerecke   HID: wacom: Perfo...
1665
  }
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1666
1667
1668
1669
1670
  static void wacom_wac_finger_report(struct hid_device *hdev,
  		struct hid_report *report)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1671
  	struct input_dev *input = wacom_wac->touch_input;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1672
  	unsigned touch_max = wacom_wac->features.touch_max;
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1673
1674
1675
1676
1677
1678
  	/* If more packets of data are expected, give us a chance to
  	 * process them rather than immediately syncing a partial
  	 * update.
  	 */
  	if (wacom_wac->hid_data.num_received < wacom_wac->hid_data.num_expected)
  		return;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1679
  	if (touch_max > 1)
601a22f37   Jason Gerecke   HID: wacom: Repor...
1680
  		input_mt_sync_frame(input);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1681
  	input_sync(input);
1b5d514a3   Jason Gerecke   HID: wacom: Ignor...
1682
  	wacom_wac->hid_data.num_received = 0;
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1683
1684
  
  	/* keep touch state for pen event */
7d059ed01   Ping Cheng   HID: wacom: use w...
1685
  	wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1686
  }
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1687
1688
1689
1690
1691
  void wacom_wac_usage_mapping(struct hid_device *hdev,
  		struct hid_field *field, struct hid_usage *usage)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
e5bc8eb1b   Jason Gerecke   HID: wacom: Add W...
1692
  	struct wacom_features *features = &wacom_wac->features;
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1693
1694
  
  	/* currently, only direct devices have proper hid report descriptors */
e5bc8eb1b   Jason Gerecke   HID: wacom: Add W...
1695
  	features->device_type |= WACOM_DEVICETYPE_DIRECT;
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1696
1697
1698
  
  	if (WACOM_PEN_FIELD(field))
  		return wacom_wac_pen_usage_mapping(hdev, field, usage);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1699
1700
1701
  
  	if (WACOM_FINGER_FIELD(field))
  		return wacom_wac_finger_usage_mapping(hdev, field, usage);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  }
  
  int wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
  		struct hid_usage *usage, __s32 value)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  
  	if (wacom->wacom_wac.features.type != HID_GENERIC)
  		return 0;
  
  	if (WACOM_PEN_FIELD(field))
  		return wacom_wac_pen_event(hdev, field, usage, value);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1714
1715
  	if (WACOM_FINGER_FIELD(field))
  		return wacom_wac_finger_event(hdev, field, usage, value);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1716
1717
  	return 0;
  }
06324e0cb   Jason Gerecke   HID: wacom: Perfo...
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
  static void wacom_report_events(struct hid_device *hdev, struct hid_report *report)
  {
  	int r;
  
  	for (r = 0; r < report->maxfield; r++) {
  		struct hid_field *field;
  		unsigned count, n;
  
  		field = report->field[r];
  		count = field->report_count;
  
  		if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
  			continue;
  
  		for (n = 0; n < count; n++)
  			wacom_wac_event(hdev, field, &field->usage[n], field->value[n]);
  	}
  }
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
  void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)
  {
  	struct wacom *wacom = hid_get_drvdata(hdev);
  	struct wacom_wac *wacom_wac = &wacom->wacom_wac;
  	struct hid_field *field = report->field[0];
  
  	if (wacom_wac->features.type != HID_GENERIC)
  		return;
  
  	if (WACOM_PEN_FIELD(field))
06324e0cb   Jason Gerecke   HID: wacom: Perfo...
1746
1747
1748
1749
1750
1751
1752
1753
  		wacom_wac_pen_pre_report(hdev, report);
  
  	if (WACOM_FINGER_FIELD(field))
  		wacom_wac_finger_pre_report(hdev, report);
  
  	wacom_report_events(hdev, report);
  
  	if (WACOM_PEN_FIELD(field))
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1754
  		return wacom_wac_pen_report(hdev, report);
5ae6e89f7   Benjamin Tissoires   HID: wacom: imple...
1755
1756
1757
  
  	if (WACOM_FINGER_FIELD(field))
  		return wacom_wac_finger_report(hdev, report);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
1758
  }
e1d38e49a   Chris Bagwell   Input: wacom - mo...
1759
  static int wacom_bpt_touch(struct wacom_wac *wacom)
cb734c036   Henrik Rydberg   Input: wacom - ad...
1760
  {
f4ccbef28   Henrik Rydberg   Input: wacom - ad...
1761
  	struct wacom_features *features = &wacom->features;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1762
  	struct input_dev *input = wacom->touch_input;
3116871f4   Benjamin Tissoires   Input: wacom - sp...
1763
  	struct input_dev *pad_input = wacom->pad_input;
cb734c036   Henrik Rydberg   Input: wacom - ad...
1764
  	unsigned char *data = wacom->data;
cb734c036   Henrik Rydberg   Input: wacom - ad...
1765
  	int i;
5a6c865d9   Chris Bagwell   Input: wacom - ig...
1766
1767
  	if (data[0] != 0x02)
  	    return 0;
cb734c036   Henrik Rydberg   Input: wacom - ad...
1768
  	for (i = 0; i < 2; i++) {
8f9068609   Chris Bagwell   Input: wacom - fi...
1769
  		int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
1924e05e6   Ping Cheng   HID: wacom - add ...
1770
1771
  		bool touch = report_touch_events(wacom)
  			   && (data[offset + 3] & 0x80);
8f9068609   Chris Bagwell   Input: wacom - fi...
1772
1773
1774
  
  		input_mt_slot(input, i);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
c5f4dec1c   Henrik Rydberg   input: mt: Move t...
1775
  		if (touch) {
8f9068609   Chris Bagwell   Input: wacom - fi...
1776
1777
  			int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
  			int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
f4ccbef28   Henrik Rydberg   Input: wacom - ad...
1778
1779
1780
1781
  			if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
  				x <<= 5;
  				y <<= 5;
  			}
cb734c036   Henrik Rydberg   Input: wacom - ad...
1782
1783
  			input_report_abs(input, ABS_MT_POSITION_X, x);
  			input_report_abs(input, ABS_MT_POSITION_Y, y);
cb734c036   Henrik Rydberg   Input: wacom - ad...
1784
  		}
cb734c036   Henrik Rydberg   Input: wacom - ad...
1785
  	}
9a1c00129   Benjamin Tissoires   HID: wacom: do no...
1786
  	input_mt_sync_frame(input);
cb734c036   Henrik Rydberg   Input: wacom - ad...
1787

3116871f4   Benjamin Tissoires   Input: wacom - sp...
1788
1789
1790
1791
  	input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);
  	input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);
  	input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);
  	input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);
7d059ed01   Ping Cheng   HID: wacom: use w...
1792
  	wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
cb734c036   Henrik Rydberg   Input: wacom - ad...
1793

3116871f4   Benjamin Tissoires   Input: wacom - sp...
1794
  	return 1;
cb734c036   Henrik Rydberg   Input: wacom - ad...
1795
  }
7d059ed01   Ping Cheng   HID: wacom: use w...
1796
  static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
73149ab84   Chris Bagwell   Input: wacom - 3r...
1797
  {
9a35c411f   Ping Cheng   Input: wacom - ad...
1798
  	struct wacom_features *features = &wacom->features;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1799
  	struct input_dev *input = wacom->touch_input;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1800
  	bool touch = data[1] & 0x80;
02295e68c   Ping Cheng   Input: wacom - us...
1801
1802
1803
  	int slot = input_mt_get_slot_by_key(input, data[0]);
  
  	if (slot < 0)
7d059ed01   Ping Cheng   HID: wacom: use w...
1804
  		return;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1805

1924e05e6   Ping Cheng   HID: wacom - add ...
1806
  	touch = touch && report_touch_events(wacom);
73149ab84   Chris Bagwell   Input: wacom - 3r...
1807

02295e68c   Ping Cheng   Input: wacom - us...
1808
  	input_mt_slot(input, slot);
73149ab84   Chris Bagwell   Input: wacom - 3r...
1809
1810
1811
1812
1813
  	input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
  
  	if (touch) {
  		int x = (data[2] << 4) | (data[4] >> 4);
  		int y = (data[3] << 4) | (data[4] & 0x0f);
9a35c411f   Ping Cheng   Input: wacom - ad...
1814
  		int width, height;
4e9049549   Jason Gerecke   Input: wacom - re...
1815

eda01dab5   Ping Cheng   HID: wacom: Add f...
1816
  		if (features->type >= INTUOSPS && features->type <= INTUOSHT2) {
0b279da7a   Jason Gerecke   Input: wacom - sc...
1817
1818
  			width  = data[5] * 100;
  			height = data[6] * 100;
9a35c411f   Ping Cheng   Input: wacom - ad...
1819
1820
1821
1822
1823
1824
1825
  		} else {
  			/*
  			 * "a" is a scaled-down area which we assume is
  			 * roughly circular and which can be described as:
  			 * a=(pi*r^2)/C.
  			 */
  			int a = data[5];
d7da3a3cc   Ping Cheng   Input: wacom - cl...
1826
1827
1828
  			int x_res = input_abs_get_res(input, ABS_MT_POSITION_X);
  			int y_res = input_abs_get_res(input, ABS_MT_POSITION_Y);
  			width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
9a35c411f   Ping Cheng   Input: wacom - ad...
1829
1830
  			height = width * y_res / x_res;
  		}
73149ab84   Chris Bagwell   Input: wacom - 3r...
1831
1832
1833
  
  		input_report_abs(input, ABS_MT_POSITION_X, x);
  		input_report_abs(input, ABS_MT_POSITION_Y, y);
4e9049549   Jason Gerecke   Input: wacom - re...
1834
1835
  		input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
  		input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
73149ab84   Chris Bagwell   Input: wacom - 3r...
1836
1837
1838
1839
1840
  	}
  }
  
  static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
  {
3116871f4   Benjamin Tissoires   Input: wacom - sp...
1841
  	struct input_dev *input = wacom->pad_input;
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
1842
  	struct wacom_features *features = &wacom->features;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1843

eda01dab5   Ping Cheng   HID: wacom: Add f...
1844
  	if (features->type == INTUOSHT || features->type == INTUOSHT2) {
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
1845
1846
1847
1848
1849
1850
  		input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);
  		input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);
  	} else {
  		input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
  		input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
  	}
73149ab84   Chris Bagwell   Input: wacom - 3r...
1851
  	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
73149ab84   Chris Bagwell   Input: wacom - 3r...
1852
1853
1854
1855
1856
  	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
  }
  
  static int wacom_bpt3_touch(struct wacom_wac *wacom)
  {
73149ab84   Chris Bagwell   Input: wacom - 3r...
1857
  	unsigned char *data = wacom->data;
19d57d3a1   Jason Gerecke   Input: wacom - fi...
1858
  	int count = data[1] & 0x07;
eda01dab5   Ping Cheng   HID: wacom: Add f...
1859
  	int  touch_changed = 0, i;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1860

5a6c865d9   Chris Bagwell   Input: wacom - ig...
1861
1862
  	if (data[0] != 0x02)
  	    return 0;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1863
1864
1865
1866
  	/* data has up to 7 fixed sized 8-byte messages starting at data[2] */
  	for (i = 0; i < count; i++) {
  		int offset = (8 * i) + 2;
  		int msg_id = data[offset];
eda01dab5   Ping Cheng   HID: wacom: Add f...
1867
  		if (msg_id >= 2 && msg_id <= 17) {
7d059ed01   Ping Cheng   HID: wacom: use w...
1868
  			wacom_bpt3_touch_msg(wacom, data + offset);
eda01dab5   Ping Cheng   HID: wacom: Add f...
1869
1870
  			touch_changed++;
  		} else if (msg_id == 128)
73149ab84   Chris Bagwell   Input: wacom - 3r...
1871
1872
1873
  			wacom_bpt3_button_msg(wacom, data + offset);
  
  	}
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1874

eda01dab5   Ping Cheng   HID: wacom: Add f...
1875
  	/* only update touch if we actually have a touchpad and touch data changed */
84dfbd7f2   Benjamin Tissoires   HID: wacom: put t...
1876
  	if (wacom->touch_input && touch_changed) {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1877
1878
1879
  		input_mt_sync_frame(wacom->touch_input);
  		wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
  	}
73149ab84   Chris Bagwell   Input: wacom - 3r...
1880

3116871f4   Benjamin Tissoires   Input: wacom - sp...
1881
  	return 1;
73149ab84   Chris Bagwell   Input: wacom - 3r...
1882
  }
2aaacb153   Chris Bagwell   Input: wacom - ad...
1883
1884
  static int wacom_bpt_pen(struct wacom_wac *wacom)
  {
961794a00   Ping Cheng   Input: wacom - ad...
1885
  	struct wacom_features *features = &wacom->features;
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1886
  	struct input_dev *input = wacom->pen_input;
2aaacb153   Chris Bagwell   Input: wacom - ad...
1887
1888
  	unsigned char *data = wacom->data;
  	int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;
4ca4ec71c   Jason Gerecke   HID: wacom: Move ...
1889
  	if (data[0] != WACOM_REPORT_PENABLED)
5a6c865d9   Chris Bagwell   Input: wacom - ig...
1890
  	    return 0;
c5981411f   Chris Bagwell   Input: wacom - re...
1891
  	prox = (data[1] & 0x20) == 0x20;
2aaacb153   Chris Bagwell   Input: wacom - ad...
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
  
  	/*
  	 * All reports shared between PEN and RUBBER tool must be
  	 * forced to a known starting value (zero) when transitioning to
  	 * out-of-prox.
  	 *
  	 * If not reset then, to userspace, it will look like lost events
  	 * if new tool comes in-prox with same values as previous tool sent.
  	 *
  	 * Hardware does report zero in most out-of-prox cases but not all.
  	 */
0149931e6   Ping Cheng   HID: wacom: set s...
1903
1904
1905
1906
1907
1908
1909
  	if (!wacom->shared->stylus_in_proximity) {
  		if (data[1] & 0x08) {
  			wacom->tool[0] = BTN_TOOL_RUBBER;
  			wacom->id[0] = ERASER_DEVICE_ID;
  		} else {
  			wacom->tool[0] = BTN_TOOL_PEN;
  			wacom->id[0] = STYLUS_DEVICE_ID;
2aaacb153   Chris Bagwell   Input: wacom - ad...
1910
  		}
0149931e6   Ping Cheng   HID: wacom: set s...
1911
1912
1913
  	}
  
  	wacom->shared->stylus_in_proximity = prox;
1924e05e6   Ping Cheng   HID: wacom - add ...
1914
  	if (delay_pen_events(wacom))
0149931e6   Ping Cheng   HID: wacom: set s...
1915
1916
1917
  		return 0;
  
  	if (prox) {
2aaacb153   Chris Bagwell   Input: wacom - ad...
1918
1919
1920
  		x = le16_to_cpup((__le16 *)&data[2]);
  		y = le16_to_cpup((__le16 *)&data[4]);
  		p = le16_to_cpup((__le16 *)&data[6]);
c18c2cec3   Chris Bagwell   Input: wacom - ad...
1921
1922
1923
1924
1925
1926
  		/*
  		 * Convert distance from out prox to distance from tablet.
  		 * distance will be greater than distance_max once
  		 * touching and applying pressure; do not report negative
  		 * distance.
  		 */
961794a00   Ping Cheng   Input: wacom - ad...
1927
1928
  		if (data[8] <= features->distance_max)
  			d = features->distance_max - data[8];
c18c2cec3   Chris Bagwell   Input: wacom - ad...
1929

2aaacb153   Chris Bagwell   Input: wacom - ad...
1930
1931
1932
  		pen = data[1] & 0x01;
  		btn1 = data[1] & 0x02;
  		btn2 = data[1] & 0x04;
0149931e6   Ping Cheng   HID: wacom: set s...
1933
1934
  	} else {
  		wacom->id[0] = 0;
2aaacb153   Chris Bagwell   Input: wacom - ad...
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
  	}
  
  	input_report_key(input, BTN_TOUCH, pen);
  	input_report_key(input, BTN_STYLUS, btn1);
  	input_report_key(input, BTN_STYLUS2, btn2);
  
  	input_report_abs(input, ABS_X, x);
  	input_report_abs(input, ABS_Y, y);
  	input_report_abs(input, ABS_PRESSURE, p);
  	input_report_abs(input, ABS_DISTANCE, d);
2aaacb153   Chris Bagwell   Input: wacom - ad...
1945
1946
1947
1948
1949
  	input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
  	input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */
  
  	return 1;
  }
e1d38e49a   Chris Bagwell   Input: wacom - mo...
1950
1951
  static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
  {
eda01dab5   Ping Cheng   HID: wacom: Add f...
1952
1953
1954
  	struct wacom_features *features = &wacom->features;
  
  	if ((features->type == INTUOSHT2) &&
eda01dab5   Ping Cheng   HID: wacom: Add f...
1955
1956
1957
  	    (features->device_type & WACOM_DEVICETYPE_PEN))
  		return wacom_intuos_irq(wacom);
  	else if (len == WACOM_PKGLEN_BBTOUCH)
e1d38e49a   Chris Bagwell   Input: wacom - mo...
1958
  		return wacom_bpt_touch(wacom);
73149ab84   Chris Bagwell   Input: wacom - 3r...
1959
1960
1961
  	else if (len == WACOM_PKGLEN_BBTOUCH3)
  		return wacom_bpt3_touch(wacom);
  	else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN)
2aaacb153   Chris Bagwell   Input: wacom - ad...
1962
  		return wacom_bpt_pen(wacom);
e1d38e49a   Chris Bagwell   Input: wacom - mo...
1963
1964
1965
  
  	return 0;
  }
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom,
  		unsigned char *data)
  {
  	unsigned char prefix;
  
  	/*
  	 * We need to reroute the event from the debug interface to the
  	 * pen interface.
  	 * We need to add the report ID to the actual pen report, so we
  	 * temporary overwrite the first byte to prevent having to kzalloc/kfree
  	 * and memcpy the report.
  	 */
  	prefix = data[0];
  	data[0] = WACOM_REPORT_BPAD_PEN;
  
  	/*
  	 * actually reroute the event.
  	 * No need to check if wacom->shared->pen is valid, hid_input_report()
  	 * will check for us.
  	 */
  	hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data,
  			 WACOM_PKGLEN_PENABLED, 1);
  
  	data[0] = prefix;
  }
  
  static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,
  		unsigned char *data)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
1995
  	struct input_dev *input = wacom->touch_input;
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
1996
1997
1998
1999
2000
2001
2002
2003
2004
  	unsigned char *finger_data, prefix;
  	unsigned id;
  	int x, y;
  	bool valid;
  
  	prefix = data[0];
  
  	for (id = 0; id < wacom->features.touch_max; id++) {
  		valid = !!(prefix & BIT(id)) &&
1924e05e6   Ping Cheng   HID: wacom - add ...
2005
  			report_touch_events(wacom);
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
  
  		input_mt_slot(input, id);
  		input_mt_report_slot_state(input, MT_TOOL_FINGER, valid);
  
  		if (!valid)
  			continue;
  
  		finger_data = data + 1 + id * 3;
  		x = finger_data[0] | ((finger_data[1] & 0x0f) << 8);
  		y = (finger_data[2] << 4) | (finger_data[1] >> 4);
  
  		input_report_abs(input, ABS_MT_POSITION_X, x);
  		input_report_abs(input, ABS_MT_POSITION_Y, y);
  	}
  
  	input_mt_sync_frame(input);
  
  	input_report_key(input, BTN_LEFT, prefix & 0x40);
  	input_report_key(input, BTN_RIGHT, prefix & 0x80);
  
  	/* keep touch state for pen event */
1924e05e6   Ping Cheng   HID: wacom - add ...
2027
  	wacom->shared->touch_down = !!prefix && report_touch_events(wacom);
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
  
  	return 1;
  }
  
  static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, size_t len)
  {
  	unsigned char *data = wacom->data;
  
  	if (!((len == WACOM_PKGLEN_BPAD_TOUCH) ||
  	      (len == WACOM_PKGLEN_BPAD_TOUCH_USB)) ||
  	    (data[0] != WACOM_REPORT_BPAD_TOUCH))
  		return 0;
  
  	if (data[1] & 0x01)
  		wacom_bamboo_pad_pen_event(wacom, &data[1]);
  
  	if (data[1] & 0x02)
  		return wacom_bamboo_pad_touch_event(wacom, &data[9]);
  
  	return 0;
  }
d3825d51c   Chris Bagwell   Input: wacom - wi...
2049
2050
  static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
  {
16bf288c4   Chris Bagwell   Input: wacom - cr...
2051
2052
  	unsigned char *data = wacom->data;
  	int connected;
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
2053
  	if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
d3825d51c   Chris Bagwell   Input: wacom - wi...
2054
  		return 0;
16bf288c4   Chris Bagwell   Input: wacom - cr...
2055
2056
  	connected = data[1] & 0x01;
  	if (connected) {
b0882cb79   Jason Gerecke   HID: wacom: Statu...
2057
  		int pid, battery, charging;
16bf288c4   Chris Bagwell   Input: wacom - cr...
2058

eda01dab5   Ping Cheng   HID: wacom: Add f...
2059
2060
  		if ((wacom->shared->type == INTUOSHT ||
  		    wacom->shared->type == INTUOSHT2) &&
44b968385   Ping Cheng   HID: wacom - make...
2061
2062
  		    wacom->shared->touch_input &&
  		    wacom->shared->touch_max) {
961794a00   Ping Cheng   Input: wacom - ad...
2063
2064
2065
2066
  			input_report_switch(wacom->shared->touch_input,
  					SW_MUTE_DEVICE, data[5] & 0x40);
  			input_sync(wacom->shared->touch_input);
  		}
16bf288c4   Chris Bagwell   Input: wacom - cr...
2067
  		pid = get_unaligned_be16(&data[6]);
ac8d10101   Benjamin Tissoires   Input: wacom - en...
2068
  		battery = (data[5] & 0x3f) * 100 / 31;
b0882cb79   Jason Gerecke   HID: wacom: Statu...
2069
  		charging = !!(data[5] & 0x80);
16bf288c4   Chris Bagwell   Input: wacom - cr...
2070
2071
  		if (wacom->pid != pid) {
  			wacom->pid = pid;
d17d1f171   Benjamin Tissoires   HID: wacom: use o...
2072
  			wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
16bf288c4   Chris Bagwell   Input: wacom - cr...
2073
  		}
ac8d10101   Benjamin Tissoires   Input: wacom - en...
2074

59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
2075
  		wacom_notify_battery(wacom, battery, charging, 1, 0);
953f2c5f7   Jason Gerecke   HID: wacom: Centr...
2076

16bf288c4   Chris Bagwell   Input: wacom - cr...
2077
2078
2079
  	} else if (wacom->pid != 0) {
  		/* disconnected while previously connected */
  		wacom->pid = 0;
d17d1f171   Benjamin Tissoires   HID: wacom: use o...
2080
  		wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);
71fa641eb   Jason Gerecke   HID: wacom: Add b...
2081
  		wacom_notify_battery(wacom, 0, 0, 0, 0);
16bf288c4   Chris Bagwell   Input: wacom - cr...
2082
  	}
d3825d51c   Chris Bagwell   Input: wacom - wi...
2083
2084
  	return 0;
  }
4ca4ec71c   Jason Gerecke   HID: wacom: Move ...
2085
2086
  static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)
  {
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2087
  	struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
4ca4ec71c   Jason Gerecke   HID: wacom: Move ...
2088
2089
2090
2091
2092
  	struct wacom_features *features = &wacom_wac->features;
  	unsigned char *data = wacom_wac->data;
  
  	if (data[0] != WACOM_REPORT_USB)
  		return 0;
eda01dab5   Ping Cheng   HID: wacom: Add f...
2093
2094
  	if ((features->type == INTUOSHT ||
  	    features->type == INTUOSHT2) &&
4ca4ec71c   Jason Gerecke   HID: wacom: Move ...
2095
2096
2097
2098
2099
  	    wacom_wac->shared->touch_input &&
  	    features->touch_max) {
  		input_report_switch(wacom_wac->shared->touch_input,
  				    SW_MUTE_DEVICE, data[8] & 0x40);
  		input_sync(wacom_wac->shared->touch_input);
16bf288c4   Chris Bagwell   Input: wacom - cr...
2100
  	}
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2101
2102
  	if (data[9] & 0x02) { /* wireless module is attached */
  		int battery = (data[8] & 0x3f) * 100 / 31;
b0882cb79   Jason Gerecke   HID: wacom: Statu...
2103
  		bool charging = !!(data[8] & 0x80);
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2104
2105
  
  		wacom_notify_battery(wacom_wac, battery, charging,
71fa641eb   Jason Gerecke   HID: wacom: Add b...
2106
  				     battery || charging, 1);
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2107

59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
2108
  		if (!wacom->battery.battery &&
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2109
2110
  		    !(features->quirks & WACOM_QUIRK_BATTERY)) {
  			features->quirks |= WACOM_QUIRK_BATTERY;
d17d1f171   Benjamin Tissoires   HID: wacom: use o...
2111
  			wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2112
2113
2114
  		}
  	}
  	else if ((features->quirks & WACOM_QUIRK_BATTERY) &&
59d69bc82   Benjamin Tissoires   HID: wacom: EKR: ...
2115
  		 wacom->battery.battery) {
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2116
  		features->quirks &= ~WACOM_QUIRK_BATTERY;
d17d1f171   Benjamin Tissoires   HID: wacom: use o...
2117
  		wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);
71fa641eb   Jason Gerecke   HID: wacom: Add b...
2118
  		wacom_notify_battery(wacom_wac, 0, 0, 0, 0);
8f93b0b2b   Jason Gerecke   HID: wacom: Provi...
2119
  	}
d3825d51c   Chris Bagwell   Input: wacom - wi...
2120
2121
  	return 0;
  }
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2122
  void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
3bea733ab   Ping Cheng   USB: wacom tablet...
2123
  {
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2124
  	bool sync;
e33da8a54   Jason Childs   Input: wacom - us...
2125
  	switch (wacom_wac->features.type) {
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2126
  	case PENPARTNER:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2127
2128
  		sync = wacom_penpartner_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2129
2130
  
  	case PL:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2131
2132
  		sync = wacom_pl_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2133
2134
2135
  
  	case WACOM_G4:
  	case GRAPHIRE:
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2136
  	case GRAPHIRE_BT:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2137
  	case WACOM_MO:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2138
2139
  		sync = wacom_graphire_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2140
2141
  
  	case PTU:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2142
2143
  		sync = wacom_ptu_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2144

c8f2edc56   Ping Cheng   Input: wacom - ad...
2145
2146
2147
  	case DTU:
  		sync = wacom_dtu_irq(wacom_wac);
  		break;
497ab1f29   Ping Cheng   Input: wacom - ad...
2148
  	case DTUS:
fff00bf8c   Ping Cheng   HID: wacom: Add s...
2149
  	case DTUSX:
497ab1f29   Ping Cheng   Input: wacom - ad...
2150
2151
  		sync = wacom_dtus_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2152
2153
2154
2155
2156
2157
2158
2159
2160
  	case INTUOS:
  	case INTUOS3S:
  	case INTUOS3:
  	case INTUOS3L:
  	case INTUOS4S:
  	case INTUOS4:
  	case INTUOS4L:
  	case CINTIQ:
  	case WACOM_BEE:
56218563a   Ping Cheng   Input: wacom - ad...
2161
  	case WACOM_13HD:
3a4b4aaa5   Ping Cheng   Input: wacom - ad...
2162
  	case WACOM_21UX2:
d838c644f   Ping Cheng   Input: wacom - ad...
2163
  	case WACOM_22HD:
803296b67   Jason Gerecke   Input: wacom - ad...
2164
  	case WACOM_24HD:
500d4160a   Ping Cheng   HID: wacom: add s...
2165
  	case WACOM_27QHD:
a112e9fdd   Ping Cheng   Input: wacom - ad...
2166
  	case DTK:
36d3c510e   Jason Gerecke   Input: wacom - su...
2167
  	case CINTIQ_HYBRID:
f7acb55cf   Jason Gerecke   HID: wacom: Add s...
2168
  	case CINTIQ_COMPANION_2:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2169
2170
  		sync = wacom_intuos_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2171

81af7e61a   Benjamin Tissoires   Input: wacom - ha...
2172
2173
2174
  	case INTUOS4WL:
  		sync = wacom_intuos_bt_irq(wacom_wac, len);
  		break;
b1e4279e4   Jason Gerecke   Input: wacom - ad...
2175
  	case WACOM_24HDT:
500d4160a   Ping Cheng   HID: wacom: add s...
2176
  	case WACOM_27QHDT:
b1e4279e4   Jason Gerecke   Input: wacom - ad...
2177
2178
  		sync = wacom_24hdt_irq(wacom_wac);
  		break;
ae584ca47   Jason Gerecke   Input: wacom - ad...
2179
2180
2181
  	case INTUOS5S:
  	case INTUOS5:
  	case INTUOS5L:
9a35c411f   Ping Cheng   Input: wacom - ad...
2182
2183
2184
  	case INTUOSPS:
  	case INTUOSPM:
  	case INTUOSPL:
ae584ca47   Jason Gerecke   Input: wacom - ad...
2185
2186
  		if (len == WACOM_PKGLEN_BBTOUCH3)
  			sync = wacom_bpt3_touch(wacom_wac);
2d13a4381   Jason Gerecke   HID: wacom: Repor...
2187
2188
  		else if (wacom_wac->data[0] == WACOM_REPORT_USB)
  			sync = wacom_status_irq(wacom_wac, len);
ae584ca47   Jason Gerecke   Input: wacom - ad...
2189
2190
2191
  		else
  			sync = wacom_intuos_irq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2192
  	case TABLETPC:
ac173837c   Ping Cheng   Input: wacom - ad...
2193
  	case TABLETPCE:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2194
  	case TABLETPC2FG:
1963518b9   Ping Cheng   Input: wacom - ad...
2195
  	case MTSCREEN:
6afdc289c   Ping Cheng   Input: wacom - ad...
2196
  	case MTTPC:
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
2197
  	case MTTPC_B:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2198
2199
  		sync = wacom_tpc_irq(wacom_wac, len);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2200

cb734c036   Henrik Rydberg   Input: wacom - ad...
2201
  	case BAMBOO_PT:
3b164a00a   Ping Cheng   HID: wacom: Clean...
2202
2203
  	case BAMBOO_PEN:
  	case BAMBOO_TOUCH:
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
2204
  	case INTUOSHT:
eda01dab5   Ping Cheng   HID: wacom: Add f...
2205
  	case INTUOSHT2:
4ca4ec71c   Jason Gerecke   HID: wacom: Move ...
2206
2207
2208
2209
  		if (wacom_wac->data[0] == WACOM_REPORT_USB)
  			sync = wacom_status_irq(wacom_wac, len);
  		else
  			sync = wacom_bpt_irq(wacom_wac, len);
cb734c036   Henrik Rydberg   Input: wacom - ad...
2210
  		break;
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
2211
2212
  	case BAMBOO_PAD:
  		sync = wacom_bamboo_pad_irq(wacom_wac, len);
cb734c036   Henrik Rydberg   Input: wacom - ad...
2213
  		break;
d3825d51c   Chris Bagwell   Input: wacom - wi...
2214
2215
2216
  	case WIRELESS:
  		sync = wacom_wireless_irq(wacom_wac, len);
  		break;
72b236d60   Aaron Skomra   HID: wacom: Add s...
2217
  	case REMOTE:
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
2218
  		sync = false;
72b236d60   Aaron Skomra   HID: wacom: Add s...
2219
  		if (wacom_wac->data[0] == WACOM_REPORT_DEVICE_LIST)
e6f2813a6   Benjamin Tissoires   HID: wacom: EKR: ...
2220
  			wacom_remote_status_irq(wacom_wac, len);
72b236d60   Aaron Skomra   HID: wacom: Add s...
2221
2222
2223
  		else
  			sync = wacom_remote_irq(wacom_wac, len);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2224
  	default:
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2225
2226
  		sync = false;
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
2227
  	}
95dd3b30c   Dmitry Torokhov   Input: wacom - ge...
2228

d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2229
  	if (sync) {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
2230
2231
2232
2233
  		if (wacom_wac->pen_input)
  			input_sync(wacom_wac->pen_input);
  		if (wacom_wac->touch_input)
  			input_sync(wacom_wac->touch_input);
d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2234
2235
2236
  		if (wacom_wac->pad_input)
  			input_sync(wacom_wac->pad_input);
  	}
3bea733ab   Ping Cheng   USB: wacom tablet...
2237
  }
eda01dab5   Ping Cheng   HID: wacom: Add f...
2238
  static void wacom_setup_basic_pro_pen(struct wacom_wac *wacom_wac)
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2239
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
2240
  	struct input_dev *input_dev = wacom_wac->pen_input;
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2241
2242
  
  	input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2243

8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2244
  	__set_bit(BTN_TOOL_PEN, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2245
2246
2247
2248
  	__set_bit(BTN_STYLUS, input_dev->keybit);
  	__set_bit(BTN_STYLUS2, input_dev->keybit);
  
  	input_set_abs_params(input_dev, ABS_DISTANCE,
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2249
  			     0, wacom_wac->features.distance_max, wacom_wac->features.distance_fuzz, 0);
eda01dab5   Ping Cheng   HID: wacom: Add f...
2250
2251
2252
2253
2254
  }
  
  static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
  {
  	struct input_dev *input_dev = wacom_wac->pen_input;
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2255
  	struct wacom_features *features = &wacom_wac->features;
eda01dab5   Ping Cheng   HID: wacom: Add f...
2256
2257
2258
2259
2260
2261
2262
  
  	wacom_setup_basic_pro_pen(wacom_wac);
  
  	__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
  	__set_bit(BTN_TOOL_BRUSH, input_dev->keybit);
  	__set_bit(BTN_TOOL_PENCIL, input_dev->keybit);
  	__set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2263
  	input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2264
  	input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, features->tilt_fuzz, 0);
26fe41245   Jason Gerecke   HID: wacom: Add a...
2265
  	input_abs_set_res(input_dev, ABS_TILT_X, 57);
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2266
  	input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, features->tilt_fuzz, 0);
26fe41245   Jason Gerecke   HID: wacom: Add a...
2267
  	input_abs_set_res(input_dev, ABS_TILT_Y, 57);
6521d0bf9   Ping Cheng   Input: wacom - sp...
2268
2269
2270
2271
  }
  
  static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
  {
2a6cdbdd4   Jason Gerecke   HID: wacom: Intro...
2272
  	struct input_dev *input_dev = wacom_wac->pen_input;
6521d0bf9   Ping Cheng   Input: wacom - sp...
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
  
  	input_set_capability(input_dev, EV_REL, REL_WHEEL);
  
  	wacom_setup_cintiq(wacom_wac);
  
  	__set_bit(BTN_LEFT, input_dev->keybit);
  	__set_bit(BTN_RIGHT, input_dev->keybit);
  	__set_bit(BTN_MIDDLE, input_dev->keybit);
  	__set_bit(BTN_SIDE, input_dev->keybit);
  	__set_bit(BTN_EXTRA, input_dev->keybit);
  	__set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
  	__set_bit(BTN_TOOL_LENS, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2285
  	input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
26fe41245   Jason Gerecke   HID: wacom: Add a...
2286
  	input_abs_set_res(input_dev, ABS_RZ, 287);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2287
2288
  	input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
  }
42f4f2727   Ping Cheng   HID: wacom: move ...
2289
  void wacom_setup_device_quirks(struct wacom *wacom)
bc73dd39e   Henrik Rydberg   Input: wacom - co...
2290
  {
42f4f2727   Ping Cheng   HID: wacom: move ...
2291
  	struct wacom_features *features = &wacom->wacom_wac.features;
bc73dd39e   Henrik Rydberg   Input: wacom - co...
2292

862cf5535   Jason Gerecke   HID: wacom: Intro...
2293
2294
  	/* The pen and pad share the same interface on most devices */
  	if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 ||
3b164a00a   Ping Cheng   HID: wacom: Clean...
2295
2296
  	    features->type == DTUS ||
  	    (features->type >= INTUOS3S && features->type <= WACOM_MO)) {
862cf5535   Jason Gerecke   HID: wacom: Intro...
2297
2298
2299
  		if (features->device_type & WACOM_DEVICETYPE_PEN)
  			features->device_type |= WACOM_DEVICETYPE_PAD;
  	}
bc73dd39e   Henrik Rydberg   Input: wacom - co...
2300
2301
  
  	/* touch device found but size is not defined. use default */
aa86b18cc   Jason Gerecke   HID: wacom: Treat...
2302
  	if (features->device_type & WACOM_DEVICETYPE_TOUCH && !features->x_max) {
bc73dd39e   Henrik Rydberg   Input: wacom - co...
2303
2304
2305
  		features->x_max = 1023;
  		features->y_max = 1023;
  	}
42f4f2727   Ping Cheng   HID: wacom: move ...
2306
2307
2308
2309
2310
2311
  	/*
  	 * Intuos5/Pro and Bamboo 3rd gen have no useful data about its
  	 * touch interface in its HID descriptor. If this is the touch
  	 * interface (PacketSize of WACOM_PKGLEN_BBTOUCH3), override the
  	 * tablet values.
  	 */
3b164a00a   Ping Cheng   HID: wacom: Clean...
2312
2313
  	if ((features->type >= INTUOS5S && features->type <= INTUOSPL) ||
  		(features->type >= INTUOSHT && features->type <= BAMBOO_PT)) {
42f4f2727   Ping Cheng   HID: wacom: move ...
2314
  		if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
862cf5535   Jason Gerecke   HID: wacom: Intro...
2315
2316
  			if (features->touch_max)
  				features->device_type |= WACOM_DEVICETYPE_TOUCH;
a3088abc6   Jiri Kosina   HID: wacom: fixup...
2317
  			if (features->type >= INTUOSHT && features->type <= BAMBOO_PT)
862cf5535   Jason Gerecke   HID: wacom: Intro...
2318
  				features->device_type |= WACOM_DEVICETYPE_PAD;
42f4f2727   Ping Cheng   HID: wacom: move ...
2319
2320
2321
  
  			features->x_max = 4096;
  			features->y_max = 4096;
42f4f2727   Ping Cheng   HID: wacom: move ...
2322
  		}
9633920e5   Jason Gerecke   HID: wacom: Enabl...
2323
2324
2325
  		else if (features->pktlen == WACOM_PKGLEN_BBTOUCH) {
  			features->device_type |= WACOM_DEVICETYPE_PAD;
  		}
42f4f2727   Ping Cheng   HID: wacom: move ...
2326
2327
2328
  	}
  
  	/*
580549ef6   Benjamin Tissoires   HID: wacom: fix B...
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  	 * Hack for the Bamboo One:
  	 * the device presents a PAD/Touch interface as most Bamboos and even
  	 * sends ghosts PAD data on it. However, later, we must disable this
  	 * ghost interface, and we can not detect it unless we set it here
  	 * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH.
  	 */
  	if (features->type == BAMBOO_PEN &&
  	    features->pktlen == WACOM_PKGLEN_BBTOUCH3)
  		features->device_type |= WACOM_DEVICETYPE_PAD;
  
  	/*
042628abd   Jason Gerecke   HID: wacom: Disco...
2340
2341
2342
2343
  	 * Raw Wacom-mode pen and touch events both come from interface
  	 * 0, whose HID descriptor has an application usage of 0xFF0D
  	 * (i.e., WACOM_VENDORDEFINED_PEN). We route pen packets back
  	 * out through the HID_GENERIC device created for interface 1,
70caee0a3   Benjamin Tissoires   HID: wacom: remov...
2344
  	 * so rewrite this one to be of type WACOM_DEVICETYPE_TOUCH.
42f4f2727   Ping Cheng   HID: wacom: move ...
2345
2346
  	 */
  	if (features->type == BAMBOO_PAD)
70caee0a3   Benjamin Tissoires   HID: wacom: remov...
2347
  		features->device_type = WACOM_DEVICETYPE_TOUCH;
42f4f2727   Ping Cheng   HID: wacom: move ...
2348

72b236d60   Aaron Skomra   HID: wacom: Add s...
2349
2350
  	if (features->type == REMOTE)
  		features->device_type = WACOM_DEVICETYPE_PAD;
42f4f2727   Ping Cheng   HID: wacom: move ...
2351

e5bc8eb1b   Jason Gerecke   HID: wacom: Add W...
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
  	switch (features->type) {
  	case PL:
  	case DTU:
  	case DTUS:
  	case DTUSX:
  	case WACOM_21UX2:
  	case WACOM_22HD:
  	case DTK:
  	case WACOM_24HD:
  	case WACOM_27QHD:
  	case CINTIQ_HYBRID:
  	case CINTIQ_COMPANION_2:
  	case CINTIQ:
  	case WACOM_BEE:
  	case WACOM_13HD:
  	case WACOM_24HDT:
  	case WACOM_27QHDT:
  	case TABLETPC:
  	case TABLETPCE:
  	case TABLETPC2FG:
  	case MTSCREEN:
  	case MTTPC:
  	case MTTPC_B:
  		features->device_type |= WACOM_DEVICETYPE_DIRECT;
  		break;
  	}
42f4f2727   Ping Cheng   HID: wacom: move ...
2378
2379
  	if (wacom->hdev->bus == BUS_BLUETOOTH)
  		features->quirks |= WACOM_QUIRK_BATTERY;
73149ab84   Chris Bagwell   Input: wacom - 3r...
2380
  	/* quirk for bamboo touch with 2 low res touches */
be853fd1c   Jason Gerecke   HID: wacom: Apply...
2381
  	if ((features->type == BAMBOO_PT || features->type == BAMBOO_TOUCH) &&
73149ab84   Chris Bagwell   Input: wacom - 3r...
2382
  	    features->pktlen == WACOM_PKGLEN_BBTOUCH) {
f4ccbef28   Henrik Rydberg   Input: wacom - ad...
2383
2384
2385
2386
  		features->x_max <<= 5;
  		features->y_max <<= 5;
  		features->x_fuzz <<= 5;
  		features->y_fuzz <<= 5;
f4ccbef28   Henrik Rydberg   Input: wacom - ad...
2387
  		features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
cb734c036   Henrik Rydberg   Input: wacom - ad...
2388
  	}
d3825d51c   Chris Bagwell   Input: wacom - wi...
2389
2390
  
  	if (features->type == WIRELESS) {
ccad85cc1   Jason Gerecke   HID: wacom: Repla...
2391
  		if (features->device_type == WACOM_DEVICETYPE_WL_MONITOR) {
ac8d10101   Benjamin Tissoires   Input: wacom - en...
2392
2393
  			features->quirks |= WACOM_QUIRK_BATTERY;
  		}
d3825d51c   Chris Bagwell   Input: wacom - wi...
2394
  	}
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
2395
2396
2397
  
  	if (features->type == REMOTE)
  		features->device_type |= WACOM_DEVICETYPE_WL_MONITOR;
bc73dd39e   Henrik Rydberg   Input: wacom - co...
2398
  }
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2399
  int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
8c0e0a4fa   Ping Cheng   Input: wacom - pr...
2400
2401
2402
  				   struct wacom_wac *wacom_wac)
  {
  	struct wacom_features *features = &wacom_wac->features;
8c0e0a4fa   Ping Cheng   Input: wacom - pr...
2403
2404
  
  	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2405
2406
  	if (!(features->device_type & WACOM_DEVICETYPE_PEN))
  		return -ENODEV;
e5bc8eb1b   Jason Gerecke   HID: wacom: Add W...
2407
2408
2409
2410
  	if (features->device_type & WACOM_DEVICETYPE_DIRECT)
  		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
  	else
  		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
7704ac937   Benjamin Tissoires   HID: wacom: imple...
2411
2412
2413
  	if (features->type == HID_GENERIC)
  		/* setup has already been done */
  		return 0;
8c0e0a4fa   Ping Cheng   Input: wacom - pr...
2414
  	__set_bit(BTN_TOUCH, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2415
  	__set_bit(ABS_MISC, input_dev->absbit);
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
  	input_set_abs_params(input_dev, ABS_X, features->x_min,
  			     features->x_max, features->x_fuzz, 0);
  	input_set_abs_params(input_dev, ABS_Y, features->y_min,
  			     features->y_max, features->y_fuzz, 0);
  	input_set_abs_params(input_dev, ABS_PRESSURE, 0,
  		features->pressure_max, features->pressure_fuzz, 0);
  
  	/* penabled devices have fixed resolution for each model */
  	input_abs_set_res(input_dev, ABS_X, features->x_resolution);
  	input_abs_set_res(input_dev, ABS_Y, features->y_resolution);
497ab1f29   Ping Cheng   Input: wacom - ad...
2426
  	switch (features->type) {
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2427
2428
  	case GRAPHIRE_BT:
  		__clear_bit(ABS_MISC, input_dev->absbit);
a2f71c6c8   Ping Cheng   HID: wacom: conso...
2429
2430
2431
  
  	case WACOM_MO:
  	case WACOM_G4:
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2432
2433
  		input_set_abs_params(input_dev, ABS_DISTANCE, 0,
  					      features->distance_max,
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2434
  					      features->distance_fuzz, 0);
a2f71c6c8   Ping Cheng   HID: wacom: conso...
2435
  		/* fall through */
803296b67   Jason Gerecke   Input: wacom - ad...
2436

a2f71c6c8   Ping Cheng   HID: wacom: conso...
2437
  	case GRAPHIRE:
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2438
  		input_set_capability(input_dev, EV_REL, REL_WHEEL);
803296b67   Jason Gerecke   Input: wacom - ad...
2439

387142bb8   Benjamin Tissoires   Input: wacom - ha...
2440
2441
2442
2443
2444
2445
2446
2447
2448
  		__set_bit(BTN_LEFT, input_dev->keybit);
  		__set_bit(BTN_RIGHT, input_dev->keybit);
  		__set_bit(BTN_MIDDLE, input_dev->keybit);
  
  		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
  		__set_bit(BTN_TOOL_PEN, input_dev->keybit);
  		__set_bit(BTN_TOOL_MOUSE, input_dev->keybit);
  		__set_bit(BTN_STYLUS, input_dev->keybit);
  		__set_bit(BTN_STYLUS2, input_dev->keybit);
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2449
  		break;
c73a1afbe   Ping Cheng   Input: wacom - ad...
2450

500d4160a   Ping Cheng   HID: wacom: add s...
2451
  	case WACOM_27QHD:
803296b67   Jason Gerecke   Input: wacom - ad...
2452
  	case WACOM_24HD:
a112e9fdd   Ping Cheng   Input: wacom - ad...
2453
  	case DTK:
d838c644f   Ping Cheng   Input: wacom - ad...
2454
  	case WACOM_22HD:
3a4b4aaa5   Ping Cheng   Input: wacom - ad...
2455
  	case WACOM_21UX2:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2456
  	case WACOM_BEE:
6521d0bf9   Ping Cheng   Input: wacom - sp...
2457
  	case CINTIQ:
56218563a   Ping Cheng   Input: wacom - ad...
2458
  	case WACOM_13HD:
a2f71c6c8   Ping Cheng   HID: wacom: conso...
2459
  	case CINTIQ_HYBRID:
f7acb55cf   Jason Gerecke   HID: wacom: Add s...
2460
  	case CINTIQ_COMPANION_2:
56218563a   Ping Cheng   Input: wacom - ad...
2461
  		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
26fe41245   Jason Gerecke   HID: wacom: Add a...
2462
  		input_abs_set_res(input_dev, ABS_Z, 287);
56218563a   Ping Cheng   Input: wacom - ad...
2463
2464
  		wacom_setup_cintiq(wacom_wac);
  		break;
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2465
2466
  	case INTUOS3:
  	case INTUOS3L:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2467
  	case INTUOS3S:
a2f71c6c8   Ping Cheng   HID: wacom: conso...
2468
2469
2470
2471
  	case INTUOS4:
  	case INTUOS4WL:
  	case INTUOS4L:
  	case INTUOS4S:
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2472
  		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
26fe41245   Jason Gerecke   HID: wacom: Add a...
2473
  		input_abs_set_res(input_dev, ABS_Z, 287);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2474
2475
2476
  		/* fall through */
  
  	case INTUOS:
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2477
  		wacom_setup_intuos(wacom_wac);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2478
  		break;
9fee61950   Jason Gerecke   Input: wacom - ad...
2479
2480
  	case INTUOS5:
  	case INTUOS5L:
9a35c411f   Ping Cheng   Input: wacom - ad...
2481
2482
  	case INTUOSPM:
  	case INTUOSPL:
ae584ca47   Jason Gerecke   Input: wacom - ad...
2483
  	case INTUOS5S:
9a35c411f   Ping Cheng   Input: wacom - ad...
2484
  	case INTUOSPS:
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2485
2486
  		input_set_abs_params(input_dev, ABS_DISTANCE, 0,
  				      features->distance_max,
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2487
  				      features->distance_fuzz, 0);
ae584ca47   Jason Gerecke   Input: wacom - ad...
2488

2636a3f2d   Jason Gerecke   HID: wacom: Split...
2489
2490
  		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
  		input_abs_set_res(input_dev, ABS_Z, 287);
ae584ca47   Jason Gerecke   Input: wacom - ad...
2491

2636a3f2d   Jason Gerecke   HID: wacom: Split...
2492
  		wacom_setup_intuos(wacom_wac);
ae584ca47   Jason Gerecke   Input: wacom - ad...
2493
  		break;
b1e4279e4   Jason Gerecke   Input: wacom - ad...
2494
  	case WACOM_24HDT:
500d4160a   Ping Cheng   HID: wacom: add s...
2495
  	case WACOM_27QHDT:
1963518b9   Ping Cheng   Input: wacom - ad...
2496
  	case MTSCREEN:
6afdc289c   Ping Cheng   Input: wacom - ad...
2497
  	case MTTPC:
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
2498
  	case MTTPC_B:
6795a524f   Ping Cheng   Input: wacom - TP...
2499
  	case TABLETPC2FG:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2500
  	case TABLETPC:
ac173837c   Ping Cheng   Input: wacom - ad...
2501
  	case TABLETPCE:
a43c7c538   Ping Cheng   Input: wacom - su...
2502
  		__clear_bit(ABS_MISC, input_dev->absbit);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2503
  		/* fall through */
497ab1f29   Ping Cheng   Input: wacom - ad...
2504
  	case DTUS:
fff00bf8c   Ping Cheng   HID: wacom: Add s...
2505
  	case DTUSX:
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2506
  	case PL:
c8f2edc56   Ping Cheng   Input: wacom - ad...
2507
  	case DTU:
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2508
  		__set_bit(BTN_TOOL_PEN, input_dev->keybit);
3512069ee   Jason Gerecke   Input: wacom - ad...
2509
  		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2510
2511
  		__set_bit(BTN_STYLUS, input_dev->keybit);
  		__set_bit(BTN_STYLUS2, input_dev->keybit);
3512069ee   Jason Gerecke   Input: wacom - ad...
2512
2513
2514
  		break;
  
  	case PTU:
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2515
  		__set_bit(BTN_STYLUS2, input_dev->keybit);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2516
2517
2518
  		/* fall through */
  
  	case PENPARTNER:
1fab84aa6   Jason Gerecke   Input: wacom - ad...
2519
  		__set_bit(BTN_TOOL_PEN, input_dev->keybit);
8da23fc11   Dmitry Torokhov   Input: wacom - ge...
2520
  		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1fab84aa6   Jason Gerecke   Input: wacom - ad...
2521
  		__set_bit(BTN_STYLUS, input_dev->keybit);
73a97f4f6   Dmitry Torokhov   Input: wacom - fi...
2522
  		break;
cb734c036   Henrik Rydberg   Input: wacom - ad...
2523

b5fd2a3e9   Ping Cheng   Input: wacom - ad...
2524
  	case INTUOSHT:
cb734c036   Henrik Rydberg   Input: wacom - ad...
2525
  	case BAMBOO_PT:
3b164a00a   Ping Cheng   HID: wacom: Clean...
2526
  	case BAMBOO_PEN:
eda01dab5   Ping Cheng   HID: wacom: Add f...
2527
  	case INTUOSHT2:
eda01dab5   Ping Cheng   HID: wacom: Add f...
2528
2529
2530
2531
2532
2533
2534
2535
2536
  		if (features->type == INTUOSHT2) {
  			wacom_setup_basic_pro_pen(wacom_wac);
  		} else {
  			__clear_bit(ABS_MISC, input_dev->absbit);
  			__set_bit(BTN_TOOL_PEN, input_dev->keybit);
  			__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
  			__set_bit(BTN_STYLUS, input_dev->keybit);
  			__set_bit(BTN_STYLUS2, input_dev->keybit);
  			input_set_abs_params(input_dev, ABS_DISTANCE, 0,
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2537
  				      features->distance_max,
bef7e2000   Jason Gerecke   HID: wacom: Add f...
2538
  				      features->distance_fuzz, 0);
eda01dab5   Ping Cheng   HID: wacom: Add f...
2539
  		}
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2540
2541
2542
2543
2544
2545
2546
  		break;
  	case BAMBOO_PAD:
  		__clear_bit(ABS_MISC, input_dev->absbit);
  		break;
  	}
  	return 0;
  }
02295e68c   Ping Cheng   Input: wacom - us...
2547

2636a3f2d   Jason Gerecke   HID: wacom: Split...
2548
2549
2550
2551
  int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
  					 struct wacom_wac *wacom_wac)
  {
  	struct wacom_features *features = &wacom_wac->features;
30ebc1aea   Ping Cheng   HID: wacom - Bamb...
2552

2636a3f2d   Jason Gerecke   HID: wacom: Split...
2553
2554
2555
2556
  	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  
  	if (!(features->device_type & WACOM_DEVICETYPE_TOUCH))
  		return -ENODEV;
e5bc8eb1b   Jason Gerecke   HID: wacom: Add W...
2557
2558
2559
2560
  	if (features->device_type & WACOM_DEVICETYPE_DIRECT)
  		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
  	else
  		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
  	if (features->type == HID_GENERIC)
  		/* setup has already been done */
  		return 0;
  
  	__set_bit(BTN_TOUCH, input_dev->keybit);
  
  	if (features->touch_max == 1) {
  		input_set_abs_params(input_dev, ABS_X, 0,
  			features->x_max, features->x_fuzz, 0);
  		input_set_abs_params(input_dev, ABS_Y, 0,
  			features->y_max, features->y_fuzz, 0);
  		input_abs_set_res(input_dev, ABS_X,
  				  features->x_resolution);
  		input_abs_set_res(input_dev, ABS_Y,
  				  features->y_resolution);
  	}
  	else if (features->touch_max > 1) {
  		input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,
  			features->x_max, features->x_fuzz, 0);
  		input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,
  			features->y_max, features->y_fuzz, 0);
  		input_abs_set_res(input_dev, ABS_MT_POSITION_X,
  				  features->x_resolution);
  		input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
  				  features->y_resolution);
  	}
  
  	switch (features->type) {
  	case INTUOS5:
  	case INTUOS5L:
  	case INTUOSPM:
  	case INTUOSPL:
  	case INTUOS5S:
  	case INTUOSPS:
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
  		input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
  		input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, features->y_max, 0, 0);
  		input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
  		break;
  
  	case WACOM_24HDT:
  		input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);
  		input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);
  		input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);
  		input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);
  		/* fall through */
  
  	case WACOM_27QHDT:
  	case MTSCREEN:
  	case MTTPC:
  	case MTTPC_B:
  	case TABLETPC2FG:
  		input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT);
  		/*fall through */
  
  	case TABLETPC:
  	case TABLETPCE:
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2617
2618
2619
  		break;
  
  	case INTUOSHT:
eda01dab5   Ping Cheng   HID: wacom: Add f...
2620
  	case INTUOSHT2:
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2621
2622
2623
2624
2625
  		input_dev->evbit[0] |= BIT_MASK(EV_SW);
  		__set_bit(SW_MUTE_DEVICE, input_dev->swbit);
  		/* fall through */
  
  	case BAMBOO_PT:
3b164a00a   Ping Cheng   HID: wacom: Clean...
2626
  	case BAMBOO_TOUCH:
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2627
2628
2629
2630
2631
2632
2633
  		if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
  			input_set_abs_params(input_dev,
  				     ABS_MT_TOUCH_MAJOR,
  				     0, features->x_max, 0, 0);
  			input_set_abs_params(input_dev,
  				     ABS_MT_TOUCH_MINOR,
  				     0, features->y_max, 0, 0);
cb734c036   Henrik Rydberg   Input: wacom - ad...
2634
  		}
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2635
  		input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
cb734c036   Henrik Rydberg   Input: wacom - ad...
2636
  		break;
2636a3f2d   Jason Gerecke   HID: wacom: Split...
2637

8c97a7654   Benjamin Tissoires   HID: wacom: add f...
2638
  	case BAMBOO_PAD:
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
2639
2640
2641
2642
2643
  		input_mt_init_slots(input_dev, features->touch_max,
  				    INPUT_MT_POINTER);
  		__set_bit(BTN_LEFT, input_dev->keybit);
  		__set_bit(BTN_RIGHT, input_dev->keybit);
  		break;
3bea733ab   Ping Cheng   USB: wacom tablet...
2644
  	}
1963518b9   Ping Cheng   Input: wacom - ad...
2645
  	return 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
2646
  }
5397df15f   Jiri Kosina   HID: wacom: wacom...
2647
  static void wacom_setup_numbered_buttons(struct input_dev *input_dev,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
  				int button_count)
  {
  	int i;
  
  	for (i = 0; i < button_count && i < 10; i++)
  		__set_bit(BTN_0 + i, input_dev->keybit);
  	for (i = 10; i < button_count && i < 16; i++)
  		__set_bit(BTN_A + (i-10), input_dev->keybit);
  	for (i = 16; i < button_count && i < 18; i++)
  		__set_bit(BTN_BASE + (i-16), input_dev->keybit);
  }
6a06281e2   Benjamin Tissoires   HID: wacom: leds:...
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
  static void wacom_24hd_update_leds(struct wacom *wacom, int mask, int group)
  {
  	struct wacom_led *led;
  	int i;
  	bool updated = false;
  
  	/*
  	 * 24HD has LED group 1 to the left and LED group 0 to the right.
  	 * So group 0 matches the second half of the buttons and thus the mask
  	 * needs to be shifted.
  	 */
  	if (group == 0)
  		mask >>= 8;
  
  	for (i = 0; i < 3; i++) {
  		led = wacom_led_find(wacom, group, i);
  		if (!led) {
  			hid_err(wacom->hdev, "can't find LED %d in group %d
  ",
  				i, group);
  			continue;
  		}
  		if (!updated && mask & BIT(i)) {
  			led->held = true;
  			led_trigger_event(&led->trigger, LED_FULL);
  		} else {
  			led->held = false;
  		}
  	}
  }
34736aa96   Benjamin Tissoires   HID: wacom: leds:...
2689
2690
2691
2692
  static bool wacom_is_led_toggled(struct wacom *wacom, int button_count,
  				 int mask, int group)
  {
  	int button_per_group;
5a0fe8abd   Benjamin Tissoires   HID: wacom: leds:...
2693
  	/*
6a06281e2   Benjamin Tissoires   HID: wacom: leds:...
2694
  	 * 21UX2 has LED group 1 to the left and LED group 0
5a0fe8abd   Benjamin Tissoires   HID: wacom: leds:...
2695
2696
2697
  	 * to the right. We need to reverse the group to match this
  	 * historical behavior.
  	 */
6a06281e2   Benjamin Tissoires   HID: wacom: leds:...
2698
  	if (wacom->wacom_wac.features.type == WACOM_21UX2)
5a0fe8abd   Benjamin Tissoires   HID: wacom: leds:...
2699
  		group = 1 - group;
34736aa96   Benjamin Tissoires   HID: wacom: leds:...
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
  	button_per_group = button_count/wacom->led.count;
  
  	return mask & (1 << (group * button_per_group));
  }
  
  static void wacom_update_led(struct wacom *wacom, int button_count, int mask,
  			     int group)
  {
  	struct wacom_led *led, *next_led;
  	int cur;
  	bool pressed;
6a06281e2   Benjamin Tissoires   HID: wacom: leds:...
2711
2712
  	if (wacom->wacom_wac.features.type == WACOM_24HD)
  		return wacom_24hd_update_leds(wacom, mask, group);
34736aa96   Benjamin Tissoires   HID: wacom: leds:...
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
  	pressed = wacom_is_led_toggled(wacom, button_count, mask, group);
  	cur = wacom->led.groups[group].select;
  
  	led = wacom_led_find(wacom, group, cur);
  	if (!led) {
  		hid_err(wacom->hdev, "can't find current LED %d in group %d
  ",
  			cur, group);
  		return;
  	}
  
  	if (!pressed) {
  		led->held = false;
  		return;
  	}
  
  	if (led->held && pressed)
  		return;
  
  	next_led = wacom_led_next(wacom, led);
  	if (!next_led) {
  		hid_err(wacom->hdev, "can't find next LED in group %d
  ",
  			group);
  		return;
  	}
  	if (next_led == led)
  		return;
  
  	next_led->held = true;
  	led_trigger_event(&next_led->trigger,
  			  wacom_leds_brightness_get(next_led));
  }
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
2746
2747
2748
  static void wacom_report_numbered_buttons(struct input_dev *input_dev,
  				int button_count, int mask)
  {
34736aa96   Benjamin Tissoires   HID: wacom: leds:...
2749
  	struct wacom *wacom = input_get_drvdata(input_dev);
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
2750
  	int i;
34736aa96   Benjamin Tissoires   HID: wacom: leds:...
2751
2752
  	for (i = 0; i < wacom->led.count; i++)
  		wacom_update_led(wacom,  button_count, mask, i);
c7f0522a1   Jason Gerecke   HID: wacom: Slim ...
2753
2754
2755
2756
2757
2758
2759
  	for (i = 0; i < button_count && i < 10; i++)
  		input_report_key(input_dev, BTN_0 + i, mask & (1 << i));
  	for (i = 10; i < button_count && i < 16; i++)
  		input_report_key(input_dev, BTN_A + (i-10), mask & (1 << i));
  	for (i = 16; i < button_count && i < 18; i++)
  		input_report_key(input_dev, BTN_BASE + (i-16), mask & (1 << i));
  }
d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2760
2761
2762
2763
  int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
  				   struct wacom_wac *wacom_wac)
  {
  	struct wacom_features *features = &wacom_wac->features;
862cf5535   Jason Gerecke   HID: wacom: Intro...
2764
2765
  	if (!(features->device_type & WACOM_DEVICETYPE_PAD))
  		return -ENODEV;
7c35dc3cd   Benjamin Tissoires   HID: wacom: EKR: ...
2766
2767
  	if (features->type == REMOTE && input_dev == wacom_wac->pad_input)
  		return -ENODEV;
d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2768
2769
2770
2771
2772
2773
2774
2775
  	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
  
  	/* kept for making legacy xf86-input-wacom working with the wheels */
  	__set_bit(ABS_MISC, input_dev->absbit);
  
  	/* kept for making legacy xf86-input-wacom accepting the pad */
  	input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);
  	input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);
12969e3bd   Benjamin Tissoires   HID: wacom: make ...
2776
2777
  	/* kept for making udev and libwacom accepting the pad */
  	__set_bit(BTN_STYLUS, input_dev->keybit);
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
2778
  	wacom_setup_numbered_buttons(input_dev, features->numbered_buttons);
d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2779
  	switch (features->type) {
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
2780
2781
  
  	case CINTIQ_HYBRID:
f7acb55cf   Jason Gerecke   HID: wacom: Add s...
2782
  	case CINTIQ_COMPANION_2:
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
2783
2784
  	case DTK:
  	case DTUS:
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2785
  	case GRAPHIRE_BT:
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2786
  		break;
3813810c7   Benjamin Tissoires   Input: wacom - sp...
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
  	case WACOM_MO:
  		__set_bit(BTN_BACK, input_dev->keybit);
  		__set_bit(BTN_LEFT, input_dev->keybit);
  		__set_bit(BTN_FORWARD, input_dev->keybit);
  		__set_bit(BTN_RIGHT, input_dev->keybit);
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
  		break;
  
  	case WACOM_G4:
  		__set_bit(BTN_BACK, input_dev->keybit);
3813810c7   Benjamin Tissoires   Input: wacom - sp...
2797
  		__set_bit(BTN_FORWARD, input_dev->keybit);
3813810c7   Benjamin Tissoires   Input: wacom - sp...
2798
2799
  		input_set_capability(input_dev, EV_REL, REL_WHEEL);
  		break;
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2800
  	case WACOM_24HD:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2801
2802
2803
2804
2805
2806
2807
  		__set_bit(KEY_PROG1, input_dev->keybit);
  		__set_bit(KEY_PROG2, input_dev->keybit);
  		__set_bit(KEY_PROG3, input_dev->keybit);
  
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
  		input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
  		break;
500d4160a   Ping Cheng   HID: wacom: add s...
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
  	case WACOM_27QHD:
  		__set_bit(KEY_PROG1, input_dev->keybit);
  		__set_bit(KEY_PROG2, input_dev->keybit);
  		__set_bit(KEY_PROG3, input_dev->keybit);
  		input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0);
  		input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */
  		input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0);
  		input_abs_set_res(input_dev, ABS_Y, 1024);
  		input_set_abs_params(input_dev, ABS_Z, -2048, 2048, 0, 0);
  		input_abs_set_res(input_dev, ABS_Z, 1024);
  		__set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);
  		break;
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2820
2821
2822
2823
2824
2825
2826
  	case WACOM_22HD:
  		__set_bit(KEY_PROG1, input_dev->keybit);
  		__set_bit(KEY_PROG2, input_dev->keybit);
  		__set_bit(KEY_PROG3, input_dev->keybit);
  		/* fall through */
  
  	case WACOM_21UX2:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2827
  	case WACOM_BEE:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2828
  	case CINTIQ:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2829
2830
2831
2832
2833
  		input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
  		input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
  		break;
  
  	case WACOM_13HD:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2834
2835
2836
2837
2838
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
  		break;
  
  	case INTUOS3:
  	case INTUOS3L:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2839
2840
2841
2842
  		input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
  		/* fall through */
  
  	case INTUOS3S:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2843
2844
  		input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
  		break;
36d3c510e   Jason Gerecke   Input: wacom - su...
2845

10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2846
2847
2848
2849
  	case INTUOS5:
  	case INTUOS5L:
  	case INTUOSPM:
  	case INTUOSPL:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2850
2851
  	case INTUOS5S:
  	case INTUOSPS:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2852
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
36d3c510e   Jason Gerecke   Input: wacom - su...
2853
  		break;
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2854

81af7e61a   Benjamin Tissoires   Input: wacom - ha...
2855
2856
2857
2858
2859
2860
2861
2862
  	case INTUOS4WL:
  		/*
  		 * For Bluetooth devices, the udev rule does not work correctly
  		 * for pads unless we add a stylus capability, which forces
  		 * ID_INPUT_TABLET to be set.
  		 */
  		__set_bit(BTN_STYLUS, input_dev->keybit);
  		/* fall through */
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2863
2864
  	case INTUOS4:
  	case INTUOS4L:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2865
  	case INTUOS4S:
10059cdc0   Benjamin Tissoires   Input: wacom - sp...
2866
2867
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
  		break;
3116871f4   Benjamin Tissoires   Input: wacom - sp...
2868
2869
  	case INTUOSHT:
  	case BAMBOO_PT:
3b164a00a   Ping Cheng   HID: wacom: Clean...
2870
  	case BAMBOO_TOUCH:
eda01dab5   Ping Cheng   HID: wacom: Add f...
2871
  	case INTUOSHT2:
3116871f4   Benjamin Tissoires   Input: wacom - sp...
2872
2873
2874
2875
2876
2877
2878
2879
  		__clear_bit(ABS_MISC, input_dev->absbit);
  
  		__set_bit(BTN_LEFT, input_dev->keybit);
  		__set_bit(BTN_FORWARD, input_dev->keybit);
  		__set_bit(BTN_BACK, input_dev->keybit);
  		__set_bit(BTN_RIGHT, input_dev->keybit);
  
  		break;
72b236d60   Aaron Skomra   HID: wacom: Add s...
2880
2881
2882
2883
  	case REMOTE:
  		input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
  		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
  		break;
d2d13f18a   Benjamin Tissoires   Input: wacom - cr...
2884
2885
  	default:
  		/* no pad supported */
b3c8e93f9   Ping Cheng   HID: wacom - retu...
2886
  		return -ENODEV;
3bea733ab   Ping Cheng   USB: wacom tablet...
2887
  	}
1963518b9   Ping Cheng   Input: wacom - ad...
2888
  	return 0;
3bea733ab   Ping Cheng   USB: wacom tablet...
2889
  }
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2890
  static const struct wacom_features wacom_features_0x00 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2891
2892
  	{ "Wacom Penpartner", 5040, 3780, 255, 0,
  	  PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2893
  static const struct wacom_features wacom_features_0x10 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2894
2895
  	{ "Wacom Graphire", 10206, 7422, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
387142bb8   Benjamin Tissoires   Input: wacom - ha...
2896
2897
  static const struct wacom_features wacom_features_0x81 =
  	{ "Wacom Graphire BT", 16704, 12064, 511, 32,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
2898
  	  GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES, 2 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2899
  static const struct wacom_features wacom_features_0x11 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2900
2901
  	{ "Wacom Graphire2 4x5", 10206, 7422, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2902
  static const struct wacom_features wacom_features_0x12 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2903
2904
  	{ "Wacom Graphire2 5x7", 13918, 10206, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2905
  static const struct wacom_features wacom_features_0x13 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2906
2907
  	{ "Wacom Graphire3", 10208, 7424, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2908
  static const struct wacom_features wacom_features_0x14 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2909
2910
  	{ "Wacom Graphire3 6x8", 16704, 12064, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2911
  static const struct wacom_features wacom_features_0x15 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2912
2913
  	{ "Wacom Graphire4 4x5", 10208, 7424, 511, 63,
  	  WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2914
  static const struct wacom_features wacom_features_0x16 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2915
2916
  	{ "Wacom Graphire4 6x8", 16704, 12064, 511, 63,
  	  WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2917
  static const struct wacom_features wacom_features_0x17 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2918
2919
  	{ "Wacom BambooFun 4x5", 14760, 9225, 511, 63,
  	  WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2920
  static const struct wacom_features wacom_features_0x18 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2921
2922
  	{ "Wacom BambooFun 6x8", 21648, 13530, 511, 63,
  	  WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2923
  static const struct wacom_features wacom_features_0x19 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2924
2925
  	{ "Wacom Bamboo1 Medium", 16704, 12064, 511, 63,
  	  GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2926
  static const struct wacom_features wacom_features_0x60 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2927
2928
  	{ "Wacom Volito", 5104, 3712, 511, 63,
  	  GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2929
  static const struct wacom_features wacom_features_0x61 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2930
2931
  	{ "Wacom PenStation2", 3250, 2320, 255, 63,
  	  GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2932
  static const struct wacom_features wacom_features_0x62 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2933
2934
  	{ "Wacom Volito2 4x5", 5104, 3712, 511, 63,
  	  GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2935
  static const struct wacom_features wacom_features_0x63 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2936
2937
  	{ "Wacom Volito2 2x3", 3248, 2320, 511, 63,
  	  GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2938
  static const struct wacom_features wacom_features_0x64 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2939
2940
  	{ "Wacom PenPartner2", 3250, 2320, 511, 63,
  	  GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2941
  static const struct wacom_features wacom_features_0x65 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2942
2943
  	{ "Wacom Bamboo", 14760, 9225, 511, 63,
  	  WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2944
  static const struct wacom_features wacom_features_0x69 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2945
2946
  	{ "Wacom Bamboo1", 5104, 3712, 511, 63,
  	  GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
11d0cf885   Ping Cheng   Input: wacom - ad...
2947
  static const struct wacom_features wacom_features_0x6A =
80befa938   Benjamin Tissoires   Input: wacom - re...
2948
2949
  	{ "Wacom Bamboo1 4x6", 14760, 9225, 1023, 63,
  	  GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
11d0cf885   Ping Cheng   Input: wacom - ad...
2950
  static const struct wacom_features wacom_features_0x6B =
80befa938   Benjamin Tissoires   Input: wacom - re...
2951
2952
  	{ "Wacom Bamboo1 5x8", 21648, 13530, 1023, 63,
  	  GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2953
  static const struct wacom_features wacom_features_0x20 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2954
2955
  	{ "Wacom Intuos 4x5", 12700, 10600, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2956
  static const struct wacom_features wacom_features_0x21 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2957
2958
  	{ "Wacom Intuos 6x8", 20320, 16240, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2959
  static const struct wacom_features wacom_features_0x22 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2960
2961
  	{ "Wacom Intuos 9x12", 30480, 24060, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2962
  static const struct wacom_features wacom_features_0x23 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2963
2964
  	{ "Wacom Intuos 12x12", 30480, 31680, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2965
  static const struct wacom_features wacom_features_0x24 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2966
2967
  	{ "Wacom Intuos 12x18", 45720, 31680, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2968
  static const struct wacom_features wacom_features_0x30 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2969
2970
  	{ "Wacom PL400", 5408, 4056, 255, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2971
  static const struct wacom_features wacom_features_0x31 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2972
2973
  	{ "Wacom PL500", 6144, 4608, 255, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2974
  static const struct wacom_features wacom_features_0x32 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2975
2976
  	{ "Wacom PL600", 6126, 4604, 255, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2977
  static const struct wacom_features wacom_features_0x33 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2978
2979
  	{ "Wacom PL600SX", 6260, 5016, 255, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2980
  static const struct wacom_features wacom_features_0x34 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2981
2982
  	{ "Wacom PL550", 6144, 4608, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2983
  static const struct wacom_features wacom_features_0x35 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2984
2985
  	{ "Wacom PL800", 7220, 5780, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2986
  static const struct wacom_features wacom_features_0x37 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2987
2988
  	{ "Wacom PL700", 6758, 5406, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2989
  static const struct wacom_features wacom_features_0x38 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2990
2991
  	{ "Wacom PL510", 6282, 4762, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2992
  static const struct wacom_features wacom_features_0x39 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2993
2994
  	{ "Wacom DTU710", 34080, 27660, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2995
  static const struct wacom_features wacom_features_0xC4 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2996
2997
  	{ "Wacom DTF521", 6282, 4762, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
2998
  static const struct wacom_features wacom_features_0xC0 =
80befa938   Benjamin Tissoires   Input: wacom - re...
2999
3000
  	{ "Wacom DTF720", 6858, 5506, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3001
  static const struct wacom_features wacom_features_0xC2 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3002
3003
  	{ "Wacom DTF720a", 6858, 5506, 511, 0,
  	  PL, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3004
  static const struct wacom_features wacom_features_0x03 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3005
3006
  	{ "Wacom Cintiq Partner", 20480, 15360, 511, 0,
  	  PTU, WACOM_PL_RES, WACOM_PL_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3007
  static const struct wacom_features wacom_features_0x41 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3008
3009
  	{ "Wacom Intuos2 4x5", 12700, 10600, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3010
  static const struct wacom_features wacom_features_0x42 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3011
3012
  	{ "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3013
  static const struct wacom_features wacom_features_0x43 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3014
3015
  	{ "Wacom Intuos2 9x12", 30480, 24060, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3016
  static const struct wacom_features wacom_features_0x44 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3017
3018
  	{ "Wacom Intuos2 12x12", 30480, 31680, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3019
  static const struct wacom_features wacom_features_0x45 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3020
3021
  	{ "Wacom Intuos2 12x18", 45720, 31680, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3022
  static const struct wacom_features wacom_features_0xB0 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3023
  	{ "Wacom Intuos3 4x5", 25400, 20320, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3024
  	  INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3025
  static const struct wacom_features wacom_features_0xB1 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3026
  	{ "Wacom Intuos3 6x8", 40640, 30480, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3027
  	  INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3028
  static const struct wacom_features wacom_features_0xB2 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3029
  	{ "Wacom Intuos3 9x12", 60960, 45720, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3030
  	  INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3031
  static const struct wacom_features wacom_features_0xB3 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3032
  	{ "Wacom Intuos3 12x12", 60960, 60960, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3033
  	  INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3034
  static const struct wacom_features wacom_features_0xB4 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3035
  	{ "Wacom Intuos3 12x19", 97536, 60960, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3036
  	  INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3037
  static const struct wacom_features wacom_features_0xB5 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3038
  	{ "Wacom Intuos3 6x11", 54204, 31750, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3039
  	  INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3040
  static const struct wacom_features wacom_features_0xB7 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3041
  	{ "Wacom Intuos3 4x6", 31496, 19685, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3042
  	  INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3043
  static const struct wacom_features wacom_features_0xB8 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3044
  	{ "Wacom Intuos4 4x6", 31496, 19685, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3045
  	  INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3046
  static const struct wacom_features wacom_features_0xB9 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3047
  	{ "Wacom Intuos4 6x9", 44704, 27940, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3048
  	  INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3049
  static const struct wacom_features wacom_features_0xBA =
80befa938   Benjamin Tissoires   Input: wacom - re...
3050
  	{ "Wacom Intuos4 8x13", 65024, 40640, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3051
  	  INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3052
  static const struct wacom_features wacom_features_0xBB =
80befa938   Benjamin Tissoires   Input: wacom - re...
3053
  	{ "Wacom Intuos4 12x19", 97536, 60960, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3054
  	  INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
3a4b4aaa5   Ping Cheng   Input: wacom - ad...
3055
  static const struct wacom_features wacom_features_0xBC =
80befa938   Benjamin Tissoires   Input: wacom - re...
3056
  	{ "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3057
  	  INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
3058
3059
  static const struct wacom_features wacom_features_0xBD =
  	{ "Wacom Intuos4 WL", 40640, 25400, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3060
  	  INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
9fee61950   Jason Gerecke   Input: wacom - ad...
3061
  static const struct wacom_features wacom_features_0x26 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3062
  	{ "Wacom Intuos5 touch S", 31496, 19685, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3063
  	  INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16 };
9fee61950   Jason Gerecke   Input: wacom - ad...
3064
  static const struct wacom_features wacom_features_0x27 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3065
  	{ "Wacom Intuos5 touch M", 44704, 27940, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3066
  	  INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 };
9fee61950   Jason Gerecke   Input: wacom - ad...
3067
  static const struct wacom_features wacom_features_0x28 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3068
  	{ "Wacom Intuos5 touch L", 65024, 40640, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3069
  	  INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 };
9fee61950   Jason Gerecke   Input: wacom - ad...
3070
  static const struct wacom_features wacom_features_0x29 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3071
  	{ "Wacom Intuos5 S", 31496, 19685, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3072
  	  INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };
9fee61950   Jason Gerecke   Input: wacom - ad...
3073
  static const struct wacom_features wacom_features_0x2A =
80befa938   Benjamin Tissoires   Input: wacom - re...
3074
  	{ "Wacom Intuos5 M", 44704, 27940, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3075
  	  INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };
9a35c411f   Ping Cheng   Input: wacom - ad...
3076
  static const struct wacom_features wacom_features_0x314 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3077
  	{ "Wacom Intuos Pro S", 31496, 19685, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3078
  	  INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3079
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
9a35c411f   Ping Cheng   Input: wacom - ad...
3080
  static const struct wacom_features wacom_features_0x315 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3081
  	{ "Wacom Intuos Pro M", 44704, 27940, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3082
  	  INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3083
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
9a35c411f   Ping Cheng   Input: wacom - ad...
3084
  static const struct wacom_features wacom_features_0x317 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3085
  	{ "Wacom Intuos Pro L", 65024, 40640, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3086
  	  INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3087
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
803296b67   Jason Gerecke   Input: wacom - ad...
3088
  static const struct wacom_features wacom_features_0xF4 =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3089
  	{ "Wacom Cintiq 24HD", 104080, 65200, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3090
  	  WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,
fa7703402   Ping Cheng   HID: wacom: add d...
3091
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
6f4d0382e   Jason Gerecke   Input: wacom - ad...
3092
  static const struct wacom_features wacom_features_0xF8 =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3093
  	{ "Wacom Cintiq 24HD touch", 104080, 65200, 2047, 63, /* Pen */
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3094
  	  WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,
fa7703402   Ping Cheng   HID: wacom: add d...
3095
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
3bd1f7e2d   Ping Cheng   Input: wacom - fi...
3096
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
b1e4279e4   Jason Gerecke   Input: wacom - ad...
3097
3098
  static const struct wacom_features wacom_features_0xF6 =
  	{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
29b473913   Benjamin Tissoires   Input: wacom - sw...
3099
3100
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
500d4160a   Ping Cheng   HID: wacom: add s...
3101
  static const struct wacom_features wacom_features_0x32A =
a7e6645ee   Ping Cheng   HID: wacom: Add m...
3102
  	{ "Wacom Cintiq 27QHD", 119740, 67520, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3103
  	  WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,
a7e6645ee   Ping Cheng   HID: wacom: Add m...
3104
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
500d4160a   Ping Cheng   HID: wacom: add s...
3105
3106
  static const struct wacom_features wacom_features_0x32B =
  	{ "Wacom Cintiq 27QHD touch", 119740, 67520, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3107
  	  WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,
500d4160a   Ping Cheng   HID: wacom: add s...
3108
3109
3110
3111
3112
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C };
  static const struct wacom_features wacom_features_0x32C =
  	{ "Wacom Cintiq 27QHD touch", .type = WACOM_27QHDT,
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3113
  static const struct wacom_features wacom_features_0x3F =
80befa938   Benjamin Tissoires   Input: wacom - re...
3114
  	{ "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3115
  	  CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3116
  static const struct wacom_features wacom_features_0xC5 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3117
  	{ "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3118
  	  WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3119
  static const struct wacom_features wacom_features_0xC6 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3120
  	{ "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3121
  	  WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };
56218563a   Ping Cheng   Input: wacom - ad...
3122
  static const struct wacom_features wacom_features_0x304 =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3123
  	{ "Wacom Cintiq 13HD", 59152, 33448, 1023, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3124
  	  WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
fa7703402   Ping Cheng   HID: wacom: add d...
3125
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
b4bf2120d   Ping Cheng   HID: wacom: Add s...
3126
3127
  static const struct wacom_features wacom_features_0x333 =
  	{ "Wacom Cintiq 13HD touch", 59152, 33448, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3128
  	  WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
b4bf2120d   Ping Cheng   HID: wacom: Add s...
3129
3130
3131
3132
3133
3134
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 };
  static const struct wacom_features wacom_features_0x335 =
  	{ "Wacom Cintiq 13HD touch", .type = WACOM_24HDT, /* Touch */
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x333, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3135
  static const struct wacom_features wacom_features_0xC7 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3136
3137
  	{ "Wacom DTU1931", 37832, 30305, 511, 0,
  	  PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
c8f2edc56   Ping Cheng   Input: wacom - ad...
3138
  static const struct wacom_features wacom_features_0xCE =
80befa938   Benjamin Tissoires   Input: wacom - re...
3139
3140
  	{ "Wacom DTU2231", 47864, 27011, 511, 0,
  	  DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3141
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBMOUSE };
c8f2edc56   Ping Cheng   Input: wacom - ad...
3142
  static const struct wacom_features wacom_features_0xF0 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3143
3144
  	{ "Wacom DTU1631", 34623, 19553, 511, 0,
  	  DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
497ab1f29   Ping Cheng   Input: wacom - ad...
3145
  static const struct wacom_features wacom_features_0xFB =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3146
  	{ "Wacom DTU1031", 21896, 13760, 511, 0,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3147
  	  DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
fa7703402   Ping Cheng   HID: wacom: add d...
3148
  	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
fff00bf8c   Ping Cheng   HID: wacom: Add s...
3149
3150
  static const struct wacom_features wacom_features_0x32F =
  	{ "Wacom DTU1031X", 22472, 12728, 511, 0,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3151
  	  DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 0,
fff00bf8c   Ping Cheng   HID: wacom: Add s...
3152
  	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
007760cf0   Aaron Skomra   HID: wacom: Add s...
3153
3154
  static const struct wacom_features wacom_features_0x336 =
  	{ "Wacom DTU1141", 23472, 13203, 1023, 0,
ff38e8293   Ping Cheng   HID: wacom: Add o...
3155
3156
  	  DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
  	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
56218563a   Ping Cheng   Input: wacom - ad...
3157
  static const struct wacom_features wacom_features_0x57 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3158
  	{ "Wacom DTK2241", 95640, 54060, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3159
  	  DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,
fa7703402   Ping Cheng   HID: wacom: add d...
3160
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
a112e9fdd   Ping Cheng   Input: wacom - ad...
3161
  static const struct wacom_features wacom_features_0x59 = /* Pen */
80befa938   Benjamin Tissoires   Input: wacom - re...
3162
  	{ "Wacom DTH2242", 95640, 54060, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3163
  	  DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,
fa7703402   Ping Cheng   HID: wacom: add d...
3164
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
a112e9fdd   Ping Cheng   Input: wacom - ad...
3165
3166
3167
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };
  static const struct wacom_features wacom_features_0x5D = /* Touch */
  	{ "Wacom DTH2242",       .type = WACOM_24HDT,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3168
3169
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
3a4b4aaa5   Ping Cheng   Input: wacom - ad...
3170
  static const struct wacom_features wacom_features_0xCC =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3171
  	{ "Wacom Cintiq 21UX2", 86800, 65200, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3172
  	  WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
fa7703402   Ping Cheng   HID: wacom: add d...
3173
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
d838c644f   Ping Cheng   Input: wacom - ad...
3174
  static const struct wacom_features wacom_features_0xFA =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3175
  	{ "Wacom Cintiq 22HD", 95440, 53860, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3176
  	  WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
fa7703402   Ping Cheng   HID: wacom: add d...
3177
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };
56218563a   Ping Cheng   Input: wacom - ad...
3178
  static const struct wacom_features wacom_features_0x5B =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3179
  	{ "Wacom Cintiq 22HDT", 95440, 53860, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3180
  	  WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,
fa7703402   Ping Cheng   HID: wacom: add d...
3181
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
3bd1f7e2d   Ping Cheng   Input: wacom - fi...
3182
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
56218563a   Ping Cheng   Input: wacom - ad...
3183
3184
  static const struct wacom_features wacom_features_0x5E =
  	{ "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3185
3186
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3187
  static const struct wacom_features wacom_features_0x90 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3188
3189
  	{ "Wacom ISDv4 90", 26202, 16325, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3190
  static const struct wacom_features wacom_features_0x93 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3191
3192
  	{ "Wacom ISDv4 93", 26202, 16325, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
11d0cf885   Ping Cheng   Input: wacom - ad...
3193
  static const struct wacom_features wacom_features_0x97 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3194
3195
  	{ "Wacom ISDv4 97", 26202, 16325, 511, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3196
  static const struct wacom_features wacom_features_0x9A =
80befa938   Benjamin Tissoires   Input: wacom - re...
3197
3198
  	{ "Wacom ISDv4 9A", 26202, 16325, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3199
  static const struct wacom_features wacom_features_0x9F =
80befa938   Benjamin Tissoires   Input: wacom - re...
3200
3201
  	{ "Wacom ISDv4 9F", 26202, 16325, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3202
  static const struct wacom_features wacom_features_0xE2 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3203
3204
  	{ "Wacom ISDv4 E2", 26202, 16325, 255, 0,
  	  TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3205
  static const struct wacom_features wacom_features_0xE3 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3206
3207
  	{ "Wacom ISDv4 E3", 26202, 16325, 255, 0,
  	  TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
1963518b9   Ping Cheng   Input: wacom - ad...
3208
  static const struct wacom_features wacom_features_0xE5 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3209
3210
  	{ "Wacom ISDv4 E5", 26202, 16325, 255, 0,
  	  MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
26fcd2a76   Manoj Iyer   Input: wacom - ad...
3211
  static const struct wacom_features wacom_features_0xE6 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3212
3213
  	{ "Wacom ISDv4 E6", 27760, 15694, 255, 0,
  	  TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
0d0e3064a   Chris Bagwell   Input: wacom - ad...
3214
  static const struct wacom_features wacom_features_0xEC =
80befa938   Benjamin Tissoires   Input: wacom - re...
3215
3216
  	{ "Wacom ISDv4 EC", 25710, 14500, 255, 0,
  	  TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
ac173837c   Ping Cheng   Input: wacom - ad...
3217
  static const struct wacom_features wacom_features_0xED =
80befa938   Benjamin Tissoires   Input: wacom - re...
3218
3219
  	{ "Wacom ISDv4 ED", 26202, 16325, 255, 0,
  	  TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
ac173837c   Ping Cheng   Input: wacom - ad...
3220
  static const struct wacom_features wacom_features_0xEF =
80befa938   Benjamin Tissoires   Input: wacom - re...
3221
3222
  	{ "Wacom ISDv4 EF", 26202, 16325, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
6afdc289c   Ping Cheng   Input: wacom - ad...
3223
  static const struct wacom_features wacom_features_0x100 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3224
3225
  	{ "Wacom ISDv4 100", 26202, 16325, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
6afdc289c   Ping Cheng   Input: wacom - ad...
3226
  static const struct wacom_features wacom_features_0x101 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3227
3228
  	{ "Wacom ISDv4 101", 26202, 16325, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
586948372   Stephan Frank   Input: wacom - ad...
3229
  static const struct wacom_features wacom_features_0x10D =
80befa938   Benjamin Tissoires   Input: wacom - re...
3230
3231
  	{ "Wacom ISDv4 10D", 26202, 16325, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2d3163f10   Jason Gerecke   Input: wacom - ad...
3232
  static const struct wacom_features wacom_features_0x10E =
80befa938   Benjamin Tissoires   Input: wacom - re...
3233
3234
  	{ "Wacom ISDv4 10E", 27760, 15694, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
9b4f60e5c   Jason Gerecke   Input: wacom - ad...
3235
  static const struct wacom_features wacom_features_0x10F =
80befa938   Benjamin Tissoires   Input: wacom - re...
3236
3237
  	{ "Wacom ISDv4 10F", 27760, 15694, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
61616ed0c   Jason Gerecke   Input: wacom - ad...
3238
  static const struct wacom_features wacom_features_0x116 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3239
3240
  	{ "Wacom ISDv4 116", 26202, 16325, 255, 0,
  	  TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
aeaf50d4e   Jason Gerecke   Input: wacom - ad...
3241
3242
3243
  static const struct wacom_features wacom_features_0x12C =
  	{ "Wacom ISDv4 12C", 27848, 15752, 2047, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
edbe265d2   Ping Cheng   Input: wacom - ad...
3244
  static const struct wacom_features wacom_features_0x4001 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3245
3246
  	{ "Wacom ISDv4 4001", 26202, 16325, 255, 0,
  	  MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
3247
  static const struct wacom_features wacom_features_0x4004 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3248
3249
  	{ "Wacom ISDv4 4004", 11060, 6220, 255, 0,
  	  MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
3250
  static const struct wacom_features wacom_features_0x5000 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3251
3252
  	{ "Wacom ISDv4 5000", 27848, 15752, 1023, 0,
  	  MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
3253
  static const struct wacom_features wacom_features_0x5002 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3254
3255
  	{ "Wacom ISDv4 5002", 29576, 16724, 1023, 0,
  	  MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
e87a344d0   Dmitry Torokhov   Input: wacom - co...
3256
  static const struct wacom_features wacom_features_0x47 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3257
3258
  	{ "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,
  	  INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
d3825d51c   Chris Bagwell   Input: wacom - wi...
3259
  static const struct wacom_features wacom_features_0x84 =
3b164a00a   Ping Cheng   HID: wacom: Clean...
3260
  	{ "Wacom Wireless Receiver", .type = WIRELESS, .touch_max = 16 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3261
  static const struct wacom_features wacom_features_0xD0 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3262
  	{ "Wacom Bamboo 2FG", 14720, 9200, 1023, 31,
3b164a00a   Ping Cheng   HID: wacom: Clean...
3263
  	  BAMBOO_TOUCH, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3264
  static const struct wacom_features wacom_features_0xD1 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3265
3266
  	{ "Wacom Bamboo 2FG 4x5", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3267
  static const struct wacom_features wacom_features_0xD2 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3268
3269
  	{ "Wacom Bamboo Craft", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3270
  static const struct wacom_features wacom_features_0xD3 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3271
3272
  	{ "Wacom Bamboo 2FG 6x8", 21648, 13700, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
57a7872fa   Kevin Granade   Input: wacom - ad...
3273
  static const struct wacom_features wacom_features_0xD4 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3274
  	{ "Wacom Bamboo Pen", 14720, 9200, 1023, 31,
3b164a00a   Ping Cheng   HID: wacom: Clean...
3275
  	  BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
18adad1c5   Gerard Braad   Input: wacom - ad...
3276
  static const struct wacom_features wacom_features_0xD5 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3277
  	{ "Wacom Bamboo Pen 6x8", 21648, 13700, 1023, 31,
3b164a00a   Ping Cheng   HID: wacom: Clean...
3278
  	  BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
7b824bbdd   Ping Cheng   Input: wacom - co...
3279
  static const struct wacom_features wacom_features_0xD6 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3280
3281
  	{ "Wacom BambooPT 2FG 4x5", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3282
  static const struct wacom_features wacom_features_0xD7 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3283
3284
  	{ "Wacom BambooPT 2FG Small", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3285
  static const struct wacom_features wacom_features_0xD8 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3286
3287
  	{ "Wacom Bamboo Comic 2FG", 21648, 13700, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
7b824bbdd   Ping Cheng   Input: wacom - co...
3288
  static const struct wacom_features wacom_features_0xDA =
80befa938   Benjamin Tissoires   Input: wacom - re...
3289
3290
  	{ "Wacom Bamboo 2FG 4x5 SE", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
f41a64eea   Ping Cheng   Input: wacom - ad...
3291
  static const struct wacom_features wacom_features_0xDB =
80befa938   Benjamin Tissoires   Input: wacom - re...
3292
3293
  	{ "Wacom Bamboo 2FG 6x8 SE", 21648, 13700, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };
73149ab84   Chris Bagwell   Input: wacom - 3r...
3294
  static const struct wacom_features wacom_features_0xDD =
80befa938   Benjamin Tissoires   Input: wacom - re...
3295
3296
          { "Wacom Bamboo Connect", 14720, 9200, 1023, 31,
            BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
73149ab84   Chris Bagwell   Input: wacom - 3r...
3297
  static const struct wacom_features wacom_features_0xDE =
80befa938   Benjamin Tissoires   Input: wacom - re...
3298
3299
          { "Wacom Bamboo 16FG 4x5", 14720, 9200, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };
73149ab84   Chris Bagwell   Input: wacom - 3r...
3300
  static const struct wacom_features wacom_features_0xDF =
80befa938   Benjamin Tissoires   Input: wacom - re...
3301
3302
          { "Wacom Bamboo 16FG 6x8", 21648, 13700, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };
f41a64eea   Ping Cheng   Input: wacom - ad...
3303
  static const struct wacom_features wacom_features_0x300 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3304
  	{ "Wacom Bamboo One S", 14720, 9225, 1023, 31,
3b164a00a   Ping Cheng   HID: wacom: Clean...
3305
  	  BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
f41a64eea   Ping Cheng   Input: wacom - ad...
3306
  static const struct wacom_features wacom_features_0x301 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3307
3308
  	{ "Wacom Bamboo One M", 21648, 13530, 1023, 31,
  	  BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
3309
  static const struct wacom_features wacom_features_0x302 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3310
3311
  	{ "Wacom Intuos PT S", 15200, 9500, 1023, 31,
  	  INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3312
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
3313
  static const struct wacom_features wacom_features_0x303 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3314
3315
  	{ "Wacom Intuos PT M", 21600, 13500, 1023, 31,
  	  INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3316
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
b5fd2a3e9   Ping Cheng   Input: wacom - ad...
3317
  static const struct wacom_features wacom_features_0x30E =
80befa938   Benjamin Tissoires   Input: wacom - re...
3318
3319
  	{ "Wacom Intuos S", 15200, 9500, 1023, 31,
  	  INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
29b473913   Benjamin Tissoires   Input: wacom - sw...
3320
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
7b4b30689   Ajay Ramaswamy   Input: wacom - ad...
3321
  static const struct wacom_features wacom_features_0x6004 =
80befa938   Benjamin Tissoires   Input: wacom - re...
3322
3323
  	{ "ISD-V4", 12800, 8000, 255, 0,
  	  TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3324
  static const struct wacom_features wacom_features_0x307 =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3325
  	{ "Wacom ISDv5 307", 59152, 33448, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3326
  	  CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
fa7703402   Ping Cheng   HID: wacom: add d...
3327
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
36d3c510e   Jason Gerecke   Input: wacom - su...
3328
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3329
  static const struct wacom_features wacom_features_0x309 =
36d3c510e   Jason Gerecke   Input: wacom - su...
3330
  	{ "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
29b473913   Benjamin Tissoires   Input: wacom - sw...
3331
3332
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
89f2ab55e   Benjamin Tissoires   HID: wacom: Add s...
3333
  static const struct wacom_features wacom_features_0x30A =
ecd618dc2   Ping Cheng   HID: wacom: Updat...
3334
  	{ "Wacom ISDv5 30A", 59152, 33448, 2047, 63,
70ee06c5f   Aaron Skomra   HID: wacom: Set b...
3335
  	  CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,
fa7703402   Ping Cheng   HID: wacom: add d...
3336
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
89f2ab55e   Benjamin Tissoires   HID: wacom: Add s...
3337
3338
3339
3340
3341
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };
  static const struct wacom_features wacom_features_0x30C =
  	{ "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
3342
3343
3344
3345
3346
3347
  static const struct wacom_features wacom_features_0x318 =
  	{ "Wacom USB Bamboo PAD", 4095, 4095, /* Touch */
  	  .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };
  static const struct wacom_features wacom_features_0x319 =
  	{ "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */
  	  .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };
f7acb55cf   Jason Gerecke   HID: wacom: Add s...
3348
3349
3350
3351
3352
3353
3354
3355
  static const struct wacom_features wacom_features_0x325 =
  	{ "Wacom ISDv5 325", 59552, 33848, 2047, 63,
  	  CINTIQ_COMPANION_2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11,
  	  WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,
  	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x326 };
  static const struct wacom_features wacom_features_0x326 = /* Touch */
  	{ "Wacom ISDv5 326", .type = HID_GENERIC, .oVid = USB_VENDOR_ID_WACOM,
  	  .oPid = 0x325 };
fefb391f8   Ping Cheng   HID: wacom: Add s...
3356
3357
3358
3359
  static const struct wacom_features wacom_features_0x323 =
  	{ "Wacom Intuos P M", 21600, 13500, 1023, 31,
  	  INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
72b236d60   Aaron Skomra   HID: wacom: Add s...
3360
  static const struct wacom_features wacom_features_0x331 =
3b164a00a   Ping Cheng   HID: wacom: Clean...
3361
3362
  	{ "Wacom Express Key Remote", .type = REMOTE,
  	  .numbered_buttons = 18, .check_for_hid_type = true,
72b236d60   Aaron Skomra   HID: wacom: Add s...
3363
  	  .hid_type = HID_TYPE_USBNONE };
eda01dab5   Ping Cheng   HID: wacom: Add f...
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
  static const struct wacom_features wacom_features_0x33B =
  	{ "Wacom Intuos S 2", 15200, 9500, 2047, 63,
  	  INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
  static const struct wacom_features wacom_features_0x33C =
  	{ "Wacom Intuos PT S 2", 15200, 9500, 2047, 63,
  	  INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
  static const struct wacom_features wacom_features_0x33D =
  	{ "Wacom Intuos P M 2", 21600, 13500, 2047, 63,
  	  INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
  static const struct wacom_features wacom_features_0x33E =
  	{ "Wacom Intuos PT M 2", 21600, 13500, 2047, 63,
  	  INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,
  	  .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };
e1123fe97   Ping Cheng   HID: wacom: Add s...
3380
3381
3382
3383
  static const struct wacom_features wacom_features_0x343 =
  	{ "Wacom DTK1651", 34616, 19559, 1023, 0,
  	  DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
  	  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
b036f6fb3   Bastian Blank   Input: wacom - ge...
3384

7704ac937   Benjamin Tissoires   HID: wacom: imple...
3385
  static const struct wacom_features wacom_features_HID_ANY_ID =
41372d5d4   Jason Gerecke   HID: wacom: Augme...
3386
  	{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
7704ac937   Benjamin Tissoires   HID: wacom: imple...
3387

29b473913   Benjamin Tissoires   Input: wacom - sw...
3388
3389
3390
  #define USB_DEVICE_WACOM(prod)						\
  	HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
  	.driver_data = (kernel_ulong_t)&wacom_features_##prod
b036f6fb3   Bastian Blank   Input: wacom - ge...
3391

387142bb8   Benjamin Tissoires   Input: wacom - ha...
3392
3393
3394
  #define BT_DEVICE_WACOM(prod)						\
  	HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
  	.driver_data = (kernel_ulong_t)&wacom_features_##prod
1483f5513   Aristeu Rozanski   Input: wacom - us...
3395

eef23a844   Mika Westerberg   HID: wacom: Add s...
3396
3397
3398
  #define I2C_DEVICE_WACOM(prod)						\
  	HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
  	.driver_data = (kernel_ulong_t)&wacom_features_##prod
7b4b30689   Ajay Ramaswamy   Input: wacom - ad...
3399
  #define USB_DEVICE_LENOVO(prod)					\
29b473913   Benjamin Tissoires   Input: wacom - sw...
3400
3401
  	HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),			\
  	.driver_data = (kernel_ulong_t)&wacom_features_##prod
7b4b30689   Ajay Ramaswamy   Input: wacom - ad...
3402

29b473913   Benjamin Tissoires   Input: wacom - sw...
3403
  const struct hid_device_id wacom_ids[] = {
b036f6fb3   Bastian Blank   Input: wacom - ge...
3404
  	{ USB_DEVICE_WACOM(0x00) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3405
  	{ USB_DEVICE_WACOM(0x03) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
  	{ USB_DEVICE_WACOM(0x10) },
  	{ USB_DEVICE_WACOM(0x11) },
  	{ USB_DEVICE_WACOM(0x12) },
  	{ USB_DEVICE_WACOM(0x13) },
  	{ USB_DEVICE_WACOM(0x14) },
  	{ USB_DEVICE_WACOM(0x15) },
  	{ USB_DEVICE_WACOM(0x16) },
  	{ USB_DEVICE_WACOM(0x17) },
  	{ USB_DEVICE_WACOM(0x18) },
  	{ USB_DEVICE_WACOM(0x19) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3416
3417
3418
3419
3420
  	{ USB_DEVICE_WACOM(0x20) },
  	{ USB_DEVICE_WACOM(0x21) },
  	{ USB_DEVICE_WACOM(0x22) },
  	{ USB_DEVICE_WACOM(0x23) },
  	{ USB_DEVICE_WACOM(0x24) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3421
3422
3423
3424
3425
  	{ USB_DEVICE_WACOM(0x26) },
  	{ USB_DEVICE_WACOM(0x27) },
  	{ USB_DEVICE_WACOM(0x28) },
  	{ USB_DEVICE_WACOM(0x29) },
  	{ USB_DEVICE_WACOM(0x2A) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3426
3427
3428
3429
3430
3431
3432
3433
3434
  	{ USB_DEVICE_WACOM(0x30) },
  	{ USB_DEVICE_WACOM(0x31) },
  	{ USB_DEVICE_WACOM(0x32) },
  	{ USB_DEVICE_WACOM(0x33) },
  	{ USB_DEVICE_WACOM(0x34) },
  	{ USB_DEVICE_WACOM(0x35) },
  	{ USB_DEVICE_WACOM(0x37) },
  	{ USB_DEVICE_WACOM(0x38) },
  	{ USB_DEVICE_WACOM(0x39) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3435
  	{ USB_DEVICE_WACOM(0x3F) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3436
3437
3438
3439
3440
  	{ USB_DEVICE_WACOM(0x41) },
  	{ USB_DEVICE_WACOM(0x42) },
  	{ USB_DEVICE_WACOM(0x43) },
  	{ USB_DEVICE_WACOM(0x44) },
  	{ USB_DEVICE_WACOM(0x45) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3441
  	{ USB_DEVICE_WACOM(0x47) },
56218563a   Ping Cheng   Input: wacom - ad...
3442
  	{ USB_DEVICE_WACOM(0x57) },
a112e9fdd   Ping Cheng   Input: wacom - ad...
3443
  	{ USB_DEVICE_WACOM(0x59) },
56218563a   Ping Cheng   Input: wacom - ad...
3444
  	{ USB_DEVICE_WACOM(0x5B) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3445
  	{ USB_DEVICE_WACOM(0x5D) },
29b473913   Benjamin Tissoires   Input: wacom - sw...
3446
  	{ USB_DEVICE_WACOM(0x5E) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3447
3448
3449
3450
3451
3452
3453
3454
3455
  	{ USB_DEVICE_WACOM(0x60) },
  	{ USB_DEVICE_WACOM(0x61) },
  	{ USB_DEVICE_WACOM(0x62) },
  	{ USB_DEVICE_WACOM(0x63) },
  	{ USB_DEVICE_WACOM(0x64) },
  	{ USB_DEVICE_WACOM(0x65) },
  	{ USB_DEVICE_WACOM(0x69) },
  	{ USB_DEVICE_WACOM(0x6A) },
  	{ USB_DEVICE_WACOM(0x6B) },
387142bb8   Benjamin Tissoires   Input: wacom - ha...
3456
  	{ BT_DEVICE_WACOM(0x81) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3457
3458
3459
3460
3461
3462
  	{ USB_DEVICE_WACOM(0x84) },
  	{ USB_DEVICE_WACOM(0x90) },
  	{ USB_DEVICE_WACOM(0x93) },
  	{ USB_DEVICE_WACOM(0x97) },
  	{ USB_DEVICE_WACOM(0x9A) },
  	{ USB_DEVICE_WACOM(0x9F) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
  	{ USB_DEVICE_WACOM(0xB0) },
  	{ USB_DEVICE_WACOM(0xB1) },
  	{ USB_DEVICE_WACOM(0xB2) },
  	{ USB_DEVICE_WACOM(0xB3) },
  	{ USB_DEVICE_WACOM(0xB4) },
  	{ USB_DEVICE_WACOM(0xB5) },
  	{ USB_DEVICE_WACOM(0xB7) },
  	{ USB_DEVICE_WACOM(0xB8) },
  	{ USB_DEVICE_WACOM(0xB9) },
  	{ USB_DEVICE_WACOM(0xBA) },
  	{ USB_DEVICE_WACOM(0xBB) },
3a4b4aaa5   Ping Cheng   Input: wacom - ad...
3474
  	{ USB_DEVICE_WACOM(0xBC) },
81af7e61a   Benjamin Tissoires   Input: wacom - ha...
3475
  	{ BT_DEVICE_WACOM(0xBD) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3476
3477
3478
  	{ USB_DEVICE_WACOM(0xC0) },
  	{ USB_DEVICE_WACOM(0xC2) },
  	{ USB_DEVICE_WACOM(0xC4) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3479
3480
3481
  	{ USB_DEVICE_WACOM(0xC5) },
  	{ USB_DEVICE_WACOM(0xC6) },
  	{ USB_DEVICE_WACOM(0xC7) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3482
  	{ USB_DEVICE_WACOM(0xCC) },
29b473913   Benjamin Tissoires   Input: wacom - sw...
3483
  	{ USB_DEVICE_WACOM(0xCE) },
cb734c036   Henrik Rydberg   Input: wacom - ad...
3484
  	{ USB_DEVICE_WACOM(0xD0) },
2aaacb153   Chris Bagwell   Input: wacom - ad...
3485
3486
3487
  	{ USB_DEVICE_WACOM(0xD1) },
  	{ USB_DEVICE_WACOM(0xD2) },
  	{ USB_DEVICE_WACOM(0xD3) },
57a7872fa   Kevin Granade   Input: wacom - ad...
3488
  	{ USB_DEVICE_WACOM(0xD4) },
18adad1c5   Gerard Braad   Input: wacom - ad...
3489
  	{ USB_DEVICE_WACOM(0xD5) },
d38acb49b   Ping Cheng   Input: wacom - ad...
3490
3491
  	{ USB_DEVICE_WACOM(0xD6) },
  	{ USB_DEVICE_WACOM(0xD7) },
a318e6b1a   David Foley   Input: wacom - ad...
3492
3493
  	{ USB_DEVICE_WACOM(0xD8) },
  	{ USB_DEVICE_WACOM(0xDA) },
47d092352   David Foley   Input: wacom - ad...
3494
  	{ USB_DEVICE_WACOM(0xDB) },
73149ab84   Chris Bagwell   Input: wacom - 3r...
3495
3496
3497
  	{ USB_DEVICE_WACOM(0xDD) },
  	{ USB_DEVICE_WACOM(0xDE) },
  	{ USB_DEVICE_WACOM(0xDF) },
b036f6fb3   Bastian Blank   Input: wacom - ge...
3498
3499
  	{ USB_DEVICE_WACOM(0xE2) },
  	{ USB_DEVICE_WACOM(0xE3) },
1963518b9   Ping Cheng   Input: wacom - ad...
3500
  	{ USB_DEVICE_WACOM(0xE5) },
26fcd2a76   Manoj Iyer   Input: wacom - ad...
3501
  	{ USB_DEVICE_WACOM(0xE6) },
0d0e3064a   Chris Bagwell   Input: wacom - ad...
3502
  	{ USB_DEVICE_WACOM(0xEC) },
ac173837c   Ping Cheng   Input: wacom - ad...
3503
3504
  	{ USB_DEVICE_WACOM(0xED) },
  	{ USB_DEVICE_WACOM(0xEF) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3505
3506
3507
3508
3509
3510
  	{ USB_DEVICE_WACOM(0xF0) },
  	{ USB_DEVICE_WACOM(0xF4) },
  	{ USB_DEVICE_WACOM(0xF6) },
  	{ USB_DEVICE_WACOM(0xF8) },
  	{ USB_DEVICE_WACOM(0xFA) },
  	{ USB_DEVICE_WACOM(0xFB) },
6afdc289c   Ping Cheng   Input: wacom - ad...
3511
3512
  	{ USB_DEVICE_WACOM(0x100) },
  	{ USB_DEVICE_WACOM(0x101) },
586948372   Stephan Frank   Input: wacom - ad...
3513
  	{ USB_DEVICE_WACOM(0x10D) },
2d3163f10   Jason Gerecke   Input: wacom - ad...
3514
  	{ USB_DEVICE_WACOM(0x10E) },
9b4f60e5c   Jason Gerecke   Input: wacom - ad...
3515
  	{ USB_DEVICE_WACOM(0x10F) },
61616ed0c   Jason Gerecke   Input: wacom - ad...
3516
  	{ USB_DEVICE_WACOM(0x116) },
aeaf50d4e   Jason Gerecke   Input: wacom - ad...
3517
  	{ USB_DEVICE_WACOM(0x12C) },
f41a64eea   Ping Cheng   Input: wacom - ad...
3518
3519
  	{ USB_DEVICE_WACOM(0x300) },
  	{ USB_DEVICE_WACOM(0x301) },
29b473913   Benjamin Tissoires   Input: wacom - sw...
3520
3521
  	{ USB_DEVICE_WACOM(0x302) },
  	{ USB_DEVICE_WACOM(0x303) },
56218563a   Ping Cheng   Input: wacom - ad...
3522
  	{ USB_DEVICE_WACOM(0x304) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3523
3524
  	{ USB_DEVICE_WACOM(0x307) },
  	{ USB_DEVICE_WACOM(0x309) },
89f2ab55e   Benjamin Tissoires   HID: wacom: Add s...
3525
3526
  	{ USB_DEVICE_WACOM(0x30A) },
  	{ USB_DEVICE_WACOM(0x30C) },
a3e6f6543   Benjamin Tissoires   Input: wacom - ke...
3527
  	{ USB_DEVICE_WACOM(0x30E) },
29b473913   Benjamin Tissoires   Input: wacom - sw...
3528
3529
3530
  	{ USB_DEVICE_WACOM(0x314) },
  	{ USB_DEVICE_WACOM(0x315) },
  	{ USB_DEVICE_WACOM(0x317) },
8c97a7654   Benjamin Tissoires   HID: wacom: add f...
3531
3532
  	{ USB_DEVICE_WACOM(0x318) },
  	{ USB_DEVICE_WACOM(0x319) },
fefb391f8   Ping Cheng   HID: wacom: Add s...
3533
  	{ USB_DEVICE_WACOM(0x323) },
f7acb55cf   Jason Gerecke   HID: wacom: Add s...
3534
3535
  	{ USB_DEVICE_WACOM(0x325) },
  	{ USB_DEVICE_WACOM(0x326) },
500d4160a   Ping Cheng   HID: wacom: add s...
3536
3537
3538
  	{ USB_DEVICE_WACOM(0x32A) },
  	{ USB_DEVICE_WACOM(0x32B) },
  	{ USB_DEVICE_WACOM(0x32C) },
fff00bf8c   Ping Cheng   HID: wacom: Add s...
3539
  	{ USB_DEVICE_WACOM(0x32F) },
72b236d60   Aaron Skomra   HID: wacom: Add s...
3540
  	{ USB_DEVICE_WACOM(0x331) },
b4bf2120d   Ping Cheng   HID: wacom: Add s...
3541
3542
  	{ USB_DEVICE_WACOM(0x333) },
  	{ USB_DEVICE_WACOM(0x335) },
007760cf0   Aaron Skomra   HID: wacom: Add s...
3543
  	{ USB_DEVICE_WACOM(0x336) },
eda01dab5   Ping Cheng   HID: wacom: Add f...
3544
3545
3546
3547
  	{ USB_DEVICE_WACOM(0x33B) },
  	{ USB_DEVICE_WACOM(0x33C) },
  	{ USB_DEVICE_WACOM(0x33D) },
  	{ USB_DEVICE_WACOM(0x33E) },
e1123fe97   Ping Cheng   HID: wacom: Add s...
3548
  	{ USB_DEVICE_WACOM(0x343) },
edbe265d2   Ping Cheng   Input: wacom - ad...
3549
  	{ USB_DEVICE_WACOM(0x4001) },
d51ddb2bf   Jason Gerecke   Input: wacom - ad...
3550
3551
3552
  	{ USB_DEVICE_WACOM(0x4004) },
  	{ USB_DEVICE_WACOM(0x5000) },
  	{ USB_DEVICE_WACOM(0x5002) },
00d6f227a   Benjamin Tissoires   HID: wacom: re-ad...
3553
  	{ USB_DEVICE_LENOVO(0x6004) },
7704ac937   Benjamin Tissoires   HID: wacom: imple...
3554
3555
  
  	{ USB_DEVICE_WACOM(HID_ANY_ID) },
eef23a844   Mika Westerberg   HID: wacom: Add s...
3556
  	{ I2C_DEVICE_WACOM(HID_ANY_ID) },
3bea733ab   Ping Cheng   USB: wacom tablet...
3557
3558
  	{ }
  };
29b473913   Benjamin Tissoires   Input: wacom - sw...
3559
  MODULE_DEVICE_TABLE(hid, wacom_ids);