wacom_wac.c 84.9 KB
Newer Older
1
/*
2
 * drivers/input/tablet/wacom_wac.c
3
 *
4
 *  USB Wacom tablet support - Wacom specific code
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.
 */
14

15
#include "wacom_wac.h"
16
#include "wacom.h"
17
#include <linux/input/mt.h>
18
#include <linux/hid.h>
19

20 21 22 23 24 25 26 27
/* 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

28 29 30 31 32
/* Scale factor relating reported contact size to logical contact area.
 * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo
 */
#define WACOM_CONTACT_AREA_SCALE 2607

33
static int wacom_penpartner_irq(struct wacom_wac *wacom)
34 35
{
	unsigned char *data = wacom->data;
36
	struct input_dev *input = wacom->input;
37 38

	switch (data[0]) {
39 40 41 42
	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;
43 44
			input_report_key(input, wacom->tool[0], 1);
			input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
45 46
			input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
			input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
47 48 49
			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));
50
		} else {
51 52 53 54
			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);
55 56
		}
		break;
57

58
	case 2:
59 60
		input_report_key(input, BTN_TOOL_PEN, 1);
		input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */
61 62
		input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));
		input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));
63 64 65
		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));
66
		break;
67

68
	default:
69 70
		dev_dbg(input->dev.parent,
			"%s: received unknown report #%d\n", __func__, data[0]);
71
		return 0;
72
        }
73

74 75 76
	return 1;
}

77
static int wacom_pl_irq(struct wacom_wac *wacom)
78
{
79
	struct wacom_features *features = &wacom->features;
80
	unsigned char *data = wacom->data;
81
	struct input_dev *input = wacom->input;
82
	int prox, pressure;
83

84
	if (data[0] != WACOM_REPORT_PENABLED) {
85 86
		dev_dbg(input->dev.parent,
			"%s: received unknown report #%d\n", __func__, data[0]);
87 88 89 90 91 92
		return 0;
	}

	prox = data[1] & 0x40;

	if (prox) {
93
		wacom->id[0] = ERASER_DEVICE_ID;
94
		pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));
95
		if (features->pressure_max > 255)
96
			pressure = (pressure << 1) | ((data[4] >> 6) & 1);
97
		pressure += (features->pressure_max + 1) / 2;
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

		/*
		 * if going from out of proximity into proximity select between the eraser
		 * and the pen based on the state of the stylus2 button, choose eraser if
		 * pressed else choose pen. if not a proximity change from out to in, send
		 * an out of proximity for previous tool then a in for new tool.
		 */
		if (!wacom->tool[0]) {
			/* Eraser bit set for DTF */
			if (data[1] & 0x10)
				wacom->tool[1] = BTN_TOOL_RUBBER;
			else
				/* Going into proximity select tool */
				wacom->tool[1] = (data[4] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
		} else {
			/* was entered with stylus2 pressed */
			if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {
				/* report out proximity for previous tool */
116 117
				input_report_key(input, wacom->tool[1], 0);
				input_sync(input);
118 119 120 121 122 123 124
				wacom->tool[1] = BTN_TOOL_PEN;
				return 0;
			}
		}
		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
			/* Unknown tool selected default to pen tool */
			wacom->tool[1] = BTN_TOOL_PEN;
125
			wacom->id[0] = STYLUS_DEVICE_ID;
126
		}
127 128 129 130 131 132 133 134
		input_report_key(input, wacom->tool[1], prox); /* report in proximity for tool */
		input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
		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);
135
		/* Only allow the stylus2 button to be reported for the pen tool. */
136
		input_report_key(input, BTN_STYLUS2, (wacom->tool[1] == BTN_TOOL_PEN) && (data[4] & 0x20));
137 138 139 140 141 142
	} else {
		/* report proximity-out of a (valid) tool */
		if (wacom->tool[1] != BTN_TOOL_RUBBER) {
			/* Unknown tool selected default to pen tool */
			wacom->tool[1] = BTN_TOOL_PEN;
		}
143
		input_report_key(input, wacom->tool[1], prox);
144 145 146 147 148 149
	}

	wacom->tool[0] = prox; /* Save proximity state */
	return 1;
}

150
static int wacom_ptu_irq(struct wacom_wac *wacom)
151 152
{
	unsigned char *data = wacom->data;
153
	struct input_dev *input = wacom->input;
154

155
	if (data[0] != WACOM_REPORT_PENABLED) {
156 157
		dev_dbg(input->dev.parent,
			"%s: received unknown report #%d\n", __func__, data[0]);
158 159 160 161
		return 0;
	}

	if (data[1] & 0x04) {
162 163
		input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20);
		input_report_key(input, BTN_TOUCH, data[1] & 0x08);
164
		wacom->id[0] = ERASER_DEVICE_ID;
165
	} else {
166 167
		input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20);
		input_report_key(input, BTN_TOUCH, data[1] & 0x01);
168
		wacom->id[0] = STYLUS_DEVICE_ID;
169
	}
170
	input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
171 172 173
	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]));
174 175
	input_report_key(input, BTN_STYLUS, data[1] & 0x02);
	input_report_key(input, BTN_STYLUS2, data[1] & 0x10);
176 177 178
	return 1;
}

179 180
static int wacom_dtu_irq(struct wacom_wac *wacom)
{
181
	unsigned char *data = wacom->data;
182
	struct input_dev *input = wacom->input;
183
	int prox = data[1] & 0x20;
184

185 186
	dev_dbg(input->dev.parent,
		"%s: received report #%d", __func__, data[0]);
187 188 189 190 191 192 193 194 195 196 197 198 199

	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]));
200
	input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]);
201 202 203 204 205 206 207 208
	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;
}

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
static int wacom_dtus_irq(struct wacom_wac *wacom)
{
	char *data = wacom->data;
	struct input_dev *input = wacom->input;
	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) {
		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);
		/*
		 * Serial number is required when expresskeys are
		 * reported through pen interface.
		 */
		input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
		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]);
		input_event(input, EV_MSC, MSC_SERIAL, 1);
		return 1;
	}
}

265
static int wacom_graphire_irq(struct wacom_wac *wacom)
266
{
267
	struct wacom_features *features = &wacom->features;
268
	unsigned char *data = wacom->data;
269
	struct input_dev *input = wacom->input;
270
	int prox;
271 272
	int rw = 0;
	int retval = 0;
273

274
	if (data[0] != WACOM_REPORT_PENABLED) {
275 276
		dev_dbg(input->dev.parent,
			"%s: received unknown report #%d\n", __func__, data[0]);
277
		goto exit;
278 279
	}

280 281 282 283
	prox = data[1] & 0x80;
	if (prox || wacom->id[0]) {
		if (prox) {
			switch ((data[1] >> 5) & 3) {
284 285 286

			case 0:	/* Pen */
				wacom->tool[0] = BTN_TOOL_PEN;
287
				wacom->id[0] = STYLUS_DEVICE_ID;
288 289 290 291
				break;

			case 1: /* Rubber */
				wacom->tool[0] = BTN_TOOL_RUBBER;
292
				wacom->id[0] = ERASER_DEVICE_ID;
293 294 295
				break;

			case 2: /* Mouse with wheel */
296
				input_report_key(input, BTN_MIDDLE, data[1] & 0x04);
297 298 299 300
				/* fall through */

			case 3: /* Mouse without wheel */
				wacom->tool[0] = BTN_TOOL_MOUSE;
301
				wacom->id[0] = CURSOR_DEVICE_ID;
302
				break;
303
			}
304
		}
305 306
		input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));
		input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));
307
		if (wacom->tool[0] != BTN_TOOL_MOUSE) {
308
			input_report_abs(input, ABS_PRESSURE, data[6] | ((data[7] & 0x03) << 8));
309 310 311
			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);
312
		} else {
313 314
			input_report_key(input, BTN_LEFT, data[1] & 0x01);
			input_report_key(input, BTN_RIGHT, data[1] & 0x02);
315 316
			if (features->type == WACOM_G4 ||
					features->type == WACOM_MO) {
317
				input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);
318
				rw = (data[7] & 0x04) - (data[7] & 0x03);
319
			} else {
320
				input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);
321
				rw = -(signed char)data[6];
322
			}
323
			input_report_rel(input, REL_WHEEL, rw);
324
		}
325 326 327

		if (!prox)
			wacom->id[0] = 0;
328 329
		input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */
		input_report_key(input, wacom->tool[0], prox);
330
		input_event(input, EV_MSC, MSC_SERIAL, 1);
331
		input_sync(input); /* sync last event */
P
Ping Cheng 已提交
332
	}
333 334

	/* send pad data */
335
	switch (features->type) {
336
	case WACOM_G4:
337 338
		prox = data[7] & 0xf8;
		if (prox || wacom->id[1]) {
339
			wacom->id[1] = PAD_DEVICE_ID;
340 341
			input_report_key(input, BTN_BACK, (data[7] & 0x40));
			input_report_key(input, BTN_FORWARD, (data[7] & 0x80));
342
			rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);
343
			input_report_rel(input, REL_WHEEL, rw);
344 345
			if (!prox)
				wacom->id[1] = 0;
346 347
			input_report_abs(input, ABS_MISC, wacom->id[1]);
			input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
348
			retval = 1;
349
		}
350
		break;
351 352

	case WACOM_MO:
353 354
		prox = (data[7] & 0xf8) || data[8];
		if (prox || wacom->id[1]) {
355
			wacom->id[1] = PAD_DEVICE_ID;
356 357 358 359
			input_report_key(input, BTN_BACK, (data[7] & 0x08));
			input_report_key(input, BTN_LEFT, (data[7] & 0x20));
			input_report_key(input, BTN_FORWARD, (data[7] & 0x10));
			input_report_key(input, BTN_RIGHT, (data[7] & 0x40));
360
			input_report_abs(input, ABS_WHEEL, (data[8] & 0x7f));
361 362
			if (!prox)
				wacom->id[1] = 0;
363 364
			input_report_abs(input, ABS_MISC, wacom->id[1]);
			input_event(input, EV_MSC, MSC_SERIAL, 0xf0);
365
			retval = 1;
366 367
		}
		break;
368
	}
369 370
exit:
	return retval;
371 372
}

373
static int wacom_intuos_inout(struct wacom_wac *wacom)
374
{
375
	struct wacom_features *features = &wacom->features;
376
	unsigned char *data = wacom->data;
377
	struct input_dev *input = wacom->input;
378
	int idx = 0;
379 380

	/* tool number */
381
	if (features->type == INTUOS)
382
		idx = data[1] & 0x01;
383 384 385

	/* Enter report */
	if ((data[1] & 0xfc) == 0xc0) {
386
		if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
387 388
			wacom->shared->stylus_in_proximity = true;

389 390 391 392 393
		/* serial number of the tool */
		wacom->serial[idx] = ((data[3] & 0x0f) << 28) +
			(data[4] << 20) + (data[5] << 12) +
			(data[6] << 4) + (data[7] >> 4);

394 395
		wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |
			((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12);
396

397
		switch (wacom->id[idx]) {
398 399
		case 0x812: /* Inking pen */
		case 0x801: /* Intuos3 Inking pen */
400
		case 0x120802: /* Intuos4/5 Inking Pen */
401 402 403 404 405 406 407 408 409 410
		case 0x012:
			wacom->tool[idx] = 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 */
411 412
		case 0x802: /* Intuos4/5 13HD/24HD General Pen */
		case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
413
		case 0x022:
414 415 416
		case 0x100804: /* Intuos4/5 13HD/24HD Art Pen */
		case 0x140802: /* Intuos4/5 13HD/24HD Classic Pen */
		case 0x160802: /* Cintiq 13HD Pro Pen */
417
		case 0x180802: /* DTH2242 Pen */
418
		case 0x100802: /* Intuos4/5 13HD/24HD General Pen */
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
			wacom->tool[idx] = BTN_TOOL_PEN;
			break;

		case 0x832: /* Stroke pen */
		case 0x032:
			wacom->tool[idx] = BTN_TOOL_BRUSH;
			break;

		case 0x007: /* Mouse 4D and 2D */
		case 0x09c:
		case 0x094:
		case 0x017: /* Intuos3 2D Mouse */
		case 0x806: /* Intuos4 Mouse */
			wacom->tool[idx] = BTN_TOOL_MOUSE;
			break;

		case 0x096: /* Lens cursor */
		case 0x097: /* Intuos3 Lens cursor */
		case 0x006: /* Intuos4 Lens cursor */
			wacom->tool[idx] = 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 */
449 450 451 452 453 454 455
		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 */
456
		case 0x18080a: /* DTH2242 Eraser */
457
		case 0x10080a: /* Intuos4/5 13HD/24HD General Pen Eraser */
458 459 460 461 462 463 464
			wacom->tool[idx] = BTN_TOOL_RUBBER;
			break;

		case 0xd12:
		case 0x912:
		case 0x112:
		case 0x913: /* Intuos3 Airbrush */
465 466
		case 0x902: /* Intuos4/5 13HD/24HD Airbrush */
		case 0x100902: /* Intuos4/5 13HD/24HD Airbrush */
467 468 469 470 471 472
			wacom->tool[idx] = BTN_TOOL_AIRBRUSH;
			break;

		default: /* Unknown tool */
			wacom->tool[idx] = BTN_TOOL_PEN;
			break;
473 474 475 476
		}
		return 1;
	}

477 478 479 480 481
	/* older I4 styli don't work with new Cintiqs */
	if (!((wacom->id[idx] >> 20) & 0x01) &&
			(features->type == WACOM_21UX2))
		return 1;

482 483 484 485 486 487 488
	/* Range Report */
	if ((data[1] & 0xfe) == 0x20) {
		input_report_key(input, BTN_TOUCH, 0);
		input_report_abs(input, ABS_PRESSURE, 0);
		input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);
	}

489 490
	/* Exit report */
	if ((data[1] & 0xfe) == 0x80) {
491
		if (features->quirks & WACOM_QUIRK_MULTI_INPUT)
492 493
			wacom->shared->stylus_in_proximity = false;

494 495 496 497
		/*
		 * Reset all states otherwise we lose the initial states
		 * when in-prox next time
		 */
498 499 500 501 502
		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);
P
Ping Cheng 已提交
503
		if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
504 505 506 507 508 509 510
			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);
511
		} else {
512 513 514 515 516
			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);
517
			if (features->type >= INTUOS3S)
518
				input_report_abs(input, ABS_Z, 0);
P
Ping Cheng 已提交
519
		}
520 521 522
		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]);
523
		wacom->id[idx] = 0;
P
Ping Cheng 已提交
524
		return 2;
525 526 527 528
	}
	return 0;
}

529
static void wacom_intuos_general(struct wacom_wac *wacom)
530
{
531
	struct wacom_features *features = &wacom->features;
532
	unsigned char *data = wacom->data;
533
	struct input_dev *input = wacom->input;
534 535 536 537 538
	unsigned int t;

	/* general pen packet */
	if ((data[1] & 0xb8) == 0xa0) {
		t = (data[6] << 2) | ((data[7] >> 6) & 3);
539
		if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) {
540
			t = (t << 1) | (data[1] & 1);
541
		}
542 543
		input_report_abs(input, ABS_PRESSURE, t);
		input_report_abs(input, ABS_TILT_X,
544
				((data[7] << 1) & 0x7e) | (data[8] >> 7));
545 546 547 548
		input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
		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);
549 550 551 552
	}

	/* airbrush second packet */
	if ((data[1] & 0xbc) == 0xb4) {
553
		input_report_abs(input, ABS_WHEEL,
554
				(data[6] << 2) | ((data[7] >> 6) & 3));
555
		input_report_abs(input, ABS_TILT_X,
556
				((data[7] << 1) & 0x7e) | (data[8] >> 7));
557
		input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
558 559 560
	}
}

561
static int wacom_intuos_irq(struct wacom_wac *wacom)
562
{
563
	struct wacom_features *features = &wacom->features;
564
	unsigned char *data = wacom->data;
565
	struct input_dev *input = wacom->input;
566
	unsigned int t;
567
	int idx = 0, result;
568

569 570 571 572 573 574 575
	if (data[0] != WACOM_REPORT_PENABLED &&
	    data[0] != WACOM_REPORT_INTUOSREAD &&
	    data[0] != WACOM_REPORT_INTUOSWRITE &&
	    data[0] != WACOM_REPORT_INTUOSPAD &&
	    data[0] != WACOM_REPORT_INTUOS5PAD) {
		dev_dbg(input->dev.parent,
			"%s: received unknown report #%d\n", __func__, data[0]);
576 577 578 579
                return 0;
	}

	/* tool number */
580
	if (features->type == INTUOS)
581
		idx = data[1] & 0x01;
582 583

	/* pad packets. Works as a second tool and is always in prox */
584
	if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD) {
585
		if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
586 587 588 589 590 591 592
			input_report_key(input, BTN_0, (data[2] & 0x01));
			input_report_key(input, BTN_1, (data[3] & 0x01));
			input_report_key(input, BTN_2, (data[3] & 0x02));
			input_report_key(input, BTN_3, (data[3] & 0x04));
			input_report_key(input, BTN_4, (data[3] & 0x08));
			input_report_key(input, BTN_5, (data[3] & 0x10));
			input_report_key(input, BTN_6, (data[3] & 0x20));
593
			if (data[1] & 0x80) {
594
				input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
595 596
			} else {
				/* Out of proximity, clear wheel value. */
597
				input_report_abs(input, ABS_WHEEL, 0);
598
			}
599
			if (features->type != INTUOS4S) {
600 601
				input_report_key(input, BTN_7, (data[3] & 0x40));
				input_report_key(input, BTN_8, (data[3] & 0x80));
602 603
			}
			if (data[1] | (data[2] & 0x01) | data[3]) {
604
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
605
			} else {
606
				input_report_abs(input, ABS_MISC, 0);
607
			}
608 609 610 611 612 613 614
		} else if (features->type == DTK) {
			input_report_key(input, BTN_0, (data[6] & 0x01));
			input_report_key(input, BTN_1, (data[6] & 0x02));
			input_report_key(input, BTN_2, (data[6] & 0x04));
			input_report_key(input, BTN_3, (data[6] & 0x08));
			input_report_key(input, BTN_4, (data[6] & 0x10));
			input_report_key(input, BTN_5, (data[6] & 0x20));
615 616 617 618 619
			if (data[6] & 0x3f) {
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
			} else {
				input_report_abs(input, ABS_MISC, 0);
			}
620 621 622 623 624 625 626 627 628 629
		} else if (features->type == WACOM_13HD) {
			input_report_key(input, BTN_0, (data[3] & 0x01));
			input_report_key(input, BTN_1, (data[4] & 0x01));
			input_report_key(input, BTN_2, (data[4] & 0x02));
			input_report_key(input, BTN_3, (data[4] & 0x04));
			input_report_key(input, BTN_4, (data[4] & 0x08));
			input_report_key(input, BTN_5, (data[4] & 0x10));
			input_report_key(input, BTN_6, (data[4] & 0x20));
			input_report_key(input, BTN_7, (data[4] & 0x40));
			input_report_key(input, BTN_8, (data[4] & 0x80));
630 631 632 633 634
			if ((data[3] & 0x01) | data[4]) {
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
			} else {
				input_report_abs(input, ABS_MISC, 0);
			}
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 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
		} else if (features->type == WACOM_24HD) {
			input_report_key(input, BTN_0, (data[6] & 0x01));
			input_report_key(input, BTN_1, (data[6] & 0x02));
			input_report_key(input, BTN_2, (data[6] & 0x04));
			input_report_key(input, BTN_3, (data[6] & 0x08));
			input_report_key(input, BTN_4, (data[6] & 0x10));
			input_report_key(input, BTN_5, (data[6] & 0x20));
			input_report_key(input, BTN_6, (data[6] & 0x40));
			input_report_key(input, BTN_7, (data[6] & 0x80));
			input_report_key(input, BTN_8, (data[8] & 0x01));
			input_report_key(input, BTN_9, (data[8] & 0x02));
			input_report_key(input, BTN_A, (data[8] & 0x04));
			input_report_key(input, BTN_B, (data[8] & 0x08));
			input_report_key(input, BTN_C, (data[8] & 0x10));
			input_report_key(input, BTN_X, (data[8] & 0x20));
			input_report_key(input, BTN_Y, (data[8] & 0x40));
			input_report_key(input, BTN_Z, (data[8] & 0x80));

			/*
			 * 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])
			 */
			input_report_key(input, KEY_PROG1, data[4] & 0x07);
			input_report_key(input, KEY_PROG2, data[4] & 0xE0);
			input_report_key(input, KEY_PROG3, data[3] & 0x1C);

			if (data[1] & 0x80) {
				input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
			} else {
				/* Out of proximity, clear wheel value. */
				input_report_abs(input, ABS_WHEEL, 0);
			}

			if (data[2] & 0x80) {
				input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f));
			} else {
				/* Out of proximity, clear second wheel value. */
				input_report_abs(input, ABS_THROTTLE, 0);
			}

			if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) {
679 680 681 682
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
			} else {
				input_report_abs(input, ABS_MISC, 0);
			}
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
		} 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).
			 */
			input_report_key(input, BTN_1, (data[4] & 0x01));
			input_report_key(input, BTN_2, (data[4] & 0x02));
			input_report_key(input, BTN_3, (data[4] & 0x04));
			input_report_key(input, BTN_4, (data[4] & 0x08));

			input_report_key(input, BTN_5, (data[4] & 0x10));  /* Right  */
			input_report_key(input, BTN_6, (data[4] & 0x20));  /* Up     */
			input_report_key(input, BTN_7, (data[4] & 0x40));  /* Left   */
			input_report_key(input, BTN_8, (data[4] & 0x80));  /* Down   */
			input_report_key(input, BTN_0, (data[3] & 0x01));  /* Center */
699
		} else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
700 701 702 703 704 705
			int i;

			/* Touch ring mode switch has no capacitive sensor */
			input_report_key(input, BTN_0, (data[3] & 0x01));

			/*
706
			 * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
707 708 709 710 711 712 713 714 715 716 717 718 719
			 * addition to the mechanical switch. Switch data is
			 * stored in data[4], capacitive data in data[5].
			 */
			for (i = 0; i < 8; i++)
				input_report_key(input, BTN_1 + i, data[4] & (1 << i));

			if (data[2] & 0x80) {
				input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f));
			} else {
				/* Out of proximity, clear wheel value. */
				input_report_abs(input, ABS_WHEEL, 0);
			}

720
			if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
721 722 723 724
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
			} else {
				input_report_abs(input, ABS_MISC, 0);
			}
725
		} else {
726
			if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
				input_report_key(input, BTN_0, (data[5] & 0x01));
				input_report_key(input, BTN_1, (data[6] & 0x01));
				input_report_key(input, BTN_2, (data[6] & 0x02));
				input_report_key(input, BTN_3, (data[6] & 0x04));
				input_report_key(input, BTN_4, (data[6] & 0x08));
				input_report_key(input, BTN_5, (data[6] & 0x10));
				input_report_key(input, BTN_6, (data[6] & 0x20));
				input_report_key(input, BTN_7, (data[6] & 0x40));
				input_report_key(input, BTN_8, (data[6] & 0x80));
				input_report_key(input, BTN_9, (data[7] & 0x01));
				input_report_key(input, BTN_A, (data[8] & 0x01));
				input_report_key(input, BTN_B, (data[8] & 0x02));
				input_report_key(input, BTN_C, (data[8] & 0x04));
				input_report_key(input, BTN_X, (data[8] & 0x08));
				input_report_key(input, BTN_Y, (data[8] & 0x10));
				input_report_key(input, BTN_Z, (data[8] & 0x20));
				input_report_key(input, BTN_BASE, (data[8] & 0x40));
				input_report_key(input, BTN_BASE2, (data[8] & 0x80));
745 746 747 748 749 750

				if (features->type == WACOM_22HD) {
					input_report_key(input, KEY_PROG1, data[9] & 0x01);
					input_report_key(input, KEY_PROG2, data[9] & 0x02);
					input_report_key(input, KEY_PROG3, data[9] & 0x04);
				}
751 752 753 754 755 756 757 758 759 760 761 762
			} else {
				input_report_key(input, BTN_0, (data[5] & 0x01));
				input_report_key(input, BTN_1, (data[5] & 0x02));
				input_report_key(input, BTN_2, (data[5] & 0x04));
				input_report_key(input, BTN_3, (data[5] & 0x08));
				input_report_key(input, BTN_4, (data[6] & 0x01));
				input_report_key(input, BTN_5, (data[6] & 0x02));
				input_report_key(input, BTN_6, (data[6] & 0x04));
				input_report_key(input, BTN_7, (data[6] & 0x08));
				input_report_key(input, BTN_8, (data[5] & 0x10));
				input_report_key(input, BTN_9, (data[6] & 0x10));
			}
763 764
			input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
			input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
765

766
			if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
767 768
				data[2] | (data[3] & 0x1f) | data[4] | data[8] |
				(data[7] & 0x01)) {
769
				input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
770
			} else {
771
				input_report_abs(input, ABS_MISC, 0);
772 773
			}
		}
774
		input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
775 776 777 778
                return 1;
	}

	/* process in/out prox events */
779
	result = wacom_intuos_inout(wacom);
780
	if (result)
781
                return result - 1;
782

783 784 785 786 787
	/* don't proceed if we don't know the ID */
	if (!wacom->id[idx])
		return 0;

	/* Only large Intuos support Lense Cursor */
788 789 790 791
	if (wacom->tool[idx] == BTN_TOOL_LENS &&
	    (features->type == INTUOS3 ||
	     features->type == INTUOS3S ||
	     features->type == INTUOS4 ||
792 793
	     features->type == INTUOS4S ||
	     features->type == INTUOS5 ||
794 795 796
	     features->type == INTUOS5S ||
	     features->type == INTUOSPM ||
	     features->type == INTUOSPS)) {
797

P
Ping Cheng 已提交
798
		return 0;
799
	}
P
Ping Cheng 已提交
800

801
	/* Cintiq doesn't send data when RDY bit isn't set */
802
	if (features->type == CINTIQ && !(data[1] & 0x40))
803 804
                 return 0;

805
	if (features->type >= INTUOS3S) {
806 807 808
		input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
		input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
		input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
809
	} else {
810 811
		input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2]));
		input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4]));
812
		input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
813 814 815
	}

	/* process general packets */
816
	wacom_intuos_general(wacom);
817

818 819
	/* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */
	if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) {
820 821 822

		if (data[1] & 0x02) {
			/* Rotation packet */
823
			if (features->type >= INTUOS3S) {
824
				/* I3 marker pen rotation */
825 826 827
				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) ;
828
				input_report_abs(input, ABS_Z, t);
829 830 831
			} else {
				/* 4D mouse rotation packet */
				t = (data[6] << 3) | ((data[7] >> 5) & 7);
832
				input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
833 834 835
					((t - 1) / 2) : -t / 2);
			}

836
		} else if (!(data[1] & 0x10) && features->type < INTUOS3S) {
837
			/* 4D mouse packet */
838 839 840
			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);
841

842 843
			input_report_key(input, BTN_SIDE,   data[8] & 0x20);
			input_report_key(input, BTN_EXTRA,  data[8] & 0x10);
844
			t = (data[6] << 2) | ((data[7] >> 6) & 3);
845
			input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
846 847

		} else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
848
			/* I4 mouse */
849
			if (features->type >= INTUOS4S && features->type <= INTUOSPL) {
850 851 852 853
				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)
854
						 - ((data[7] & 0x40) >> 6));
855 856
				input_report_key(input, BTN_SIDE,   data[6] & 0x08);
				input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
857

858
				input_report_abs(input, ABS_TILT_X,
859
					((data[7] << 1) & 0x7e) | (data[8] >> 7));
860
				input_report_abs(input, ABS_TILT_Y, data[8] & 0x7f);
861 862
			} else {
				/* 2D mouse packet */
863 864 865 866
				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)
867 868
						 - ((data[8] & 0x02) >> 1));

869
				/* I3 2D mouse side buttons */
870
				if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
871 872
					input_report_key(input, BTN_SIDE,   data[8] & 0x40);
					input_report_key(input, BTN_EXTRA,  data[8] & 0x20);
873
				}
874
			}
875
		} else if ((features->type < INTUOS3S || features->type == INTUOS3L ||
876 877
				features->type == INTUOS4L || features->type == INTUOS5L ||
				features->type == INTUOSPL) &&
878
			   wacom->tool[idx] == BTN_TOOL_LENS) {
879
			/* Lens cursor packets */
880 881 882 883 884
			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);
885 886 887
		}
	}

888 889 890
	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]);
891 892 893
	return 1;
}

894 895 896 897 898 899 900 901 902 903 904
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);
}

static int wacom_24hdt_irq(struct wacom_wac *wacom)
{
	struct input_dev *input = wacom->input;
905
	unsigned char *data = wacom->data;
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922
	int i;
	int current_num_contacts = data[61];
	int contacts_to_send = 0;

	/*
	 * First packet resets the counter since only the first
	 * packet in series will have non-zero current_num_contacts.
	 */
	if (current_num_contacts)
		wacom->num_contacts_left = current_num_contacts;

	/* There are at most 4 contacts per packet */
	contacts_to_send = min(4, wacom->num_contacts_left);

	for (i = 0; i < contacts_to_send; i++) {
		int offset = (WACOM_BYTES_PER_24HDT_PACKET * i) + 1;
		bool touch = data[offset] & 0x1 && !wacom->shared->stylus_in_proximity;
923
		int slot = input_mt_get_slot_by_key(input, data[offset + 1]);
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954

		if (slot < 0)
			continue;
		input_mt_slot(input, slot);
		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);

		if (touch) {
			int t_x = le16_to_cpup((__le16 *)&data[offset + 2]);
			int c_x = le16_to_cpup((__le16 *)&data[offset + 4]);
			int t_y = le16_to_cpup((__le16 *)&data[offset + 6]);
			int c_y = le16_to_cpup((__le16 *)&data[offset + 8]);
			int w = le16_to_cpup((__le16 *)&data[offset + 10]);
			int h = le16_to_cpup((__le16 *)&data[offset + 12]);

			input_report_abs(input, ABS_MT_POSITION_X, t_x);
			input_report_abs(input, ABS_MT_POSITION_Y, t_y);
			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);
		}
	}
	input_mt_report_pointer_emulation(input, true);

	wacom->num_contacts_left -= contacts_to_send;
	if (wacom->num_contacts_left <= 0)
		wacom->num_contacts_left = 0;

	return 1;
}

955 956 957
static int wacom_mt_touch(struct wacom_wac *wacom)
{
	struct input_dev *input = wacom->input;
958
	unsigned char *data = wacom->data;
959 960 961
	int i;
	int current_num_contacts = data[2];
	int contacts_to_send = 0;
962 963 964 965 966
	int x_offset = 0;

	/* MTTPC does not support Height and Width */
	if (wacom->features.type == MTTPC)
		x_offset = -4;
967 968 969 970 971 972 973 974 975 976 977 978

	/*
	 * First packet resets the counter since only the first
	 * packet in series will have non-zero current_num_contacts.
	 */
	if (current_num_contacts)
		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++) {
979
		int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;
980 981
		bool touch = data[offset] & 0x1;
		int id = le16_to_cpup((__le16 *)&data[offset + 1]);
982
		int slot = input_mt_get_slot_by_key(input, id);
983 984 985 986 987 988 989

		if (slot < 0)
			continue;

		input_mt_slot(input, slot);
		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
		if (touch) {
990 991
			int x = le16_to_cpup((__le16 *)&data[offset + x_offset + 7]);
			int y = le16_to_cpup((__le16 *)&data[offset + x_offset + 9]);
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
			input_report_abs(input, ABS_MT_POSITION_X, x);
			input_report_abs(input, ABS_MT_POSITION_Y, y);
		}
	}
	input_mt_report_pointer_emulation(input, true);

	wacom->num_contacts_left -= contacts_to_send;
	if (wacom->num_contacts_left < 0)
		wacom->num_contacts_left = 0;

	return 1;
}

1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
static int wacom_tpc_mt_touch(struct wacom_wac *wacom)
{
	struct input_dev *input = wacom->input;
	unsigned char *data = wacom->data;
	int contact_with_no_pen_down_count = 0;
	int i;

	for (i = 0; i < 2; i++) {
		int p = data[1] & (1 << i);
		bool touch = p && !wacom->shared->stylus_in_proximity;

		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);
			contact_with_no_pen_down_count++;
		}
	}
1027
	input_mt_report_pointer_emulation(input, true);
1028 1029 1030 1031 1032 1033 1034

	/* keep touch state for pen event */
	wacom->shared->touch_down = (contact_with_no_pen_down_count > 0);

	return 1;
}

1035
static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)
1036
{
1037
	unsigned char *data = wacom->data;
1038
	struct input_dev *input = wacom->input;
1039 1040
	bool prox;
	int x = 0, y = 0;
1041

1042 1043 1044
	if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)
		return 0;

1045 1046 1047 1048 1049
	if (!wacom->shared->stylus_in_proximity) {
		if (len == WACOM_PKGLEN_TPC1FG) {
			prox = data[0] & 0x01;
			x = get_unaligned_le16(&data[1]);
			y = get_unaligned_le16(&data[3]);
1050
		} else {
1051 1052 1053 1054 1055 1056 1057
			prox = data[1] & 0x01;
			x = le16_to_cpup((__le16 *)&data[2]);
			y = le16_to_cpup((__le16 *)&data[4]);
		}
	} else
		/* force touch out when pen is in prox */
		prox = 0;
1058

1059 1060 1061 1062 1063
	if (prox) {
		input_report_abs(input, ABS_X, x);
		input_report_abs(input, ABS_Y, y);
	}
	input_report_key(input, BTN_TOUCH, prox);
1064

1065 1066
	/* keep touch state for pen events */
	wacom->shared->touch_down = prox;
1067

1068
	return 1;
1069 1070
}

1071
static int wacom_tpc_pen(struct wacom_wac *wacom)
1072
{
1073
	unsigned char *data = wacom->data;
1074
	struct input_dev *input = wacom->input;
1075
	bool prox = data[1] & 0x20;
1076

1077
	if (!wacom->shared->stylus_in_proximity) /* first in prox */
1078 1079 1080
		/* Going into proximity select tool */
		wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;

1081 1082 1083 1084 1085 1086 1087 1088 1089
	/* keep pen state for touch events */
	wacom->shared->stylus_in_proximity = prox;

	/* send pen events only when touch is up or forced out */
	if (!wacom->shared->touch_down) {
		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]));
1090
		input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x03) << 8) | data[6]);
1091 1092 1093
		input_report_key(input, BTN_TOUCH, data[1] & 0x05);
		input_report_key(input, wacom->tool[0], prox);
		return 1;
1094 1095
	}

1096
	return 0;
1097 1098 1099 1100
}

static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
{
1101
	unsigned char *data = wacom->data;
1102

1103 1104
	dev_dbg(wacom->input->dev.parent,
		"%s: received report #%d\n", __func__, data[0]);
1105

1106 1107
	switch (len) {
	case WACOM_PKGLEN_TPC1FG:
1108
		return wacom_tpc_single_touch(wacom, len);
1109 1110

	case WACOM_PKGLEN_TPC2FG:
1111
		return wacom_tpc_mt_touch(wacom);
1112 1113 1114 1115 1116 1117

	default:
		switch (data[0]) {
		case WACOM_REPORT_TPC1FG:
		case WACOM_REPORT_TPCHID:
		case WACOM_REPORT_TPCST:
1118
		case WACOM_REPORT_TPC1FGE:
1119 1120
			return wacom_tpc_single_touch(wacom, len);

1121 1122 1123
		case WACOM_REPORT_TPCMT:
			return wacom_mt_touch(wacom);

1124 1125 1126 1127
		case WACOM_REPORT_PENABLED:
			return wacom_tpc_pen(wacom);
		}
	}
1128

1129
	return 0;
1130 1131
}

1132
static int wacom_bpt_touch(struct wacom_wac *wacom)
1133
{
1134
	struct wacom_features *features = &wacom->features;
1135 1136 1137 1138
	struct input_dev *input = wacom->input;
	unsigned char *data = wacom->data;
	int i;

1139 1140 1141
	if (data[0] != 0x02)
	    return 0;

1142
	for (i = 0; i < 2; i++) {
1143 1144
		int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);
		bool touch = data[offset + 3] & 0x80;
1145

1146 1147 1148 1149 1150 1151
		/*
		 * Touch events need to be disabled while stylus is
		 * in proximity because user's hand is resting on touchpad
		 * and sending unwanted events.  User expects tablet buttons
		 * to continue working though.
		 */
1152 1153 1154 1155
		touch = touch && !wacom->shared->stylus_in_proximity;

		input_mt_slot(input, i);
		input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
1156
		if (touch) {
1157 1158
			int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;
			int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;
1159 1160 1161 1162
			if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {
				x <<= 5;
				y <<= 5;
			}
1163 1164 1165 1166 1167
			input_report_abs(input, ABS_MT_POSITION_X, x);
			input_report_abs(input, ABS_MT_POSITION_Y, y);
		}
	}

1168
	input_mt_report_pointer_emulation(input, true);
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179

	input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);
	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
	input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);
	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);

	input_sync(input);

	return 0;
}

1180 1181
static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)
{
1182
	struct wacom_features *features = &wacom->features;
1183 1184
	struct input_dev *input = wacom->input;
	bool touch = data[1] & 0x80;
1185 1186 1187 1188
	int slot = input_mt_get_slot_by_key(input, data[0]);

	if (slot < 0)
		return;
1189 1190 1191

	touch = touch && !wacom->shared->stylus_in_proximity;

1192
	input_mt_slot(input, slot);
1193 1194 1195 1196 1197
	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);
1198
		int width, height;
1199

1200
		if (features->type >= INTUOSPS && features->type <= INTUOSPL) {
1201 1202
			width  = data[5] * 100;
			height = data[6] * 100;
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
		} 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];
			int x_res  = input_abs_get_res(input, ABS_X);
			int y_res  = input_abs_get_res(input, ABS_Y);
			width  = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);
			height = width * y_res / x_res;
		}
1215 1216 1217

		input_report_abs(input, ABS_MT_POSITION_X, x);
		input_report_abs(input, ABS_MT_POSITION_Y, y);
1218 1219
		input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);
		input_report_abs(input, ABS_MT_TOUCH_MINOR, height);
1220 1221 1222 1223 1224 1225
	}
}

static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)
{
	struct input_dev *input = wacom->input;
1226
	struct wacom_features *features = &wacom->features;
1227

1228 1229 1230 1231 1232 1233 1234
	if (features->type == INTUOSHT) {
		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);
	}
1235 1236 1237 1238 1239 1240 1241 1242
	input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);
	input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);
}

static int wacom_bpt3_touch(struct wacom_wac *wacom)
{
	struct input_dev *input = wacom->input;
	unsigned char *data = wacom->data;
1243
	int count = data[1] & 0x07;
1244 1245
	int i;

1246 1247 1248
	if (data[0] != 0x02)
	    return 0;

1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266
	/* 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];

		if (msg_id >= 2 && msg_id <= 17)
			wacom_bpt3_touch_msg(wacom, data + offset);
		else if (msg_id == 128)
			wacom_bpt3_button_msg(wacom, data + offset);

	}
	input_mt_report_pointer_emulation(input, true);

	input_sync(input);

	return 0;
}

1267 1268
static int wacom_bpt_pen(struct wacom_wac *wacom)
{
1269
	struct wacom_features *features = &wacom->features;
1270 1271 1272 1273
	struct input_dev *input = wacom->input;
	unsigned char *data = wacom->data;
	int prox = 0, x = 0, y = 0, p = 0, d = 0, pen = 0, btn1 = 0, btn2 = 0;

1274
	if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_USB)
1275 1276
	    return 0;

1277 1278 1279 1280 1281 1282 1283 1284 1285
	if (data[0] == WACOM_REPORT_USB) {
		if (features->type == INTUOSHT && features->touch_max) {
			input_report_switch(wacom->shared->touch_input,
					    SW_MUTE_DEVICE, data[8] & 0x40);
			input_sync(wacom->shared->touch_input);
		}
		return 0;
	}

1286
	prox = (data[1] & 0x20) == 0x20;
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311

	/*
	 * 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.
	 */
	if (prox) {
		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;
			}
			wacom->shared->stylus_in_proximity = true;
		}
		x = le16_to_cpup((__le16 *)&data[2]);
		y = le16_to_cpup((__le16 *)&data[4]);
		p = le16_to_cpup((__le16 *)&data[6]);
1312 1313 1314 1315 1316 1317
		/*
		 * 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.
		 */
1318 1319
		if (data[8] <= features->distance_max)
			d = features->distance_max - data[8];
1320

1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
		pen = data[1] & 0x01;
		btn1 = data[1] & 0x02;
		btn2 = data[1] & 0x04;
	}

	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);

	if (!prox) {
		wacom->id[0] = 0;
		wacom->shared->stylus_in_proximity = false;
	}

	input_report_key(input, wacom->tool[0], prox); /* PEN or RUBBER */
	input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */

	return 1;
}

1346 1347 1348 1349
static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
{
	if (len == WACOM_PKGLEN_BBTOUCH)
		return wacom_bpt_touch(wacom);
1350 1351 1352
	else if (len == WACOM_PKGLEN_BBTOUCH3)
		return wacom_bpt3_touch(wacom);
	else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN)
1353
		return wacom_bpt_pen(wacom);
1354 1355 1356 1357

	return 0;
}

1358 1359
static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)
{
1360 1361 1362
	unsigned char *data = wacom->data;
	int connected;

1363
	if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)
1364 1365
		return 0;

1366 1367
	connected = data[1] & 0x01;
	if (connected) {
1368
		int pid, battery;
1369

1370 1371 1372 1373 1374 1375 1376
		if ((wacom->shared->type == INTUOSHT) &&
				wacom->shared->touch_max) {
			input_report_switch(wacom->shared->touch_input,
					SW_MUTE_DEVICE, data[5] & 0x40);
			input_sync(wacom->shared->touch_input);
		}

1377
		pid = get_unaligned_be16(&data[6]);
1378
		battery = data[5] & 0x3f;
1379 1380 1381 1382
		if (wacom->pid != pid) {
			wacom->pid = pid;
			wacom_schedule_work(wacom);
		}
1383
		wacom->battery_capacity = battery;
1384 1385 1386 1387
	} else if (wacom->pid != 0) {
		/* disconnected while previously connected */
		wacom->pid = 0;
		wacom_schedule_work(wacom);
1388
		wacom->battery_capacity = 0;
1389 1390
	}

1391 1392 1393
	return 0;
}

1394
void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
1395
{
1396 1397
	bool sync;

1398
	switch (wacom_wac->features.type) {
1399
	case PENPARTNER:
1400 1401
		sync = wacom_penpartner_irq(wacom_wac);
		break;
1402 1403

	case PL:
1404 1405
		sync = wacom_pl_irq(wacom_wac);
		break;
1406 1407 1408 1409

	case WACOM_G4:
	case GRAPHIRE:
	case WACOM_MO:
1410 1411
		sync = wacom_graphire_irq(wacom_wac);
		break;
1412 1413

	case PTU:
1414 1415
		sync = wacom_ptu_irq(wacom_wac);
		break;
1416

1417 1418 1419 1420
	case DTU:
		sync = wacom_dtu_irq(wacom_wac);
		break;

1421 1422 1423 1424
	case DTUS:
		sync = wacom_dtus_irq(wacom_wac);
		break;

1425 1426 1427 1428 1429 1430 1431 1432 1433
	case INTUOS:
	case INTUOS3S:
	case INTUOS3:
	case INTUOS3L:
	case INTUOS4S:
	case INTUOS4:
	case INTUOS4L:
	case CINTIQ:
	case WACOM_BEE:
1434
	case WACOM_13HD:
1435
	case WACOM_21UX2:
1436
	case WACOM_22HD:
1437
	case WACOM_24HD:
1438
	case DTK:
1439
	case CINTIQ_HYBRID:
1440 1441
		sync = wacom_intuos_irq(wacom_wac);
		break;
1442

1443 1444 1445 1446
	case WACOM_24HDT:
		sync = wacom_24hdt_irq(wacom_wac);
		break;

1447 1448 1449
	case INTUOS5S:
	case INTUOS5:
	case INTUOS5L:
1450 1451 1452
	case INTUOSPS:
	case INTUOSPM:
	case INTUOSPL:
1453 1454 1455 1456 1457 1458
		if (len == WACOM_PKGLEN_BBTOUCH3)
			sync = wacom_bpt3_touch(wacom_wac);
		else
			sync = wacom_intuos_irq(wacom_wac);
		break;

1459
	case TABLETPC:
1460
	case TABLETPCE:
1461
	case TABLETPC2FG:
1462
	case MTSCREEN:
1463
	case MTTPC:
1464 1465
		sync = wacom_tpc_irq(wacom_wac, len);
		break;
1466

1467
	case BAMBOO_PT:
1468
	case INTUOSHT:
1469 1470 1471
		sync = wacom_bpt_irq(wacom_wac, len);
		break;

1472 1473 1474 1475
	case WIRELESS:
		sync = wacom_wireless_irq(wacom_wac, len);
		break;

1476
	default:
1477 1478
		sync = false;
		break;
1479
	}
1480 1481 1482

	if (sync)
		input_sync(wacom_wac->input);
1483 1484
}

1485
static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503
{
	struct input_dev *input_dev = wacom_wac->input;

	input_set_capability(input_dev, EV_MSC, MSC_SERIAL);

	__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
	__set_bit(BTN_TOOL_PEN, 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);
	__set_bit(BTN_STYLUS, input_dev->keybit);
	__set_bit(BTN_STYLUS2, input_dev->keybit);

	input_set_abs_params(input_dev, ABS_DISTANCE,
			     0, wacom_wac->features.distance_max, 0, 0);
	input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
	input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
	input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
}

static void wacom_setup_intuos(struct wacom_wac *wacom_wac)
{
	struct input_dev *input_dev = wacom_wac->input;

	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);

1522 1523 1524 1525
	input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
	input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
}

1526 1527 1528 1529
void wacom_setup_device_quirks(struct wacom_features *features)
{

	/* touch device found but size is not defined. use default */
1530
	if (features->device_type == BTN_TOOL_FINGER && !features->x_max) {
1531 1532 1533 1534 1535
		features->x_max = 1023;
		features->y_max = 1023;
	}

	/* these device have multiple inputs */
P
Ping Cheng 已提交
1536
	if (features->type >= WIRELESS ||
1537
	    (features->type >= INTUOS5S && features->type <= INTUOSHT) ||
1538
	    (features->oVid && features->oPid))
1539
		features->quirks |= WACOM_QUIRK_MULTI_INPUT;
1540

1541
	/* quirk for bamboo touch with 2 low res touches */
1542
	if (features->type == BAMBOO_PT &&
1543
	    features->pktlen == WACOM_PKGLEN_BBTOUCH) {
1544 1545 1546 1547 1548
		features->x_max <<= 5;
		features->y_max <<= 5;
		features->x_fuzz <<= 5;
		features->y_fuzz <<= 5;
		features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;
1549
	}
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559

	if (features->type == WIRELESS) {

		/* monitor never has input and pen/touch have delayed create */
		features->quirks |= WACOM_QUIRK_NO_INPUT;

		/* must be monitor interface if no device_type set */
		if (!features->device_type)
			features->quirks |= WACOM_QUIRK_MONITOR;
	}
1560 1561
}

1562 1563
static void wacom_abs_set_axis(struct input_dev *input_dev,
			       struct wacom_wac *wacom_wac)
1564
{
1565 1566
	struct wacom_features *features = &wacom_wac->features;

1567
	if (features->device_type == BTN_TOOL_PEN) {
1568 1569 1570 1571 1572 1573
		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_set_abs_params(input_dev, ABS_PRESSURE, 0,
			features->pressure_max, features->pressure_fuzz, 0);
1574

1575 1576 1577 1578
		/* 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);
	} else {
1579 1580 1581 1582 1583 1584
		if (features->touch_max <= 2) {
			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,
1585
					  features->x_resolution);
1586
			input_abs_set_res(input_dev, ABS_Y,
1587
					  features->y_resolution);
1588 1589 1590 1591 1592 1593 1594 1595
		}

		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,
1596
					  features->x_resolution);
1597
			input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
1598
					  features->y_resolution);
1599
		}
1600
	}
1601
}
1602

1603 1604 1605 1606 1607 1608 1609 1610 1611
int wacom_setup_input_capabilities(struct input_dev *input_dev,
				   struct wacom_wac *wacom_wac)
{
	struct wacom_features *features = &wacom_wac->features;
	int i;

	input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

	__set_bit(BTN_TOUCH, input_dev->keybit);
1612 1613
	__set_bit(ABS_MISC, input_dev->absbit);

1614 1615
	wacom_abs_set_axis(input_dev, wacom_wac);

1616
	switch (features->type) {
1617
	case WACOM_MO:
1618 1619
		input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
		/* fall through */
1620 1621

	case WACOM_G4:
1622 1623
		input_set_capability(input_dev, EV_MSC, MSC_SERIAL);

1624 1625
		__set_bit(BTN_BACK, input_dev->keybit);
		__set_bit(BTN_FORWARD, input_dev->keybit);
1626 1627 1628
		/* fall through */

	case GRAPHIRE:
1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639
		input_set_capability(input_dev, EV_REL, REL_WHEEL);

		__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);
1640 1641

		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1642 1643
		break;

1644 1645 1646 1647 1648 1649 1650 1651
	case WACOM_24HD:
		__set_bit(BTN_A, input_dev->keybit);
		__set_bit(BTN_B, input_dev->keybit);
		__set_bit(BTN_C, input_dev->keybit);
		__set_bit(BTN_X, input_dev->keybit);
		__set_bit(BTN_Y, input_dev->keybit);
		__set_bit(BTN_Z, input_dev->keybit);

1652
		for (i = 6; i < 10; i++)
1653 1654 1655 1656 1657
			__set_bit(BTN_0 + i, input_dev->keybit);

		__set_bit(KEY_PROG1, input_dev->keybit);
		__set_bit(KEY_PROG2, input_dev->keybit);
		__set_bit(KEY_PROG3, input_dev->keybit);
1658 1659 1660

		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
		input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
1661 1662 1663 1664 1665
		/* fall through */

	case DTK:
		for (i = 0; i < 6; i++)
			__set_bit(BTN_0 + i, input_dev->keybit);
1666

1667 1668
		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

1669 1670 1671
		wacom_setup_cintiq(wacom_wac);
		break;

1672 1673 1674 1675 1676 1677
	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 */

1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
	case WACOM_21UX2:
		__set_bit(BTN_A, input_dev->keybit);
		__set_bit(BTN_B, input_dev->keybit);
		__set_bit(BTN_C, input_dev->keybit);
		__set_bit(BTN_X, input_dev->keybit);
		__set_bit(BTN_Y, input_dev->keybit);
		__set_bit(BTN_Z, input_dev->keybit);
		__set_bit(BTN_BASE, input_dev->keybit);
		__set_bit(BTN_BASE2, input_dev->keybit);
		/* fall through */

1689
	case WACOM_BEE:
1690 1691 1692
		__set_bit(BTN_8, input_dev->keybit);
		__set_bit(BTN_9, input_dev->keybit);
		/* fall through */
1693

1694 1695 1696 1697
	case CINTIQ:
		for (i = 0; i < 8; i++)
			__set_bit(BTN_0 + i, input_dev->keybit);

1698 1699
		input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
		input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
1700
		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1701 1702 1703

		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

1704 1705 1706
		wacom_setup_cintiq(wacom_wac);
		break;

1707 1708 1709 1710 1711 1712 1713 1714 1715
	case WACOM_13HD:
		for (i = 0; i < 9; i++)
			__set_bit(BTN_0 + i, input_dev->keybit);

		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
		wacom_setup_cintiq(wacom_wac);
		break;

1716 1717
	case INTUOS3:
	case INTUOS3L:
1718 1719 1720 1721 1722 1723
		__set_bit(BTN_4, input_dev->keybit);
		__set_bit(BTN_5, input_dev->keybit);
		__set_bit(BTN_6, input_dev->keybit);
		__set_bit(BTN_7, input_dev->keybit);

		input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
1724 1725 1726
		/* fall through */

	case INTUOS3S:
1727 1728 1729 1730 1731 1732 1733
		__set_bit(BTN_0, input_dev->keybit);
		__set_bit(BTN_1, input_dev->keybit);
		__set_bit(BTN_2, input_dev->keybit);
		__set_bit(BTN_3, input_dev->keybit);

		input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
1734 1735 1736
		/* fall through */

	case INTUOS:
1737 1738
		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);

1739
		wacom_setup_intuos(wacom_wac);
1740 1741
		break;

1742 1743
	case INTUOS5:
	case INTUOS5L:
1744 1745
	case INTUOSPM:
	case INTUOSPL:
1746 1747 1748 1749 1750 1751 1752
		if (features->device_type == BTN_TOOL_PEN) {
			__set_bit(BTN_7, input_dev->keybit);
			__set_bit(BTN_8, input_dev->keybit);
		}
		/* fall through */

	case INTUOS5S:
1753
	case INTUOSPS:
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);

		if (features->device_type == BTN_TOOL_PEN) {
			for (i = 0; i < 7; i++)
				__set_bit(BTN_0 + i, input_dev->keybit);

			input_set_abs_params(input_dev, ABS_DISTANCE, 0,
					      features->distance_max,
					      0, 0);

			input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);

			wacom_setup_intuos(wacom_wac);
		} else if (features->device_type == BTN_TOOL_FINGER) {
			__clear_bit(ABS_MISC, input_dev->absbit);

			input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
1771 1772 1773
			                     0, features->x_max, 0, 0);
			input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
			                     0, features->y_max, 0, 0);
1774
			input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);
1775 1776 1777
		}
		break;

1778 1779
	case INTUOS4:
	case INTUOS4L:
1780 1781
		__set_bit(BTN_7, input_dev->keybit);
		__set_bit(BTN_8, input_dev->keybit);
1782 1783 1784
		/* fall through */

	case INTUOS4S:
1785 1786 1787 1788 1789
		for (i = 0; i < 7; i++)
			__set_bit(BTN_0 + i, input_dev->keybit);

		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
		wacom_setup_intuos(wacom_wac);
1790 1791

		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1792 1793
		break;

1794 1795 1796 1797 1798 1799 1800 1801 1802
	case WACOM_24HDT:
		if (features->device_type == BTN_TOOL_FINGER) {
			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 */

1803
	case MTSCREEN:
1804
	case MTTPC:
1805 1806
	case TABLETPC2FG:
		if (features->device_type == BTN_TOOL_FINGER) {
1807 1808 1809 1810 1811 1812
			unsigned int flags = INPUT_MT_DIRECT;

			if (wacom_wac->features.type == TABLETPC2FG)
				flags = 0;

			input_mt_init_slots(input_dev, features->touch_max, flags);
1813
		}
1814 1815 1816
		/* fall through */

	case TABLETPC:
1817
	case TABLETPCE:
1818 1819
		__clear_bit(ABS_MISC, input_dev->absbit);

1820 1821
		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

1822
		if (features->device_type != BTN_TOOL_PEN)
1823
			break;  /* no need to process stylus stuff */
1824

1825 1826
		/* fall through */

1827
	case DTUS:
1828
	case PL:
1829
	case DTU:
1830 1831
		if (features->type == DTUS) {
			input_set_capability(input_dev, EV_MSC, MSC_SERIAL);
1832
			for (i = 0; i < 4; i++)
1833 1834
				__set_bit(BTN_0 + i, input_dev->keybit);
		}
1835
		__set_bit(BTN_TOOL_PEN, input_dev->keybit);
1836
		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1837 1838
		__set_bit(BTN_STYLUS, input_dev->keybit);
		__set_bit(BTN_STYLUS2, input_dev->keybit);
1839 1840 1841 1842 1843

		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
		break;

	case PTU:
1844
		__set_bit(BTN_STYLUS2, input_dev->keybit);
1845 1846 1847
		/* fall through */

	case PENPARTNER:
1848
		__set_bit(BTN_TOOL_PEN, input_dev->keybit);
1849
		__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
1850
		__set_bit(BTN_STYLUS, input_dev->keybit);
1851 1852

		__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1853
		break;
1854

1855
	case INTUOSHT:
1856 1857 1858 1859 1860 1861 1862
		if (features->touch_max &&
		    features->device_type == BTN_TOOL_FINGER) {
			input_dev->evbit[0] |= BIT_MASK(EV_SW);
			__set_bit(SW_MUTE_DEVICE, input_dev->swbit);
		}
		/* fall through */

1863 1864 1865
	case BAMBOO_PT:
		__clear_bit(ABS_MISC, input_dev->absbit);

1866
		if (features->device_type == BTN_TOOL_FINGER) {
1867

1868 1869 1870 1871 1872
			__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);

1873 1874 1875 1876 1877 1878 1879
			if (features->touch_max) {
				/* touch interface */
				unsigned int flags = INPUT_MT_POINTER;

				__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
				if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
					input_set_abs_params(input_dev,
1880
						     ABS_MT_TOUCH_MAJOR,
1881
						     0, features->x_max, 0, 0);
1882
					input_set_abs_params(input_dev,
1883 1884
						     ABS_MT_TOUCH_MINOR,
						     0, features->y_max, 0, 0);
1885 1886 1887 1888 1889 1890
				} else {
					__set_bit(BTN_TOOL_FINGER, input_dev->keybit);
					__set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
					flags = 0;
				}
				input_mt_init_slots(input_dev, features->touch_max, flags);
1891
			} else {
1892 1893 1894 1895
				/* buttons/keys only interface */
				__clear_bit(ABS_X, input_dev->absbit);
				__clear_bit(ABS_Y, input_dev->absbit);
				__clear_bit(BTN_TOUCH, input_dev->keybit);
1896
			}
1897
		} else if (features->device_type == BTN_TOOL_PEN) {
1898
			__set_bit(INPUT_PROP_POINTER, input_dev->propbit);
1899 1900 1901 1902
			__set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
			__set_bit(BTN_TOOL_PEN, input_dev->keybit);
			__set_bit(BTN_STYLUS, input_dev->keybit);
			__set_bit(BTN_STYLUS2, input_dev->keybit);
1903 1904 1905
			input_set_abs_params(input_dev, ABS_DISTANCE, 0,
					      features->distance_max,
					      0, 0);
1906 1907
		}
		break;
1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925

	case CINTIQ_HYBRID:
		__set_bit(BTN_1, input_dev->keybit);
		__set_bit(BTN_2, input_dev->keybit);
		__set_bit(BTN_3, input_dev->keybit);
		__set_bit(BTN_4, input_dev->keybit);

		__set_bit(BTN_5, input_dev->keybit);
		__set_bit(BTN_6, input_dev->keybit);
		__set_bit(BTN_7, input_dev->keybit);
		__set_bit(BTN_8, input_dev->keybit);
		__set_bit(BTN_0, input_dev->keybit);

		input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
		__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);

		wacom_setup_cintiq(wacom_wac);
		break;
1926
	}
1927
	return 0;
1928 1929
}

1930
static const struct wacom_features wacom_features_0x00 =
1931 1932
	{ "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,
	  0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
1933
static const struct wacom_features wacom_features_0x10 =
1934 1935
	{ "Wacom Graphire",       WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1936
static const struct wacom_features wacom_features_0x11 =
1937 1938
	{ "Wacom Graphire2 4x5",  WACOM_PKGLEN_GRAPHIRE,  10206,  7422,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1939
static const struct wacom_features wacom_features_0x12 =
1940 1941
	{ "Wacom Graphire2 5x7",  WACOM_PKGLEN_GRAPHIRE,  13918, 10206,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1942
static const struct wacom_features wacom_features_0x13 =
1943 1944
	{ "Wacom Graphire3",      WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1945
static const struct wacom_features wacom_features_0x14 =
1946 1947
	{ "Wacom Graphire3 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1948
static const struct wacom_features wacom_features_0x15 =
1949 1950
	{ "Wacom Graphire4 4x5",  WACOM_PKGLEN_GRAPHIRE,  10208,  7424,  511,
	  63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1951
static const struct wacom_features wacom_features_0x16 =
1952 1953
	{ "Wacom Graphire4 6x8",  WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
	  63, WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1954
static const struct wacom_features wacom_features_0x17 =
1955 1956
	{ "Wacom BambooFun 4x5",  WACOM_PKGLEN_BBFUN,     14760,  9225,  511,
	  63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1957
static const struct wacom_features wacom_features_0x18 =
1958 1959
	{ "Wacom BambooFun 6x8",  WACOM_PKGLEN_BBFUN,     21648, 13530,  511,
	  63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1960
static const struct wacom_features wacom_features_0x19 =
1961 1962
	{ "Wacom Bamboo1 Medium", WACOM_PKGLEN_GRAPHIRE,  16704, 12064,  511,
	  63, GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };
1963
static const struct wacom_features wacom_features_0x60 =
1964 1965
	{ "Wacom Volito",         WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
	  63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1966
static const struct wacom_features wacom_features_0x61 =
1967 1968
	{ "Wacom PenStation2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  255,
	  63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1969
static const struct wacom_features wacom_features_0x62 =
1970 1971
	{ "Wacom Volito2 4x5",    WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
	  63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1972
static const struct wacom_features wacom_features_0x63 =
1973 1974
	{ "Wacom Volito2 2x3",    WACOM_PKGLEN_GRAPHIRE,   3248,  2320,  511,
	  63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1975
static const struct wacom_features wacom_features_0x64 =
1976 1977
	{ "Wacom PenPartner2",    WACOM_PKGLEN_GRAPHIRE,   3250,  2320,  511,
	  63, GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };
1978
static const struct wacom_features wacom_features_0x65 =
1979 1980
	{ "Wacom Bamboo",         WACOM_PKGLEN_BBFUN,     14760,  9225,  511,
	  63, WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1981
static const struct wacom_features wacom_features_0x69 =
1982 1983
	{ "Wacom Bamboo1",        WACOM_PKGLEN_GRAPHIRE,   5104,  3712,  511,
	  63, GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };
1984 1985 1986 1987 1988 1989
static const struct wacom_features wacom_features_0x6A =
	{ "Wacom Bamboo1 4x6",    WACOM_PKGLEN_GRAPHIRE,  14760,  9225, 1023,
	  63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x6B =
	{ "Wacom Bamboo1 5x8",    WACOM_PKGLEN_GRAPHIRE,  21648, 13530, 1023,
	  63, GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1990
static const struct wacom_features wacom_features_0x20 =
1991 1992
	{ "Wacom Intuos 4x5",     WACOM_PKGLEN_INTUOS,    12700, 10600, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1993
static const struct wacom_features wacom_features_0x21 =
1994 1995
	{ "Wacom Intuos 6x8",     WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1996
static const struct wacom_features wacom_features_0x22 =
1997 1998
	{ "Wacom Intuos 9x12",    WACOM_PKGLEN_INTUOS,    30480, 24060, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
1999
static const struct wacom_features wacom_features_0x23 =
2000 2001
	{ "Wacom Intuos 12x12",   WACOM_PKGLEN_INTUOS,    30480, 31680, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2002
static const struct wacom_features wacom_features_0x24 =
2003 2004
	{ "Wacom Intuos 12x18",   WACOM_PKGLEN_INTUOS,    45720, 31680, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2005
static const struct wacom_features wacom_features_0x30 =
2006 2007
	{ "Wacom PL400",          WACOM_PKGLEN_GRAPHIRE,   5408,  4056,  255,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2008
static const struct wacom_features wacom_features_0x31 =
2009 2010
	{ "Wacom PL500",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  255,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2011
static const struct wacom_features wacom_features_0x32 =
2012 2013
	{ "Wacom PL600",          WACOM_PKGLEN_GRAPHIRE,   6126,  4604,  255,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2014
static const struct wacom_features wacom_features_0x33 =
2015 2016
	{ "Wacom PL600SX",        WACOM_PKGLEN_GRAPHIRE,   6260,  5016,  255,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2017
static const struct wacom_features wacom_features_0x34 =
2018 2019
	{ "Wacom PL550",          WACOM_PKGLEN_GRAPHIRE,   6144,  4608,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2020
static const struct wacom_features wacom_features_0x35 =
2021 2022
	{ "Wacom PL800",          WACOM_PKGLEN_GRAPHIRE,   7220,  5780,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2023
static const struct wacom_features wacom_features_0x37 =
2024 2025
	{ "Wacom PL700",          WACOM_PKGLEN_GRAPHIRE,   6758,  5406,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2026
static const struct wacom_features wacom_features_0x38 =
2027 2028
	{ "Wacom PL510",          WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2029
static const struct wacom_features wacom_features_0x39 =
2030 2031
	{ "Wacom DTU710",         WACOM_PKGLEN_GRAPHIRE,  34080, 27660,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2032
static const struct wacom_features wacom_features_0xC4 =
2033 2034
	{ "Wacom DTF521",         WACOM_PKGLEN_GRAPHIRE,   6282,  4762,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2035
static const struct wacom_features wacom_features_0xC0 =
2036 2037
	{ "Wacom DTF720",         WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2038
static const struct wacom_features wacom_features_0xC2 =
2039 2040
	{ "Wacom DTF720a",        WACOM_PKGLEN_GRAPHIRE,   6858,  5506,  511,
	  0, PL, WACOM_PL_RES, WACOM_PL_RES };
2041
static const struct wacom_features wacom_features_0x03 =
2042 2043
	{ "Wacom Cintiq Partner", WACOM_PKGLEN_GRAPHIRE,  20480, 15360,  511,
	  0, PTU, WACOM_PL_RES, WACOM_PL_RES };
2044
static const struct wacom_features wacom_features_0x41 =
2045 2046
	{ "Wacom Intuos2 4x5",    WACOM_PKGLEN_INTUOS,    12700, 10600, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2047
static const struct wacom_features wacom_features_0x42 =
2048 2049
	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2050
static const struct wacom_features wacom_features_0x43 =
2051 2052
	{ "Wacom Intuos2 9x12",   WACOM_PKGLEN_INTUOS,    30480, 24060, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2053
static const struct wacom_features wacom_features_0x44 =
2054 2055
	{ "Wacom Intuos2 12x12",  WACOM_PKGLEN_INTUOS,    30480, 31680, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2056
static const struct wacom_features wacom_features_0x45 =
2057 2058
	{ "Wacom Intuos2 12x18",  WACOM_PKGLEN_INTUOS,    45720, 31680, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2059
static const struct wacom_features wacom_features_0xB0 =
2060 2061
	{ "Wacom Intuos3 4x5",    WACOM_PKGLEN_INTUOS,    25400, 20320, 1023,
	  63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2062
static const struct wacom_features wacom_features_0xB1 =
2063 2064
	{ "Wacom Intuos3 6x8",    WACOM_PKGLEN_INTUOS,    40640, 30480, 1023,
	  63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2065
static const struct wacom_features wacom_features_0xB2 =
2066 2067
	{ "Wacom Intuos3 9x12",   WACOM_PKGLEN_INTUOS,    60960, 45720, 1023,
	  63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2068
static const struct wacom_features wacom_features_0xB3 =
2069 2070
	{ "Wacom Intuos3 12x12",  WACOM_PKGLEN_INTUOS,    60960, 60960, 1023,
	  63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2071
static const struct wacom_features wacom_features_0xB4 =
2072 2073
	{ "Wacom Intuos3 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 1023,
	  63, INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2074
static const struct wacom_features wacom_features_0xB5 =
2075 2076
	{ "Wacom Intuos3 6x11",   WACOM_PKGLEN_INTUOS,    54204, 31750, 1023,
	  63, INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2077
static const struct wacom_features wacom_features_0xB7 =
2078 2079
	{ "Wacom Intuos3 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 1023,
	  63, INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2080
static const struct wacom_features wacom_features_0xB8 =
2081 2082
	{ "Wacom Intuos4 4x6",    WACOM_PKGLEN_INTUOS,    31496, 19685, 2047,
	  63, INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2083
static const struct wacom_features wacom_features_0xB9 =
2084 2085
	{ "Wacom Intuos4 6x9",    WACOM_PKGLEN_INTUOS,    44704, 27940, 2047,
	  63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2086
static const struct wacom_features wacom_features_0xBA =
2087 2088
	{ "Wacom Intuos4 8x13",   WACOM_PKGLEN_INTUOS,    65024, 40640, 2047,
	  63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2089
static const struct wacom_features wacom_features_0xBB =
2090 2091
	{ "Wacom Intuos4 12x19",  WACOM_PKGLEN_INTUOS,    97536, 60960, 2047,
	  63, INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2092
static const struct wacom_features wacom_features_0xBC =
2093
	{ "Wacom Intuos4 WL",     WACOM_PKGLEN_INTUOS,    40640, 25400, 2047,
2094
	  63, INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2095 2096
static const struct wacom_features wacom_features_0x26 =
	{ "Wacom Intuos5 touch S", WACOM_PKGLEN_INTUOS,  31496, 19685, 2047,
2097 2098
	  63, INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
2099 2100
static const struct wacom_features wacom_features_0x27 =
	{ "Wacom Intuos5 touch M", WACOM_PKGLEN_INTUOS,  44704, 27940, 2047,
2101 2102
	  63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
2103 2104
static const struct wacom_features wacom_features_0x28 =
	{ "Wacom Intuos5 touch L", WACOM_PKGLEN_INTUOS, 65024, 40640, 2047,
2105 2106
	  63, INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
2107 2108 2109 2110 2111 2112
static const struct wacom_features wacom_features_0x29 =
	{ "Wacom Intuos5 S", WACOM_PKGLEN_INTUOS,  31496, 19685, 2047,
	  63, INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
static const struct wacom_features wacom_features_0x2A =
	{ "Wacom Intuos5 M", WACOM_PKGLEN_INTUOS,  44704, 27940, 2047,
	  63, INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124
static const struct wacom_features wacom_features_0x314 =
	{ "Wacom Intuos Pro S", WACOM_PKGLEN_INTUOS,  31496, 19685, 2047,
	  63, INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
static const struct wacom_features wacom_features_0x315 =
	{ "Wacom Intuos Pro M", WACOM_PKGLEN_INTUOS,  44704, 27940, 2047,
	  63, INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
static const struct wacom_features wacom_features_0x317 =
	{ "Wacom Intuos Pro L", WACOM_PKGLEN_INTUOS,  65024, 40640, 2047,
	  63, INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .touch_max = 16 };
2125
static const struct wacom_features wacom_features_0xF4 =
2126 2127 2128
	{ "Wacom Cintiq 24HD",       WACOM_PKGLEN_INTUOS,   104480, 65600, 2047,
	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
static const struct wacom_features wacom_features_0xF8 =
2129
	{ "Wacom Cintiq 24HD touch", WACOM_PKGLEN_INTUOS,   104480, 65600, 2047, /* Pen */
2130 2131
	  63, WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };
2132 2133 2134
static const struct wacom_features wacom_features_0xF6 =
	{ "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10 };
2135
static const struct wacom_features wacom_features_0x3F =
2136 2137
	{ "Wacom Cintiq 21UX",    WACOM_PKGLEN_INTUOS,    87200, 65600, 1023,
	  63, CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2138
static const struct wacom_features wacom_features_0xC5 =
2139 2140
	{ "Wacom Cintiq 20WSX",   WACOM_PKGLEN_INTUOS,    86680, 54180, 1023,
	  63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2141
static const struct wacom_features wacom_features_0xC6 =
2142 2143
	{ "Wacom Cintiq 12WX",    WACOM_PKGLEN_INTUOS,    53020, 33440, 1023,
	  63, WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2144 2145 2146
static const struct wacom_features wacom_features_0x304 =
	{ "Wacom Cintiq 13HD",    WACOM_PKGLEN_INTUOS,    59552, 33848, 1023,
	  63, WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2147
static const struct wacom_features wacom_features_0xC7 =
2148 2149
	{ "Wacom DTU1931",        WACOM_PKGLEN_GRAPHIRE,  37832, 30305,  511,
	  0, PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2150
static const struct wacom_features wacom_features_0xCE =
2151 2152
	{ "Wacom DTU2231",        WACOM_PKGLEN_GRAPHIRE,  47864, 27011,  511,
	  0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2153
static const struct wacom_features wacom_features_0xF0 =
2154 2155
	{ "Wacom DTU1631",        WACOM_PKGLEN_GRAPHIRE,  34623, 19553,  511,
	  0, DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2156 2157 2158
static const struct wacom_features wacom_features_0xFB =
	{ "Wacom DTU1031",        WACOM_PKGLEN_DTUS,      22096, 13960,  511,
	  0, DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2159 2160 2161
static const struct wacom_features wacom_features_0x57 =
	{ "Wacom DTK2241",        WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
	  63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES};
2162 2163 2164 2165 2166 2167 2168
static const struct wacom_features wacom_features_0x59 = /* Pen */
	{ "Wacom DTH2242",        WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
	  63, DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };
static const struct wacom_features wacom_features_0x5D = /* Touch */
	{ "Wacom DTH2242",       .type = WACOM_24HDT,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10 };
2169
static const struct wacom_features wacom_features_0xCC =
2170 2171
	{ "Wacom Cintiq 21UX2",   WACOM_PKGLEN_INTUOS,    87200, 65600, 2047,
	  63, WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2172 2173 2174
static const struct wacom_features wacom_features_0xFA =
	{ "Wacom Cintiq 22HD",    WACOM_PKGLEN_INTUOS,    95840, 54260, 2047,
	  63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES };
2175 2176
static const struct wacom_features wacom_features_0x5B =
	{ "Wacom Cintiq 22HDT", WACOM_PKGLEN_INTUOS,      95840, 54260, 2047,
2177 2178
	  63, WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };
2179 2180 2181
static const struct wacom_features wacom_features_0x5E =
	{ "Wacom Cintiq 22HDT", .type = WACOM_24HDT,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10 };
2182
static const struct wacom_features wacom_features_0x90 =
2183 2184
	{ "Wacom ISDv4 90",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2185
static const struct wacom_features wacom_features_0x93 =
2186 2187
	{ "Wacom ISDv4 93",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2188 2189 2190
static const struct wacom_features wacom_features_0x97 =
	{ "Wacom ISDv4 97",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  511,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2191
static const struct wacom_features wacom_features_0x9A =
2192 2193
	{ "Wacom ISDv4 9A",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2194
static const struct wacom_features wacom_features_0x9F =
2195 2196
	{ "Wacom ISDv4 9F",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2197
static const struct wacom_features wacom_features_0xE2 =
2198
	{ "Wacom ISDv4 E2",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,
2199 2200
	  0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2201
static const struct wacom_features wacom_features_0xE3 =
2202
	{ "Wacom ISDv4 E3",       WACOM_PKGLEN_TPC2FG,    26202, 16325,  255,
2203 2204
	  0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2205 2206 2207
static const struct wacom_features wacom_features_0xE5 =
	{ "Wacom ISDv4 E5",       WACOM_PKGLEN_MTOUCH,    26202, 16325,  255,
	  0, MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2208 2209
static const struct wacom_features wacom_features_0xE6 =
	{ "Wacom ISDv4 E6",       WACOM_PKGLEN_TPC2FG,    27760, 15694,  255,
2210
	  0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
2211
	  .touch_max = 2 };
2212 2213 2214
static const struct wacom_features wacom_features_0xEC =
	{ "Wacom ISDv4 EC",       WACOM_PKGLEN_GRAPHIRE,  25710, 14500,  255,
	  0, TABLETPC,    WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2215 2216 2217 2218 2219 2220
static const struct wacom_features wacom_features_0xED =
	{ "Wacom ISDv4 ED",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xEF =
	{ "Wacom ISDv4 EF",       WACOM_PKGLEN_GRAPHIRE,  26202, 16325,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2221 2222 2223 2224 2225 2226
static const struct wacom_features wacom_features_0x100 =
	{ "Wacom ISDv4 100",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x101 =
	{ "Wacom ISDv4 101",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2227 2228 2229
static const struct wacom_features wacom_features_0x10D =
	{ "Wacom ISDv4 10D",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2230 2231 2232
static const struct wacom_features wacom_features_0x10E =
	{ "Wacom ISDv4 10E",      WACOM_PKGLEN_MTTPC,     27760, 15694,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2233 2234 2235
static const struct wacom_features wacom_features_0x10F =
	{ "Wacom ISDv4 10F",      WACOM_PKGLEN_MTTPC,     27760, 15694,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2236 2237 2238
static const struct wacom_features wacom_features_0x4001 =
	{ "Wacom ISDv4 4001",      WACOM_PKGLEN_MTTPC,     26202, 16325,  255,
	  0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2239
static const struct wacom_features wacom_features_0x47 =
2240 2241
	{ "Wacom Intuos2 6x8",    WACOM_PKGLEN_INTUOS,    20320, 16240, 1023,
	  31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2242 2243
static const struct wacom_features wacom_features_0x84 =
	{ "Wacom Wireless Receiver", WACOM_PKGLEN_WIRELESS, 0, 0, 0,
2244
	  0, WIRELESS, 0, 0, .touch_max = 16 };
2245
static const struct wacom_features wacom_features_0xD0 =
2246
	{ "Wacom Bamboo 2FG",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
2247 2248
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2249
static const struct wacom_features wacom_features_0xD1 =
2250
	{ "Wacom Bamboo 2FG 4x5", WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
2251 2252
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2253
static const struct wacom_features wacom_features_0xD2 =
2254
	{ "Wacom Bamboo Craft",   WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
2255 2256
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2257
static const struct wacom_features wacom_features_0xD3 =
2258
	{ "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13700, 1023,
2259 2260
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2261
static const struct wacom_features wacom_features_0xD4 =
2262
	{ "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200, 1023,
2263
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2264
static const struct wacom_features wacom_features_0xD5 =
2265
	{ "Wacom Bamboo Pen 6x8",     WACOM_PKGLEN_BBFUN, 21648, 13700, 1023,
2266
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2267
static const struct wacom_features wacom_features_0xD6 =
2268
	{ "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN,   14720,  9200, 1023,
2269 2270
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2271
static const struct wacom_features wacom_features_0xD7 =
2272
	{ "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720,  9200, 1023,
2273 2274
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2275
static const struct wacom_features wacom_features_0xD8 =
2276
	{ "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13700, 1023,
2277 2278
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2279
static const struct wacom_features wacom_features_0xDA =
2280
	{ "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN,  14720,  9200, 1023,
2281 2282
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2283
static const struct wacom_features wacom_features_0xDB =
2284
	{ "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN,  21648, 13700, 1023,
2285 2286
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 2 };
2287 2288 2289 2290 2291
static const struct wacom_features wacom_features_0xDD =
        { "Wacom Bamboo Connect", WACOM_PKGLEN_BBPEN,     14720,  9200, 1023,
          31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0xDE =
        { "Wacom Bamboo 16FG 4x5", WACOM_PKGLEN_BBPEN,    14720,  9200, 1023,
2292 2293
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 16 };
2294 2295
static const struct wacom_features wacom_features_0xDF =
        { "Wacom Bamboo 16FG 6x8", WACOM_PKGLEN_BBPEN,    21648, 13700, 1023,
2296 2297
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 16 };
2298 2299 2300 2301 2302 2303
static const struct wacom_features wacom_features_0x300 =
	{ "Wacom Bamboo One S",    WACOM_PKGLEN_BBPEN,    14720,  9225, 1023,
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
static const struct wacom_features wacom_features_0x301 =
	{ "Wacom Bamboo One M",    WACOM_PKGLEN_BBPEN,    21648, 13530, 1023,
	  31, BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
static const struct wacom_features wacom_features_0x302 =
	{ "Wacom Intuos PT S",     WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 16 };
static const struct wacom_features wacom_features_0x303 =
	{ "Wacom Intuos PT M",     WACOM_PKGLEN_BBPEN,    21600, 13500, 1023,
	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,
	  .touch_max = 16 };
static const struct wacom_features wacom_features_0x30E =
	{ "Wacom Intuos S",        WACOM_PKGLEN_BBPEN,    15200,  9500, 1023,
	  31, INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2315
static const struct wacom_features wacom_features_0x6004 =
2316 2317
	{ "ISD-V4",               WACOM_PKGLEN_GRAPHIRE,  12800,  8000,  255,
	  0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };
2318 2319 2320 2321 2322 2323 2324
static const struct wacom_features wacom_features_0x0307 =
	{ "Wacom ISDv5 307", WACOM_PKGLEN_INTUOS,  59552,  33848, 2047,
	  63, CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES,
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };
static const struct wacom_features wacom_features_0x0309 =
	{ "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */
	  .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10 };
2325 2326 2327 2328 2329

#define USB_DEVICE_WACOM(prod)					\
	USB_DEVICE(USB_VENDOR_ID_WACOM, prod),			\
	.driver_info = (kernel_ulong_t)&wacom_features_##prod

2330 2331 2332 2333 2334
#define USB_DEVICE_DETAILED(prod, class, sub, proto)			\
	USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_WACOM, prod, class,	\
				      sub, proto),			\
	.driver_info = (kernel_ulong_t)&wacom_features_##prod

2335 2336 2337 2338
#define USB_DEVICE_LENOVO(prod)					\
	USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),			\
	.driver_info = (kernel_ulong_t)&wacom_features_##prod

2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357
const struct usb_device_id wacom_ids[] = {
	{ USB_DEVICE_WACOM(0x00) },
	{ 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) },
	{ 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) },
2358 2359
	{ USB_DEVICE_WACOM(0x6A) },
	{ USB_DEVICE_WACOM(0x6B) },
2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382
	{ USB_DEVICE_WACOM(0x20) },
	{ USB_DEVICE_WACOM(0x21) },
	{ USB_DEVICE_WACOM(0x22) },
	{ USB_DEVICE_WACOM(0x23) },
	{ USB_DEVICE_WACOM(0x24) },
	{ 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) },
	{ USB_DEVICE_WACOM(0xC4) },
	{ USB_DEVICE_WACOM(0xC0) },
	{ USB_DEVICE_WACOM(0xC2) },
	{ USB_DEVICE_WACOM(0x03) },
	{ USB_DEVICE_WACOM(0x41) },
	{ USB_DEVICE_WACOM(0x42) },
	{ USB_DEVICE_WACOM(0x43) },
	{ USB_DEVICE_WACOM(0x44) },
	{ USB_DEVICE_WACOM(0x45) },
2383
	{ USB_DEVICE_WACOM(0x57) },
2384
	{ USB_DEVICE_WACOM(0x59) },
2385
	{ USB_DEVICE_DETAILED(0x5D, USB_CLASS_HID, 0, 0) },
2386 2387
	{ USB_DEVICE_WACOM(0x5B) },
	{ USB_DEVICE_DETAILED(0x5E, USB_CLASS_HID, 0, 0) },
2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398
	{ 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) },
2399
	{ USB_DEVICE_WACOM(0xBC) },
2400 2401 2402 2403 2404
	{ USB_DEVICE_WACOM(0x26) },
	{ USB_DEVICE_WACOM(0x27) },
	{ USB_DEVICE_WACOM(0x28) },
	{ USB_DEVICE_WACOM(0x29) },
	{ USB_DEVICE_WACOM(0x2A) },
2405 2406 2407 2408
	{ USB_DEVICE_WACOM(0x3F) },
	{ USB_DEVICE_WACOM(0xC5) },
	{ USB_DEVICE_WACOM(0xC6) },
	{ USB_DEVICE_WACOM(0xC7) },
2409 2410 2411 2412 2413 2414 2415
	/*
	 * DTU-2231 has two interfaces on the same configuration,
	 * only one is used.
	 */
	{ USB_DEVICE_DETAILED(0xCE, USB_CLASS_HID,
			      USB_INTERFACE_SUBCLASS_BOOT,
			      USB_INTERFACE_PROTOCOL_MOUSE) },
2416
	{ USB_DEVICE_WACOM(0x84) },
2417
	{ USB_DEVICE_WACOM(0xD0) },
2418 2419 2420
	{ USB_DEVICE_WACOM(0xD1) },
	{ USB_DEVICE_WACOM(0xD2) },
	{ USB_DEVICE_WACOM(0xD3) },
2421
	{ USB_DEVICE_WACOM(0xD4) },
2422
	{ USB_DEVICE_WACOM(0xD5) },
2423 2424
	{ USB_DEVICE_WACOM(0xD6) },
	{ USB_DEVICE_WACOM(0xD7) },
2425 2426
	{ USB_DEVICE_WACOM(0xD8) },
	{ USB_DEVICE_WACOM(0xDA) },
2427
	{ USB_DEVICE_WACOM(0xDB) },
2428 2429 2430
	{ USB_DEVICE_WACOM(0xDD) },
	{ USB_DEVICE_WACOM(0xDE) },
	{ USB_DEVICE_WACOM(0xDF) },
2431
	{ USB_DEVICE_WACOM(0xF0) },
2432
	{ USB_DEVICE_WACOM(0xCC) },
2433 2434
	{ USB_DEVICE_WACOM(0x90) },
	{ USB_DEVICE_WACOM(0x93) },
2435
	{ USB_DEVICE_WACOM(0x97) },
2436 2437 2438 2439
	{ USB_DEVICE_WACOM(0x9A) },
	{ USB_DEVICE_WACOM(0x9F) },
	{ USB_DEVICE_WACOM(0xE2) },
	{ USB_DEVICE_WACOM(0xE3) },
2440
	{ USB_DEVICE_WACOM(0xE5) },
2441
	{ USB_DEVICE_WACOM(0xE6) },
2442
	{ USB_DEVICE_WACOM(0xEC) },
2443 2444
	{ USB_DEVICE_WACOM(0xED) },
	{ USB_DEVICE_WACOM(0xEF) },
2445 2446
	{ USB_DEVICE_WACOM(0x100) },
	{ USB_DEVICE_WACOM(0x101) },
2447
	{ USB_DEVICE_WACOM(0x10D) },
2448
	{ USB_DEVICE_WACOM(0x10E) },
2449
	{ USB_DEVICE_WACOM(0x10F) },
2450 2451
	{ USB_DEVICE_WACOM(0x300) },
	{ USB_DEVICE_WACOM(0x301) },
2452 2453 2454
	{ USB_DEVICE_DETAILED(0x302, USB_CLASS_HID, 0, 0) },
	{ USB_DEVICE_DETAILED(0x303, USB_CLASS_HID, 0, 0) },
	{ USB_DEVICE_DETAILED(0x30E, USB_CLASS_HID, 0, 0) },
2455
	{ USB_DEVICE_WACOM(0x304) },
2456 2457 2458
	{ USB_DEVICE_DETAILED(0x314, USB_CLASS_HID, 0, 0) },
	{ USB_DEVICE_DETAILED(0x315, USB_CLASS_HID, 0, 0) },
	{ USB_DEVICE_DETAILED(0x317, USB_CLASS_HID, 0, 0) },
2459
	{ USB_DEVICE_WACOM(0x4001) },
2460
	{ USB_DEVICE_WACOM(0x47) },
2461
	{ USB_DEVICE_WACOM(0xF4) },
2462
	{ USB_DEVICE_WACOM(0xF8) },
2463
	{ USB_DEVICE_DETAILED(0xF6, USB_CLASS_HID, 0, 0) },
2464
	{ USB_DEVICE_WACOM(0xFA) },
2465
	{ USB_DEVICE_WACOM(0xFB) },
2466 2467
	{ USB_DEVICE_WACOM(0x0307) },
	{ USB_DEVICE_DETAILED(0x0309, USB_CLASS_HID, 0, 0) },
2468
	{ USB_DEVICE_LENOVO(0x6004) },
2469 2470 2471
	{ }
};
MODULE_DEVICE_TABLE(usb, wacom_ids);