diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2018-04-05 07:28:59 -0400 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2018-04-05 07:28:59 -0400 |
| commit | 9931753b6c5ebf78ad0b8cb056234369f0b3c561 (patch) | |
| tree | 5dd29dd7ce43c911dbda8cda71158d46f3ceea68 | |
| parent | e2d39e0f95cb414b1fb6530f8429ad411586922b (diff) | |
| parent | 7ba8fc0904e3cdfe5b02aaf6fa8fcdb76ad67b0f (diff) | |
Merge branch 'for-4.17/wacom' into for-linus
Pull support for 3rd generation Intuos BT device
| -rw-r--r-- | drivers/hid/wacom_wac.c | 223 | ||||
| -rw-r--r-- | drivers/hid/wacom_wac.h | 4 |
2 files changed, 179 insertions, 48 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 90c38a0523e9..6da16a879c9f 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c | |||
| @@ -1202,15 +1202,24 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) | |||
| 1202 | 1202 | ||
| 1203 | static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) | 1203 | static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) |
| 1204 | { | 1204 | { |
| 1205 | const int pen_frame_len = 14; | 1205 | int pen_frame_len, pen_frames; |
| 1206 | const int pen_frames = 7; | ||
| 1207 | 1206 | ||
| 1208 | struct input_dev *pen_input = wacom->pen_input; | 1207 | struct input_dev *pen_input = wacom->pen_input; |
| 1209 | unsigned char *data = wacom->data; | 1208 | unsigned char *data = wacom->data; |
| 1210 | int i; | 1209 | int i; |
| 1211 | 1210 | ||
| 1212 | wacom->serial[0] = get_unaligned_le64(&data[99]); | 1211 | if (wacom->features.type == INTUOSP2_BT) { |
| 1213 | wacom->id[0] = get_unaligned_le16(&data[107]); | 1212 | wacom->serial[0] = get_unaligned_le64(&data[99]); |
| 1213 | wacom->id[0] = get_unaligned_le16(&data[107]); | ||
| 1214 | pen_frame_len = 14; | ||
| 1215 | pen_frames = 7; | ||
| 1216 | } else { | ||
| 1217 | wacom->serial[0] = get_unaligned_le64(&data[33]); | ||
| 1218 | wacom->id[0] = get_unaligned_le16(&data[41]); | ||
| 1219 | pen_frame_len = 8; | ||
| 1220 | pen_frames = 4; | ||
| 1221 | } | ||
| 1222 | |||
| 1214 | if (wacom->serial[0] >> 52 == 1) { | 1223 | if (wacom->serial[0] >> 52 == 1) { |
| 1215 | /* Add back in missing bits of ID for non-USI pens */ | 1224 | /* Add back in missing bits of ID for non-USI pens */ |
| 1216 | wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; | 1225 | wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF; |
| @@ -1227,21 +1236,35 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) | |||
| 1227 | continue; | 1236 | continue; |
| 1228 | 1237 | ||
| 1229 | if (range) { | 1238 | if (range) { |
| 1230 | /* Fix rotation alignment: userspace expects zero at left */ | ||
| 1231 | int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); | ||
| 1232 | rotation += 1800/4; | ||
| 1233 | if (rotation > 899) | ||
| 1234 | rotation -= 1800; | ||
| 1235 | |||
| 1236 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); | 1239 | input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); |
| 1237 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); | 1240 | input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); |
| 1238 | input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); | 1241 | |
| 1239 | input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); | 1242 | if (wacom->features.type == INTUOSP2_BT) { |
| 1240 | input_report_abs(pen_input, ABS_Z, rotation); | 1243 | /* Fix rotation alignment: userspace expects zero at left */ |
| 1241 | input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); | 1244 | int16_t rotation = |
| 1245 | (int16_t)get_unaligned_le16(&frame[9]); | ||
| 1246 | rotation += 1800/4; | ||
| 1247 | |||
| 1248 | if (rotation > 899) | ||
| 1249 | rotation -= 1800; | ||
| 1250 | |||
| 1251 | input_report_abs(pen_input, ABS_TILT_X, | ||
| 1252 | (char)frame[7]); | ||
| 1253 | input_report_abs(pen_input, ABS_TILT_Y, | ||
| 1254 | (char)frame[8]); | ||
| 1255 | input_report_abs(pen_input, ABS_Z, rotation); | ||
| 1256 | input_report_abs(pen_input, ABS_WHEEL, | ||
| 1257 | get_unaligned_le16(&frame[11])); | ||
| 1258 | } | ||
| 1242 | } | 1259 | } |
| 1243 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); | 1260 | input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); |
| 1244 | input_report_abs(pen_input, ABS_DISTANCE, range ? frame[13] : wacom->features.distance_max); | 1261 | if (wacom->features.type == INTUOSP2_BT) { |
| 1262 | input_report_abs(pen_input, ABS_DISTANCE, | ||
| 1263 | range ? frame[13] : wacom->features.distance_max); | ||
| 1264 | } else { | ||
| 1265 | input_report_abs(pen_input, ABS_DISTANCE, | ||
| 1266 | range ? frame[7] : wacom->features.distance_max); | ||
| 1267 | } | ||
| 1245 | 1268 | ||
| 1246 | input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01); | 1269 | input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01); |
| 1247 | input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02); | 1270 | input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02); |
| @@ -1357,20 +1380,52 @@ static void wacom_intuos_pro2_bt_battery(struct wacom_wac *wacom) | |||
| 1357 | battery_status, chg, 1, chg); | 1380 | battery_status, chg, 1, chg); |
| 1358 | } | 1381 | } |
| 1359 | 1382 | ||
| 1383 | static void wacom_intuos_gen3_bt_pad(struct wacom_wac *wacom) | ||
| 1384 | { | ||
| 1385 | struct input_dev *pad_input = wacom->pad_input; | ||
| 1386 | unsigned char *data = wacom->data; | ||
| 1387 | |||
| 1388 | int buttons = data[44]; | ||
| 1389 | |||
| 1390 | wacom_report_numbered_buttons(pad_input, 4, buttons); | ||
| 1391 | |||
| 1392 | input_report_key(pad_input, wacom->tool[1], buttons ? 1 : 0); | ||
| 1393 | input_report_abs(pad_input, ABS_MISC, buttons ? PAD_DEVICE_ID : 0); | ||
| 1394 | input_event(pad_input, EV_MSC, MSC_SERIAL, 0xffffffff); | ||
| 1395 | |||
| 1396 | input_sync(pad_input); | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | static void wacom_intuos_gen3_bt_battery(struct wacom_wac *wacom) | ||
| 1400 | { | ||
| 1401 | unsigned char *data = wacom->data; | ||
| 1402 | |||
| 1403 | bool chg = data[45] & 0x80; | ||
| 1404 | int battery_status = data[45] & 0x7F; | ||
| 1405 | |||
| 1406 | wacom_notify_battery(wacom, WACOM_POWER_SUPPLY_STATUS_AUTO, | ||
| 1407 | battery_status, chg, 1, chg); | ||
| 1408 | } | ||
| 1409 | |||
| 1360 | static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len) | 1410 | static int wacom_intuos_pro2_bt_irq(struct wacom_wac *wacom, size_t len) |
| 1361 | { | 1411 | { |
| 1362 | unsigned char *data = wacom->data; | 1412 | unsigned char *data = wacom->data; |
| 1363 | 1413 | ||
| 1364 | if (data[0] != 0x80) { | 1414 | if (data[0] != 0x80 && data[0] != 0x81) { |
| 1365 | dev_dbg(wacom->pen_input->dev.parent, | 1415 | dev_dbg(wacom->pen_input->dev.parent, |
| 1366 | "%s: received unknown report #%d\n", __func__, data[0]); | 1416 | "%s: received unknown report #%d\n", __func__, data[0]); |
| 1367 | return 0; | 1417 | return 0; |
| 1368 | } | 1418 | } |
| 1369 | 1419 | ||
| 1370 | wacom_intuos_pro2_bt_pen(wacom); | 1420 | wacom_intuos_pro2_bt_pen(wacom); |
| 1371 | wacom_intuos_pro2_bt_touch(wacom); | 1421 | if (wacom->features.type == INTUOSP2_BT) { |
| 1372 | wacom_intuos_pro2_bt_pad(wacom); | 1422 | wacom_intuos_pro2_bt_touch(wacom); |
| 1373 | wacom_intuos_pro2_bt_battery(wacom); | 1423 | wacom_intuos_pro2_bt_pad(wacom); |
| 1424 | wacom_intuos_pro2_bt_battery(wacom); | ||
| 1425 | } else { | ||
| 1426 | wacom_intuos_gen3_bt_pad(wacom); | ||
| 1427 | wacom_intuos_gen3_bt_battery(wacom); | ||
| 1428 | } | ||
| 1374 | return 0; | 1429 | return 0; |
| 1375 | } | 1430 | } |
| 1376 | 1431 | ||
| @@ -1660,7 +1715,8 @@ int wacom_equivalent_usage(int usage) | |||
| 1660 | usage == WACOM_HID_WD_TOUCHSTRIP || | 1715 | usage == WACOM_HID_WD_TOUCHSTRIP || |
| 1661 | usage == WACOM_HID_WD_TOUCHSTRIP2 || | 1716 | usage == WACOM_HID_WD_TOUCHSTRIP2 || |
| 1662 | usage == WACOM_HID_WD_TOUCHRING || | 1717 | usage == WACOM_HID_WD_TOUCHRING || |
| 1663 | usage == WACOM_HID_WD_TOUCHRINGSTATUS) { | 1718 | usage == WACOM_HID_WD_TOUCHRINGSTATUS || |
| 1719 | usage == WACOM_HID_WD_REPORT_VALID) { | ||
| 1664 | return usage; | 1720 | return usage; |
| 1665 | } | 1721 | } |
| 1666 | 1722 | ||
| @@ -2017,7 +2073,7 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev, | |||
| 2017 | } | 2073 | } |
| 2018 | 2074 | ||
| 2019 | static void wacom_wac_pad_report(struct hid_device *hdev, | 2075 | static void wacom_wac_pad_report(struct hid_device *hdev, |
| 2020 | struct hid_report *report) | 2076 | struct hid_report *report, struct hid_field *field) |
| 2021 | { | 2077 | { |
| 2022 | struct wacom *wacom = hid_get_drvdata(hdev); | 2078 | struct wacom *wacom = hid_get_drvdata(hdev); |
| 2023 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | 2079 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; |
| @@ -2025,7 +2081,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev, | |||
| 2025 | bool active = wacom_wac->hid_data.inrange_state != 0; | 2081 | bool active = wacom_wac->hid_data.inrange_state != 0; |
| 2026 | 2082 | ||
| 2027 | /* report prox for expresskey events */ | 2083 | /* report prox for expresskey events */ |
| 2028 | if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) && | 2084 | if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) && |
| 2029 | wacom_wac->hid_data.pad_input_event_flag) { | 2085 | wacom_wac->hid_data.pad_input_event_flag) { |
| 2030 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); | 2086 | input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); |
| 2031 | input_sync(input); | 2087 | input_sync(input); |
| @@ -2144,6 +2200,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field | |||
| 2144 | struct input_dev *input = wacom_wac->pen_input; | 2200 | struct input_dev *input = wacom_wac->pen_input; |
| 2145 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); | 2201 | unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); |
| 2146 | 2202 | ||
| 2203 | if (wacom_wac->is_invalid_bt_frame) | ||
| 2204 | return; | ||
| 2205 | |||
| 2147 | switch (equivalent_usage) { | 2206 | switch (equivalent_usage) { |
| 2148 | case HID_GD_Z: | 2207 | case HID_GD_Z: |
| 2149 | /* | 2208 | /* |
| @@ -2240,6 +2299,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field | |||
| 2240 | features->offset_bottom); | 2299 | features->offset_bottom); |
| 2241 | features->offset_bottom = value; | 2300 | features->offset_bottom = value; |
| 2242 | return; | 2301 | return; |
| 2302 | case WACOM_HID_WD_REPORT_VALID: | ||
| 2303 | wacom_wac->is_invalid_bt_frame = !value; | ||
| 2304 | return; | ||
| 2243 | } | 2305 | } |
| 2244 | 2306 | ||
| 2245 | /* send pen events only when touch is up or forced out | 2307 | /* send pen events only when touch is up or forced out |
| @@ -2258,6 +2320,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field | |||
| 2258 | static void wacom_wac_pen_pre_report(struct hid_device *hdev, | 2320 | static void wacom_wac_pen_pre_report(struct hid_device *hdev, |
| 2259 | struct hid_report *report) | 2321 | struct hid_report *report) |
| 2260 | { | 2322 | { |
| 2323 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
| 2324 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 2325 | |||
| 2326 | wacom_wac->is_invalid_bt_frame = false; | ||
| 2261 | return; | 2327 | return; |
| 2262 | } | 2328 | } |
| 2263 | 2329 | ||
| @@ -2270,6 +2336,9 @@ static void wacom_wac_pen_report(struct hid_device *hdev, | |||
| 2270 | bool range = wacom_wac->hid_data.inrange_state; | 2336 | bool range = wacom_wac->hid_data.inrange_state; |
| 2271 | bool sense = wacom_wac->hid_data.sense_state; | 2337 | bool sense = wacom_wac->hid_data.sense_state; |
| 2272 | 2338 | ||
| 2339 | if (wacom_wac->is_invalid_bt_frame) | ||
| 2340 | return; | ||
| 2341 | |||
| 2273 | if (!wacom_wac->tool[0] && range) { /* first in range */ | 2342 | if (!wacom_wac->tool[0] && range) { /* first in range */ |
| 2274 | /* Going into range select tool */ | 2343 | /* Going into range select tool */ |
| 2275 | if (wacom_wac->hid_data.invert_state) | 2344 | if (wacom_wac->hid_data.invert_state) |
| @@ -2572,11 +2641,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field, | |||
| 2572 | wacom_wac_finger_event(hdev, field, usage, value); | 2641 | wacom_wac_finger_event(hdev, field, usage, value); |
| 2573 | } | 2642 | } |
| 2574 | 2643 | ||
| 2575 | static void wacom_report_events(struct hid_device *hdev, struct hid_report *report) | 2644 | static void wacom_report_events(struct hid_device *hdev, |
| 2645 | struct hid_report *report, int collection_index, | ||
| 2646 | int field_index) | ||
| 2576 | { | 2647 | { |
| 2577 | int r; | 2648 | int r; |
| 2578 | 2649 | ||
| 2579 | for (r = 0; r < report->maxfield; r++) { | 2650 | for (r = field_index; r < report->maxfield; r++) { |
| 2580 | struct hid_field *field; | 2651 | struct hid_field *field; |
| 2581 | unsigned count, n; | 2652 | unsigned count, n; |
| 2582 | 2653 | ||
| @@ -2586,30 +2657,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo | |||
| 2586 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) | 2657 | if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) |
| 2587 | continue; | 2658 | continue; |
| 2588 | 2659 | ||
| 2589 | for (n = 0; n < count; n++) | 2660 | for (n = 0 ; n < count; n++) { |
| 2590 | wacom_wac_event(hdev, field, &field->usage[n], field->value[n]); | 2661 | if (field->usage[n].collection_index == collection_index) |
| 2662 | wacom_wac_event(hdev, field, &field->usage[n], | ||
| 2663 | field->value[n]); | ||
| 2664 | else | ||
| 2665 | return; | ||
| 2666 | } | ||
| 2591 | } | 2667 | } |
| 2592 | } | 2668 | } |
| 2593 | 2669 | ||
| 2594 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | 2670 | static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, |
| 2671 | int collection_index, struct hid_field *field, | ||
| 2672 | int field_index) | ||
| 2595 | { | 2673 | { |
| 2596 | struct wacom *wacom = hid_get_drvdata(hdev); | 2674 | struct wacom *wacom = hid_get_drvdata(hdev); |
| 2597 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 2598 | struct hid_field *field = report->field[0]; | ||
| 2599 | 2675 | ||
| 2600 | if (wacom_wac->features.type != HID_GENERIC) | 2676 | wacom_report_events(hdev, report, collection_index, field_index); |
| 2601 | return; | ||
| 2602 | |||
| 2603 | wacom_wac_battery_pre_report(hdev, report); | ||
| 2604 | |||
| 2605 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) | ||
| 2606 | wacom_wac_pad_pre_report(hdev, report); | ||
| 2607 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) | ||
| 2608 | wacom_wac_pen_pre_report(hdev, report); | ||
| 2609 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) | ||
| 2610 | wacom_wac_finger_pre_report(hdev, report); | ||
| 2611 | |||
| 2612 | wacom_report_events(hdev, report); | ||
| 2613 | 2677 | ||
| 2614 | /* | 2678 | /* |
| 2615 | * Non-input reports may be sent prior to the device being | 2679 | * Non-input reports may be sent prior to the device being |
| @@ -2619,16 +2683,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | |||
| 2619 | * processing functions. | 2683 | * processing functions. |
| 2620 | */ | 2684 | */ |
| 2621 | if (report->type != HID_INPUT_REPORT) | 2685 | if (report->type != HID_INPUT_REPORT) |
| 2622 | return; | 2686 | return -1; |
| 2623 | |||
| 2624 | wacom_wac_battery_report(hdev, report); | ||
| 2625 | 2687 | ||
| 2626 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) | 2688 | if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) |
| 2627 | wacom_wac_pad_report(hdev, report); | 2689 | wacom_wac_pad_report(hdev, report, field); |
| 2628 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) | 2690 | else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) |
| 2629 | wacom_wac_pen_report(hdev, report); | 2691 | wacom_wac_pen_report(hdev, report); |
| 2630 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) | 2692 | else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) |
| 2631 | wacom_wac_finger_report(hdev, report); | 2693 | wacom_wac_finger_report(hdev, report); |
| 2694 | |||
| 2695 | return 0; | ||
| 2696 | } | ||
| 2697 | |||
| 2698 | void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) | ||
| 2699 | { | ||
| 2700 | struct wacom *wacom = hid_get_drvdata(hdev); | ||
| 2701 | struct wacom_wac *wacom_wac = &wacom->wacom_wac; | ||
| 2702 | struct hid_field *field; | ||
| 2703 | bool pad_in_hid_field = false, pen_in_hid_field = false, | ||
| 2704 | finger_in_hid_field = false; | ||
| 2705 | int r; | ||
| 2706 | int prev_collection = -1; | ||
| 2707 | |||
| 2708 | if (wacom_wac->features.type != HID_GENERIC) | ||
| 2709 | return; | ||
| 2710 | |||
| 2711 | for (r = 0; r < report->maxfield; r++) { | ||
| 2712 | field = report->field[r]; | ||
| 2713 | |||
| 2714 | if (WACOM_PAD_FIELD(field)) | ||
| 2715 | pad_in_hid_field = true; | ||
| 2716 | if (WACOM_PEN_FIELD(field)) | ||
| 2717 | pen_in_hid_field = true; | ||
| 2718 | if (WACOM_FINGER_FIELD(field)) | ||
| 2719 | finger_in_hid_field = true; | ||
| 2720 | } | ||
| 2721 | |||
| 2722 | wacom_wac_battery_pre_report(hdev, report); | ||
| 2723 | |||
| 2724 | if (pad_in_hid_field && wacom->wacom_wac.pad_input) | ||
| 2725 | wacom_wac_pad_pre_report(hdev, report); | ||
| 2726 | if (pen_in_hid_field && wacom->wacom_wac.pen_input) | ||
| 2727 | wacom_wac_pen_pre_report(hdev, report); | ||
| 2728 | if (finger_in_hid_field && wacom->wacom_wac.touch_input) | ||
| 2729 | wacom_wac_finger_pre_report(hdev, report); | ||
| 2730 | |||
| 2731 | for (r = 0; r < report->maxfield; r++) { | ||
| 2732 | field = report->field[r]; | ||
| 2733 | |||
| 2734 | if (field->usage[0].collection_index != prev_collection) { | ||
| 2735 | if (wacom_wac_collection(hdev, report, | ||
| 2736 | field->usage[0].collection_index, field, r) < 0) | ||
| 2737 | return; | ||
| 2738 | prev_collection = field->usage[0].collection_index; | ||
| 2739 | } | ||
| 2740 | } | ||
| 2741 | |||
| 2742 | wacom_wac_battery_report(hdev, report); | ||
| 2632 | } | 2743 | } |
| 2633 | 2744 | ||
| 2634 | static int wacom_bpt_touch(struct wacom_wac *wacom) | 2745 | static int wacom_bpt_touch(struct wacom_wac *wacom) |
| @@ -3093,6 +3204,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
| 3093 | break; | 3204 | break; |
| 3094 | 3205 | ||
| 3095 | case INTUOSP2_BT: | 3206 | case INTUOSP2_BT: |
| 3207 | case INTUOSHT3_BT: | ||
| 3096 | sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); | 3208 | sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); |
| 3097 | break; | 3209 | break; |
| 3098 | 3210 | ||
| @@ -3272,6 +3384,12 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
| 3272 | features->quirks |= WACOM_QUIRK_BATTERY; | 3384 | features->quirks |= WACOM_QUIRK_BATTERY; |
| 3273 | } | 3385 | } |
| 3274 | 3386 | ||
| 3387 | if (features->type == INTUOSHT3_BT) { | ||
| 3388 | features->device_type |= WACOM_DEVICETYPE_PEN | | ||
| 3389 | WACOM_DEVICETYPE_PAD; | ||
| 3390 | features->quirks |= WACOM_QUIRK_BATTERY; | ||
| 3391 | } | ||
| 3392 | |||
| 3275 | switch (features->type) { | 3393 | switch (features->type) { |
| 3276 | case PL: | 3394 | case PL: |
| 3277 | case DTU: | 3395 | case DTU: |
| @@ -3466,7 +3584,9 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, | |||
| 3466 | case BAMBOO_PT: | 3584 | case BAMBOO_PT: |
| 3467 | case BAMBOO_PEN: | 3585 | case BAMBOO_PEN: |
| 3468 | case INTUOSHT2: | 3586 | case INTUOSHT2: |
| 3469 | if (features->type == INTUOSHT2) { | 3587 | case INTUOSHT3_BT: |
| 3588 | if (features->type == INTUOSHT2 || | ||
| 3589 | features->type == INTUOSHT3_BT) { | ||
| 3470 | wacom_setup_basic_pro_pen(wacom_wac); | 3590 | wacom_setup_basic_pro_pen(wacom_wac); |
| 3471 | } else { | 3591 | } else { |
| 3472 | __clear_bit(ABS_MISC, input_dev->absbit); | 3592 | __clear_bit(ABS_MISC, input_dev->absbit); |
| @@ -3887,6 +4007,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, | |||
| 3887 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); | 4007 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
| 3888 | break; | 4008 | break; |
| 3889 | 4009 | ||
| 4010 | case INTUOSHT3_BT: | ||
| 3890 | case HID_GENERIC: | 4011 | case HID_GENERIC: |
| 3891 | break; | 4012 | break; |
| 3892 | 4013 | ||
| @@ -4415,6 +4536,12 @@ static const struct wacom_features wacom_features_0x360 = | |||
| 4415 | static const struct wacom_features wacom_features_0x361 = | 4536 | static const struct wacom_features wacom_features_0x361 = |
| 4416 | { "Wacom Intuos Pro L", 62200, 43200, 8191, 63, | 4537 | { "Wacom Intuos Pro L", 62200, 43200, 8191, 63, |
| 4417 | INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 }; | 4538 | INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 }; |
| 4539 | static const struct wacom_features wacom_features_0x377 = | ||
| 4540 | { "Wacom Intuos BT S", 15200, 9500, 4095, 63, | ||
| 4541 | INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; | ||
| 4542 | static const struct wacom_features wacom_features_0x379 = | ||
| 4543 | { "Wacom Intuos BT M", 21600, 13500, 4095, 63, | ||
| 4544 | INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; | ||
| 4418 | static const struct wacom_features wacom_features_0x37A = | 4545 | static const struct wacom_features wacom_features_0x37A = |
| 4419 | { "Wacom One by Wacom S", 15200, 9500, 2047, 63, | 4546 | { "Wacom One by Wacom S", 15200, 9500, 2047, 63, |
| 4420 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 4547 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
| @@ -4589,6 +4716,8 @@ const struct hid_device_id wacom_ids[] = { | |||
| 4589 | { USB_DEVICE_WACOM(0x343) }, | 4716 | { USB_DEVICE_WACOM(0x343) }, |
| 4590 | { BT_DEVICE_WACOM(0x360) }, | 4717 | { BT_DEVICE_WACOM(0x360) }, |
| 4591 | { BT_DEVICE_WACOM(0x361) }, | 4718 | { BT_DEVICE_WACOM(0x361) }, |
| 4719 | { BT_DEVICE_WACOM(0x377) }, | ||
| 4720 | { BT_DEVICE_WACOM(0x379) }, | ||
| 4592 | { USB_DEVICE_WACOM(0x37A) }, | 4721 | { USB_DEVICE_WACOM(0x37A) }, |
| 4593 | { USB_DEVICE_WACOM(0x37B) }, | 4722 | { USB_DEVICE_WACOM(0x37B) }, |
| 4594 | { USB_DEVICE_WACOM(0x4001) }, | 4723 | { USB_DEVICE_WACOM(0x4001) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 15d9c14fbdf7..295fd3718caa 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
| @@ -118,6 +118,7 @@ | |||
| 118 | #define WACOM_HID_WD_TOUCHSTRIP2 (WACOM_HID_UP_WACOMDIGITIZER | 0x0137) | 118 | #define WACOM_HID_WD_TOUCHSTRIP2 (WACOM_HID_UP_WACOMDIGITIZER | 0x0137) |
| 119 | #define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138) | 119 | #define WACOM_HID_WD_TOUCHRING (WACOM_HID_UP_WACOMDIGITIZER | 0x0138) |
| 120 | #define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139) | 120 | #define WACOM_HID_WD_TOUCHRINGSTATUS (WACOM_HID_UP_WACOMDIGITIZER | 0x0139) |
| 121 | #define WACOM_HID_WD_REPORT_VALID (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0) | ||
| 121 | #define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401) | 122 | #define WACOM_HID_WD_ACCELEROMETER_X (WACOM_HID_UP_WACOMDIGITIZER | 0x0401) |
| 122 | #define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402) | 123 | #define WACOM_HID_WD_ACCELEROMETER_Y (WACOM_HID_UP_WACOMDIGITIZER | 0x0402) |
| 123 | #define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403) | 124 | #define WACOM_HID_WD_ACCELEROMETER_Z (WACOM_HID_UP_WACOMDIGITIZER | 0x0403) |
| @@ -213,6 +214,7 @@ enum { | |||
| 213 | INTUOSPM, | 214 | INTUOSPM, |
| 214 | INTUOSPL, | 215 | INTUOSPL, |
| 215 | INTUOSP2_BT, | 216 | INTUOSP2_BT, |
| 217 | INTUOSHT3_BT, | ||
| 216 | WACOM_21UX2, | 218 | WACOM_21UX2, |
| 217 | WACOM_22HD, | 219 | WACOM_22HD, |
| 218 | DTK, | 220 | DTK, |
| @@ -352,7 +354,7 @@ struct wacom_wac { | |||
| 352 | bool has_mute_touch_switch; | 354 | bool has_mute_touch_switch; |
| 353 | bool has_mode_change; | 355 | bool has_mode_change; |
| 354 | bool is_direct_mode; | 356 | bool is_direct_mode; |
| 355 | 357 | bool is_invalid_bt_frame; | |
| 356 | }; | 358 | }; |
| 357 | 359 | ||
| 358 | #endif | 360 | #endif |
