5119 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * USB Wacom tablet support - Wacom specific code4 */5 6#include "wacom_wac.h"7#include "wacom.h"8#include <linux/input/mt.h>9#include <linux/jiffies.h>10 11/* resolution for penabled devices */12#define WACOM_PL_RES 2013#define WACOM_PENPRTN_RES 4014#define WACOM_VOLITO_RES 5015#define WACOM_GRAPHIRE_RES 8016#define WACOM_INTUOS_RES 10017#define WACOM_INTUOS3_RES 20018 19/* Newer Cintiq and DTU have an offset between tablet and screen areas */20#define WACOM_DTU_OFFSET 20021#define WACOM_CINTIQ_OFFSET 40022 23/*24 * Scale factor relating reported contact size to logical contact area.25 * 2^14/pi is a good approximation on Intuos5 and 3rd-gen Bamboo26 */27#define WACOM_CONTACT_AREA_SCALE 260728 29static bool touch_arbitration = 1;30module_param(touch_arbitration, bool, 0644);31MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)");32 33static void wacom_report_numbered_buttons(struct input_dev *input_dev,34 int button_count, int mask);35 36static int wacom_numbered_button_to_key(int n);37 38static void wacom_update_led(struct wacom *wacom, int button_count, int mask,39 int group);40 41static void wacom_force_proxout(struct wacom_wac *wacom_wac)42{43 struct input_dev *input = wacom_wac->pen_input;44 45 wacom_wac->shared->stylus_in_proximity = 0;46 47 input_report_key(input, BTN_TOUCH, 0);48 input_report_key(input, BTN_STYLUS, 0);49 input_report_key(input, BTN_STYLUS2, 0);50 input_report_key(input, BTN_STYLUS3, 0);51 input_report_key(input, wacom_wac->tool[0], 0);52 if (wacom_wac->serial[0]) {53 input_report_abs(input, ABS_MISC, 0);54 }55 input_report_abs(input, ABS_PRESSURE, 0);56 57 wacom_wac->tool[0] = 0;58 wacom_wac->id[0] = 0;59 wacom_wac->serial[0] = 0;60 61 input_sync(input);62}63 64void wacom_idleprox_timeout(struct timer_list *list)65{66 struct wacom *wacom = from_timer(wacom, list, idleprox_timer);67 struct wacom_wac *wacom_wac = &wacom->wacom_wac;68 69 if (!wacom_wac->hid_data.sense_state) {70 return;71 }72 73 hid_warn(wacom->hdev, "%s: tool appears to be hung in-prox. forcing it out.\n", __func__);74 wacom_force_proxout(wacom_wac);75}76 77/*78 * Percent of battery capacity for Graphire.79 * 8th value means AC online and show 100% capacity.80 */81static unsigned short batcap_gr[8] = { 1, 15, 25, 35, 50, 70, 100, 100 };82 83/*84 * Percent of battery capacity for Intuos4 WL, AC has a separate bit.85 */86static unsigned short batcap_i4[8] = { 1, 15, 30, 45, 60, 70, 85, 100 };87 88static void __wacom_notify_battery(struct wacom_battery *battery,89 int bat_status, int bat_capacity,90 bool bat_charging, bool bat_connected,91 bool ps_connected)92{93 bool changed = battery->bat_status != bat_status ||94 battery->battery_capacity != bat_capacity ||95 battery->bat_charging != bat_charging ||96 battery->bat_connected != bat_connected ||97 battery->ps_connected != ps_connected;98 99 if (changed) {100 battery->bat_status = bat_status;101 battery->battery_capacity = bat_capacity;102 battery->bat_charging = bat_charging;103 battery->bat_connected = bat_connected;104 battery->ps_connected = ps_connected;105 106 if (battery->battery)107 power_supply_changed(battery->battery);108 }109}110 111static void wacom_notify_battery(struct wacom_wac *wacom_wac,112 int bat_status, int bat_capacity, bool bat_charging,113 bool bat_connected, bool ps_connected)114{115 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);116 bool bat_initialized = wacom->battery.battery;117 bool has_quirk = wacom_wac->features.quirks & WACOM_QUIRK_BATTERY;118 119 if (bat_initialized != has_quirk)120 wacom_schedule_work(wacom_wac, WACOM_WORKER_BATTERY);121 122 __wacom_notify_battery(&wacom->battery, bat_status, bat_capacity,123 bat_charging, bat_connected, ps_connected);124}125 126static int wacom_penpartner_irq(struct wacom_wac *wacom)127{128 unsigned char *data = wacom->data;129 struct input_dev *input = wacom->pen_input;130 131 switch (data[0]) {132 case 1:133 if (data[5] & 0x80) {134 wacom->tool[0] = (data[5] & 0x20) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;135 wacom->id[0] = (data[5] & 0x20) ? ERASER_DEVICE_ID : STYLUS_DEVICE_ID;136 input_report_key(input, wacom->tool[0], 1);137 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */138 input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));139 input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));140 input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);141 input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -127));142 input_report_key(input, BTN_STYLUS, (data[5] & 0x40));143 } else {144 input_report_key(input, wacom->tool[0], 0);145 input_report_abs(input, ABS_MISC, 0); /* report tool id */146 input_report_abs(input, ABS_PRESSURE, -1);147 input_report_key(input, BTN_TOUCH, 0);148 }149 break;150 151 case 2:152 input_report_key(input, BTN_TOOL_PEN, 1);153 input_report_abs(input, ABS_MISC, STYLUS_DEVICE_ID); /* report tool id */154 input_report_abs(input, ABS_X, get_unaligned_le16(&data[1]));155 input_report_abs(input, ABS_Y, get_unaligned_le16(&data[3]));156 input_report_abs(input, ABS_PRESSURE, (signed char)data[6] + 127);157 input_report_key(input, BTN_TOUCH, ((signed char)data[6] > -80) && !(data[5] & 0x20));158 input_report_key(input, BTN_STYLUS, (data[5] & 0x40));159 break;160 161 default:162 dev_dbg(input->dev.parent,163 "%s: received unknown report #%d\n", __func__, data[0]);164 return 0;165 }166 167 return 1;168}169 170static int wacom_pl_irq(struct wacom_wac *wacom)171{172 struct wacom_features *features = &wacom->features;173 unsigned char *data = wacom->data;174 struct input_dev *input = wacom->pen_input;175 int prox, pressure;176 177 if (data[0] != WACOM_REPORT_PENABLED) {178 dev_dbg(input->dev.parent,179 "%s: received unknown report #%d\n", __func__, data[0]);180 return 0;181 }182 183 prox = data[1] & 0x40;184 185 if (!wacom->id[0]) {186 if ((data[0] & 0x10) || (data[4] & 0x20)) {187 wacom->tool[0] = BTN_TOOL_RUBBER;188 wacom->id[0] = ERASER_DEVICE_ID;189 }190 else {191 wacom->tool[0] = BTN_TOOL_PEN;192 wacom->id[0] = STYLUS_DEVICE_ID;193 }194 }195 196 /* If the eraser is in prox, STYLUS2 is always set. If we197 * mis-detected the type and notice that STYLUS2 isn't set198 * then force the eraser out of prox and let the pen in.199 */200 if (wacom->tool[0] == BTN_TOOL_RUBBER && !(data[4] & 0x20)) {201 input_report_key(input, BTN_TOOL_RUBBER, 0);202 input_report_abs(input, ABS_MISC, 0);203 input_sync(input);204 wacom->tool[0] = BTN_TOOL_PEN;205 wacom->id[0] = STYLUS_DEVICE_ID;206 }207 208 if (prox) {209 pressure = (signed char)((data[7] << 1) | ((data[4] >> 2) & 1));210 if (features->pressure_max > 255)211 pressure = (pressure << 1) | ((data[4] >> 6) & 1);212 pressure += (features->pressure_max + 1) / 2;213 214 input_report_abs(input, ABS_X, data[3] | (data[2] << 7) | ((data[1] & 0x03) << 14));215 input_report_abs(input, ABS_Y, data[6] | (data[5] << 7) | ((data[4] & 0x03) << 14));216 input_report_abs(input, ABS_PRESSURE, pressure);217 218 input_report_key(input, BTN_TOUCH, data[4] & 0x08);219 input_report_key(input, BTN_STYLUS, data[4] & 0x10);220 /* Only allow the stylus2 button to be reported for the pen tool. */221 input_report_key(input, BTN_STYLUS2, (wacom->tool[0] == BTN_TOOL_PEN) && (data[4] & 0x20));222 }223 224 if (!prox)225 wacom->id[0] = 0;226 input_report_key(input, wacom->tool[0], prox);227 input_report_abs(input, ABS_MISC, wacom->id[0]);228 return 1;229}230 231static int wacom_ptu_irq(struct wacom_wac *wacom)232{233 unsigned char *data = wacom->data;234 struct input_dev *input = wacom->pen_input;235 236 if (data[0] != WACOM_REPORT_PENABLED) {237 dev_dbg(input->dev.parent,238 "%s: received unknown report #%d\n", __func__, data[0]);239 return 0;240 }241 242 if (data[1] & 0x04) {243 input_report_key(input, BTN_TOOL_RUBBER, data[1] & 0x20);244 input_report_key(input, BTN_TOUCH, data[1] & 0x08);245 wacom->id[0] = ERASER_DEVICE_ID;246 } else {247 input_report_key(input, BTN_TOOL_PEN, data[1] & 0x20);248 input_report_key(input, BTN_TOUCH, data[1] & 0x01);249 wacom->id[0] = STYLUS_DEVICE_ID;250 }251 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */252 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));253 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));254 input_report_abs(input, ABS_PRESSURE, le16_to_cpup((__le16 *)&data[6]));255 input_report_key(input, BTN_STYLUS, data[1] & 0x02);256 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);257 return 1;258}259 260static int wacom_dtu_irq(struct wacom_wac *wacom)261{262 unsigned char *data = wacom->data;263 struct input_dev *input = wacom->pen_input;264 int prox = data[1] & 0x20;265 266 dev_dbg(input->dev.parent,267 "%s: received report #%d", __func__, data[0]);268 269 if (prox) {270 /* Going into proximity select tool */271 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;272 if (wacom->tool[0] == BTN_TOOL_PEN)273 wacom->id[0] = STYLUS_DEVICE_ID;274 else275 wacom->id[0] = ERASER_DEVICE_ID;276 }277 input_report_key(input, BTN_STYLUS, data[1] & 0x02);278 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);279 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));280 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));281 input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]);282 input_report_key(input, BTN_TOUCH, data[1] & 0x05);283 if (!prox) /* out-prox */284 wacom->id[0] = 0;285 input_report_key(input, wacom->tool[0], prox);286 input_report_abs(input, ABS_MISC, wacom->id[0]);287 return 1;288}289 290static int wacom_dtus_irq(struct wacom_wac *wacom)291{292 unsigned char *data = wacom->data;293 struct input_dev *input = wacom->pen_input;294 unsigned short prox, pressure = 0;295 296 if (data[0] != WACOM_REPORT_DTUS && data[0] != WACOM_REPORT_DTUSPAD) {297 dev_dbg(input->dev.parent,298 "%s: received unknown report #%d", __func__, data[0]);299 return 0;300 } else if (data[0] == WACOM_REPORT_DTUSPAD) {301 input = wacom->pad_input;302 input_report_key(input, BTN_0, (data[1] & 0x01));303 input_report_key(input, BTN_1, (data[1] & 0x02));304 input_report_key(input, BTN_2, (data[1] & 0x04));305 input_report_key(input, BTN_3, (data[1] & 0x08));306 input_report_abs(input, ABS_MISC,307 data[1] & 0x0f ? PAD_DEVICE_ID : 0);308 return 1;309 } else {310 prox = data[1] & 0x80;311 if (prox) {312 switch ((data[1] >> 3) & 3) {313 case 1: /* Rubber */314 wacom->tool[0] = BTN_TOOL_RUBBER;315 wacom->id[0] = ERASER_DEVICE_ID;316 break;317 318 case 2: /* Pen */319 wacom->tool[0] = BTN_TOOL_PEN;320 wacom->id[0] = STYLUS_DEVICE_ID;321 break;322 }323 }324 325 input_report_key(input, BTN_STYLUS, data[1] & 0x20);326 input_report_key(input, BTN_STYLUS2, data[1] & 0x40);327 input_report_abs(input, ABS_X, get_unaligned_be16(&data[3]));328 input_report_abs(input, ABS_Y, get_unaligned_be16(&data[5]));329 pressure = ((data[1] & 0x03) << 8) | (data[2] & 0xff);330 input_report_abs(input, ABS_PRESSURE, pressure);331 input_report_key(input, BTN_TOUCH, pressure > 10);332 333 if (!prox) /* out-prox */334 wacom->id[0] = 0;335 input_report_key(input, wacom->tool[0], prox);336 input_report_abs(input, ABS_MISC, wacom->id[0]);337 return 1;338 }339}340 341static int wacom_graphire_irq(struct wacom_wac *wacom)342{343 struct wacom_features *features = &wacom->features;344 unsigned char *data = wacom->data;345 struct input_dev *input = wacom->pen_input;346 struct input_dev *pad_input = wacom->pad_input;347 int battery_capacity, ps_connected;348 int prox;349 int rw = 0;350 int retval = 0;351 352 if (features->type == GRAPHIRE_BT) {353 if (data[0] != WACOM_REPORT_PENABLED_BT) {354 dev_dbg(input->dev.parent,355 "%s: received unknown report #%d\n", __func__,356 data[0]);357 goto exit;358 }359 } else if (data[0] != WACOM_REPORT_PENABLED) {360 dev_dbg(input->dev.parent,361 "%s: received unknown report #%d\n", __func__, data[0]);362 goto exit;363 }364 365 prox = data[1] & 0x80;366 if (prox || wacom->id[0]) {367 if (prox) {368 switch ((data[1] >> 5) & 3) {369 370 case 0: /* Pen */371 wacom->tool[0] = BTN_TOOL_PEN;372 wacom->id[0] = STYLUS_DEVICE_ID;373 break;374 375 case 1: /* Rubber */376 wacom->tool[0] = BTN_TOOL_RUBBER;377 wacom->id[0] = ERASER_DEVICE_ID;378 break;379 380 case 2: /* Mouse with wheel */381 input_report_key(input, BTN_MIDDLE, data[1] & 0x04);382 fallthrough;383 384 case 3: /* Mouse without wheel */385 wacom->tool[0] = BTN_TOOL_MOUSE;386 wacom->id[0] = CURSOR_DEVICE_ID;387 break;388 }389 }390 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));391 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));392 if (wacom->tool[0] != BTN_TOOL_MOUSE) {393 if (features->type == GRAPHIRE_BT)394 input_report_abs(input, ABS_PRESSURE, data[6] |395 (((__u16) (data[1] & 0x08)) << 5));396 else397 input_report_abs(input, ABS_PRESSURE, data[6] |398 ((data[7] & 0x03) << 8));399 input_report_key(input, BTN_TOUCH, data[1] & 0x01);400 input_report_key(input, BTN_STYLUS, data[1] & 0x02);401 input_report_key(input, BTN_STYLUS2, data[1] & 0x04);402 } else {403 input_report_key(input, BTN_LEFT, data[1] & 0x01);404 input_report_key(input, BTN_RIGHT, data[1] & 0x02);405 if (features->type == WACOM_G4 ||406 features->type == WACOM_MO) {407 input_report_abs(input, ABS_DISTANCE, data[6] & 0x3f);408 rw = (data[7] & 0x04) - (data[7] & 0x03);409 } else if (features->type == GRAPHIRE_BT) {410 /* Compute distance between mouse and tablet */411 rw = 44 - (data[6] >> 2);412 rw = clamp_val(rw, 0, 31);413 input_report_abs(input, ABS_DISTANCE, rw);414 if (((data[1] >> 5) & 3) == 2) {415 /* Mouse with wheel */416 input_report_key(input, BTN_MIDDLE,417 data[1] & 0x04);418 rw = (data[6] & 0x01) ? -1 :419 (data[6] & 0x02) ? 1 : 0;420 } else {421 rw = 0;422 }423 } else {424 input_report_abs(input, ABS_DISTANCE, data[7] & 0x3f);425 rw = -(signed char)data[6];426 }427 input_report_rel(input, REL_WHEEL, rw);428 }429 430 if (!prox)431 wacom->id[0] = 0;432 input_report_abs(input, ABS_MISC, wacom->id[0]); /* report tool id */433 input_report_key(input, wacom->tool[0], prox);434 input_sync(input); /* sync last event */435 }436 437 /* send pad data */438 switch (features->type) {439 case WACOM_G4:440 prox = data[7] & 0xf8;441 if (prox || wacom->id[1]) {442 wacom->id[1] = PAD_DEVICE_ID;443 input_report_key(pad_input, BTN_BACK, (data[7] & 0x40));444 input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x80));445 rw = ((data[7] & 0x18) >> 3) - ((data[7] & 0x20) >> 3);446 input_report_rel(pad_input, REL_WHEEL, rw);447 if (!prox)448 wacom->id[1] = 0;449 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);450 retval = 1;451 }452 break;453 454 case WACOM_MO:455 prox = (data[7] & 0xf8) || data[8];456 if (prox || wacom->id[1]) {457 wacom->id[1] = PAD_DEVICE_ID;458 input_report_key(pad_input, BTN_BACK, (data[7] & 0x08));459 input_report_key(pad_input, BTN_LEFT, (data[7] & 0x20));460 input_report_key(pad_input, BTN_FORWARD, (data[7] & 0x10));461 input_report_key(pad_input, BTN_RIGHT, (data[7] & 0x40));462 input_report_abs(pad_input, ABS_WHEEL, (data[8] & 0x7f));463 if (!prox)464 wacom->id[1] = 0;465 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);466 retval = 1;467 }468 break;469 case GRAPHIRE_BT:470 prox = data[7] & 0x03;471 if (prox || wacom->id[1]) {472 wacom->id[1] = PAD_DEVICE_ID;473 input_report_key(pad_input, BTN_0, (data[7] & 0x02));474 input_report_key(pad_input, BTN_1, (data[7] & 0x01));475 if (!prox)476 wacom->id[1] = 0;477 input_report_abs(pad_input, ABS_MISC, wacom->id[1]);478 retval = 1;479 }480 break;481 }482 483 /* Store current battery capacity and power supply state */484 if (features->type == GRAPHIRE_BT) {485 rw = (data[7] >> 2 & 0x07);486 battery_capacity = batcap_gr[rw];487 ps_connected = rw == 7;488 wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,489 battery_capacity, ps_connected, 1,490 ps_connected);491 }492exit:493 return retval;494}495 496static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac)497{498 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);499 struct wacom_features *features = &wacom_wac->features;500 struct hid_report *r;501 struct hid_report_enum *re;502 503 re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]);504 if (features->type == INTUOSHT2)505 r = re->report_id_hash[WACOM_REPORT_INTUOSHT2_ID];506 else507 r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1];508 if (r) {509 hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT);510 }511}512 513static int wacom_intuos_pad(struct wacom_wac *wacom)514{515 struct wacom_features *features = &wacom->features;516 unsigned char *data = wacom->data;517 struct input_dev *input = wacom->pad_input;518 int i;519 int buttons = 0, nbuttons = features->numbered_buttons;520 int keys = 0, nkeys = 0;521 int ring1 = 0, ring2 = 0;522 int strip1 = 0, strip2 = 0;523 bool prox = false;524 bool wrench = false, keyboard = false, mute_touch = false, menu = false,525 info = false;526 527 /* pad packets. Works as a second tool and is always in prox */528 if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||529 data[0] == WACOM_REPORT_CINTIQPAD))530 return 0;531 532 if (features->type >= INTUOS4S && features->type <= INTUOS4L) {533 buttons = (data[3] << 1) | (data[2] & 0x01);534 ring1 = data[1];535 } else if (features->type == DTK) {536 buttons = data[6];537 } else if (features->type == WACOM_13HD) {538 buttons = (data[4] << 1) | (data[3] & 0x01);539 } else if (features->type == WACOM_24HD) {540 buttons = (data[8] << 8) | data[6];541 ring1 = data[1];542 ring2 = data[2];543 544 /*545 * Three "buttons" are available on the 24HD which are546 * physically implemented as a touchstrip. Each button547 * is approximately 3 bits wide with a 2 bit spacing.548 * The raw touchstrip bits are stored at:549 * ((data[3] & 0x1f) << 8) | data[4])550 */551 nkeys = 3;552 keys = ((data[3] & 0x1C) ? 1<<2 : 0) |553 ((data[4] & 0xE0) ? 1<<1 : 0) |554 ((data[4] & 0x07) ? 1<<0 : 0);555 keyboard = !!(data[4] & 0xE0);556 info = !!(data[3] & 0x1C);557 558 if (features->oPid) {559 mute_touch = !!(data[4] & 0x07);560 if (mute_touch)561 wacom->shared->is_touch_on =562 !wacom->shared->is_touch_on;563 } else {564 wrench = !!(data[4] & 0x07);565 }566 } else if (features->type == WACOM_27QHD) {567 nkeys = 3;568 keys = data[2] & 0x07;569 570 wrench = !!(data[2] & 0x01);571 keyboard = !!(data[2] & 0x02);572 573 if (features->oPid) {574 mute_touch = !!(data[2] & 0x04);575 if (mute_touch)576 wacom->shared->is_touch_on =577 !wacom->shared->is_touch_on;578 } else {579 menu = !!(data[2] & 0x04);580 }581 input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));582 input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));583 input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));584 } else if (features->type == CINTIQ_HYBRID) {585 /*586 * Do not send hardware buttons under Android. They587 * are already sent to the system through GPIO (and588 * have different meaning).589 *590 * d-pad right -> data[4] & 0x10591 * d-pad up -> data[4] & 0x20592 * d-pad left -> data[4] & 0x40593 * d-pad down -> data[4] & 0x80594 * d-pad center -> data[3] & 0x01595 */596 buttons = (data[4] << 1) | (data[3] & 0x01);597 } else if (features->type == CINTIQ_COMPANION_2) {598 /* d-pad right -> data[2] & 0x10599 * d-pad up -> data[2] & 0x20600 * d-pad left -> data[2] & 0x40601 * d-pad down -> data[2] & 0x80602 * d-pad center -> data[1] & 0x01603 */604 buttons = ((data[2] >> 4) << 7) |605 ((data[1] & 0x04) << 4) |606 ((data[2] & 0x0F) << 2) |607 (data[1] & 0x03);608 } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {609 /*610 * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in611 * addition to the mechanical switch. Switch data is612 * stored in data[4], capacitive data in data[5].613 *614 * Touch ring mode switch (data[3]) has no capacitive sensor615 */616 buttons = (data[4] << 1) | (data[3] & 0x01);617 ring1 = data[2];618 } else {619 if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {620 buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) |621 (data[6] << 1) | (data[5] & 0x01);622 623 if (features->type == WACOM_22HD) {624 nkeys = 3;625 keys = data[9] & 0x07;626 627 info = !!(data[9] & 0x01);628 wrench = !!(data[9] & 0x02);629 }630 } else {631 buttons = ((data[6] & 0x10) << 5) |632 ((data[5] & 0x10) << 4) |633 ((data[6] & 0x0F) << 4) |634 (data[5] & 0x0F);635 }636 strip1 = ((data[1] & 0x1f) << 8) | data[2];637 strip2 = ((data[3] & 0x1f) << 8) | data[4];638 }639 640 prox = (buttons & ~(~0U << nbuttons)) | (keys & ~(~0U << nkeys)) |641 (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2;642 643 wacom_report_numbered_buttons(input, nbuttons, buttons);644 645 for (i = 0; i < nkeys; i++)646 input_report_key(input, KEY_PROG1 + i, keys & (1 << i));647 648 input_report_key(input, KEY_BUTTONCONFIG, wrench);649 input_report_key(input, KEY_ONSCREEN_KEYBOARD, keyboard);650 input_report_key(input, KEY_CONTROLPANEL, menu);651 input_report_key(input, KEY_INFO, info);652 653 if (wacom->shared && wacom->shared->touch_input) {654 input_report_switch(wacom->shared->touch_input,655 SW_MUTE_DEVICE,656 !wacom->shared->is_touch_on);657 input_sync(wacom->shared->touch_input);658 }659 660 input_report_abs(input, ABS_RX, strip1);661 input_report_abs(input, ABS_RY, strip2);662 663 input_report_abs(input, ABS_WHEEL, (ring1 & 0x80) ? (ring1 & 0x7f) : 0);664 input_report_abs(input, ABS_THROTTLE, (ring2 & 0x80) ? (ring2 & 0x7f) : 0);665 666 input_report_key(input, wacom->tool[1], prox ? 1 : 0);667 input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);668 669 input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);670 671 return 1;672}673 674static int wacom_intuos_id_mangle(int tool_id)675{676 return (tool_id & ~0xFFF) << 4 | (tool_id & 0xFFF);677}678 679static bool wacom_is_art_pen(int tool_id)680{681 bool is_art_pen = false;682 683 switch (tool_id) {684 case 0x885: /* Intuos3 Marker Pen */685 case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */686 case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */687 is_art_pen = true;688 break;689 }690 return is_art_pen;691}692 693static int wacom_intuos_get_tool_type(int tool_id)694{695 switch (tool_id) {696 case 0x812: /* Inking pen */697 case 0x801: /* Intuos3 Inking pen */698 case 0x12802: /* Intuos4/5 Inking Pen */699 case 0x012:700 return BTN_TOOL_PENCIL;701 702 case 0x832: /* Stroke pen */703 case 0x032:704 return BTN_TOOL_BRUSH;705 706 case 0x007: /* Mouse 4D and 2D */707 case 0x09c:708 case 0x094:709 case 0x017: /* Intuos3 2D Mouse */710 case 0x806: /* Intuos4 Mouse */711 return BTN_TOOL_MOUSE;712 713 case 0x096: /* Lens cursor */714 case 0x097: /* Intuos3 Lens cursor */715 case 0x006: /* Intuos4 Lens cursor */716 return BTN_TOOL_LENS;717 718 case 0xd12:719 case 0x912:720 case 0x112:721 case 0x913: /* Intuos3 Airbrush */722 case 0x902: /* Intuos4/5 13HD/24HD Airbrush */723 case 0x10902: /* Intuos4/5 13HD/24HD Airbrush */724 return BTN_TOOL_AIRBRUSH;725 726 default:727 if (tool_id & 0x0008)728 return BTN_TOOL_RUBBER;729 return BTN_TOOL_PEN;730 }731}732 733static void wacom_exit_report(struct wacom_wac *wacom)734{735 struct input_dev *input = wacom->pen_input;736 struct wacom_features *features = &wacom->features;737 unsigned char *data = wacom->data;738 int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;739 740 /*741 * Reset all states otherwise we lose the initial states742 * when in-prox next time743 */744 input_report_abs(input, ABS_X, 0);745 input_report_abs(input, ABS_Y, 0);746 input_report_abs(input, ABS_DISTANCE, 0);747 input_report_abs(input, ABS_TILT_X, 0);748 input_report_abs(input, ABS_TILT_Y, 0);749 if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {750 input_report_key(input, BTN_LEFT, 0);751 input_report_key(input, BTN_MIDDLE, 0);752 input_report_key(input, BTN_RIGHT, 0);753 input_report_key(input, BTN_SIDE, 0);754 input_report_key(input, BTN_EXTRA, 0);755 input_report_abs(input, ABS_THROTTLE, 0);756 input_report_abs(input, ABS_RZ, 0);757 } else {758 input_report_abs(input, ABS_PRESSURE, 0);759 input_report_key(input, BTN_STYLUS, 0);760 input_report_key(input, BTN_STYLUS2, 0);761 input_report_key(input, BTN_TOUCH, 0);762 input_report_abs(input, ABS_WHEEL, 0);763 if (features->type >= INTUOS3S)764 input_report_abs(input, ABS_Z, 0);765 }766 input_report_key(input, wacom->tool[idx], 0);767 input_report_abs(input, ABS_MISC, 0); /* reset tool id */768 input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);769 wacom->id[idx] = 0;770}771 772static int wacom_intuos_inout(struct wacom_wac *wacom)773{774 struct wacom_features *features = &wacom->features;775 unsigned char *data = wacom->data;776 struct input_dev *input = wacom->pen_input;777 int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;778 779 if (!(((data[1] & 0xfc) == 0xc0) || /* in prox */780 ((data[1] & 0xfe) == 0x20) || /* in range */781 ((data[1] & 0xfe) == 0x80))) /* out prox */782 return 0;783 784 /* Enter report */785 if ((data[1] & 0xfc) == 0xc0) {786 /* serial number of the tool */787 wacom->serial[idx] = ((__u64)(data[3] & 0x0f) << 28) +788 (data[4] << 20) + (data[5] << 12) +789 (data[6] << 4) + (data[7] >> 4);790 791 wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) |792 ((data[7] & 0x0f) << 16) | ((data[8] & 0xf0) << 8);793 794 wacom->tool[idx] = wacom_intuos_get_tool_type(wacom->id[idx]);795 796 wacom->shared->stylus_in_proximity = true;797 return 1;798 }799 800 /* in Range */801 if ((data[1] & 0xfe) == 0x20) {802 if (features->type != INTUOSHT2)803 wacom->shared->stylus_in_proximity = true;804 805 /* in Range while exiting */806 if (wacom->reporting_data) {807 input_report_key(input, BTN_TOUCH, 0);808 input_report_abs(input, ABS_PRESSURE, 0);809 input_report_abs(input, ABS_DISTANCE, wacom->features.distance_max);810 return 2;811 }812 return 1;813 }814 815 /* Exit report */816 if ((data[1] & 0xfe) == 0x80) {817 wacom->shared->stylus_in_proximity = false;818 wacom->reporting_data = false;819 820 /* don't report exit if we don't know the ID */821 if (!wacom->id[idx])822 return 1;823 824 wacom_exit_report(wacom);825 return 2;826 }827 828 return 0;829}830 831static inline bool touch_is_muted(struct wacom_wac *wacom_wac)832{833 return wacom_wac->probe_complete &&834 wacom_wac->shared->has_mute_touch_switch &&835 !wacom_wac->shared->is_touch_on;836}837 838static inline bool report_touch_events(struct wacom_wac *wacom)839{840 return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1);841}842 843static inline bool delay_pen_events(struct wacom_wac *wacom)844{845 return (wacom->shared->touch_down && touch_arbitration);846}847 848static int wacom_intuos_general(struct wacom_wac *wacom)849{850 struct wacom_features *features = &wacom->features;851 unsigned char *data = wacom->data;852 struct input_dev *input = wacom->pen_input;853 int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;854 unsigned char type = (data[1] >> 1) & 0x0F;855 unsigned int x, y, distance, t;856 857 if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ &&858 data[0] != WACOM_REPORT_INTUOS_PEN)859 return 0;860 861 if (delay_pen_events(wacom))862 return 1;863 864 /* don't report events if we don't know the tool ID */865 if (!wacom->id[idx]) {866 /* but reschedule a read of the current tool */867 wacom_intuos_schedule_prox_event(wacom);868 return 1;869 }870 871 /*872 * don't report events for invalid data873 */874 /* older I4 styli don't work with new Cintiqs */875 if ((!((wacom->id[idx] >> 16) & 0x01) &&876 (features->type == WACOM_21UX2)) ||877 /* Only large Intuos support Lense Cursor */878 (wacom->tool[idx] == BTN_TOOL_LENS &&879 (features->type == INTUOS3 ||880 features->type == INTUOS3S ||881 features->type == INTUOS4 ||882 features->type == INTUOS4S ||883 features->type == INTUOS5 ||884 features->type == INTUOS5S ||885 features->type == INTUOSPM ||886 features->type == INTUOSPS)) ||887 /* Cintiq doesn't send data when RDY bit isn't set */888 (features->type == CINTIQ && !(data[1] & 0x40)))889 return 1;890 891 x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1);892 y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1);893 distance = data[9] >> 2;894 if (features->type < INTUOS3S) {895 x >>= 1;896 y >>= 1;897 distance >>= 1;898 }899 if (features->type == INTUOSHT2)900 distance = features->distance_max - distance;901 input_report_abs(input, ABS_X, x);902 input_report_abs(input, ABS_Y, y);903 input_report_abs(input, ABS_DISTANCE, distance);904 905 switch (type) {906 case 0x00:907 case 0x01:908 case 0x02:909 case 0x03:910 /* general pen packet */911 t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1);912 if (features->pressure_max < 2047)913 t >>= 1;914 input_report_abs(input, ABS_PRESSURE, t);915 if (features->type != INTUOSHT2) {916 input_report_abs(input, ABS_TILT_X,917 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);918 input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);919 }920 input_report_key(input, BTN_STYLUS, data[1] & 2);921 input_report_key(input, BTN_STYLUS2, data[1] & 4);922 input_report_key(input, BTN_TOUCH, t > 10);923 break;924 925 case 0x0a:926 /* airbrush second packet */927 input_report_abs(input, ABS_WHEEL,928 (data[6] << 2) | ((data[7] >> 6) & 3));929 input_report_abs(input, ABS_TILT_X,930 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);931 input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);932 break;933 934 case 0x05:935 /* Rotation packet */936 if (features->type >= INTUOS3S) {937 /* I3 marker pen rotation */938 t = (data[6] << 3) | ((data[7] >> 5) & 7);939 t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :940 ((t-1) / 2 + 450)) : (450 - t / 2) ;941 input_report_abs(input, ABS_Z, t);942 } else {943 /* 4D mouse 2nd packet */944 t = (data[6] << 3) | ((data[7] >> 5) & 7);945 input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?946 ((t - 1) / 2) : -t / 2);947 }948 break;949 950 case 0x04:951 /* 4D mouse 1st packet */952 input_report_key(input, BTN_LEFT, data[8] & 0x01);953 input_report_key(input, BTN_MIDDLE, data[8] & 0x02);954 input_report_key(input, BTN_RIGHT, data[8] & 0x04);955 956 input_report_key(input, BTN_SIDE, data[8] & 0x20);957 input_report_key(input, BTN_EXTRA, data[8] & 0x10);958 t = (data[6] << 2) | ((data[7] >> 6) & 3);959 input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);960 break;961 962 case 0x06:963 /* I4 mouse */964 input_report_key(input, BTN_LEFT, data[6] & 0x01);965 input_report_key(input, BTN_MIDDLE, data[6] & 0x02);966 input_report_key(input, BTN_RIGHT, data[6] & 0x04);967 input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)968 - ((data[7] & 0x40) >> 6));969 input_report_key(input, BTN_SIDE, data[6] & 0x08);970 input_report_key(input, BTN_EXTRA, data[6] & 0x10);971 972 input_report_abs(input, ABS_TILT_X,973 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);974 input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);975 break;976 977 case 0x08:978 if (wacom->tool[idx] == BTN_TOOL_MOUSE) {979 /* 2D mouse packet */980 input_report_key(input, BTN_LEFT, data[8] & 0x04);981 input_report_key(input, BTN_MIDDLE, data[8] & 0x08);982 input_report_key(input, BTN_RIGHT, data[8] & 0x10);983 input_report_rel(input, REL_WHEEL, (data[8] & 0x01)984 - ((data[8] & 0x02) >> 1));985 986 /* I3 2D mouse side buttons */987 if (features->type >= INTUOS3S && features->type <= INTUOS3L) {988 input_report_key(input, BTN_SIDE, data[8] & 0x40);989 input_report_key(input, BTN_EXTRA, data[8] & 0x20);990 }991 }992 else if (wacom->tool[idx] == BTN_TOOL_LENS) {993 /* Lens cursor packets */994 input_report_key(input, BTN_LEFT, data[8] & 0x01);995 input_report_key(input, BTN_MIDDLE, data[8] & 0x02);996 input_report_key(input, BTN_RIGHT, data[8] & 0x04);997 input_report_key(input, BTN_SIDE, data[8] & 0x10);998 input_report_key(input, BTN_EXTRA, data[8] & 0x08);999 }1000 break;1001 1002 case 0x07:1003 case 0x09:1004 case 0x0b:1005 case 0x0c:1006 case 0x0d:1007 case 0x0e:1008 case 0x0f:1009 /* unhandled */1010 break;1011 }1012 1013 input_report_abs(input, ABS_MISC,1014 wacom_intuos_id_mangle(wacom->id[idx])); /* report tool id */1015 input_report_key(input, wacom->tool[idx], 1);1016 input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);1017 wacom->reporting_data = true;1018 return 2;1019}1020 1021static int wacom_intuos_irq(struct wacom_wac *wacom)1022{1023 unsigned char *data = wacom->data;1024 struct input_dev *input = wacom->pen_input;1025 int result;1026 1027 if (data[0] != WACOM_REPORT_PENABLED &&1028 data[0] != WACOM_REPORT_INTUOS_ID1 &&1029 data[0] != WACOM_REPORT_INTUOS_ID2 &&1030 data[0] != WACOM_REPORT_INTUOSPAD &&1031 data[0] != WACOM_REPORT_INTUOS_PEN &&1032 data[0] != WACOM_REPORT_CINTIQ &&1033 data[0] != WACOM_REPORT_CINTIQPAD &&1034 data[0] != WACOM_REPORT_INTUOS5PAD) {1035 dev_dbg(input->dev.parent,1036 "%s: received unknown report #%d\n", __func__, data[0]);1037 return 0;1038 }1039 1040 /* process pad events */1041 result = wacom_intuos_pad(wacom);1042 if (result)1043 return result;1044 1045 /* process in/out prox events */1046 result = wacom_intuos_inout(wacom);1047 if (result)1048 return result - 1;1049 1050 /* process general packets */1051 result = wacom_intuos_general(wacom);1052 if (result)1053 return result - 1;1054 1055 return 0;1056}1057 1058static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)1059{1060 unsigned char *data = wacom_wac->data;1061 struct input_dev *input;1062 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);1063 struct wacom_remote *remote = wacom->remote;1064 int bat_charging, bat_percent, touch_ring_mode;1065 __u32 serial;1066 int i, index = -1;1067 unsigned long flags;1068 1069 if (data[0] != WACOM_REPORT_REMOTE) {1070 hid_dbg(wacom->hdev, "%s: received unknown report #%d",1071 __func__, data[0]);1072 return 0;1073 }1074 1075 serial = data[3] + (data[4] << 8) + (data[5] << 16);1076 wacom_wac->id[0] = PAD_DEVICE_ID;1077 1078 spin_lock_irqsave(&remote->remote_lock, flags);1079 1080 for (i = 0; i < WACOM_MAX_REMOTES; i++) {1081 if (remote->remotes[i].serial == serial) {1082 index = i;1083 break;1084 }1085 }1086 1087 if (index < 0 || !remote->remotes[index].registered)1088 goto out;1089 1090 remote->remotes[i].active_time = ktime_get();1091 input = remote->remotes[index].input;1092 1093 input_report_key(input, BTN_0, (data[9] & 0x01));1094 input_report_key(input, BTN_1, (data[9] & 0x02));1095 input_report_key(input, BTN_2, (data[9] & 0x04));1096 input_report_key(input, BTN_3, (data[9] & 0x08));1097 input_report_key(input, BTN_4, (data[9] & 0x10));1098 input_report_key(input, BTN_5, (data[9] & 0x20));1099 input_report_key(input, BTN_6, (data[9] & 0x40));1100 input_report_key(input, BTN_7, (data[9] & 0x80));1101 1102 input_report_key(input, BTN_8, (data[10] & 0x01));1103 input_report_key(input, BTN_9, (data[10] & 0x02));1104 input_report_key(input, BTN_A, (data[10] & 0x04));1105 input_report_key(input, BTN_B, (data[10] & 0x08));1106 input_report_key(input, BTN_C, (data[10] & 0x10));1107 input_report_key(input, BTN_X, (data[10] & 0x20));1108 input_report_key(input, BTN_Y, (data[10] & 0x40));1109 input_report_key(input, BTN_Z, (data[10] & 0x80));1110 1111 input_report_key(input, BTN_BASE, (data[11] & 0x01));1112 input_report_key(input, BTN_BASE2, (data[11] & 0x02));1113 1114 if (data[12] & 0x80)1115 input_report_abs(input, ABS_WHEEL, (data[12] & 0x7f) - 1);1116 else1117 input_report_abs(input, ABS_WHEEL, 0);1118 1119 bat_percent = data[7] & 0x7f;1120 bat_charging = !!(data[7] & 0x80);1121 1122 if (data[9] | data[10] | (data[11] & 0x03) | data[12])1123 input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);1124 else1125 input_report_abs(input, ABS_MISC, 0);1126 1127 input_event(input, EV_MSC, MSC_SERIAL, serial);1128 1129 input_sync(input);1130 1131 /*Which mode select (LED light) is currently on?*/1132 touch_ring_mode = (data[11] & 0xC0) >> 6;1133 1134 for (i = 0; i < WACOM_MAX_REMOTES; i++) {1135 if (remote->remotes[i].serial == serial)1136 wacom->led.groups[i].select = touch_ring_mode;1137 }1138 1139 __wacom_notify_battery(&remote->remotes[index].battery,1140 WACOM_POWER_SUPPLY_STATUS_AUTO, bat_percent,1141 bat_charging, 1, bat_charging);1142 1143out:1144 spin_unlock_irqrestore(&remote->remote_lock, flags);1145 return 0;1146}1147 1148static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)1149{1150 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);1151 unsigned char *data = wacom_wac->data;1152 struct wacom_remote *remote = wacom->remote;1153 struct wacom_remote_work_data remote_data;1154 unsigned long flags;1155 int i, ret;1156 1157 if (data[0] != WACOM_REPORT_DEVICE_LIST)1158 return;1159 1160 memset(&remote_data, 0, sizeof(struct wacom_remote_work_data));1161 1162 for (i = 0; i < WACOM_MAX_REMOTES; i++) {1163 int j = i * 6;1164 int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4];1165 1166 remote_data.remote[i].serial = serial;1167 }1168 1169 spin_lock_irqsave(&remote->remote_lock, flags);1170 1171 ret = kfifo_in(&remote->remote_fifo, &remote_data, sizeof(remote_data));1172 if (ret != sizeof(remote_data)) {1173 spin_unlock_irqrestore(&remote->remote_lock, flags);1174 hid_err(wacom->hdev, "Can't queue Remote status event.\n");1175 return;1176 }1177 1178 spin_unlock_irqrestore(&remote->remote_lock, flags);1179 1180 wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE);1181}1182 1183static int int_dist(int x1, int y1, int x2, int y2)1184{1185 int x = x2 - x1;1186 int y = y2 - y1;1187 1188 return int_sqrt(x*x + y*y);1189}1190 1191static void wacom_intuos_bt_process_data(struct wacom_wac *wacom,1192 unsigned char *data)1193{1194 memcpy(wacom->data, data, 10);1195 wacom_intuos_irq(wacom);1196 1197 input_sync(wacom->pen_input);1198 if (wacom->pad_input)1199 input_sync(wacom->pad_input);1200}1201 1202static int wacom_intuos_bt_irq(struct wacom_wac *wacom, size_t len)1203{1204 unsigned char data[WACOM_PKGLEN_MAX];1205 int i = 1;1206 unsigned power_raw, battery_capacity, bat_charging, ps_connected;1207 1208 memcpy(data, wacom->data, len);1209 1210 switch (data[0]) {1211 case 0x04:1212 wacom_intuos_bt_process_data(wacom, data + i);1213 i += 10;1214 fallthrough;1215 case 0x03:1216 wacom_intuos_bt_process_data(wacom, data + i);1217 i += 10;1218 wacom_intuos_bt_process_data(wacom, data + i);1219 i += 10;1220 power_raw = data[i];1221 bat_charging = (power_raw & 0x08) ? 1 : 0;1222 ps_connected = (power_raw & 0x10) ? 1 : 0;1223 battery_capacity = batcap_i4[power_raw & 0x07];1224 wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,1225 battery_capacity, bat_charging,1226 battery_capacity || bat_charging,1227 ps_connected);1228 break;1229 default:1230 dev_dbg(wacom->pen_input->dev.parent,1231 "Unknown report: %d,%d size:%zu\n",1232 data[0], data[1], len);1233 return 0;1234 }1235 return 0;1236}1237 1238static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)1239{1240 struct input_dev *input = wacom->touch_input;1241 unsigned touch_max = wacom->features.touch_max;1242 int count = 0;1243 int i;1244 1245 if (!touch_max)1246 return 0;1247 1248 if (touch_max == 1)1249 return test_bit(BTN_TOUCH, input->key) &&1250 report_touch_events(wacom);1251 1252 for (i = 0; i < input->mt->num_slots; i++) {1253 struct input_mt_slot *ps = &input->mt->slots[i];1254 int id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);1255 if (id >= 0)1256 count++;1257 }1258 1259 return count;1260}1261 1262static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)1263{1264 int pen_frame_len, pen_frames;1265 1266 struct input_dev *pen_input = wacom->pen_input;1267 unsigned char *data = wacom->data;1268 int number_of_valid_frames = 0;1269 ktime_t time_interval = 15000000;1270 ktime_t time_packet_received = ktime_get();1271 int i;1272 1273 if (wacom->features.type == INTUOSP2_BT ||1274 wacom->features.type == INTUOSP2S_BT) {1275 wacom->serial[0] = get_unaligned_le64(&data[99]);1276 wacom->id[0] = get_unaligned_le16(&data[107]);1277 pen_frame_len = 14;1278 pen_frames = 7;1279 } else {1280 wacom->serial[0] = get_unaligned_le64(&data[33]);1281 wacom->id[0] = get_unaligned_le16(&data[41]);1282 pen_frame_len = 8;1283 pen_frames = 4;1284 }1285 1286 if (wacom->serial[0] >> 52 == 1) {1287 /* Add back in missing bits of ID for non-USI pens */1288 wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;1289 }1290 1291 /* number of valid frames */1292 for (i = 0; i < pen_frames; i++) {1293 unsigned char *frame = &data[i*pen_frame_len + 1];1294 bool valid = frame[0] & 0x80;1295 1296 if (valid)1297 number_of_valid_frames++;1298 }1299 1300 if (number_of_valid_frames) {1301 if (wacom->hid_data.time_delayed)1302 time_interval = ktime_get() - wacom->hid_data.time_delayed;1303 time_interval = div_u64(time_interval, number_of_valid_frames);1304 wacom->hid_data.time_delayed = time_packet_received;1305 }1306 1307 for (i = 0; i < number_of_valid_frames; i++) {1308 unsigned char *frame = &data[i*pen_frame_len + 1];1309 bool valid = frame[0] & 0x80;1310 bool prox = frame[0] & 0x40;1311 bool range = frame[0] & 0x20;1312 bool invert = frame[0] & 0x10;1313 int frames_number_reversed = number_of_valid_frames - i - 1;1314 ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval;1315 1316 if (!valid)1317 continue;1318 1319 if (!prox) {1320 wacom->shared->stylus_in_proximity = false;1321 wacom_exit_report(wacom);1322 input_sync(pen_input);1323 1324 wacom->tool[0] = 0;1325 wacom->id[0] = 0;1326 wacom->serial[0] = 0;1327 wacom->hid_data.time_delayed = 0;1328 return;1329 }1330 1331 if (range) {1332 if (!wacom->tool[0]) { /* first in range */1333 /* Going into range select tool */1334 if (invert)1335 wacom->tool[0] = BTN_TOOL_RUBBER;1336 else if (wacom->id[0])1337 wacom->tool[0] = wacom_intuos_get_tool_type(wacom->id[0]);1338 else1339 wacom->tool[0] = BTN_TOOL_PEN;1340 }1341 1342 input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));1343 input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));1344 1345 if (wacom->features.type == INTUOSP2_BT ||1346 wacom->features.type == INTUOSP2S_BT) {1347 /* Fix rotation alignment: userspace expects zero at left */1348 int16_t rotation =1349 (int16_t)get_unaligned_le16(&frame[9]);1350 rotation += 1800/4;1351 1352 if (rotation > 899)1353 rotation -= 1800;1354 1355 input_report_abs(pen_input, ABS_TILT_X,1356 (char)frame[7]);1357 input_report_abs(pen_input, ABS_TILT_Y,1358 (char)frame[8]);1359 input_report_abs(pen_input, ABS_Z, rotation);1360 input_report_abs(pen_input, ABS_WHEEL,1361 get_unaligned_le16(&frame[11]));1362 }1363 }1364 1365 if (wacom->tool[0]) {1366 input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));1367 if (wacom->features.type == INTUOSP2_BT ||1368 wacom->features.type == INTUOSP2S_BT) {1369 input_report_abs(pen_input, ABS_DISTANCE,1370 range ? frame[13] : wacom->features.distance_max);1371 } else {1372 input_report_abs(pen_input, ABS_DISTANCE,1373 range ? frame[7] : wacom->features.distance_max);1374 }1375 1376 input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x09);1377 input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02);1378 input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04);1379 1380 input_report_key(pen_input, wacom->tool[0], prox);1381 input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]);1382 input_report_abs(pen_input, ABS_MISC,1383 wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */1384 }1385 1386 wacom->shared->stylus_in_proximity = prox;1387 1388 /* add timestamp to unpack the frames */1389 input_set_timestamp(pen_input, event_timestamp);1390 1391 input_sync(pen_input);1392 }1393}1394 1395static void wacom_intuos_pro2_bt_touch(struct wacom_wac *wacom)1396{1397 const int finger_touch_len = 8;1398 const int finger_frames = 4;1399 const int finger_frame_len = 43;1400 1401 struct input_dev *touch_input = wacom->touch_input;1402 unsigned char *data = wacom->data;1403 int num_contacts_left = 5;1404 int i, j;1405 1406 for (i = 0; i < finger_frames; i++) {1407 unsigned char *frame = &data[i*finger_frame_len + 109];1408 int current_num_contacts = frame[0] & 0x7F;1409 int contacts_to_send;1410 1411 if (!(frame[0] & 0x80))1412 continue;1413 1414 /*1415 * First packet resets the counter since only the first1416 * packet in series will have non-zero current_num_contacts.1417 */1418 if (current_num_contacts)1419 wacom->num_contacts_left = current_num_contacts;1420 1421 contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);1422 1423 for (j = 0; j < contacts_to_send; j++) {1424 unsigned char *touch = &frame[j*finger_touch_len + 1];1425 int slot = input_mt_get_slot_by_key(touch_input, touch[0]);1426 int x = get_unaligned_le16(&touch[2]);1427 int y = get_unaligned_le16(&touch[4]);1428 int w = touch[6] * input_abs_get_res(touch_input, ABS_MT_POSITION_X);1429 int h = touch[7] * input_abs_get_res(touch_input, ABS_MT_POSITION_Y);1430 1431 if (slot < 0)1432 continue;1433 1434 input_mt_slot(touch_input, slot);1435 input_mt_report_slot_state(touch_input, MT_TOOL_FINGER, touch[1] & 0x01);1436 input_report_abs(touch_input, ABS_MT_POSITION_X, x);1437 input_report_abs(touch_input, ABS_MT_POSITION_Y, y);1438 input_report_abs(touch_input, ABS_MT_TOUCH_MAJOR, max(w, h));1439 input_report_abs(touch_input, ABS_MT_TOUCH_MINOR, min(w, h));1440 input_report_abs(touch_input, ABS_MT_ORIENTATION, w > h);1441 }1442 1443 input_mt_sync_frame(touch_input);1444 1445 wacom->num_contacts_left -= contacts_to_send;1446 if (wacom->num_contacts_left <= 0) {1447 wacom->num_contacts_left = 0;1448 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);1449 input_sync(touch_input);1450 }1451 }1452 1453 if (wacom->num_contacts_left == 0) {1454 // Be careful that we don't accidentally call input_sync with1455 // only a partial set of fingers of processed1456 input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7));1457 input_sync(touch_input);1458 }1459 1460}1461 1462static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)1463{1464 struct input_dev *pad_input = wacom->pad_input;1465 unsigned char *data = wacom->data;1466 int nbuttons = wacom->features.numbered_buttons;1467 1468 int expresskeys = data[282];1469 int center = (data[281] & 0x40) >> 6;1470 int ring = data[285] & 0x7F;1471 bool ringstatus = data[285] & 0x80;1472 bool prox = expresskeys || center || ringstatus;1473 1474 /* Fix touchring data: userspace expects 0 at left and increasing clockwise */1475 ring = 71 - ring;1476 ring += 3*72/16;1477 if (ring > 71)1478 ring -= 72;1479 1480 wacom_report_numbered_buttons(pad_input, nbuttons,1481 expresskeys | (center << (nbuttons - 1)));1482 1483 input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0);1484 1485 input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0);1486 input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);1487 input_event(pad_input, EV_MSC, MSC_SERIAL, 0xffffffff);1488 1489 input_sync(pad_input);1490}1491 1492static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom)1493{1494 unsigned char *data = wacom->data;1495 1496 bool chg = data[284] & 0x80;1497 int battery_status = data[284] & 0x7F;1498 1499 wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,1500 battery_status, chg, 1, chg);1501}1502 1503static void wacom_intuos_gen3_bt_pad(struct wacom_wac *wacom)1504{1505 struct input_dev *pad_input = wacom->pad_input;1506 unsigned char *data = wacom->data;1507 1508 int buttons = data[44];1509 1510 wacom_report_numbered_buttons(pad_input, 4, buttons);1511 1512 input_report_key(pad_input, wacom->tool[1], buttons ? 1 : 0);1513 input_report_abs(pad_input, ABS_MISC, buttons ? PAD_DEVICE_ID : 0);1514 input_event(pad_input, EV_MSC, MSC_SERIAL, 0xffffffff);1515 1516 input_sync(pad_input);1517}1518 1519static void wacom_intuos_gen3_bt_battery(struct wacom_wac *wacom)1520{1521 unsigned char *data = wacom->data;1522 1523 bool chg = data[45] & 0x80;1524 int battery_status = data[45] & 0x7F;1525 1526 wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,1527 battery_status, chg, 1, chg);1528}1529 1530static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len)1531{1532 unsigned char *data = wacom->data;1533 1534 if (data[0] != 0x80 && data[0] != 0x81) {1535 dev_dbg(wacom->pen_input->dev.parent,1536 "%s: received unknown report #%d\n", __func__, data[0]);1537 return 0;1538 }1539 1540 wacom_intuos_pro2_bt_pen(wacom);1541 if (wacom->features.type == INTUOSP2_BT ||1542 wacom->features.type == INTUOSP2S_BT) {1543 wacom_intuos_pro2_bt_touch(wacom);1544 wacom_intuos_pro2_bt_pad(wacom);1545 wacom_intuos_pro2_bt_battery(wacom);1546 } else {1547 wacom_intuos_gen3_bt_pad(wacom);1548 wacom_intuos_gen3_bt_battery(wacom);1549 }1550 return 0;1551}1552 1553static int wacom_24hdt_irq(struct wacom_wac *wacom)1554{1555 struct input_dev *input = wacom->touch_input;1556 unsigned char *data = wacom->data;1557 int i;1558 int current_num_contacts = data[61];1559 int contacts_to_send = 0;1560 int num_contacts_left = 4; /* maximum contacts per packet */1561 int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;1562 int y_offset = 2;1563 1564 if (touch_is_muted(wacom) && !wacom->shared->touch_down)1565 return 0;1566 1567 if (wacom->features.type == WACOM_27QHDT) {1568 current_num_contacts = data[63];1569 num_contacts_left = 10;1570 byte_per_packet = WACOM_BYTES_PER_QHDTHID_PACKET;1571 y_offset = 0;1572 }1573 1574 /*1575 * First packet resets the counter since only the first1576 * packet in series will have non-zero current_num_contacts.1577 */1578 if (current_num_contacts)1579 wacom->num_contacts_left = current_num_contacts;1580 1581 contacts_to_send = min(num_contacts_left, wacom->num_contacts_left);1582 1583 for (i = 0; i < contacts_to_send; i++) {1584 int offset = (byte_per_packet * i) + 1;1585 bool touch = (data[offset] & 0x1) && report_touch_events(wacom);1586 int slot = input_mt_get_slot_by_key(input, data[offset + 1]);1587 1588 if (slot < 0)1589 continue;1590 input_mt_slot(input, slot);1591 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);1592 1593 if (touch) {1594 int t_x = get_unaligned_le16(&data[offset + 2]);1595 int t_y = get_unaligned_le16(&data[offset + 4 + y_offset]);1596 1597 input_report_abs(input, ABS_MT_POSITION_X, t_x);1598 input_report_abs(input, ABS_MT_POSITION_Y, t_y);1599 1600 if (wacom->features.type != WACOM_27QHDT) {1601 int c_x = get_unaligned_le16(&data[offset + 4]);1602 int c_y = get_unaligned_le16(&data[offset + 8]);1603 int w = get_unaligned_le16(&data[offset + 10]);1604 int h = get_unaligned_le16(&data[offset + 12]);1605 1606 input_report_abs(input, ABS_MT_TOUCH_MAJOR, min(w,h));1607 input_report_abs(input, ABS_MT_WIDTH_MAJOR,1608 min(w, h) + int_dist(t_x, t_y, c_x, c_y));1609 input_report_abs(input, ABS_MT_WIDTH_MINOR, min(w, h));1610 input_report_abs(input, ABS_MT_ORIENTATION, w > h);1611 }1612 }1613 }1614 input_mt_sync_frame(input);1615 1616 wacom->num_contacts_left -= contacts_to_send;1617 if (wacom->num_contacts_left <= 0) {1618 wacom->num_contacts_left = 0;1619 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);1620 }1621 return 1;1622}1623 1624static int wacom_mt_touch(struct wacom_wac *wacom)1625{1626 struct input_dev *input = wacom->touch_input;1627 unsigned char *data = wacom->data;1628 int i;1629 int current_num_contacts = data[2];1630 int contacts_to_send = 0;1631 int x_offset = 0;1632 1633 /* MTTPC does not support Height and Width */1634 if (wacom->features.type == MTTPC || wacom->features.type == MTTPC_B)1635 x_offset = -4;1636 1637 /*1638 * First packet resets the counter since only the first1639 * packet in series will have non-zero current_num_contacts.1640 */1641 if (current_num_contacts)1642 wacom->num_contacts_left = current_num_contacts;1643 1644 /* There are at most 5 contacts per packet */1645 contacts_to_send = min(5, wacom->num_contacts_left);1646 1647 for (i = 0; i < contacts_to_send; i++) {1648 int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3;1649 bool touch = (data[offset] & 0x1) && report_touch_events(wacom);1650 int id = get_unaligned_le16(&data[offset + 1]);1651 int slot = input_mt_get_slot_by_key(input, id);1652 1653 if (slot < 0)1654 continue;1655 1656 input_mt_slot(input, slot);1657 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);1658 if (touch) {1659 int x = get_unaligned_le16(&data[offset + x_offset + 7]);1660 int y = get_unaligned_le16(&data[offset + x_offset + 9]);1661 input_report_abs(input, ABS_MT_POSITION_X, x);1662 input_report_abs(input, ABS_MT_POSITION_Y, y);1663 }1664 }1665 input_mt_sync_frame(input);1666 1667 wacom->num_contacts_left -= contacts_to_send;1668 if (wacom->num_contacts_left <= 0) {1669 wacom->num_contacts_left = 0;1670 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);1671 }1672 return 1;1673}1674 1675static int wacom_tpc_mt_touch(struct wacom_wac *wacom)1676{1677 struct input_dev *input = wacom->touch_input;1678 unsigned char *data = wacom->data;1679 int i;1680 1681 for (i = 0; i < 2; i++) {1682 int p = data[1] & (1 << i);1683 bool touch = p && report_touch_events(wacom);1684 1685 input_mt_slot(input, i);1686 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);1687 if (touch) {1688 int x = le16_to_cpup((__le16 *)&data[i * 2 + 2]) & 0x7fff;1689 int y = le16_to_cpup((__le16 *)&data[i * 2 + 6]) & 0x7fff;1690 1691 input_report_abs(input, ABS_MT_POSITION_X, x);1692 input_report_abs(input, ABS_MT_POSITION_Y, y);1693 }1694 }1695 input_mt_sync_frame(input);1696 1697 /* keep touch state for pen event */1698 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);1699 1700 return 1;1701}1702 1703static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len)1704{1705 unsigned char *data = wacom->data;1706 struct input_dev *input = wacom->touch_input;1707 bool prox = report_touch_events(wacom);1708 int x = 0, y = 0;1709 1710 if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG)1711 return 0;1712 1713 if (len == WACOM_PKGLEN_TPC1FG) {1714 prox = prox && (data[0] & 0x01);1715 x = get_unaligned_le16(&data[1]);1716 y = get_unaligned_le16(&data[3]);1717 } else if (len == WACOM_PKGLEN_TPC1FG_B) {1718 prox = prox && (data[2] & 0x01);1719 x = get_unaligned_le16(&data[3]);1720 y = get_unaligned_le16(&data[5]);1721 } else {1722 prox = prox && (data[1] & 0x01);1723 x = le16_to_cpup((__le16 *)&data[2]);1724 y = le16_to_cpup((__le16 *)&data[4]);1725 }1726 1727 if (prox) {1728 input_report_abs(input, ABS_X, x);1729 input_report_abs(input, ABS_Y, y);1730 }1731 input_report_key(input, BTN_TOUCH, prox);1732 1733 /* keep touch state for pen events */1734 wacom->shared->touch_down = prox;1735 1736 return 1;1737}1738 1739static int wacom_tpc_pen(struct wacom_wac *wacom)1740{1741 unsigned char *data = wacom->data;1742 struct input_dev *input = wacom->pen_input;1743 bool prox = data[1] & 0x20;1744 1745 if (!wacom->shared->stylus_in_proximity) /* first in prox */1746 /* Going into proximity select tool */1747 wacom->tool[0] = (data[1] & 0x0c) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;1748 1749 /* keep pen state for touch events */1750 wacom->shared->stylus_in_proximity = prox;1751 1752 /* send pen events only when touch is up or forced out1753 * or touch arbitration is off1754 */1755 if (!delay_pen_events(wacom)) {1756 input_report_key(input, BTN_STYLUS, data[1] & 0x02);1757 input_report_key(input, BTN_STYLUS2, data[1] & 0x10);1758 input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2]));1759 input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4]));1760 input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x07) << 8) | data[6]);1761 input_report_key(input, BTN_TOUCH, data[1] & 0x05);1762 input_report_key(input, wacom->tool[0], prox);1763 return 1;1764 }1765 1766 return 0;1767}1768 1769static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)1770{1771 unsigned char *data = wacom->data;1772 1773 if (wacom->pen_input) {1774 dev_dbg(wacom->pen_input->dev.parent,1775 "%s: received report #%d\n", __func__, data[0]);1776 1777 if (len == WACOM_PKGLEN_PENABLED ||1778 data[0] == WACOM_REPORT_PENABLED)1779 return wacom_tpc_pen(wacom);1780 }1781 else if (wacom->touch_input) {1782 dev_dbg(wacom->touch_input->dev.parent,1783 "%s: received report #%d\n", __func__, data[0]);1784 1785 switch (len) {1786 case WACOM_PKGLEN_TPC1FG:1787 return wacom_tpc_single_touch(wacom, len);1788 1789 case WACOM_PKGLEN_TPC2FG:1790 return wacom_tpc_mt_touch(wacom);1791 1792 default:1793 switch (data[0]) {1794 case WACOM_REPORT_TPC1FG:1795 case WACOM_REPORT_TPCHID:1796 case WACOM_REPORT_TPCST:1797 case WACOM_REPORT_TPC1FGE:1798 return wacom_tpc_single_touch(wacom, len);1799 1800 case WACOM_REPORT_TPCMT:1801 case WACOM_REPORT_TPCMT2:1802 return wacom_mt_touch(wacom);1803 1804 }1805 }1806 }1807 1808 return 0;1809}1810 1811static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage,1812 int value, int num, int denom)1813{1814 struct input_absinfo *abs = &input->absinfo[usage->code];1815 int range = (abs->maximum - abs->minimum + 1);1816 1817 value += num*range/denom;1818 if (value > abs->maximum)1819 value -= range;1820 else if (value < abs->minimum)1821 value += range;1822 return value;1823}1824 1825int wacom_equivalent_usage(int usage)1826{1827 if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) {1828 int subpage = (usage & 0xFF00) << 8;1829 int subusage = (usage & 0xFF);1830 1831 if (subpage == WACOM_HID_SP_PAD ||1832 subpage == WACOM_HID_SP_BUTTON ||1833 subpage == WACOM_HID_SP_DIGITIZER ||1834 subpage == WACOM_HID_SP_DIGITIZERINFO ||1835 usage == WACOM_HID_WD_SENSE ||1836 usage == WACOM_HID_WD_SERIALHI ||1837 usage == WACOM_HID_WD_TOOLTYPE ||1838 usage == WACOM_HID_WD_DISTANCE ||1839 usage == WACOM_HID_WD_TOUCHSTRIP ||1840 usage == WACOM_HID_WD_TOUCHSTRIP2 ||1841 usage == WACOM_HID_WD_TOUCHRING ||1842 usage == WACOM_HID_WD_TOUCHRINGSTATUS ||1843 usage == WACOM_HID_WD_REPORT_VALID ||1844 usage == WACOM_HID_WD_BARRELSWITCH3 ||1845 usage == WACOM_HID_WD_SEQUENCENUMBER) {1846 return usage;1847 }1848 1849 if (subpage == HID_UP_UNDEFINED)1850 subpage = HID_UP_DIGITIZER;1851 1852 return subpage | subusage;1853 }1854 1855 if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMTOUCH) {1856 int subpage = (usage & 0xFF00) << 8;1857 int subusage = (usage & 0xFF);1858 1859 if (usage == WACOM_HID_WT_REPORT_VALID)1860 return usage;1861 1862 if (subpage == HID_UP_UNDEFINED)1863 subpage = WACOM_HID_SP_DIGITIZER;1864 1865 return subpage | subusage;1866 }1867 1868 return usage;1869}1870 1871static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage,1872 struct hid_field *field, __u8 type, __u16 code, int fuzz)1873{1874 struct wacom *wacom = input_get_drvdata(input);1875 struct wacom_wac *wacom_wac = &wacom->wacom_wac;1876 struct wacom_features *features = &wacom_wac->features;1877 int fmin = field->logical_minimum;1878 int fmax = field->logical_maximum;1879 unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);1880 int resolution_code = code;1881 int resolution;1882 1883 if (equivalent_usage == HID_DG_TWIST) {1884 resolution_code = ABS_RZ;1885 }1886 1887 resolution = hidinput_calc_abs_res(field, resolution_code);1888 1889 if (equivalent_usage == HID_GD_X) {1890 fmin += features->offset_left;1891 fmax -= features->offset_right;1892 }1893 if (equivalent_usage == HID_GD_Y) {1894 fmin += features->offset_top;1895 fmax -= features->offset_bottom;1896 }1897 1898 usage->type = type;1899 usage->code = code;1900 1901 switch (type) {1902 case EV_ABS:1903 input_set_abs_params(input, code, fmin, fmax, fuzz, 0);1904 1905 /* older tablet may miss physical usage */1906 if ((code == ABS_X || code == ABS_Y) && !resolution) {1907 resolution = WACOM_INTUOS_RES;1908 hid_warn(input,1909 "Using default resolution for axis type 0x%x code 0x%x\n",1910 type, code);1911 }1912 input_abs_set_res(input, code, resolution);1913 break;1914 case EV_REL:1915 case EV_KEY:1916 case EV_MSC:1917 case EV_SW:1918 input_set_capability(input, type, code);1919 break;1920 }1921}1922 1923static void wacom_wac_battery_usage_mapping(struct hid_device *hdev,1924 struct hid_field *field, struct hid_usage *usage)1925{1926 return;1927}1928 1929static void wacom_wac_battery_event(struct hid_device *hdev, struct hid_field *field,1930 struct hid_usage *usage, __s32 value)1931{1932 struct wacom *wacom = hid_get_drvdata(hdev);1933 struct wacom_wac *wacom_wac = &wacom->wacom_wac;1934 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);1935 1936 switch (equivalent_usage) {1937 case HID_DG_BATTERYSTRENGTH:1938 if (value == 0) {1939 wacom_wac->hid_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN;1940 }1941 else {1942 value = value * 100 / (field->logical_maximum - field->logical_minimum);1943 wacom_wac->hid_data.battery_capacity = value;1944 wacom_wac->hid_data.bat_connected = 1;1945 wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;1946 }1947 wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;1948 break;1949 case WACOM_HID_WD_BATTERY_LEVEL:1950 value = value * 100 / (field->logical_maximum - field->logical_minimum);1951 wacom_wac->hid_data.battery_capacity = value;1952 wacom_wac->hid_data.bat_connected = 1;1953 wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;1954 wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;1955 break;1956 case WACOM_HID_WD_BATTERY_CHARGING:1957 wacom_wac->hid_data.bat_charging = value;1958 wacom_wac->hid_data.ps_connected = value;1959 wacom_wac->hid_data.bat_connected = 1;1960 wacom_wac->hid_data.bat_status = WACOM_POWER_SUPPLY_STATUS_AUTO;1961 wacom_wac->features.quirks |= WACOM_QUIRK_BATTERY;1962 break;1963 }1964}1965 1966static void wacom_wac_battery_pre_report(struct hid_device *hdev,1967 struct hid_report *report)1968{1969 return;1970}1971 1972static void wacom_wac_battery_report(struct hid_device *hdev,1973 struct hid_report *report)1974{1975 struct wacom *wacom = hid_get_drvdata(hdev);1976 struct wacom_wac *wacom_wac = &wacom->wacom_wac;1977 1978 int status = wacom_wac->hid_data.bat_status;1979 int capacity = wacom_wac->hid_data.battery_capacity;1980 bool charging = wacom_wac->hid_data.bat_charging;1981 bool connected = wacom_wac->hid_data.bat_connected;1982 bool powered = wacom_wac->hid_data.ps_connected;1983 1984 wacom_notify_battery(wacom_wac, status, capacity, charging,1985 connected, powered);1986}1987 1988static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,1989 struct hid_field *field, struct hid_usage *usage)1990{1991 struct wacom *wacom = hid_get_drvdata(hdev);1992 struct wacom_wac *wacom_wac = &wacom->wacom_wac;1993 struct wacom_features *features = &wacom_wac->features;1994 struct input_dev *input = wacom_wac->pad_input;1995 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);1996 1997 switch (equivalent_usage) {1998 case WACOM_HID_WD_ACCELEROMETER_X:1999 __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit);2000 wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 0);2001 features->device_type |= WACOM_DEVICETYPE_PAD;2002 break;2003 case WACOM_HID_WD_ACCELEROMETER_Y:2004 __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit);2005 wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 0);2006 features->device_type |= WACOM_DEVICETYPE_PAD;2007 break;2008 case WACOM_HID_WD_ACCELEROMETER_Z:2009 __set_bit(INPUT_PROP_ACCELEROMETER, input->propbit);2010 wacom_map_usage(input, usage, field, EV_ABS, ABS_Z, 0);2011 features->device_type |= WACOM_DEVICETYPE_PAD;2012 break;2013 case WACOM_HID_WD_BUTTONCENTER:2014 case WACOM_HID_WD_BUTTONHOME:2015 case WACOM_HID_WD_BUTTONUP:2016 case WACOM_HID_WD_BUTTONDOWN:2017 case WACOM_HID_WD_BUTTONLEFT:2018 case WACOM_HID_WD_BUTTONRIGHT:2019 wacom_map_usage(input, usage, field, EV_KEY,2020 wacom_numbered_button_to_key(features->numbered_buttons),2021 0);2022 features->numbered_buttons++;2023 features->device_type |= WACOM_DEVICETYPE_PAD;2024 break;2025 case WACOM_HID_WD_MUTE_DEVICE:2026 /* softkey touch switch */2027 wacom_wac->is_soft_touch_switch = true;2028 fallthrough;2029 case WACOM_HID_WD_TOUCHONOFF:2030 /*2031 * These two usages, which are used to mute touch events, come2032 * from the pad packet, but are reported on the touch2033 * interface. Because the touch interface may not have2034 * been created yet, we cannot call wacom_map_usage(). In2035 * order to process the usages when we receive them, we set2036 * the usage type and code directly.2037 */2038 wacom_wac->has_mute_touch_switch = true;2039 usage->type = EV_SW;2040 usage->code = SW_MUTE_DEVICE;2041 break;2042 case WACOM_HID_WD_TOUCHSTRIP:2043 wacom_map_usage(input, usage, field, EV_ABS, ABS_RX, 0);2044 features->device_type |= WACOM_DEVICETYPE_PAD;2045 break;2046 case WACOM_HID_WD_TOUCHSTRIP2:2047 wacom_map_usage(input, usage, field, EV_ABS, ABS_RY, 0);2048 features->device_type |= WACOM_DEVICETYPE_PAD;2049 break;2050 case WACOM_HID_WD_TOUCHRING:2051 if (field->flags & HID_MAIN_ITEM_RELATIVE) {2052 wacom_wac->relring_count++;2053 if (wacom_wac->relring_count == 1) {2054 wacom_map_usage(input, usage, field, EV_REL, REL_WHEEL_HI_RES, 0);2055 set_bit(REL_WHEEL, input->relbit);2056 }2057 else if (wacom_wac->relring_count == 2) {2058 wacom_map_usage(input, usage, field, EV_REL, REL_HWHEEL_HI_RES, 0);2059 set_bit(REL_HWHEEL, input->relbit);2060 }2061 } else {2062 wacom_wac->absring_count++;2063 if (wacom_wac->absring_count == 1)2064 wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);2065 else if (wacom_wac->absring_count == 2)2066 wacom_map_usage(input, usage, field, EV_ABS, ABS_THROTTLE, 0);2067 }2068 features->device_type |= WACOM_DEVICETYPE_PAD;2069 break;2070 case WACOM_HID_WD_TOUCHRINGSTATUS:2071 /*2072 * Only set up type/code association. Completely mapping2073 * this usage may overwrite the axis resolution and range.2074 */2075 usage->type = EV_ABS;2076 usage->code = ABS_WHEEL;2077 set_bit(EV_ABS, input->evbit);2078 features->device_type |= WACOM_DEVICETYPE_PAD;2079 break;2080 case WACOM_HID_WD_BUTTONCONFIG:2081 wacom_map_usage(input, usage, field, EV_KEY, KEY_BUTTONCONFIG, 0);2082 features->device_type |= WACOM_DEVICETYPE_PAD;2083 break;2084 case WACOM_HID_WD_ONSCREEN_KEYBOARD:2085 wacom_map_usage(input, usage, field, EV_KEY, KEY_ONSCREEN_KEYBOARD, 0);2086 features->device_type |= WACOM_DEVICETYPE_PAD;2087 break;2088 case WACOM_HID_WD_CONTROLPANEL:2089 wacom_map_usage(input, usage, field, EV_KEY, KEY_CONTROLPANEL, 0);2090 features->device_type |= WACOM_DEVICETYPE_PAD;2091 break;2092 case WACOM_HID_WD_MODE_CHANGE:2093 /* do not overwrite previous data */2094 if (!wacom_wac->has_mode_change) {2095 wacom_wac->has_mode_change = true;2096 wacom_wac->is_direct_mode = true;2097 }2098 features->device_type |= WACOM_DEVICETYPE_PAD;2099 break;2100 }2101 2102 switch (equivalent_usage & 0xfffffff0) {2103 case WACOM_HID_WD_EXPRESSKEY00:2104 wacom_map_usage(input, usage, field, EV_KEY,2105 wacom_numbered_button_to_key(features->numbered_buttons),2106 0);2107 features->numbered_buttons++;2108 features->device_type |= WACOM_DEVICETYPE_PAD;2109 break;2110 }2111}2112 2113static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field,2114 struct hid_usage *usage, __s32 value)2115{2116 struct wacom *wacom = hid_get_drvdata(hdev);2117 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2118 struct input_dev *input = wacom_wac->pad_input;2119 struct wacom_features *features = &wacom_wac->features;2120 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);2121 int i;2122 bool do_report = false;2123 2124 /*2125 * Avoid reporting this event and setting inrange_state if this usage2126 * hasn't been mapped.2127 */2128 if (!usage->type && equivalent_usage != WACOM_HID_WD_MODE_CHANGE)2129 return;2130 2131 if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) {2132 bool is_abs_touchring = usage->hid == WACOM_HID_WD_TOUCHRING &&2133 !(field->flags & HID_MAIN_ITEM_RELATIVE);2134 2135 if (!is_abs_touchring)2136 wacom_wac->hid_data.inrange_state |= value;2137 }2138 2139 /* Process touch switch state first since it is reported through touch interface,2140 * which is indepentent of pad interface. In the case when there are no other pad2141 * events, the pad interface will not even be created.2142 */2143 if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) ||2144 (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) {2145 if (wacom_wac->shared->touch_input) {2146 bool *is_touch_on = &wacom_wac->shared->is_touch_on;2147 2148 if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value)2149 *is_touch_on = !(*is_touch_on);2150 else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)2151 *is_touch_on = value;2152 2153 input_report_switch(wacom_wac->shared->touch_input,2154 SW_MUTE_DEVICE, !(*is_touch_on));2155 input_sync(wacom_wac->shared->touch_input);2156 }2157 return;2158 }2159 2160 if (!input)2161 return;2162 2163 switch (equivalent_usage) {2164 case WACOM_HID_WD_TOUCHRING:2165 /*2166 * Userspace expects touchrings to increase in value with2167 * clockwise gestures and have their zero point at the2168 * tablet's left. HID events "should" be clockwise-2169 * increasing and zero at top, though the MobileStudio2170 * Pro and 2nd-gen Intuos Pro don't do this...2171 */2172 if (hdev->vendor == 0x56a &&2173 (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */2174 hdev->product == 0x357 || hdev->product == 0x358 || /* Intuos Pro 2 */2175 hdev->product == 0x392 || /* Intuos Pro 2 */2176 hdev->product == 0x398 || hdev->product == 0x399 || /* MobileStudio Pro */2177 hdev->product == 0x3AA)) { /* MobileStudio Pro */2178 value = (field->logical_maximum - value);2179 2180 if (hdev->product == 0x357 || hdev->product == 0x358 ||2181 hdev->product == 0x392)2182 value = wacom_offset_rotation(input, usage, value, 3, 16);2183 else if (hdev->product == 0x34d || hdev->product == 0x34e ||2184 hdev->product == 0x398 || hdev->product == 0x399 ||2185 hdev->product == 0x3AA)2186 value = wacom_offset_rotation(input, usage, value, 1, 2);2187 }2188 else if (field->flags & HID_MAIN_ITEM_RELATIVE) {2189 int hires_value = value * 120 / usage->resolution_multiplier;2190 int *ring_value;2191 int lowres_code;2192 2193 if (usage->code == REL_WHEEL_HI_RES) {2194 /* We must invert the sign for vertical2195 * relative scrolling. Clockwise2196 * rotation produces positive values2197 * from HW, but userspace treats2198 * positive REL_WHEEL as a scroll *up*!2199 */2200 hires_value = -hires_value;2201 ring_value = &wacom_wac->hid_data.ring_value;2202 lowres_code = REL_WHEEL;2203 }2204 else if (usage->code == REL_HWHEEL_HI_RES) {2205 /* No need to invert the sign for2206 * horizontal relative scrolling.2207 * Clockwise rotation produces positive2208 * values from HW and userspace treats2209 * positive REL_HWHEEL as a scroll2210 * right.2211 */2212 ring_value = &wacom_wac->hid_data.ring2_value;2213 lowres_code = REL_HWHEEL;2214 }2215 else {2216 hid_err(wacom->hdev, "unrecognized relative wheel with code %d\n",2217 usage->code);2218 break;2219 }2220 2221 value = hires_value;2222 *ring_value += hires_value;2223 2224 /* Emulate a legacy wheel click for every 1202225 * units of hi-res travel.2226 */2227 if (*ring_value >= 120 || *ring_value <= -120) {2228 int clicks = *ring_value / 120;2229 2230 input_event(input, usage->type, lowres_code, clicks);2231 *ring_value -= clicks * 120;2232 }2233 }2234 else {2235 value = wacom_offset_rotation(input, usage, value, 1, 4);2236 }2237 do_report = true;2238 break;2239 case WACOM_HID_WD_TOUCHRINGSTATUS:2240 if (!value)2241 input_event(input, usage->type, usage->code, 0);2242 break;2243 2244 case WACOM_HID_WD_MODE_CHANGE:2245 if (wacom_wac->is_direct_mode != value) {2246 wacom_wac->is_direct_mode = value;2247 wacom_schedule_work(&wacom->wacom_wac, WACOM_WORKER_MODE_CHANGE);2248 }2249 break;2250 2251 case WACOM_HID_WD_BUTTONCENTER:2252 for (i = 0; i < wacom->led.count; i++)2253 wacom_update_led(wacom, features->numbered_buttons,2254 value, i);2255 fallthrough;2256 default:2257 do_report = true;2258 break;2259 }2260 2261 if (do_report) {2262 input_event(input, usage->type, usage->code, value);2263 if (value)2264 wacom_wac->hid_data.pad_input_event_flag = true;2265 }2266}2267 2268static void wacom_wac_pad_pre_report(struct hid_device *hdev,2269 struct hid_report *report)2270{2271 struct wacom *wacom = hid_get_drvdata(hdev);2272 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2273 2274 wacom_wac->hid_data.inrange_state = 0;2275}2276 2277static void wacom_wac_pad_report(struct hid_device *hdev,2278 struct hid_report *report, struct hid_field *field)2279{2280 struct wacom *wacom = hid_get_drvdata(hdev);2281 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2282 struct input_dev *input = wacom_wac->pad_input;2283 bool active = wacom_wac->hid_data.inrange_state != 0;2284 2285 /* report prox for expresskey events */2286 if (wacom_wac->hid_data.pad_input_event_flag) {2287 input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0);2288 input_sync(input);2289 if (!active)2290 wacom_wac->hid_data.pad_input_event_flag = false;2291 }2292}2293 2294static void wacom_set_barrel_switch3_usage(struct wacom_wac *wacom_wac)2295{2296 struct input_dev *input = wacom_wac->pen_input;2297 struct wacom_features *features = &wacom_wac->features;2298 2299 if (!(features->quirks & WACOM_QUIRK_AESPEN) &&2300 wacom_wac->hid_data.barrelswitch &&2301 wacom_wac->hid_data.barrelswitch2 &&2302 wacom_wac->hid_data.serialhi &&2303 !wacom_wac->hid_data.barrelswitch3) {2304 input_set_capability(input, EV_KEY, BTN_STYLUS3);2305 features->quirks |= WACOM_QUIRK_PEN_BUTTON3;2306 }2307}2308 2309static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,2310 struct hid_field *field, struct hid_usage *usage)2311{2312 struct wacom *wacom = hid_get_drvdata(hdev);2313 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2314 struct wacom_features *features = &wacom_wac->features;2315 struct input_dev *input = wacom_wac->pen_input;2316 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);2317 2318 switch (equivalent_usage) {2319 case HID_GD_X:2320 wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4);2321 break;2322 case HID_GD_Y:2323 wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4);2324 break;2325 case WACOM_HID_WD_DISTANCE:2326 case HID_GD_Z:2327 wacom_map_usage(input, usage, field, EV_ABS, ABS_DISTANCE, 0);2328 break;2329 case HID_DG_TIPPRESSURE:2330 wacom_map_usage(input, usage, field, EV_ABS, ABS_PRESSURE, 0);2331 break;2332 case HID_DG_INRANGE:2333 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);2334 break;2335 case HID_DG_INVERT:2336 wacom_map_usage(input, usage, field, EV_KEY,2337 BTN_TOOL_RUBBER, 0);2338 break;2339 case HID_DG_TILT_X:2340 wacom_map_usage(input, usage, field, EV_ABS, ABS_TILT_X, 0);2341 break;2342 case HID_DG_TILT_Y:2343 wacom_map_usage(input, usage, field, EV_ABS, ABS_TILT_Y, 0);2344 break;2345 case HID_DG_TWIST:2346 wacom_map_usage(input, usage, field, EV_ABS, ABS_Z, 0);2347 break;2348 case HID_DG_ERASER:2349 input_set_capability(input, EV_KEY, BTN_TOOL_RUBBER);2350 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);2351 break;2352 case HID_DG_TIPSWITCH:2353 input_set_capability(input, EV_KEY, BTN_TOOL_PEN);2354 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);2355 break;2356 case HID_DG_BARRELSWITCH:2357 wacom_wac->hid_data.barrelswitch = true;2358 wacom_set_barrel_switch3_usage(wacom_wac);2359 wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS, 0);2360 break;2361 case HID_DG_BARRELSWITCH2:2362 wacom_wac->hid_data.barrelswitch2 = true;2363 wacom_set_barrel_switch3_usage(wacom_wac);2364 wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS2, 0);2365 break;2366 case HID_DG_TOOLSERIALNUMBER:2367 features->quirks |= WACOM_QUIRK_TOOLSERIAL;2368 wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0);2369 break;2370 case HID_DG_SCANTIME:2371 wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0);2372 break;2373 case WACOM_HID_WD_SENSE:2374 features->quirks |= WACOM_QUIRK_SENSE;2375 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);2376 break;2377 case WACOM_HID_WD_SERIALHI:2378 wacom_wac->hid_data.serialhi = true;2379 wacom_set_barrel_switch3_usage(wacom_wac);2380 wacom_map_usage(input, usage, field, EV_ABS, ABS_MISC, 0);2381 break;2382 case WACOM_HID_WD_FINGERWHEEL:2383 input_set_capability(input, EV_KEY, BTN_TOOL_AIRBRUSH);2384 wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);2385 break;2386 case WACOM_HID_WD_BARRELSWITCH3:2387 wacom_wac->hid_data.barrelswitch3 = true;2388 wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);2389 features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;2390 break;2391 case WACOM_HID_WD_SEQUENCENUMBER:2392 wacom_wac->hid_data.sequence_number = -1;2393 break;2394 }2395}2396 2397static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field,2398 struct hid_usage *usage, __s32 value)2399{2400 struct wacom *wacom = hid_get_drvdata(hdev);2401 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2402 struct wacom_features *features = &wacom_wac->features;2403 struct input_dev *input = wacom_wac->pen_input;2404 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);2405 2406 if (wacom_wac->is_invalid_bt_frame)2407 return;2408 2409 switch (equivalent_usage) {2410 case HID_GD_Z:2411 /*2412 * HID_GD_Z "should increase as the control's position is2413 * moved from high to low", while ABS_DISTANCE instead2414 * increases in value as the tool moves from low to high.2415 */2416 value = field->logical_maximum - value;2417 break;2418 case HID_DG_INRANGE:2419 mod_timer(&wacom->idleprox_timer, jiffies + msecs_to_jiffies(100));2420 wacom_wac->hid_data.inrange_state = value;2421 if (!(features->quirks & WACOM_QUIRK_SENSE))2422 wacom_wac->hid_data.sense_state = value;2423 return;2424 case HID_DG_INVERT:2425 wacom_wac->hid_data.invert_state = value;2426 return;2427 case HID_DG_ERASER:2428 case HID_DG_TIPSWITCH:2429 wacom_wac->hid_data.tipswitch |= value;2430 return;2431 case HID_DG_BARRELSWITCH:2432 wacom_wac->hid_data.barrelswitch = value;2433 return;2434 case HID_DG_BARRELSWITCH2:2435 wacom_wac->hid_data.barrelswitch2 = value;2436 return;2437 case HID_DG_TOOLSERIALNUMBER:2438 if (value) {2439 wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);2440 wacom_wac->serial[0] |= wacom_s32tou(value, field->report_size);2441 }2442 return;2443 case HID_DG_TWIST:2444 /* don't modify the value if the pen doesn't support the feature */2445 if (!wacom_is_art_pen(wacom_wac->id[0])) return;2446 2447 /*2448 * Userspace expects pen twist to have its zero point when2449 * the buttons/finger is on the tablet's left. HID values2450 * are zero when buttons are toward the top.2451 */2452 value = wacom_offset_rotation(input, usage, value, 1, 4);2453 break;2454 case WACOM_HID_WD_SENSE:2455 wacom_wac->hid_data.sense_state = value;2456 return;2457 case WACOM_HID_WD_SERIALHI:2458 if (value) {2459 __u32 raw_value = wacom_s32tou(value, field->report_size);2460 2461 wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);2462 wacom_wac->serial[0] |= ((__u64)raw_value) << 32;2463 /*2464 * Non-USI EMR devices may contain additional tool type2465 * information here. See WACOM_HID_WD_TOOLTYPE case for2466 * more details.2467 */2468 if (value >> 20 == 1) {2469 wacom_wac->id[0] |= raw_value & 0xFFFFF;2470 }2471 }2472 return;2473 case WACOM_HID_WD_TOOLTYPE:2474 /*2475 * Some devices (MobileStudio Pro, and possibly later2476 * devices as well) do not return the complete tool2477 * type in their WACOM_HID_WD_TOOLTYPE usage. Use a2478 * bitwise OR so the complete value can be built2479 * up over time :(2480 */2481 wacom_wac->id[0] |= wacom_s32tou(value, field->report_size);2482 return;2483 case WACOM_HID_WD_OFFSETLEFT:2484 if (features->offset_left && value != features->offset_left)2485 hid_warn(hdev, "%s: overriding existing left offset "2486 "%d -> %d\n", __func__, value,2487 features->offset_left);2488 features->offset_left = value;2489 return;2490 case WACOM_HID_WD_OFFSETRIGHT:2491 if (features->offset_right && value != features->offset_right)2492 hid_warn(hdev, "%s: overriding existing right offset "2493 "%d -> %d\n", __func__, value,2494 features->offset_right);2495 features->offset_right = value;2496 return;2497 case WACOM_HID_WD_OFFSETTOP:2498 if (features->offset_top && value != features->offset_top)2499 hid_warn(hdev, "%s: overriding existing top offset "2500 "%d -> %d\n", __func__, value,2501 features->offset_top);2502 features->offset_top = value;2503 return;2504 case WACOM_HID_WD_OFFSETBOTTOM:2505 if (features->offset_bottom && value != features->offset_bottom)2506 hid_warn(hdev, "%s: overriding existing bottom offset "2507 "%d -> %d\n", __func__, value,2508 features->offset_bottom);2509 features->offset_bottom = value;2510 return;2511 case WACOM_HID_WD_REPORT_VALID:2512 wacom_wac->is_invalid_bt_frame = !value;2513 return;2514 case WACOM_HID_WD_BARRELSWITCH3:2515 wacom_wac->hid_data.barrelswitch3 = value;2516 return;2517 case WACOM_HID_WD_SEQUENCENUMBER:2518 if (wacom_wac->hid_data.sequence_number != value &&2519 wacom_wac->hid_data.sequence_number >= 0) {2520 int sequence_size = field->logical_maximum - field->logical_minimum + 1;2521 int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size;2522 hid_warn(hdev, "Dropped %d packets", drop_count);2523 }2524 wacom_wac->hid_data.sequence_number = value + 1;2525 if (wacom_wac->hid_data.sequence_number > field->logical_maximum)2526 wacom_wac->hid_data.sequence_number = field->logical_minimum;2527 return;2528 }2529 2530 /* send pen events only when touch is up or forced out2531 * or touch arbitration is off2532 */2533 if (!usage->type || delay_pen_events(wacom_wac))2534 return;2535 2536 /* send pen events only when the pen is in range */2537 if (wacom_wac->hid_data.inrange_state)2538 input_event(input, usage->type, usage->code, value);2539 else if (wacom_wac->shared->stylus_in_proximity && !wacom_wac->hid_data.sense_state)2540 input_event(input, usage->type, usage->code, 0);2541}2542 2543static void wacom_wac_pen_pre_report(struct hid_device *hdev,2544 struct hid_report *report)2545{2546 struct wacom *wacom = hid_get_drvdata(hdev);2547 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2548 2549 wacom_wac->is_invalid_bt_frame = false;2550 return;2551}2552 2553static void wacom_wac_pen_report(struct hid_device *hdev,2554 struct hid_report *report)2555{2556 struct wacom *wacom = hid_get_drvdata(hdev);2557 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2558 struct input_dev *input = wacom_wac->pen_input;2559 bool range = wacom_wac->hid_data.inrange_state;2560 bool sense = wacom_wac->hid_data.sense_state;2561 bool entering_range = !wacom_wac->tool[0] && range;2562 2563 if (wacom_wac->is_invalid_bt_frame)2564 return;2565 2566 if (entering_range) { /* first in range */2567 /* Going into range select tool */2568 if (wacom_wac->hid_data.invert_state)2569 wacom_wac->tool[0] = BTN_TOOL_RUBBER;2570 else if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN)2571 wacom_wac->tool[0] = BTN_TOOL_PEN;2572 else if (wacom_wac->id[0])2573 wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]);2574 else2575 wacom_wac->tool[0] = BTN_TOOL_PEN;2576 }2577 2578 /* keep pen state for touch events */2579 wacom_wac->shared->stylus_in_proximity = sense;2580 2581 if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) {2582 int id = wacom_wac->id[0];2583 if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3) {2584 int sw_state = wacom_wac->hid_data.barrelswitch |2585 (wacom_wac->hid_data.barrelswitch2 << 1);2586 wacom_wac->hid_data.barrelswitch = sw_state == 1;2587 wacom_wac->hid_data.barrelswitch2 = sw_state == 2;2588 wacom_wac->hid_data.barrelswitch3 = sw_state == 3;2589 }2590 input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch);2591 input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2);2592 input_report_key(input, BTN_STYLUS3, wacom_wac->hid_data.barrelswitch3);2593 2594 /*2595 * Non-USI EMR tools should have their IDs mangled to2596 * match the legacy behavior of wacom_intuos_general2597 */2598 if (wacom_wac->serial[0] >> 52 == 1)2599 id = wacom_intuos_id_mangle(id);2600 2601 /*2602 * To ensure compatibility with xf86-input-wacom, we should2603 * report the BTN_TOOL_* event prior to the ABS_MISC or2604 * MSC_SERIAL events.2605 */2606 input_report_key(input, BTN_TOUCH,2607 wacom_wac->hid_data.tipswitch);2608 input_report_key(input, wacom_wac->tool[0], sense);2609 if (wacom_wac->serial[0]) {2610 /*2611 * xf86-input-wacom does not accept a serial number2612 * of '0'. Report the low 32 bits if possible, but2613 * if they are zero, report the upper ones instead.2614 */2615 __u32 serial_lo = wacom_wac->serial[0] & 0xFFFFFFFFu;2616 __u32 serial_hi = wacom_wac->serial[0] >> 32;2617 input_event(input, EV_MSC, MSC_SERIAL, (int)(serial_lo ? serial_lo : serial_hi));2618 input_report_abs(input, ABS_MISC, sense ? id : 0);2619 }2620 2621 wacom_wac->hid_data.tipswitch = false;2622 2623 input_sync(input);2624 }2625 2626 /* Handle AES battery timeout behavior */2627 if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN) {2628 if (entering_range)2629 cancel_delayed_work(&wacom->aes_battery_work);2630 if (!sense)2631 schedule_delayed_work(&wacom->aes_battery_work,2632 msecs_to_jiffies(WACOM_AES_BATTERY_TIMEOUT));2633 }2634 2635 if (!sense) {2636 wacom_wac->tool[0] = 0;2637 wacom_wac->id[0] = 0;2638 wacom_wac->serial[0] = 0;2639 }2640}2641 2642static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,2643 struct hid_field *field, struct hid_usage *usage)2644{2645 struct wacom *wacom = hid_get_drvdata(hdev);2646 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2647 struct input_dev *input = wacom_wac->touch_input;2648 unsigned touch_max = wacom_wac->features.touch_max;2649 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);2650 2651 switch (equivalent_usage) {2652 case HID_GD_X:2653 if (touch_max == 1)2654 wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4);2655 else2656 wacom_map_usage(input, usage, field, EV_ABS,2657 ABS_MT_POSITION_X, 4);2658 break;2659 case HID_GD_Y:2660 if (touch_max == 1)2661 wacom_map_usage(input, usage, field, EV_ABS, ABS_Y, 4);2662 else2663 wacom_map_usage(input, usage, field, EV_ABS,2664 ABS_MT_POSITION_Y, 4);2665 break;2666 case HID_DG_WIDTH:2667 case HID_DG_HEIGHT:2668 wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MAJOR, 0);2669 wacom_map_usage(input, usage, field, EV_ABS, ABS_MT_TOUCH_MINOR, 0);2670 input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0);2671 break;2672 case HID_DG_TIPSWITCH:2673 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0);2674 break;2675 case HID_DG_CONTACTCOUNT:2676 wacom_wac->hid_data.cc_report = field->report->id;2677 wacom_wac->hid_data.cc_index = field->index;2678 wacom_wac->hid_data.cc_value_index = usage->usage_index;2679 break;2680 case HID_DG_CONTACTID:2681 if ((field->logical_maximum - field->logical_minimum) < touch_max) {2682 /*2683 * The HID descriptor for G11 sensors leaves logical2684 * maximum set to '1' despite it being a multitouch2685 * device. Override to a sensible number.2686 */2687 field->logical_maximum = 255;2688 }2689 break;2690 case HID_DG_SCANTIME:2691 wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0);2692 break;2693 }2694}2695 2696static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,2697 struct input_dev *input)2698{2699 struct hid_data *hid_data = &wacom_wac->hid_data;2700 bool mt = wacom_wac->features.touch_max > 1;2701 bool touch_down = hid_data->tipswitch && hid_data->confidence;2702 bool prox = touch_down && report_touch_events(wacom_wac);2703 2704 if (touch_is_muted(wacom_wac)) {2705 if (!wacom_wac->shared->touch_down)2706 return;2707 prox = false;2708 }2709 2710 wacom_wac->hid_data.num_received++;2711 if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected)2712 return;2713 2714 if (mt) {2715 int slot;2716 2717 slot = input_mt_get_slot_by_key(input, hid_data->id);2718 if (slot < 0) {2719 return;2720 } else {2721 struct input_mt_slot *ps = &input->mt->slots[slot];2722 int mt_id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);2723 2724 if (!prox && mt_id < 0) {2725 // No data to send for this slot; short-circuit2726 return;2727 }2728 }2729 2730 input_mt_slot(input, slot);2731 input_mt_report_slot_state(input, MT_TOOL_FINGER, prox);2732 }2733 else {2734 input_report_key(input, BTN_TOUCH, prox);2735 }2736 2737 if (prox) {2738 input_report_abs(input, mt ? ABS_MT_POSITION_X : ABS_X,2739 hid_data->x);2740 input_report_abs(input, mt ? ABS_MT_POSITION_Y : ABS_Y,2741 hid_data->y);2742 2743 if (test_bit(ABS_MT_TOUCH_MAJOR, input->absbit)) {2744 input_report_abs(input, ABS_MT_TOUCH_MAJOR, max(hid_data->width, hid_data->height));2745 input_report_abs(input, ABS_MT_TOUCH_MINOR, min(hid_data->width, hid_data->height));2746 if (hid_data->width != hid_data->height)2747 input_report_abs(input, ABS_MT_ORIENTATION, hid_data->width <= hid_data->height ? 0 : 1);2748 }2749 }2750}2751 2752static void wacom_wac_finger_event(struct hid_device *hdev,2753 struct hid_field *field, struct hid_usage *usage, __s32 value)2754{2755 struct wacom *wacom = hid_get_drvdata(hdev);2756 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2757 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);2758 struct wacom_features *features = &wacom->wacom_wac.features;2759 2760 if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down)2761 return;2762 2763 if (wacom_wac->is_invalid_bt_frame)2764 return;2765 2766 switch (equivalent_usage) {2767 case HID_DG_CONFIDENCE:2768 wacom_wac->hid_data.confidence = value;2769 break;2770 case HID_GD_X:2771 wacom_wac->hid_data.x = value;2772 break;2773 case HID_GD_Y:2774 wacom_wac->hid_data.y = value;2775 break;2776 case HID_DG_WIDTH:2777 wacom_wac->hid_data.width = value;2778 break;2779 case HID_DG_HEIGHT:2780 wacom_wac->hid_data.height = value;2781 break;2782 case HID_DG_CONTACTID:2783 wacom_wac->hid_data.id = value;2784 break;2785 case HID_DG_TIPSWITCH:2786 wacom_wac->hid_data.tipswitch = value;2787 break;2788 case WACOM_HID_WT_REPORT_VALID:2789 wacom_wac->is_invalid_bt_frame = !value;2790 return;2791 case HID_DG_CONTACTMAX:2792 if (!features->touch_max) {2793 features->touch_max = value;2794 } else {2795 hid_warn(hdev, "%s: ignoring attempt to overwrite non-zero touch_max "2796 "%d -> %d\n", __func__, features->touch_max, value);2797 }2798 return;2799 }2800 2801 if (usage->usage_index + 1 == field->report_count) {2802 if (equivalent_usage == wacom_wac->hid_data.last_slot_field)2803 wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);2804 }2805}2806 2807static void wacom_wac_finger_pre_report(struct hid_device *hdev,2808 struct hid_report *report)2809{2810 struct wacom *wacom = hid_get_drvdata(hdev);2811 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2812 struct hid_data* hid_data = &wacom_wac->hid_data;2813 int i;2814 2815 if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down)2816 return;2817 2818 wacom_wac->is_invalid_bt_frame = false;2819 2820 hid_data->confidence = true;2821 2822 hid_data->cc_report = 0;2823 hid_data->cc_index = -1;2824 hid_data->cc_value_index = -1;2825 2826 for (i = 0; i < report->maxfield; i++) {2827 struct hid_field *field = report->field[i];2828 int j;2829 2830 for (j = 0; j < field->maxusage; j++) {2831 struct hid_usage *usage = &field->usage[j];2832 unsigned int equivalent_usage =2833 wacom_equivalent_usage(usage->hid);2834 2835 switch (equivalent_usage) {2836 case HID_GD_X:2837 case HID_GD_Y:2838 case HID_DG_WIDTH:2839 case HID_DG_HEIGHT:2840 case HID_DG_CONTACTID:2841 case HID_DG_INRANGE:2842 case HID_DG_INVERT:2843 case HID_DG_TIPSWITCH:2844 hid_data->last_slot_field = equivalent_usage;2845 break;2846 case HID_DG_CONTACTCOUNT:2847 hid_data->cc_report = report->id;2848 hid_data->cc_index = i;2849 hid_data->cc_value_index = j;2850 break;2851 }2852 }2853 }2854 2855 if (hid_data->cc_report != 0 &&2856 hid_data->cc_index >= 0) {2857 struct hid_field *field = report->field[hid_data->cc_index];2858 int value = field->value[hid_data->cc_value_index];2859 if (value) {2860 hid_data->num_expected = value;2861 hid_data->num_received = 0;2862 }2863 }2864 else {2865 hid_data->num_expected = wacom_wac->features.touch_max;2866 hid_data->num_received = 0;2867 }2868}2869 2870static void wacom_wac_finger_report(struct hid_device *hdev,2871 struct hid_report *report)2872{2873 struct wacom *wacom = hid_get_drvdata(hdev);2874 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2875 struct input_dev *input = wacom_wac->touch_input;2876 unsigned touch_max = wacom_wac->features.touch_max;2877 2878 /* if there was nothing to process, don't send an empty sync */2879 if (wacom_wac->hid_data.num_expected == 0)2880 return;2881 2882 /* If more packets of data are expected, give us a chance to2883 * process them rather than immediately syncing a partial2884 * update.2885 */2886 if (wacom_wac->hid_data.num_received < wacom_wac->hid_data.num_expected)2887 return;2888 2889 if (touch_max > 1)2890 input_mt_sync_frame(input);2891 2892 input_sync(input);2893 wacom_wac->hid_data.num_received = 0;2894 wacom_wac->hid_data.num_expected = 0;2895 2896 /* keep touch state for pen event */2897 wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);2898}2899 2900void wacom_wac_usage_mapping(struct hid_device *hdev,2901 struct hid_field *field, struct hid_usage *usage)2902{2903 struct wacom *wacom = hid_get_drvdata(hdev);2904 struct wacom_wac *wacom_wac = &wacom->wacom_wac;2905 struct wacom_features *features = &wacom_wac->features;2906 2907 if (WACOM_DIRECT_DEVICE(field))2908 features->device_type |= WACOM_DEVICETYPE_DIRECT;2909 2910 /* usage tests must precede field tests */2911 if (WACOM_BATTERY_USAGE(usage))2912 wacom_wac_battery_usage_mapping(hdev, field, usage);2913 else if (WACOM_PAD_FIELD(field))2914 wacom_wac_pad_usage_mapping(hdev, field, usage);2915 else if (WACOM_PEN_FIELD(field))2916 wacom_wac_pen_usage_mapping(hdev, field, usage);2917 else if (WACOM_FINGER_FIELD(field))2918 wacom_wac_finger_usage_mapping(hdev, field, usage);2919}2920 2921void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,2922 struct hid_usage *usage, __s32 value)2923{2924 struct wacom *wacom = hid_get_drvdata(hdev);2925 2926 if (wacom->wacom_wac.features.type != HID_GENERIC)2927 return;2928 2929 if (value > field->logical_maximum || value < field->logical_minimum)2930 return;2931 2932 /* usage tests must precede field tests */2933 if (WACOM_BATTERY_USAGE(usage))2934 wacom_wac_battery_event(hdev, field, usage, value);2935 else if (WACOM_PAD_FIELD(field))2936 wacom_wac_pad_event(hdev, field, usage, value);2937 else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)2938 wacom_wac_pen_event(hdev, field, usage, value);2939 else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)2940 wacom_wac_finger_event(hdev, field, usage, value);2941}2942 2943static void wacom_report_events(struct hid_device *hdev,2944 struct hid_report *report, int collection_index,2945 int field_index)2946{2947 int r;2948 2949 for (r = field_index; r < report->maxfield; r++) {2950 struct hid_field *field;2951 unsigned count, n;2952 2953 field = report->field[r];2954 count = field->report_count;2955 2956 if (!(HID_MAIN_ITEM_VARIABLE & field->flags))2957 continue;2958 2959 for (n = 0 ; n < count; n++) {2960 if (field->usage[n].collection_index == collection_index)2961 wacom_wac_event(hdev, field, &field->usage[n],2962 field->value[n]);2963 else2964 return;2965 }2966 }2967}2968 2969static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report,2970 int collection_index, struct hid_field *field,2971 int field_index)2972{2973 struct wacom *wacom = hid_get_drvdata(hdev);2974 2975 wacom_report_events(hdev, report, collection_index, field_index);2976 2977 /*2978 * Non-input reports may be sent prior to the device being2979 * completely initialized. Since only their events need2980 * to be processed, exit after 'wacom_report_events' has2981 * been called to prevent potential crashes in the report-2982 * processing functions.2983 */2984 if (report->type != HID_INPUT_REPORT)2985 return -1;2986 2987 if (WACOM_PAD_FIELD(field))2988 return 0;2989 else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)2990 wacom_wac_pen_report(hdev, report);2991 else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)2992 wacom_wac_finger_report(hdev, report);2993 2994 return 0;2995}2996 2997void wacom_wac_report(struct hid_device *hdev, struct hid_report *report)2998{2999 struct wacom *wacom = hid_get_drvdata(hdev);3000 struct wacom_wac *wacom_wac = &wacom->wacom_wac;3001 struct hid_field *field;3002 bool pad_in_hid_field = false, pen_in_hid_field = false,3003 finger_in_hid_field = false, true_pad = false;3004 int r;3005 int prev_collection = -1;3006 3007 if (wacom_wac->features.type != HID_GENERIC)3008 return;3009 3010 for (r = 0; r < report->maxfield; r++) {3011 field = report->field[r];3012 3013 if (WACOM_PAD_FIELD(field))3014 pad_in_hid_field = true;3015 if (WACOM_PEN_FIELD(field))3016 pen_in_hid_field = true;3017 if (WACOM_FINGER_FIELD(field))3018 finger_in_hid_field = true;3019 if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY)3020 true_pad = true;3021 }3022 3023 wacom_wac_battery_pre_report(hdev, report);3024 3025 if (pad_in_hid_field && wacom_wac->pad_input)3026 wacom_wac_pad_pre_report(hdev, report);3027 if (pen_in_hid_field && wacom_wac->pen_input)3028 wacom_wac_pen_pre_report(hdev, report);3029 if (finger_in_hid_field && wacom_wac->touch_input)3030 wacom_wac_finger_pre_report(hdev, report);3031 3032 for (r = 0; r < report->maxfield; r++) {3033 field = report->field[r];3034 3035 if (field->usage[0].collection_index != prev_collection) {3036 if (wacom_wac_collection(hdev, report,3037 field->usage[0].collection_index, field, r) < 0)3038 return;3039 prev_collection = field->usage[0].collection_index;3040 }3041 }3042 3043 wacom_wac_battery_report(hdev, report);3044 3045 if (true_pad && wacom_wac->pad_input)3046 wacom_wac_pad_report(hdev, report, field);3047}3048 3049static int wacom_bpt_touch(struct wacom_wac *wacom)3050{3051 struct wacom_features *features = &wacom->features;3052 struct input_dev *input = wacom->touch_input;3053 struct input_dev *pad_input = wacom->pad_input;3054 unsigned char *data = wacom->data;3055 int i;3056 3057 if (data[0] != 0x02)3058 return 0;3059 3060 for (i = 0; i < 2; i++) {3061 int offset = (data[1] & 0x80) ? (8 * i) : (9 * i);3062 bool touch = report_touch_events(wacom)3063 && (data[offset + 3] & 0x80);3064 3065 input_mt_slot(input, i);3066 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);3067 if (touch) {3068 int x = get_unaligned_be16(&data[offset + 3]) & 0x7ff;3069 int y = get_unaligned_be16(&data[offset + 5]) & 0x7ff;3070 if (features->quirks & WACOM_QUIRK_BBTOUCH_LOWRES) {3071 x <<= 5;3072 y <<= 5;3073 }3074 input_report_abs(input, ABS_MT_POSITION_X, x);3075 input_report_abs(input, ABS_MT_POSITION_Y, y);3076 }3077 }3078 3079 input_mt_sync_frame(input);3080 3081 input_report_key(pad_input, BTN_LEFT, (data[1] & 0x08) != 0);3082 input_report_key(pad_input, BTN_FORWARD, (data[1] & 0x04) != 0);3083 input_report_key(pad_input, BTN_BACK, (data[1] & 0x02) != 0);3084 input_report_key(pad_input, BTN_RIGHT, (data[1] & 0x01) != 0);3085 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);3086 3087 return 1;3088}3089 3090static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data)3091{3092 struct wacom_features *features = &wacom->features;3093 struct input_dev *input = wacom->touch_input;3094 bool touch = data[1] & 0x80;3095 int slot = input_mt_get_slot_by_key(input, data[0]);3096 3097 if (slot < 0)3098 return;3099 3100 touch = touch && report_touch_events(wacom);3101 3102 input_mt_slot(input, slot);3103 input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);3104 3105 if (touch) {3106 int x = (data[2] << 4) | (data[4] >> 4);3107 int y = (data[3] << 4) | (data[4] & 0x0f);3108 int width, height;3109 3110 if (features->type >= INTUOSPS && features->type <= INTUOSHT2) {3111 width = data[5] * 100;3112 height = data[6] * 100;3113 } else {3114 /*3115 * "a" is a scaled-down area which we assume is3116 * roughly circular and which can be described as:3117 * a=(pi*r^2)/C.3118 */3119 int a = data[5];3120 int x_res = input_abs_get_res(input, ABS_MT_POSITION_X);3121 int y_res = input_abs_get_res(input, ABS_MT_POSITION_Y);3122 width = 2 * int_sqrt(a * WACOM_CONTACT_AREA_SCALE);3123 height = width * y_res / x_res;3124 }3125 3126 input_report_abs(input, ABS_MT_POSITION_X, x);3127 input_report_abs(input, ABS_MT_POSITION_Y, y);3128 input_report_abs(input, ABS_MT_TOUCH_MAJOR, width);3129 input_report_abs(input, ABS_MT_TOUCH_MINOR, height);3130 }3131}3132 3133static void wacom_bpt3_button_msg(struct wacom_wac *wacom, unsigned char *data)3134{3135 struct input_dev *input = wacom->pad_input;3136 struct wacom_features *features = &wacom->features;3137 3138 if (features->type == INTUOSHT || features->type == INTUOSHT2) {3139 input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0);3140 input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0);3141 } else {3142 input_report_key(input, BTN_BACK, (data[1] & 0x02) != 0);3143 input_report_key(input, BTN_LEFT, (data[1] & 0x08) != 0);3144 }3145 input_report_key(input, BTN_FORWARD, (data[1] & 0x04) != 0);3146 input_report_key(input, BTN_RIGHT, (data[1] & 0x01) != 0);3147}3148 3149static int wacom_bpt3_touch(struct wacom_wac *wacom)3150{3151 unsigned char *data = wacom->data;3152 int count = data[1] & 0x07;3153 int touch_changed = 0, i;3154 3155 if (data[0] != 0x02)3156 return 0;3157 3158 /* data has up to 7 fixed sized 8-byte messages starting at data[2] */3159 for (i = 0; i < count; i++) {3160 int offset = (8 * i) + 2;3161 int msg_id = data[offset];3162 3163 if (msg_id >= 2 && msg_id <= 17) {3164 wacom_bpt3_touch_msg(wacom, data + offset);3165 touch_changed++;3166 } else if (msg_id == 128)3167 wacom_bpt3_button_msg(wacom, data + offset);3168 3169 }3170 3171 /* only update touch if we actually have a touchpad and touch data changed */3172 if (wacom->touch_input && touch_changed) {3173 input_mt_sync_frame(wacom->touch_input);3174 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);3175 }3176 3177 return 1;3178}3179 3180static int wacom_bpt_pen(struct wacom_wac *wacom)3181{3182 struct wacom_features *features = &wacom->features;3183 struct input_dev *input = wacom->pen_input;3184 unsigned char *data = wacom->data;3185 int x = 0, y = 0, p = 0, d = 0;3186 bool pen = false, btn1 = false, btn2 = false;3187 bool range, prox, rdy;3188 3189 if (data[0] != WACOM_REPORT_PENABLED)3190 return 0;3191 3192 range = (data[1] & 0x80) == 0x80;3193 prox = (data[1] & 0x40) == 0x40;3194 rdy = (data[1] & 0x20) == 0x20;3195 3196 wacom->shared->stylus_in_proximity = range;3197 if (delay_pen_events(wacom))3198 return 0;3199 3200 if (rdy) {3201 p = le16_to_cpup((__le16 *)&data[6]);3202 pen = data[1] & 0x01;3203 btn1 = data[1] & 0x02;3204 btn2 = data[1] & 0x04;3205 }3206 if (prox) {3207 x = le16_to_cpup((__le16 *)&data[2]);3208 y = le16_to_cpup((__le16 *)&data[4]);3209 3210 if (data[1] & 0x08) {3211 wacom->tool[0] = BTN_TOOL_RUBBER;3212 wacom->id[0] = ERASER_DEVICE_ID;3213 } else {3214 wacom->tool[0] = BTN_TOOL_PEN;3215 wacom->id[0] = STYLUS_DEVICE_ID;3216 }3217 wacom->reporting_data = true;3218 }3219 if (range) {3220 /*3221 * Convert distance from out prox to distance from tablet.3222 * distance will be greater than distance_max once3223 * touching and applying pressure; do not report negative3224 * distance.3225 */3226 if (data[8] <= features->distance_max)3227 d = features->distance_max - data[8];3228 } else {3229 wacom->id[0] = 0;3230 }3231 3232 if (wacom->reporting_data) {3233 input_report_key(input, BTN_TOUCH, pen);3234 input_report_key(input, BTN_STYLUS, btn1);3235 input_report_key(input, BTN_STYLUS2, btn2);3236 3237 if (prox || !range) {3238 input_report_abs(input, ABS_X, x);3239 input_report_abs(input, ABS_Y, y);3240 }3241 input_report_abs(input, ABS_PRESSURE, p);3242 input_report_abs(input, ABS_DISTANCE, d);3243 3244 input_report_key(input, wacom->tool[0], range); /* PEN or RUBBER */3245 input_report_abs(input, ABS_MISC, wacom->id[0]); /* TOOL ID */3246 }3247 3248 if (!range) {3249 wacom->reporting_data = false;3250 }3251 3252 return 1;3253}3254 3255static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)3256{3257 struct wacom_features *features = &wacom->features;3258 3259 if ((features->type == INTUOSHT2) &&3260 (features->device_type & WACOM_DEVICETYPE_PEN))3261 return wacom_intuos_irq(wacom);3262 else if (len == WACOM_PKGLEN_BBTOUCH)3263 return wacom_bpt_touch(wacom);3264 else if (len == WACOM_PKGLEN_BBTOUCH3)3265 return wacom_bpt3_touch(wacom);3266 else if (len == WACOM_PKGLEN_BBFUN || len == WACOM_PKGLEN_BBPEN)3267 return wacom_bpt_pen(wacom);3268 3269 return 0;3270}3271 3272static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom,3273 unsigned char *data)3274{3275 unsigned char prefix;3276 3277 /*3278 * We need to reroute the event from the debug interface to the3279 * pen interface.3280 * We need to add the report ID to the actual pen report, so we3281 * temporary overwrite the first byte to prevent having to kzalloc/kfree3282 * and memcpy the report.3283 */3284 prefix = data[0];3285 data[0] = WACOM_REPORT_BPAD_PEN;3286 3287 /*3288 * actually reroute the event.3289 * No need to check if wacom->shared->pen is valid, hid_input_report()3290 * will check for us.3291 */3292 hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data,3293 WACOM_PKGLEN_PENABLED, 1);3294 3295 data[0] = prefix;3296}3297 3298static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom,3299 unsigned char *data)3300{3301 struct input_dev *input = wacom->touch_input;3302 unsigned char *finger_data, prefix;3303 unsigned id;3304 int x, y;3305 bool valid;3306 3307 prefix = data[0];3308 3309 for (id = 0; id < wacom->features.touch_max; id++) {3310 valid = !!(prefix & BIT(id)) &&3311 report_touch_events(wacom);3312 3313 input_mt_slot(input, id);3314 input_mt_report_slot_state(input, MT_TOOL_FINGER, valid);3315 3316 if (!valid)3317 continue;3318 3319 finger_data = data + 1 + id * 3;3320 x = finger_data[0] | ((finger_data[1] & 0x0f) << 8);3321 y = (finger_data[2] << 4) | (finger_data[1] >> 4);3322 3323 input_report_abs(input, ABS_MT_POSITION_X, x);3324 input_report_abs(input, ABS_MT_POSITION_Y, y);3325 }3326 3327 input_mt_sync_frame(input);3328 3329 input_report_key(input, BTN_LEFT, prefix & 0x40);3330 input_report_key(input, BTN_RIGHT, prefix & 0x80);3331 3332 /* keep touch state for pen event */3333 wacom->shared->touch_down = !!prefix && report_touch_events(wacom);3334 3335 return 1;3336}3337 3338static int wacom_bamboo_pad_irq(struct wacom_wac *wacom, size_t len)3339{3340 unsigned char *data = wacom->data;3341 3342 if (!((len == WACOM_PKGLEN_BPAD_TOUCH) ||3343 (len == WACOM_PKGLEN_BPAD_TOUCH_USB)) ||3344 (data[0] != WACOM_REPORT_BPAD_TOUCH))3345 return 0;3346 3347 if (data[1] & 0x01)3348 wacom_bamboo_pad_pen_event(wacom, &data[1]);3349 3350 if (data[1] & 0x02)3351 return wacom_bamboo_pad_touch_event(wacom, &data[9]);3352 3353 return 0;3354}3355 3356static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len)3357{3358 unsigned char *data = wacom->data;3359 int connected;3360 3361 if (len != WACOM_PKGLEN_WIRELESS || data[0] != WACOM_REPORT_WL)3362 return 0;3363 3364 connected = data[1] & 0x01;3365 if (connected) {3366 int pid, battery, charging;3367 3368 if ((wacom->shared->type == INTUOSHT ||3369 wacom->shared->type == INTUOSHT2) &&3370 wacom->shared->touch_input &&3371 wacom->shared->touch_max) {3372 input_report_switch(wacom->shared->touch_input,3373 SW_MUTE_DEVICE, data[5] & 0x40);3374 input_sync(wacom->shared->touch_input);3375 }3376 3377 pid = get_unaligned_be16(&data[6]);3378 battery = (data[5] & 0x3f) * 100 / 31;3379 charging = !!(data[5] & 0x80);3380 if (wacom->pid != pid) {3381 wacom->pid = pid;3382 wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);3383 }3384 3385 wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO,3386 battery, charging, 1, 0);3387 3388 } else if (wacom->pid != 0) {3389 /* disconnected while previously connected */3390 wacom->pid = 0;3391 wacom_schedule_work(wacom, WACOM_WORKER_WIRELESS);3392 wacom_notify_battery(wacom, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0);3393 }3394 3395 return 0;3396}3397 3398static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len)3399{3400 struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);3401 struct wacom_features *features = &wacom_wac->features;3402 unsigned char *data = wacom_wac->data;3403 3404 if (data[0] != WACOM_REPORT_USB)3405 return 0;3406 3407 if ((features->type == INTUOSHT ||3408 features->type == INTUOSHT2) &&3409 wacom_wac->shared->touch_input &&3410 features->touch_max) {3411 input_report_switch(wacom_wac->shared->touch_input,3412 SW_MUTE_DEVICE, data[8] & 0x40);3413 input_sync(wacom_wac->shared->touch_input);3414 }3415 3416 if (data[9] & 0x02) { /* wireless module is attached */3417 int battery = (data[8] & 0x3f) * 100 / 31;3418 bool charging = !!(data[8] & 0x80);3419 3420 features->quirks |= WACOM_QUIRK_BATTERY;3421 wacom_notify_battery(wacom_wac, WACOM_POWER_SUPPLY_STATUS_AUTO,3422 battery, charging, battery || charging, 1);3423 }3424 else if ((features->quirks & WACOM_QUIRK_BATTERY) &&3425 wacom->battery.battery) {3426 features->quirks &= ~WACOM_QUIRK_BATTERY;3427 wacom_notify_battery(wacom_wac, POWER_SUPPLY_STATUS_UNKNOWN, 0, 0, 0, 0);3428 }3429 return 0;3430}3431 3432void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)3433{3434 bool sync;3435 3436 switch (wacom_wac->features.type) {3437 case PENPARTNER:3438 sync = wacom_penpartner_irq(wacom_wac);3439 break;3440 3441 case PL:3442 sync = wacom_pl_irq(wacom_wac);3443 break;3444 3445 case WACOM_G4:3446 case GRAPHIRE:3447 case GRAPHIRE_BT:3448 case WACOM_MO:3449 sync = wacom_graphire_irq(wacom_wac);3450 break;3451 3452 case PTU:3453 sync = wacom_ptu_irq(wacom_wac);3454 break;3455 3456 case DTU:3457 sync = wacom_dtu_irq(wacom_wac);3458 break;3459 3460 case DTUS:3461 case DTUSX:3462 sync = wacom_dtus_irq(wacom_wac);3463 break;3464 3465 case INTUOS:3466 case INTUOS3S:3467 case INTUOS3:3468 case INTUOS3L:3469 case INTUOS4S:3470 case INTUOS4:3471 case INTUOS4L:3472 case CINTIQ:3473 case WACOM_BEE:3474 case WACOM_13HD:3475 case WACOM_21UX2:3476 case WACOM_22HD:3477 case WACOM_24HD:3478 case WACOM_27QHD:3479 case DTK:3480 case CINTIQ_HYBRID:3481 case CINTIQ_COMPANION_2:3482 sync = wacom_intuos_irq(wacom_wac);3483 break;3484 3485 case INTUOS4WL:3486 sync = wacom_intuos_bt_irq(wacom_wac, len);3487 break;3488 3489 case WACOM_24HDT:3490 case WACOM_27QHDT:3491 sync = wacom_24hdt_irq(wacom_wac);3492 break;3493 3494 case INTUOS5S:3495 case INTUOS5:3496 case INTUOS5L:3497 case INTUOSPS:3498 case INTUOSPM:3499 case INTUOSPL:3500 if (len == WACOM_PKGLEN_BBTOUCH3)3501 sync = wacom_bpt3_touch(wacom_wac);3502 else if (wacom_wac->data[0] == WACOM_REPORT_USB)3503 sync = wacom_status_irq(wacom_wac, len);3504 else3505 sync = wacom_intuos_irq(wacom_wac);3506 break;3507 3508 case INTUOSP2_BT:3509 case INTUOSP2S_BT:3510 case INTUOSHT3_BT:3511 sync = wacom_intuos_pro2_bt_irq(wacom_wac, len);3512 break;3513 3514 case TABLETPC:3515 case TABLETPCE:3516 case TABLETPC2FG:3517 case MTSCREEN:3518 case MTTPC:3519 case MTTPC_B:3520 sync = wacom_tpc_irq(wacom_wac, len);3521 break;3522 3523 case BAMBOO_PT:3524 case BAMBOO_PEN:3525 case BAMBOO_TOUCH:3526 case INTUOSHT:3527 case INTUOSHT2:3528 if (wacom_wac->data[0] == WACOM_REPORT_USB)3529 sync = wacom_status_irq(wacom_wac, len);3530 else3531 sync = wacom_bpt_irq(wacom_wac, len);3532 break;3533 3534 case BAMBOO_PAD:3535 sync = wacom_bamboo_pad_irq(wacom_wac, len);3536 break;3537 3538 case WIRELESS:3539 sync = wacom_wireless_irq(wacom_wac, len);3540 break;3541 3542 case REMOTE:3543 sync = false;3544 if (wacom_wac->data[0] == WACOM_REPORT_DEVICE_LIST)3545 wacom_remote_status_irq(wacom_wac, len);3546 else3547 sync = wacom_remote_irq(wacom_wac, len);3548 break;3549 3550 default:3551 sync = false;3552 break;3553 }3554 3555 if (sync) {3556 if (wacom_wac->pen_input)3557 input_sync(wacom_wac->pen_input);3558 if (wacom_wac->touch_input)3559 input_sync(wacom_wac->touch_input);3560 if (wacom_wac->pad_input)3561 input_sync(wacom_wac->pad_input);3562 }3563}3564 3565static void wacom_setup_basic_pro_pen(struct wacom_wac *wacom_wac)3566{3567 struct input_dev *input_dev = wacom_wac->pen_input;3568 3569 input_set_capability(input_dev, EV_MSC, MSC_SERIAL);3570 3571 __set_bit(BTN_TOOL_PEN, input_dev->keybit);3572 __set_bit(BTN_STYLUS, input_dev->keybit);3573 __set_bit(BTN_STYLUS2, input_dev->keybit);3574 3575 input_set_abs_params(input_dev, ABS_DISTANCE,3576 0, wacom_wac->features.distance_max, wacom_wac->features.distance_fuzz, 0);3577}3578 3579static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)3580{3581 struct input_dev *input_dev = wacom_wac->pen_input;3582 struct wacom_features *features = &wacom_wac->features;3583 3584 wacom_setup_basic_pro_pen(wacom_wac);3585 3586 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);3587 __set_bit(BTN_TOOL_BRUSH, input_dev->keybit);3588 __set_bit(BTN_TOOL_PENCIL, input_dev->keybit);3589 __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit);3590 3591 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);3592 input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, features->tilt_fuzz, 0);3593 input_abs_set_res(input_dev, ABS_TILT_X, 57);3594 input_set_abs_params(input_dev, ABS_TILT_Y, -64, 63, features->tilt_fuzz, 0);3595 input_abs_set_res(input_dev, ABS_TILT_Y, 57);3596}3597 3598static void wacom_setup_intuos(struct wacom_wac *wacom_wac)3599{3600 struct input_dev *input_dev = wacom_wac->pen_input;3601 3602 input_set_capability(input_dev, EV_REL, REL_WHEEL);3603 3604 wacom_setup_cintiq(wacom_wac);3605 3606 __set_bit(BTN_LEFT, input_dev->keybit);3607 __set_bit(BTN_RIGHT, input_dev->keybit);3608 __set_bit(BTN_MIDDLE, input_dev->keybit);3609 __set_bit(BTN_SIDE, input_dev->keybit);3610 __set_bit(BTN_EXTRA, input_dev->keybit);3611 __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);3612 __set_bit(BTN_TOOL_LENS, input_dev->keybit);3613 3614 input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);3615 input_abs_set_res(input_dev, ABS_RZ, 287);3616 input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);3617}3618 3619void wacom_setup_device_quirks(struct wacom *wacom)3620{3621 struct wacom_wac *wacom_wac = &wacom->wacom_wac;3622 struct wacom_features *features = &wacom->wacom_wac.features;3623 3624 /* The pen and pad share the same interface on most devices */3625 if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 ||3626 features->type == DTUS ||3627 (features->type >= INTUOS3S && features->type <= WACOM_MO)) {3628 if (features->device_type & WACOM_DEVICETYPE_PEN)3629 features->device_type |= WACOM_DEVICETYPE_PAD;3630 }3631 3632 /* touch device found but size is not defined. use default */3633 if (features->device_type & WACOM_DEVICETYPE_TOUCH && !features->x_max) {3634 features->x_max = 1023;3635 features->y_max = 1023;3636 }3637 3638 /*3639 * Intuos5/Pro and Bamboo 3rd gen have no useful data about its3640 * touch interface in its HID descriptor. If this is the touch3641 * interface (PacketSize of WACOM_PKGLEN_BBTOUCH3), override the3642 * tablet values.3643 */3644 if ((features->type >= INTUOS5S && features->type <= INTUOSPL) ||3645 (features->type >= INTUOSHT && features->type <= BAMBOO_PT)) {3646 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {3647 if (features->touch_max)3648 features->device_type |= WACOM_DEVICETYPE_TOUCH;3649 if (features->type >= INTUOSHT && features->type <= BAMBOO_PT)3650 features->device_type |= WACOM_DEVICETYPE_PAD;3651 3652 if (features->type == INTUOSHT2) {3653 features->x_max = features->x_max / 10;3654 features->y_max = features->y_max / 10;3655 }3656 else {3657 features->x_max = 4096;3658 features->y_max = 4096;3659 }3660 }3661 else if (features->pktlen == WACOM_PKGLEN_BBTOUCH) {3662 features->device_type |= WACOM_DEVICETYPE_PAD;3663 }3664 }3665 3666 /*3667 * Hack for the Bamboo One:3668 * the device presents a PAD/Touch interface as most Bamboos and even3669 * sends ghosts PAD data on it. However, later, we must disable this3670 * ghost interface, and we can not detect it unless we set it here3671 * to WACOM_DEVICETYPE_PAD or WACOM_DEVICETYPE_TOUCH.3672 */3673 if (features->type == BAMBOO_PEN &&3674 features->pktlen == WACOM_PKGLEN_BBTOUCH3)3675 features->device_type |= WACOM_DEVICETYPE_PAD;3676 3677 /*3678 * Raw Wacom-mode pen and touch events both come from interface3679 * 0, whose HID descriptor has an application usage of 0xFF0D3680 * (i.e., WACOM_HID_WD_DIGITIZER). We route pen packets back3681 * out through the HID_GENERIC device created for interface 1,3682 * so rewrite this one to be of type WACOM_DEVICETYPE_TOUCH.3683 */3684 if (features->type == BAMBOO_PAD)3685 features->device_type = WACOM_DEVICETYPE_TOUCH;3686 3687 if (features->type == REMOTE)3688 features->device_type = WACOM_DEVICETYPE_PAD;3689 3690 if (features->type == INTUOSP2_BT ||3691 features->type == INTUOSP2S_BT) {3692 features->device_type |= WACOM_DEVICETYPE_PEN |3693 WACOM_DEVICETYPE_PAD |3694 WACOM_DEVICETYPE_TOUCH;3695 features->quirks |= WACOM_QUIRK_BATTERY;3696 }3697 3698 if (features->type == INTUOSHT3_BT) {3699 features->device_type |= WACOM_DEVICETYPE_PEN |3700 WACOM_DEVICETYPE_PAD;3701 features->quirks |= WACOM_QUIRK_BATTERY;3702 }3703 3704 switch (features->type) {3705 case PL:3706 case DTU:3707 case DTUS:3708 case DTUSX:3709 case WACOM_21UX2:3710 case WACOM_22HD:3711 case DTK:3712 case WACOM_24HD:3713 case WACOM_27QHD:3714 case CINTIQ_HYBRID:3715 case CINTIQ_COMPANION_2:3716 case CINTIQ:3717 case WACOM_BEE:3718 case WACOM_13HD:3719 case WACOM_24HDT:3720 case WACOM_27QHDT:3721 case TABLETPC:3722 case TABLETPCE:3723 case TABLETPC2FG:3724 case MTSCREEN:3725 case MTTPC:3726 case MTTPC_B:3727 features->device_type |= WACOM_DEVICETYPE_DIRECT;3728 break;3729 }3730 3731 if (wacom->hdev->bus == BUS_BLUETOOTH)3732 features->quirks |= WACOM_QUIRK_BATTERY;3733 3734 /* quirk for bamboo touch with 2 low res touches */3735 if ((features->type == BAMBOO_PT || features->type == BAMBOO_TOUCH) &&3736 features->pktlen == WACOM_PKGLEN_BBTOUCH) {3737 features->x_max <<= 5;3738 features->y_max <<= 5;3739 features->x_fuzz <<= 5;3740 features->y_fuzz <<= 5;3741 features->quirks |= WACOM_QUIRK_BBTOUCH_LOWRES;3742 }3743 3744 if (features->type == WIRELESS) {3745 if (features->device_type == WACOM_DEVICETYPE_WL_MONITOR) {3746 features->quirks |= WACOM_QUIRK_BATTERY;3747 }3748 }3749 3750 if (features->type == REMOTE)3751 features->device_type |= WACOM_DEVICETYPE_WL_MONITOR;3752 3753 /* HID descriptor for DTK-2451 / DTH-2452 claims to report lots3754 * of things it shouldn't. Lets fix up the damage...3755 */3756 if (wacom->hdev->product == 0x382 || wacom->hdev->product == 0x37d) {3757 features->quirks &= ~WACOM_QUIRK_TOOLSERIAL;3758 __clear_bit(BTN_TOOL_BRUSH, wacom_wac->pen_input->keybit);3759 __clear_bit(BTN_TOOL_PENCIL, wacom_wac->pen_input->keybit);3760 __clear_bit(BTN_TOOL_AIRBRUSH, wacom_wac->pen_input->keybit);3761 __clear_bit(ABS_Z, wacom_wac->pen_input->absbit);3762 __clear_bit(ABS_DISTANCE, wacom_wac->pen_input->absbit);3763 __clear_bit(ABS_TILT_X, wacom_wac->pen_input->absbit);3764 __clear_bit(ABS_TILT_Y, wacom_wac->pen_input->absbit);3765 __clear_bit(ABS_WHEEL, wacom_wac->pen_input->absbit);3766 __clear_bit(ABS_MISC, wacom_wac->pen_input->absbit);3767 __clear_bit(MSC_SERIAL, wacom_wac->pen_input->mscbit);3768 __clear_bit(EV_MSC, wacom_wac->pen_input->evbit);3769 }3770}3771 3772int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,3773 struct wacom_wac *wacom_wac)3774{3775 struct wacom_features *features = &wacom_wac->features;3776 3777 if (!(features->device_type & WACOM_DEVICETYPE_PEN))3778 return -ENODEV;3779 3780 if (features->device_type & WACOM_DEVICETYPE_DIRECT)3781 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);3782 else3783 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);3784 3785 if (features->type == HID_GENERIC)3786 /* setup has already been done */3787 return 0;3788 3789 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);3790 __set_bit(BTN_TOUCH, input_dev->keybit);3791 __set_bit(ABS_MISC, input_dev->absbit);3792 3793 input_set_abs_params(input_dev, ABS_X, 0 + features->offset_left,3794 features->x_max - features->offset_right,3795 features->x_fuzz, 0);3796 input_set_abs_params(input_dev, ABS_Y, 0 + features->offset_top,3797 features->y_max - features->offset_bottom,3798 features->y_fuzz, 0);3799 input_set_abs_params(input_dev, ABS_PRESSURE, 0,3800 features->pressure_max, features->pressure_fuzz, 0);3801 3802 /* penabled devices have fixed resolution for each model */3803 input_abs_set_res(input_dev, ABS_X, features->x_resolution);3804 input_abs_set_res(input_dev, ABS_Y, features->y_resolution);3805 3806 switch (features->type) {3807 case GRAPHIRE_BT:3808 __clear_bit(ABS_MISC, input_dev->absbit);3809 fallthrough;3810 3811 case WACOM_MO:3812 case WACOM_G4:3813 input_set_abs_params(input_dev, ABS_DISTANCE, 0,3814 features->distance_max,3815 features->distance_fuzz, 0);3816 fallthrough;3817 3818 case GRAPHIRE:3819 input_set_capability(input_dev, EV_REL, REL_WHEEL);3820 3821 __set_bit(BTN_LEFT, input_dev->keybit);3822 __set_bit(BTN_RIGHT, input_dev->keybit);3823 __set_bit(BTN_MIDDLE, input_dev->keybit);3824 3825 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);3826 __set_bit(BTN_TOOL_PEN, input_dev->keybit);3827 __set_bit(BTN_TOOL_MOUSE, input_dev->keybit);3828 __set_bit(BTN_STYLUS, input_dev->keybit);3829 __set_bit(BTN_STYLUS2, input_dev->keybit);3830 break;3831 3832 case WACOM_27QHD:3833 case WACOM_24HD:3834 case DTK:3835 case WACOM_22HD:3836 case WACOM_21UX2:3837 case WACOM_BEE:3838 case CINTIQ:3839 case WACOM_13HD:3840 case CINTIQ_HYBRID:3841 case CINTIQ_COMPANION_2:3842 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);3843 input_abs_set_res(input_dev, ABS_Z, 287);3844 wacom_setup_cintiq(wacom_wac);3845 break;3846 3847 case INTUOS3:3848 case INTUOS3L:3849 case INTUOS3S:3850 case INTUOS4:3851 case INTUOS4WL:3852 case INTUOS4L:3853 case INTUOS4S:3854 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);3855 input_abs_set_res(input_dev, ABS_Z, 287);3856 fallthrough;3857 3858 case INTUOS:3859 wacom_setup_intuos(wacom_wac);3860 break;3861 3862 case INTUOS5:3863 case INTUOS5L:3864 case INTUOSPM:3865 case INTUOSPL:3866 case INTUOS5S:3867 case INTUOSPS:3868 case INTUOSP2_BT:3869 case INTUOSP2S_BT:3870 input_set_abs_params(input_dev, ABS_DISTANCE, 0,3871 features->distance_max,3872 features->distance_fuzz, 0);3873 3874 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);3875 input_abs_set_res(input_dev, ABS_Z, 287);3876 3877 wacom_setup_intuos(wacom_wac);3878 break;3879 3880 case WACOM_24HDT:3881 case WACOM_27QHDT:3882 case MTSCREEN:3883 case MTTPC:3884 case MTTPC_B:3885 case TABLETPC2FG:3886 case TABLETPC:3887 case TABLETPCE:3888 __clear_bit(ABS_MISC, input_dev->absbit);3889 fallthrough;3890 3891 case DTUS:3892 case DTUSX:3893 case PL:3894 case DTU:3895 __set_bit(BTN_TOOL_PEN, input_dev->keybit);3896 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);3897 __set_bit(BTN_STYLUS, input_dev->keybit);3898 __set_bit(BTN_STYLUS2, input_dev->keybit);3899 break;3900 3901 case PTU:3902 __set_bit(BTN_STYLUS2, input_dev->keybit);3903 fallthrough;3904 3905 case PENPARTNER:3906 __set_bit(BTN_TOOL_PEN, input_dev->keybit);3907 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);3908 __set_bit(BTN_STYLUS, input_dev->keybit);3909 break;3910 3911 case INTUOSHT:3912 case BAMBOO_PT:3913 case BAMBOO_PEN:3914 case INTUOSHT2:3915 case INTUOSHT3_BT:3916 if (features->type == INTUOSHT2 ||3917 features->type == INTUOSHT3_BT) {3918 wacom_setup_basic_pro_pen(wacom_wac);3919 } else {3920 __clear_bit(ABS_MISC, input_dev->absbit);3921 __set_bit(BTN_TOOL_PEN, input_dev->keybit);3922 __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);3923 __set_bit(BTN_STYLUS, input_dev->keybit);3924 __set_bit(BTN_STYLUS2, input_dev->keybit);3925 input_set_abs_params(input_dev, ABS_DISTANCE, 0,3926 features->distance_max,3927 features->distance_fuzz, 0);3928 }3929 break;3930 case BAMBOO_PAD:3931 __clear_bit(ABS_MISC, input_dev->absbit);3932 break;3933 }3934 return 0;3935}3936 3937int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,3938 struct wacom_wac *wacom_wac)3939{3940 struct wacom_features *features = &wacom_wac->features;3941 3942 if (!(features->device_type & WACOM_DEVICETYPE_TOUCH))3943 return -ENODEV;3944 3945 if (features->device_type & WACOM_DEVICETYPE_DIRECT)3946 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);3947 else3948 __set_bit(INPUT_PROP_POINTER, input_dev->propbit);3949 3950 if (features->type == HID_GENERIC)3951 /* setup has already been done */3952 return 0;3953 3954 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);3955 __set_bit(BTN_TOUCH, input_dev->keybit);3956 3957 if (features->touch_max == 1) {3958 input_set_abs_params(input_dev, ABS_X, 0,3959 features->x_max, features->x_fuzz, 0);3960 input_set_abs_params(input_dev, ABS_Y, 0,3961 features->y_max, features->y_fuzz, 0);3962 input_abs_set_res(input_dev, ABS_X,3963 features->x_resolution);3964 input_abs_set_res(input_dev, ABS_Y,3965 features->y_resolution);3966 }3967 else if (features->touch_max > 1) {3968 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0,3969 features->x_max, features->x_fuzz, 0);3970 input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0,3971 features->y_max, features->y_fuzz, 0);3972 input_abs_set_res(input_dev, ABS_MT_POSITION_X,3973 features->x_resolution);3974 input_abs_set_res(input_dev, ABS_MT_POSITION_Y,3975 features->y_resolution);3976 }3977 3978 switch (features->type) {3979 case INTUOSP2_BT:3980 case INTUOSP2S_BT:3981 input_dev->evbit[0] |= BIT_MASK(EV_SW);3982 __set_bit(SW_MUTE_DEVICE, input_dev->swbit);3983 3984 if (wacom_wac->shared->touch->product == 0x361) {3985 input_set_abs_params(input_dev, ABS_MT_POSITION_X,3986 0, 12440, 4, 0);3987 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,3988 0, 8640, 4, 0);3989 }3990 else if (wacom_wac->shared->touch->product == 0x360) {3991 input_set_abs_params(input_dev, ABS_MT_POSITION_X,3992 0, 8960, 4, 0);3993 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,3994 0, 5920, 4, 0);3995 }3996 else if (wacom_wac->shared->touch->product == 0x393) {3997 input_set_abs_params(input_dev, ABS_MT_POSITION_X,3998 0, 6400, 4, 0);3999 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,4000 0, 4000, 4, 0);4001 }4002 input_abs_set_res(input_dev, ABS_MT_POSITION_X, 40);4003 input_abs_set_res(input_dev, ABS_MT_POSITION_Y, 40);4004 4005 fallthrough;4006 4007 case INTUOS5:4008 case INTUOS5L:4009 case INTUOSPM:4010 case INTUOSPL:4011 case INTUOS5S:4012 case INTUOSPS:4013 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);4014 input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, features->y_max, 0, 0);4015 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);4016 break;4017 4018 case WACOM_24HDT:4019 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, features->x_max, 0, 0);4020 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 0, features->x_max, 0, 0);4021 input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, 0, features->y_max, 0, 0);4022 input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0);4023 fallthrough;4024 4025 case WACOM_27QHDT:4026 if (wacom_wac->shared->touch->product == 0x32C ||4027 wacom_wac->shared->touch->product == 0xF6) {4028 input_dev->evbit[0] |= BIT_MASK(EV_SW);4029 __set_bit(SW_MUTE_DEVICE, input_dev->swbit);4030 wacom_wac->has_mute_touch_switch = true;4031 wacom_wac->is_soft_touch_switch = true;4032 }4033 fallthrough;4034 4035 case MTSCREEN:4036 case MTTPC:4037 case MTTPC_B:4038 case TABLETPC2FG:4039 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_DIRECT);4040 fallthrough;4041 4042 case TABLETPC:4043 case TABLETPCE:4044 break;4045 4046 case INTUOSHT:4047 case INTUOSHT2:4048 input_dev->evbit[0] |= BIT_MASK(EV_SW);4049 __set_bit(SW_MUTE_DEVICE, input_dev->swbit);4050 fallthrough;4051 4052 case BAMBOO_PT:4053 case BAMBOO_TOUCH:4054 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {4055 input_set_abs_params(input_dev,4056 ABS_MT_TOUCH_MAJOR,4057 0, features->x_max, 0, 0);4058 input_set_abs_params(input_dev,4059 ABS_MT_TOUCH_MINOR,4060 0, features->y_max, 0, 0);4061 }4062 input_mt_init_slots(input_dev, features->touch_max, INPUT_MT_POINTER);4063 break;4064 4065 case BAMBOO_PAD:4066 input_mt_init_slots(input_dev, features->touch_max,4067 INPUT_MT_POINTER);4068 __set_bit(BTN_LEFT, input_dev->keybit);4069 __set_bit(BTN_RIGHT, input_dev->keybit);4070 break;4071 }4072 return 0;4073}4074 4075static int wacom_numbered_button_to_key(int n)4076{4077 if (n < 10)4078 return BTN_0 + n;4079 else if (n < 16)4080 return BTN_A + (n-10);4081 else if (n < 18)4082 return BTN_BASE + (n-16);4083 else4084 return 0;4085}4086 4087static void wacom_setup_numbered_buttons(struct input_dev *input_dev,4088 int button_count)4089{4090 int i;4091 4092 for (i = 0; i < button_count; i++) {4093 int key = wacom_numbered_button_to_key(i);4094 4095 if (key)4096 __set_bit(key, input_dev->keybit);4097 }4098}4099 4100static void wacom_24hd_update_leds(struct wacom *wacom, int mask, int group)4101{4102 struct wacom_led *led;4103 int i;4104 bool updated = false;4105 4106 /*4107 * 24HD has LED group 1 to the left and LED group 0 to the right.4108 * So group 0 matches the second half of the buttons and thus the mask4109 * needs to be shifted.4110 */4111 if (group == 0)4112 mask >>= 8;4113 4114 for (i = 0; i < 3; i++) {4115 led = wacom_led_find(wacom, group, i);4116 if (!led) {4117 hid_err(wacom->hdev, "can't find LED %d in group %d\n",4118 i, group);4119 continue;4120 }4121 if (!updated && mask & BIT(i)) {4122 led->held = true;4123 led_trigger_event(&led->trigger, LED_FULL);4124 } else {4125 led->held = false;4126 }4127 }4128}4129 4130static bool wacom_is_led_toggled(struct wacom *wacom, int button_count,4131 int mask, int group)4132{4133 int group_button;4134 4135 /*4136 * 21UX2 has LED group 1 to the left and LED group 04137 * to the right. We need to reverse the group to match this4138 * historical behavior.4139 */4140 if (wacom->wacom_wac.features.type == WACOM_21UX2)4141 group = 1 - group;4142 4143 group_button = group * (button_count/wacom->led.count);4144 4145 if (wacom->wacom_wac.features.type == INTUOSP2_BT)4146 group_button = 8;4147 4148 return mask & (1 << group_button);4149}4150 4151static void wacom_update_led(struct wacom *wacom, int button_count, int mask,4152 int group)4153{4154 struct wacom_led *led, *next_led;4155 int cur;4156 bool pressed;4157 4158 if (wacom->wacom_wac.features.type == WACOM_24HD)4159 return wacom_24hd_update_leds(wacom, mask, group);4160 4161 pressed = wacom_is_led_toggled(wacom, button_count, mask, group);4162 cur = wacom->led.groups[group].select;4163 4164 led = wacom_led_find(wacom, group, cur);4165 if (!led) {4166 hid_err(wacom->hdev, "can't find current LED %d in group %d\n",4167 cur, group);4168 return;4169 }4170 4171 if (!pressed) {4172 led->held = false;4173 return;4174 }4175 4176 if (led->held && pressed)4177 return;4178 4179 next_led = wacom_led_next(wacom, led);4180 if (!next_led) {4181 hid_err(wacom->hdev, "can't find next LED in group %d\n",4182 group);4183 return;4184 }4185 if (next_led == led)4186 return;4187 4188 next_led->held = true;4189 led_trigger_event(&next_led->trigger,4190 wacom_leds_brightness_get(next_led));4191}4192 4193static void wacom_report_numbered_buttons(struct input_dev *input_dev,4194 int button_count, int mask)4195{4196 struct wacom *wacom = input_get_drvdata(input_dev);4197 int i;4198 4199 for (i = 0; i < wacom->led.count; i++)4200 wacom_update_led(wacom, button_count, mask, i);4201 4202 for (i = 0; i < button_count; i++) {4203 int key = wacom_numbered_button_to_key(i);4204 4205 if (key)4206 input_report_key(input_dev, key, mask & (1 << i));4207 }4208}4209 4210int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,4211 struct wacom_wac *wacom_wac)4212{4213 struct wacom_features *features = &wacom_wac->features;4214 4215 if ((features->type == HID_GENERIC) && features->numbered_buttons > 0)4216 features->device_type |= WACOM_DEVICETYPE_PAD;4217 4218 if (!(features->device_type & WACOM_DEVICETYPE_PAD))4219 return -ENODEV;4220 4221 if (features->type == REMOTE && input_dev == wacom_wac->pad_input)4222 return -ENODEV;4223 4224 input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);4225 4226 /* kept for making legacy xf86-input-wacom working with the wheels */4227 __set_bit(ABS_MISC, input_dev->absbit);4228 4229 /* kept for making legacy xf86-input-wacom accepting the pad */4230 if (!(input_dev->absinfo && (input_dev->absinfo[ABS_X].minimum ||4231 input_dev->absinfo[ABS_X].maximum)))4232 input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);4233 if (!(input_dev->absinfo && (input_dev->absinfo[ABS_Y].minimum ||4234 input_dev->absinfo[ABS_Y].maximum)))4235 input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);4236 4237 /* kept for making udev and libwacom accepting the pad */4238 __set_bit(BTN_STYLUS, input_dev->keybit);4239 4240 wacom_setup_numbered_buttons(input_dev, features->numbered_buttons);4241 4242 switch (features->type) {4243 4244 case CINTIQ_HYBRID:4245 case CINTIQ_COMPANION_2:4246 case DTK:4247 case DTUS:4248 case GRAPHIRE_BT:4249 break;4250 4251 case WACOM_MO:4252 __set_bit(BTN_BACK, input_dev->keybit);4253 __set_bit(BTN_LEFT, input_dev->keybit);4254 __set_bit(BTN_FORWARD, input_dev->keybit);4255 __set_bit(BTN_RIGHT, input_dev->keybit);4256 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4257 break;4258 4259 case WACOM_G4:4260 __set_bit(BTN_BACK, input_dev->keybit);4261 __set_bit(BTN_FORWARD, input_dev->keybit);4262 input_set_capability(input_dev, EV_REL, REL_WHEEL);4263 break;4264 4265 case WACOM_24HD:4266 __set_bit(KEY_PROG1, input_dev->keybit);4267 __set_bit(KEY_PROG2, input_dev->keybit);4268 __set_bit(KEY_PROG3, input_dev->keybit);4269 4270 __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit);4271 __set_bit(KEY_INFO, input_dev->keybit);4272 4273 if (!features->oPid)4274 __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);4275 4276 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4277 input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);4278 break;4279 4280 case WACOM_27QHD:4281 __set_bit(KEY_PROG1, input_dev->keybit);4282 __set_bit(KEY_PROG2, input_dev->keybit);4283 __set_bit(KEY_PROG3, input_dev->keybit);4284 4285 __set_bit(KEY_ONSCREEN_KEYBOARD, input_dev->keybit);4286 __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);4287 4288 if (!features->oPid)4289 __set_bit(KEY_CONTROLPANEL, input_dev->keybit);4290 input_set_abs_params(input_dev, ABS_X, -2048, 2048, 0, 0);4291 input_abs_set_res(input_dev, ABS_X, 1024); /* points/g */4292 input_set_abs_params(input_dev, ABS_Y, -2048, 2048, 0, 0);4293 input_abs_set_res(input_dev, ABS_Y, 1024);4294 input_set_abs_params(input_dev, ABS_Z, -2048, 2048, 0, 0);4295 input_abs_set_res(input_dev, ABS_Z, 1024);4296 __set_bit(INPUT_PROP_ACCELEROMETER, input_dev->propbit);4297 break;4298 4299 case WACOM_22HD:4300 __set_bit(KEY_PROG1, input_dev->keybit);4301 __set_bit(KEY_PROG2, input_dev->keybit);4302 __set_bit(KEY_PROG3, input_dev->keybit);4303 4304 __set_bit(KEY_BUTTONCONFIG, input_dev->keybit);4305 __set_bit(KEY_INFO, input_dev->keybit);4306 fallthrough;4307 4308 case WACOM_21UX2:4309 case WACOM_BEE:4310 case CINTIQ:4311 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);4312 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);4313 break;4314 4315 case WACOM_13HD:4316 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4317 break;4318 4319 case INTUOS3:4320 case INTUOS3L:4321 input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);4322 fallthrough;4323 4324 case INTUOS3S:4325 input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);4326 break;4327 4328 case INTUOS5:4329 case INTUOS5L:4330 case INTUOSPM:4331 case INTUOSPL:4332 case INTUOS5S:4333 case INTUOSPS:4334 case INTUOSP2_BT:4335 case INTUOSP2S_BT:4336 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4337 break;4338 4339 case INTUOS4WL:4340 /*4341 * For Bluetooth devices, the udev rule does not work correctly4342 * for pads unless we add a stylus capability, which forces4343 * ID_INPUT_TABLET to be set.4344 */4345 __set_bit(BTN_STYLUS, input_dev->keybit);4346 fallthrough;4347 4348 case INTUOS4:4349 case INTUOS4L:4350 case INTUOS4S:4351 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4352 break;4353 4354 case INTUOSHT:4355 case BAMBOO_PT:4356 case BAMBOO_TOUCH:4357 case INTUOSHT2:4358 __clear_bit(ABS_MISC, input_dev->absbit);4359 4360 __set_bit(BTN_LEFT, input_dev->keybit);4361 __set_bit(BTN_FORWARD, input_dev->keybit);4362 __set_bit(BTN_BACK, input_dev->keybit);4363 __set_bit(BTN_RIGHT, input_dev->keybit);4364 4365 break;4366 4367 case REMOTE:4368 input_set_capability(input_dev, EV_MSC, MSC_SERIAL);4369 input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);4370 break;4371 4372 case INTUOSHT3_BT:4373 case HID_GENERIC:4374 break;4375 4376 default:4377 /* no pad supported */4378 return -ENODEV;4379 }4380 return 0;4381}4382 4383static const struct wacom_features wacom_features_0x00 =4384 { "Wacom Penpartner", 5040, 3780, 255, 0,4385 PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };4386static const struct wacom_features wacom_features_0x10 =4387 { "Wacom Graphire", 10206, 7422, 511, 63,4388 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4389static const struct wacom_features wacom_features_0x81 =4390 { "Wacom Graphire BT", 16704, 12064, 511, 32,4391 GRAPHIRE_BT, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES, 2 };4392static const struct wacom_features wacom_features_0x11 =4393 { "Wacom Graphire2 4x5", 10206, 7422, 511, 63,4394 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4395static const struct wacom_features wacom_features_0x12 =4396 { "Wacom Graphire2 5x7", 13918, 10206, 511, 63,4397 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4398static const struct wacom_features wacom_features_0x13 =4399 { "Wacom Graphire3", 10208, 7424, 511, 63,4400 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4401static const struct wacom_features wacom_features_0x14 =4402 { "Wacom Graphire3 6x8", 16704, 12064, 511, 63,4403 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4404static const struct wacom_features wacom_features_0x15 =4405 { "Wacom Graphire4 4x5", 10208, 7424, 511, 63,4406 WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4407static const struct wacom_features wacom_features_0x16 =4408 { "Wacom Graphire4 6x8", 16704, 12064, 511, 63,4409 WACOM_G4, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4410static const struct wacom_features wacom_features_0x17 =4411 { "Wacom BambooFun 4x5", 14760, 9225, 511, 63,4412 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4413static const struct wacom_features wacom_features_0x18 =4414 { "Wacom BambooFun 6x8", 21648, 13530, 511, 63,4415 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4416static const struct wacom_features wacom_features_0x19 =4417 { "Wacom Bamboo1 Medium", 16704, 12064, 511, 63,4418 GRAPHIRE, WACOM_GRAPHIRE_RES, WACOM_GRAPHIRE_RES };4419static const struct wacom_features wacom_features_0x60 =4420 { "Wacom Volito", 5104, 3712, 511, 63,4421 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };4422static const struct wacom_features wacom_features_0x61 =4423 { "Wacom PenStation2", 3250, 2320, 255, 63,4424 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };4425static const struct wacom_features wacom_features_0x62 =4426 { "Wacom Volito2 4x5", 5104, 3712, 511, 63,4427 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };4428static const struct wacom_features wacom_features_0x63 =4429 { "Wacom Volito2 2x3", 3248, 2320, 511, 63,4430 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };4431static const struct wacom_features wacom_features_0x64 =4432 { "Wacom PenPartner2", 3250, 2320, 511, 63,4433 GRAPHIRE, WACOM_VOLITO_RES, WACOM_VOLITO_RES };4434static const struct wacom_features wacom_features_0x65 =4435 { "Wacom Bamboo", 14760, 9225, 511, 63,4436 WACOM_MO, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4437static const struct wacom_features wacom_features_0x69 =4438 { "Wacom Bamboo1", 5104, 3712, 511, 63,4439 GRAPHIRE, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };4440static const struct wacom_features wacom_features_0x6A =4441 { "Wacom Bamboo1 4x6", 14760, 9225, 1023, 63,4442 GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4443static const struct wacom_features wacom_features_0x6B =4444 { "Wacom Bamboo1 5x8", 21648, 13530, 1023, 63,4445 GRAPHIRE, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4446static const struct wacom_features wacom_features_0x20 =4447 { "Wacom Intuos 4x5", 12700, 10600, 1023, 31,4448 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4449static const struct wacom_features wacom_features_0x21 =4450 { "Wacom Intuos 6x8", 20320, 16240, 1023, 31,4451 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4452static const struct wacom_features wacom_features_0x22 =4453 { "Wacom Intuos 9x12", 30480, 24060, 1023, 31,4454 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4455static const struct wacom_features wacom_features_0x23 =4456 { "Wacom Intuos 12x12", 30480, 31680, 1023, 31,4457 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4458static const struct wacom_features wacom_features_0x24 =4459 { "Wacom Intuos 12x18", 45720, 31680, 1023, 31,4460 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4461static const struct wacom_features wacom_features_0x30 =4462 { "Wacom PL400", 5408, 4056, 255, 0,4463 PL, WACOM_PL_RES, WACOM_PL_RES };4464static const struct wacom_features wacom_features_0x31 =4465 { "Wacom PL500", 6144, 4608, 255, 0,4466 PL, WACOM_PL_RES, WACOM_PL_RES };4467static const struct wacom_features wacom_features_0x32 =4468 { "Wacom PL600", 6126, 4604, 255, 0,4469 PL, WACOM_PL_RES, WACOM_PL_RES };4470static const struct wacom_features wacom_features_0x33 =4471 { "Wacom PL600SX", 6260, 5016, 255, 0,4472 PL, WACOM_PL_RES, WACOM_PL_RES };4473static const struct wacom_features wacom_features_0x34 =4474 { "Wacom PL550", 6144, 4608, 511, 0,4475 PL, WACOM_PL_RES, WACOM_PL_RES };4476static const struct wacom_features wacom_features_0x35 =4477 { "Wacom PL800", 7220, 5780, 511, 0,4478 PL, WACOM_PL_RES, WACOM_PL_RES };4479static const struct wacom_features wacom_features_0x37 =4480 { "Wacom PL700", 6758, 5406, 511, 0,4481 PL, WACOM_PL_RES, WACOM_PL_RES };4482static const struct wacom_features wacom_features_0x38 =4483 { "Wacom PL510", 6282, 4762, 511, 0,4484 PL, WACOM_PL_RES, WACOM_PL_RES };4485static const struct wacom_features wacom_features_0x39 =4486 { "Wacom DTU710", 34080, 27660, 511, 0,4487 PL, WACOM_PL_RES, WACOM_PL_RES };4488static const struct wacom_features wacom_features_0xC4 =4489 { "Wacom DTF521", 6282, 4762, 511, 0,4490 PL, WACOM_PL_RES, WACOM_PL_RES };4491static const struct wacom_features wacom_features_0xC0 =4492 { "Wacom DTF720", 6858, 5506, 511, 0,4493 PL, WACOM_PL_RES, WACOM_PL_RES };4494static const struct wacom_features wacom_features_0xC2 =4495 { "Wacom DTF720a", 6858, 5506, 511, 0,4496 PL, WACOM_PL_RES, WACOM_PL_RES };4497static const struct wacom_features wacom_features_0x03 =4498 { "Wacom Cintiq Partner", 20480, 15360, 511, 0,4499 PTU, WACOM_PL_RES, WACOM_PL_RES };4500static const struct wacom_features wacom_features_0x41 =4501 { "Wacom Intuos2 4x5", 12700, 10600, 1023, 31,4502 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4503static const struct wacom_features wacom_features_0x42 =4504 { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,4505 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4506static const struct wacom_features wacom_features_0x43 =4507 { "Wacom Intuos2 9x12", 30480, 24060, 1023, 31,4508 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4509static const struct wacom_features wacom_features_0x44 =4510 { "Wacom Intuos2 12x12", 30480, 31680, 1023, 31,4511 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4512static const struct wacom_features wacom_features_0x45 =4513 { "Wacom Intuos2 12x18", 45720, 31680, 1023, 31,4514 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4515static const struct wacom_features wacom_features_0xB0 =4516 { "Wacom Intuos3 4x5", 25400, 20320, 1023, 63,4517 INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };4518static const struct wacom_features wacom_features_0xB1 =4519 { "Wacom Intuos3 6x8", 40640, 30480, 1023, 63,4520 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4521static const struct wacom_features wacom_features_0xB2 =4522 { "Wacom Intuos3 9x12", 60960, 45720, 1023, 63,4523 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4524static const struct wacom_features wacom_features_0xB3 =4525 { "Wacom Intuos3 12x12", 60960, 60960, 1023, 63,4526 INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4527static const struct wacom_features wacom_features_0xB4 =4528 { "Wacom Intuos3 12x19", 97536, 60960, 1023, 63,4529 INTUOS3L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4530static const struct wacom_features wacom_features_0xB5 =4531 { "Wacom Intuos3 6x11", 54204, 31750, 1023, 63,4532 INTUOS3, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4533static const struct wacom_features wacom_features_0xB7 =4534 { "Wacom Intuos3 4x6", 31496, 19685, 1023, 63,4535 INTUOS3S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 4 };4536static const struct wacom_features wacom_features_0xB8 =4537 { "Wacom Intuos4 4x6", 31496, 19685, 2047, 63,4538 INTUOS4S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };4539static const struct wacom_features wacom_features_0xB9 =4540 { "Wacom Intuos4 6x9", 44704, 27940, 2047, 63,4541 INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4542static const struct wacom_features wacom_features_0xBA =4543 { "Wacom Intuos4 8x13", 65024, 40640, 2047, 63,4544 INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4545static const struct wacom_features wacom_features_0xBB =4546 { "Wacom Intuos4 12x19", 97536, 60960, 2047, 63,4547 INTUOS4L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4548static const struct wacom_features wacom_features_0xBC =4549 { "Wacom Intuos4 WL", 40640, 25400, 2047, 63,4550 INTUOS4, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4551static const struct wacom_features wacom_features_0xBD =4552 { "Wacom Intuos4 WL", 40640, 25400, 2047, 63,4553 INTUOS4WL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4554static const struct wacom_features wacom_features_0x26 =4555 { "Wacom Intuos5 touch S", 31496, 19685, 2047, 63,4556 INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16 };4557static const struct wacom_features wacom_features_0x27 =4558 { "Wacom Intuos5 touch M", 44704, 27940, 2047, 63,4559 INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 };4560static const struct wacom_features wacom_features_0x28 =4561 { "Wacom Intuos5 touch L", 65024, 40640, 2047, 63,4562 INTUOS5L, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16 };4563static const struct wacom_features wacom_features_0x29 =4564 { "Wacom Intuos5 S", 31496, 19685, 2047, 63,4565 INTUOS5S, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7 };4566static const struct wacom_features wacom_features_0x2A =4567 { "Wacom Intuos5 M", 44704, 27940, 2047, 63,4568 INTUOS5, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9 };4569static const struct wacom_features wacom_features_0x314 =4570 { "Wacom Intuos Pro S", 31496, 19685, 2047, 63,4571 INTUOSPS, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7, .touch_max = 16,4572 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4573static const struct wacom_features wacom_features_0x315 =4574 { "Wacom Intuos Pro M", 44704, 27940, 2047, 63,4575 INTUOSPM, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16,4576 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4577static const struct wacom_features wacom_features_0x317 =4578 { "Wacom Intuos Pro L", 65024, 40640, 2047, 63,4579 INTUOSPL, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 16,4580 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4581static const struct wacom_features wacom_features_0xF4 =4582 { "Wacom Cintiq 24HD", 104480, 65600, 2047, 63,4583 WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,4584 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4585 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4586static const struct wacom_features wacom_features_0xF8 =4587 { "Wacom Cintiq 24HD touch", 104480, 65600, 2047, 63, /* Pen */4588 WACOM_24HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 16,4589 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4590 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4591 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf6 };4592static const struct wacom_features wacom_features_0xF6 =4593 { "Wacom Cintiq 24HD touch", .type = WACOM_24HDT, /* Touch */4594 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0xf8, .touch_max = 10,4595 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4596static const struct wacom_features wacom_features_0x32A =4597 { "Wacom Cintiq 27QHD", 120140, 67920, 2047, 63,4598 WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,4599 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4600 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4601static const struct wacom_features wacom_features_0x32B =4602 { "Wacom Cintiq 27QHD touch", 120140, 67920, 2047, 63,4603 WACOM_27QHD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 0,4604 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4605 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4606 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32C };4607static const struct wacom_features wacom_features_0x32C =4608 { "Wacom Cintiq 27QHD touch", .type = WACOM_27QHDT,4609 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x32B, .touch_max = 10 };4610static const struct wacom_features wacom_features_0x3F =4611 { "Wacom Cintiq 21UX", 87200, 65600, 1023, 63,4612 CINTIQ, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 8 };4613static const struct wacom_features wacom_features_0xC5 =4614 { "Wacom Cintiq 20WSX", 86680, 54180, 1023, 63,4615 WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };4616static const struct wacom_features wacom_features_0xC6 =4617 { "Wacom Cintiq 12WX", 53020, 33440, 1023, 63,4618 WACOM_BEE, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 10 };4619static const struct wacom_features wacom_features_0x304 =4620 { "Wacom Cintiq 13HD", 59552, 33848, 1023, 63,4621 WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,4622 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4623 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4624static const struct wacom_features wacom_features_0x333 =4625 { "Wacom Cintiq 13HD touch", 59552, 33848, 2047, 63,4626 WACOM_13HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,4627 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4628 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4629 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x335 };4630static const struct wacom_features wacom_features_0x335 =4631 { "Wacom Cintiq 13HD touch", .type = WACOM_24HDT, /* Touch */4632 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x333, .touch_max = 10,4633 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4634static const struct wacom_features wacom_features_0xC7 =4635 { "Wacom DTU1931", 37832, 30305, 511, 0,4636 PL, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4637static const struct wacom_features wacom_features_0xCE =4638 { "Wacom DTU2231", 47864, 27011, 511, 0,4639 DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES,4640 .check_for_hid_type = true, .hid_type = HID_TYPE_USBMOUSE };4641static const struct wacom_features wacom_features_0xF0 =4642 { "Wacom DTU1631", 34623, 19553, 511, 0,4643 DTU, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4644static const struct wacom_features wacom_features_0xFB =4645 { "Wacom DTU1031", 22096, 13960, 511, 0,4646 DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,4647 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,4648 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };4649static const struct wacom_features wacom_features_0x32F =4650 { "Wacom DTU1031X", 22672, 12928, 511, 0,4651 DTUSX, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 0,4652 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,4653 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };4654static const struct wacom_features wacom_features_0x336 =4655 { "Wacom DTU1141", 23672, 13403, 1023, 0,4656 DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,4657 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,4658 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };4659static const struct wacom_features wacom_features_0x57 =4660 { "Wacom DTK2241", 95840, 54260, 2047, 63,4661 DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,4662 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4663 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4664static const struct wacom_features wacom_features_0x59 = /* Pen */4665 { "Wacom DTH2242", 95840, 54260, 2047, 63,4666 DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,4667 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4668 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4669 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5D };4670static const struct wacom_features wacom_features_0x5D = /* Touch */4671 { "Wacom DTH2242", .type = WACOM_24HDT,4672 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x59, .touch_max = 10,4673 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4674static const struct wacom_features wacom_features_0xCC =4675 { "Wacom Cintiq 21UX2", 87200, 65600, 2047, 63,4676 WACOM_21UX2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,4677 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4678 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4679static const struct wacom_features wacom_features_0xFA =4680 { "Wacom Cintiq 22HD", 95840, 54260, 2047, 63,4681 WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,4682 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4683 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET };4684static const struct wacom_features wacom_features_0x5B =4685 { "Wacom Cintiq 22HDT", 95840, 54260, 2047, 63,4686 WACOM_22HD, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 18,4687 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4688 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4689 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5e };4690static const struct wacom_features wacom_features_0x5E =4691 { "Wacom Cintiq 22HDT", .type = WACOM_24HDT,4692 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x5b, .touch_max = 10,4693 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4694static const struct wacom_features wacom_features_0x90 =4695 { "Wacom ISDv4 90", 26202, 16325, 255, 0,4696 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; /* Pen-only */4697static const struct wacom_features wacom_features_0x93 =4698 { "Wacom ISDv4 93", 26202, 16325, 255, 0,4699 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 1 };4700static const struct wacom_features wacom_features_0x97 =4701 { "Wacom ISDv4 97", 26202, 16325, 511, 0,4702 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; /* Pen-only */4703static const struct wacom_features wacom_features_0x9A =4704 { "Wacom ISDv4 9A", 26202, 16325, 255, 0,4705 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 1 };4706static const struct wacom_features wacom_features_0x9F =4707 { "Wacom ISDv4 9F", 26202, 16325, 255, 0,4708 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 1 };4709static const struct wacom_features wacom_features_0xE2 =4710 { "Wacom ISDv4 E2", 26202, 16325, 255, 0,4711 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4712static const struct wacom_features wacom_features_0xE3 =4713 { "Wacom ISDv4 E3", 26202, 16325, 255, 0,4714 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4715static const struct wacom_features wacom_features_0xE5 =4716 { "Wacom ISDv4 E5", 26202, 16325, 255, 0,4717 MTSCREEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4718static const struct wacom_features wacom_features_0xE6 =4719 { "Wacom ISDv4 E6", 27760, 15694, 255, 0,4720 TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4721static const struct wacom_features wacom_features_0xEC =4722 { "Wacom ISDv4 EC", 25710, 14500, 255, 0,4723 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; /* Pen-only */4724static const struct wacom_features wacom_features_0xED =4725 { "Wacom ISDv4 ED", 26202, 16325, 255, 0,4726 TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 1 };4727static const struct wacom_features wacom_features_0xEF =4728 { "Wacom ISDv4 EF", 26202, 16325, 255, 0,4729 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; /* Pen-only */4730static const struct wacom_features wacom_features_0x100 =4731 { "Wacom ISDv4 100", 26202, 16325, 255, 0,4732 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4733static const struct wacom_features wacom_features_0x101 =4734 { "Wacom ISDv4 101", 26202, 16325, 255, 0,4735 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4736static const struct wacom_features wacom_features_0x10D =4737 { "Wacom ISDv4 10D", 26202, 16325, 255, 0,4738 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4739static const struct wacom_features wacom_features_0x10E =4740 { "Wacom ISDv4 10E", 27760, 15694, 255, 0,4741 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4742static const struct wacom_features wacom_features_0x10F =4743 { "Wacom ISDv4 10F", 27760, 15694, 255, 0,4744 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4745static const struct wacom_features wacom_features_0x116 =4746 { "Wacom ISDv4 116", 26202, 16325, 255, 0,4747 TABLETPCE, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 1 };4748static const struct wacom_features wacom_features_0x12C =4749 { "Wacom ISDv4 12C", 27848, 15752, 2047, 0,4750 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; /* Pen-only */4751static const struct wacom_features wacom_features_0x4001 =4752 { "Wacom ISDv4 4001", 26202, 16325, 255, 0,4753 MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4754static const struct wacom_features wacom_features_0x4004 =4755 { "Wacom ISDv4 4004", 11060, 6220, 255, 0,4756 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4757static const struct wacom_features wacom_features_0x5000 =4758 { "Wacom ISDv4 5000", 27848, 15752, 1023, 0,4759 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4760static const struct wacom_features wacom_features_0x5002 =4761 { "Wacom ISDv4 5002", 29576, 16724, 1023, 0,4762 MTTPC_B, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4763static const struct wacom_features wacom_features_0x47 =4764 { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31,4765 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4766static const struct wacom_features wacom_features_0x84 =4767 { "Wacom Wireless Receiver", .type = WIRELESS, .touch_max = 16 };4768static const struct wacom_features wacom_features_0xD0 =4769 { "Wacom Bamboo 2FG", 14720, 9200, 1023, 31,4770 BAMBOO_TOUCH, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4771static const struct wacom_features wacom_features_0xD1 =4772 { "Wacom Bamboo 2FG 4x5", 14720, 9200, 1023, 31,4773 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4774static const struct wacom_features wacom_features_0xD2 =4775 { "Wacom Bamboo Craft", 14720, 9200, 1023, 31,4776 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4777static const struct wacom_features wacom_features_0xD3 =4778 { "Wacom Bamboo 2FG 6x8", 21648, 13700, 1023, 31,4779 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4780static const struct wacom_features wacom_features_0xD4 =4781 { "Wacom Bamboo Pen", 14720, 9200, 1023, 31,4782 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4783static const struct wacom_features wacom_features_0xD5 =4784 { "Wacom Bamboo Pen 6x8", 21648, 13700, 1023, 31,4785 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4786static const struct wacom_features wacom_features_0xD6 =4787 { "Wacom BambooPT 2FG 4x5", 14720, 9200, 1023, 31,4788 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4789static const struct wacom_features wacom_features_0xD7 =4790 { "Wacom BambooPT 2FG Small", 14720, 9200, 1023, 31,4791 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4792static const struct wacom_features wacom_features_0xD8 =4793 { "Wacom Bamboo Comic 2FG", 21648, 13700, 1023, 31,4794 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4795static const struct wacom_features wacom_features_0xDA =4796 { "Wacom Bamboo 2FG 4x5 SE", 14720, 9200, 1023, 31,4797 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4798static const struct wacom_features wacom_features_0xDB =4799 { "Wacom Bamboo 2FG 6x8 SE", 21648, 13700, 1023, 31,4800 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 };4801static const struct wacom_features wacom_features_0xDD =4802 { "Wacom Bamboo Connect", 14720, 9200, 1023, 31,4803 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4804static const struct wacom_features wacom_features_0xDE =4805 { "Wacom Bamboo 16FG 4x5", 14720, 9200, 1023, 31,4806 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };4807static const struct wacom_features wacom_features_0xDF =4808 { "Wacom Bamboo 16FG 6x8", 21648, 13700, 1023, 31,4809 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 };4810static const struct wacom_features wacom_features_0x300 =4811 { "Wacom Bamboo One S", 14720, 9225, 1023, 31,4812 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4813static const struct wacom_features wacom_features_0x301 =4814 { "Wacom Bamboo One M", 21648, 13530, 1023, 31,4815 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4816static const struct wacom_features wacom_features_0x302 =4817 { "Wacom Intuos PT S", 15200, 9500, 1023, 31,4818 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,4819 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4820static const struct wacom_features wacom_features_0x303 =4821 { "Wacom Intuos PT M", 21600, 13500, 1023, 31,4822 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,4823 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4824static const struct wacom_features wacom_features_0x30E =4825 { "Wacom Intuos S", 15200, 9500, 1023, 31,4826 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,4827 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4828static const struct wacom_features wacom_features_0x6004 =4829 { "ISD-V4", 12800, 8000, 255, 0,4830 TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4831static const struct wacom_features wacom_features_0x307 =4832 { "Wacom ISDv5 307", 59552, 33848, 2047, 63,4833 CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,4834 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4835 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4836 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x309 };4837static const struct wacom_features wacom_features_0x309 =4838 { "Wacom ISDv5 309", .type = WACOM_24HDT, /* Touch */4839 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x0307, .touch_max = 10,4840 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4841static const struct wacom_features wacom_features_0x30A =4842 { "Wacom ISDv5 30A", 59552, 33848, 2047, 63,4843 CINTIQ_HYBRID, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9,4844 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4845 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4846 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30C };4847static const struct wacom_features wacom_features_0x30C =4848 { "Wacom ISDv5 30C", .type = WACOM_24HDT, /* Touch */4849 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x30A, .touch_max = 10,4850 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4851static const struct wacom_features wacom_features_0x318 =4852 { "Wacom USB Bamboo PAD", 4095, 4095, /* Touch */4853 .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };4854static const struct wacom_features wacom_features_0x319 =4855 { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */4856 .type = BAMBOO_PAD, 35, 48, .touch_max = 4 };4857static const struct wacom_features wacom_features_0x325 =4858 { "Wacom ISDv5 325", 59552, 33848, 2047, 63,4859 CINTIQ_COMPANION_2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11,4860 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4861 WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET,4862 .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x326 };4863static const struct wacom_features wacom_features_0x326 = /* Touch */4864 { "Wacom ISDv5 326", .type = HID_GENERIC, .oVid = USB_VENDOR_ID_WACOM,4865 .oPid = 0x325 };4866static const struct wacom_features wacom_features_0x323 =4867 { "Wacom Intuos P M", 21600, 13500, 1023, 31,4868 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES,4869 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4870static const struct wacom_features wacom_features_0x331 =4871 { "Wacom Express Key Remote", .type = REMOTE,4872 .numbered_buttons = 18, .check_for_hid_type = true,4873 .hid_type = HID_TYPE_USBNONE };4874static const struct wacom_features wacom_features_0x33B =4875 { "Wacom Intuos S 2", 15200, 9500, 2047, 63,4876 INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,4877 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4878static const struct wacom_features wacom_features_0x33C =4879 { "Wacom Intuos PT S 2", 15200, 9500, 2047, 63,4880 INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,4881 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4882static const struct wacom_features wacom_features_0x33D =4883 { "Wacom Intuos P M 2", 21600, 13500, 2047, 63,4884 INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES,4885 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4886static const struct wacom_features wacom_features_0x33E =4887 { "Wacom Intuos PT M 2", 21600, 13500, 2047, 63,4888 INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16,4889 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE };4890static const struct wacom_features wacom_features_0x343 =4891 { "Wacom DTK1651", 34816, 19759, 1023, 0,4892 DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,4893 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET,4894 WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };4895static const struct wacom_features wacom_features_0x360 =4896 { "Wacom Intuos Pro M", 44800, 29600, 8191, 63,4897 INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 };4898static const struct wacom_features wacom_features_0x361 =4899 { "Wacom Intuos Pro L", 62200, 43200, 8191, 63,4900 INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 };4901static const struct wacom_features wacom_features_0x377 =4902 { "Wacom Intuos BT S", 15200, 9500, 4095, 63,4903 INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };4904static const struct wacom_features wacom_features_0x379 =4905 { "Wacom Intuos BT M", 21600, 13500, 4095, 63,4906 INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };4907static const struct wacom_features wacom_features_0x37A =4908 { "Wacom One by Wacom S", 15200, 9500, 2047, 63,4909 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4910static const struct wacom_features wacom_features_0x37B =4911 { "Wacom One by Wacom M", 21600, 13500, 2047, 63,4912 BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES };4913static const struct wacom_features wacom_features_0x393 =4914 { "Wacom Intuos Pro S", 31920, 19950, 8191, 63,4915 INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7,4916 .touch_max = 10 };4917static const struct wacom_features wacom_features_0x3c6 =4918 { "Wacom Intuos BT S", 15200, 9500, 4095, 63,4919 INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };4920static const struct wacom_features wacom_features_0x3c8 =4921 { "Wacom Intuos BT M", 21600, 13500, 4095, 63,4922 INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };4923static const struct wacom_features wacom_features_0x3dd =4924 { "Wacom Intuos Pro S", 31920, 19950, 8191, 63,4925 INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7,4926 .touch_max = 10 };4927 4928static const struct wacom_features wacom_features_HID_ANY_ID =4929 { "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };4930 4931static const struct wacom_features wacom_features_0x94 =4932 { "Wacom Bootloader", .type = BOOTLOADER };4933 4934#define USB_DEVICE_WACOM(prod) \4935 HID_DEVICE(BUS_USB, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\4936 .driver_data = (kernel_ulong_t)&wacom_features_##prod4937 4938#define BT_DEVICE_WACOM(prod) \4939 HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\4940 .driver_data = (kernel_ulong_t)&wacom_features_##prod4941 4942#define I2C_DEVICE_WACOM(prod) \4943 HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\4944 .driver_data = (kernel_ulong_t)&wacom_features_##prod4945 4946#define USB_DEVICE_LENOVO(prod) \4947 HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod), \4948 .driver_data = (kernel_ulong_t)&wacom_features_##prod4949 4950const struct hid_device_id wacom_ids[] = {4951 { USB_DEVICE_WACOM(0x00) },4952 { USB_DEVICE_WACOM(0x03) },4953 { USB_DEVICE_WACOM(0x10) },4954 { USB_DEVICE_WACOM(0x11) },4955 { USB_DEVICE_WACOM(0x12) },4956 { USB_DEVICE_WACOM(0x13) },4957 { USB_DEVICE_WACOM(0x14) },4958 { USB_DEVICE_WACOM(0x15) },4959 { USB_DEVICE_WACOM(0x16) },4960 { USB_DEVICE_WACOM(0x17) },4961 { USB_DEVICE_WACOM(0x18) },4962 { USB_DEVICE_WACOM(0x19) },4963 { USB_DEVICE_WACOM(0x20) },4964 { USB_DEVICE_WACOM(0x21) },4965 { USB_DEVICE_WACOM(0x22) },4966 { USB_DEVICE_WACOM(0x23) },4967 { USB_DEVICE_WACOM(0x24) },4968 { USB_DEVICE_WACOM(0x26) },4969 { USB_DEVICE_WACOM(0x27) },4970 { USB_DEVICE_WACOM(0x28) },4971 { USB_DEVICE_WACOM(0x29) },4972 { USB_DEVICE_WACOM(0x2A) },4973 { USB_DEVICE_WACOM(0x30) },4974 { USB_DEVICE_WACOM(0x31) },4975 { USB_DEVICE_WACOM(0x32) },4976 { USB_DEVICE_WACOM(0x33) },4977 { USB_DEVICE_WACOM(0x34) },4978 { USB_DEVICE_WACOM(0x35) },4979 { USB_DEVICE_WACOM(0x37) },4980 { USB_DEVICE_WACOM(0x38) },4981 { USB_DEVICE_WACOM(0x39) },4982 { USB_DEVICE_WACOM(0x3F) },4983 { USB_DEVICE_WACOM(0x41) },4984 { USB_DEVICE_WACOM(0x42) },4985 { USB_DEVICE_WACOM(0x43) },4986 { USB_DEVICE_WACOM(0x44) },4987 { USB_DEVICE_WACOM(0x45) },4988 { USB_DEVICE_WACOM(0x47) },4989 { USB_DEVICE_WACOM(0x57) },4990 { USB_DEVICE_WACOM(0x59) },4991 { USB_DEVICE_WACOM(0x5B) },4992 { USB_DEVICE_WACOM(0x5D) },4993 { USB_DEVICE_WACOM(0x5E) },4994 { USB_DEVICE_WACOM(0x60) },4995 { USB_DEVICE_WACOM(0x61) },4996 { USB_DEVICE_WACOM(0x62) },4997 { USB_DEVICE_WACOM(0x63) },4998 { USB_DEVICE_WACOM(0x64) },4999 { USB_DEVICE_WACOM(0x65) },5000 { USB_DEVICE_WACOM(0x69) },5001 { USB_DEVICE_WACOM(0x6A) },5002 { USB_DEVICE_WACOM(0x6B) },5003 { BT_DEVICE_WACOM(0x81) },5004 { USB_DEVICE_WACOM(0x84) },5005 { USB_DEVICE_WACOM(0x90) },5006 { USB_DEVICE_WACOM(0x93) },5007 { USB_DEVICE_WACOM(0x94) },5008 { USB_DEVICE_WACOM(0x97) },5009 { USB_DEVICE_WACOM(0x9A) },5010 { USB_DEVICE_WACOM(0x9F) },5011 { USB_DEVICE_WACOM(0xB0) },5012 { USB_DEVICE_WACOM(0xB1) },5013 { USB_DEVICE_WACOM(0xB2) },5014 { USB_DEVICE_WACOM(0xB3) },5015 { USB_DEVICE_WACOM(0xB4) },5016 { USB_DEVICE_WACOM(0xB5) },5017 { USB_DEVICE_WACOM(0xB7) },5018 { USB_DEVICE_WACOM(0xB8) },5019 { USB_DEVICE_WACOM(0xB9) },5020 { USB_DEVICE_WACOM(0xBA) },5021 { USB_DEVICE_WACOM(0xBB) },5022 { USB_DEVICE_WACOM(0xBC) },5023 { BT_DEVICE_WACOM(0xBD) },5024 { USB_DEVICE_WACOM(0xC0) },5025 { USB_DEVICE_WACOM(0xC2) },5026 { USB_DEVICE_WACOM(0xC4) },5027 { USB_DEVICE_WACOM(0xC5) },5028 { USB_DEVICE_WACOM(0xC6) },5029 { USB_DEVICE_WACOM(0xC7) },5030 { USB_DEVICE_WACOM(0xCC) },5031 { USB_DEVICE_WACOM(0xCE) },5032 { USB_DEVICE_WACOM(0xD0) },5033 { USB_DEVICE_WACOM(0xD1) },5034 { USB_DEVICE_WACOM(0xD2) },5035 { USB_DEVICE_WACOM(0xD3) },5036 { USB_DEVICE_WACOM(0xD4) },5037 { USB_DEVICE_WACOM(0xD5) },5038 { USB_DEVICE_WACOM(0xD6) },5039 { USB_DEVICE_WACOM(0xD7) },5040 { USB_DEVICE_WACOM(0xD8) },5041 { USB_DEVICE_WACOM(0xDA) },5042 { USB_DEVICE_WACOM(0xDB) },5043 { USB_DEVICE_WACOM(0xDD) },5044 { USB_DEVICE_WACOM(0xDE) },5045 { USB_DEVICE_WACOM(0xDF) },5046 { USB_DEVICE_WACOM(0xE2) },5047 { USB_DEVICE_WACOM(0xE3) },5048 { USB_DEVICE_WACOM(0xE5) },5049 { USB_DEVICE_WACOM(0xE6) },5050 { USB_DEVICE_WACOM(0xEC) },5051 { USB_DEVICE_WACOM(0xED) },5052 { USB_DEVICE_WACOM(0xEF) },5053 { USB_DEVICE_WACOM(0xF0) },5054 { USB_DEVICE_WACOM(0xF4) },5055 { USB_DEVICE_WACOM(0xF6) },5056 { USB_DEVICE_WACOM(0xF8) },5057 { USB_DEVICE_WACOM(0xFA) },5058 { USB_DEVICE_WACOM(0xFB) },5059 { USB_DEVICE_WACOM(0x100) },5060 { USB_DEVICE_WACOM(0x101) },5061 { USB_DEVICE_WACOM(0x10D) },5062 { USB_DEVICE_WACOM(0x10E) },5063 { USB_DEVICE_WACOM(0x10F) },5064 { USB_DEVICE_WACOM(0x116) },5065 { USB_DEVICE_WACOM(0x12C) },5066 { USB_DEVICE_WACOM(0x300) },5067 { USB_DEVICE_WACOM(0x301) },5068 { USB_DEVICE_WACOM(0x302) },5069 { USB_DEVICE_WACOM(0x303) },5070 { USB_DEVICE_WACOM(0x304) },5071 { USB_DEVICE_WACOM(0x307) },5072 { USB_DEVICE_WACOM(0x309) },5073 { USB_DEVICE_WACOM(0x30A) },5074 { USB_DEVICE_WACOM(0x30C) },5075 { USB_DEVICE_WACOM(0x30E) },5076 { USB_DEVICE_WACOM(0x314) },5077 { USB_DEVICE_WACOM(0x315) },5078 { USB_DEVICE_WACOM(0x317) },5079 { USB_DEVICE_WACOM(0x318) },5080 { USB_DEVICE_WACOM(0x319) },5081 { USB_DEVICE_WACOM(0x323) },5082 { USB_DEVICE_WACOM(0x325) },5083 { USB_DEVICE_WACOM(0x326) },5084 { USB_DEVICE_WACOM(0x32A) },5085 { USB_DEVICE_WACOM(0x32B) },5086 { USB_DEVICE_WACOM(0x32C) },5087 { USB_DEVICE_WACOM(0x32F) },5088 { USB_DEVICE_WACOM(0x331) },5089 { USB_DEVICE_WACOM(0x333) },5090 { USB_DEVICE_WACOM(0x335) },5091 { USB_DEVICE_WACOM(0x336) },5092 { USB_DEVICE_WACOM(0x33B) },5093 { USB_DEVICE_WACOM(0x33C) },5094 { USB_DEVICE_WACOM(0x33D) },5095 { USB_DEVICE_WACOM(0x33E) },5096 { USB_DEVICE_WACOM(0x343) },5097 { BT_DEVICE_WACOM(0x360) },5098 { BT_DEVICE_WACOM(0x361) },5099 { BT_DEVICE_WACOM(0x377) },5100 { BT_DEVICE_WACOM(0x379) },5101 { USB_DEVICE_WACOM(0x37A) },5102 { USB_DEVICE_WACOM(0x37B) },5103 { BT_DEVICE_WACOM(0x393) },5104 { BT_DEVICE_WACOM(0x3c6) },5105 { BT_DEVICE_WACOM(0x3c8) },5106 { BT_DEVICE_WACOM(0x3dd) },5107 { USB_DEVICE_WACOM(0x4001) },5108 { USB_DEVICE_WACOM(0x4004) },5109 { USB_DEVICE_WACOM(0x5000) },5110 { USB_DEVICE_WACOM(0x5002) },5111 { USB_DEVICE_LENOVO(0x6004) },5112 5113 { USB_DEVICE_WACOM(HID_ANY_ID) },5114 { I2C_DEVICE_WACOM(HID_ANY_ID) },5115 { BT_DEVICE_WACOM(HID_ANY_ID) },5116 { }5117};5118MODULE_DEVICE_TABLE(hid, wacom_ids);5119