@@ -1202,15 +1202,24 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
1202
1202
1203
1203
static void wacom_intuos_pro2_bt_pen (struct wacom_wac * wacom )
1204
1204
{
1205
- const int pen_frame_len = 14 ;
1206
- const int pen_frames = 7 ;
1205
+ int pen_frame_len , pen_frames ;
1207
1206
1208
1207
struct input_dev * pen_input = wacom -> pen_input ;
1209
1208
unsigned char * data = wacom -> data ;
1210
1209
int i ;
1211
1210
1212
- wacom -> serial [0 ] = get_unaligned_le64 (& data [99 ]);
1213
- wacom -> id [0 ] = get_unaligned_le16 (& data [107 ]);
1211
+ if (wacom -> features .type == INTUOSP2_BT ) {
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
1223
if (wacom -> serial [0 ] >> 52 == 1 ) {
1215
1224
/* Add back in missing bits of ID for non-USI pens */
1216
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
1236
continue ;
1228
1237
1229
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
1239
input_report_abs (pen_input , ABS_X , get_unaligned_le16 (& frame [1 ]));
1237
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 ]);
1239
- input_report_abs (pen_input , ABS_TILT_Y , (char )frame [8 ]);
1240
- input_report_abs (pen_input , ABS_Z , rotation );
1241
- input_report_abs (pen_input , ABS_WHEEL , get_unaligned_le16 (& frame [11 ]));
1241
+
1242
+ if (wacom -> features .type == INTUOSP2_BT ) {
1243
+ /* Fix rotation alignment: userspace expects zero at left */
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
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
1269
input_report_key (pen_input , BTN_TOUCH , frame [0 ] & 0x01 );
1247
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
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
1410
static int wacom_intuos_pro2_bt_irq (struct wacom_wac * wacom , size_t len )
1361
1411
{
1362
1412
unsigned char * data = wacom -> data ;
1363
1413
1364
- if (data [0 ] != 0x80 ) {
1414
+ if (data [0 ] != 0x80 && data [ 0 ] != 0x81 ) {
1365
1415
dev_dbg (wacom -> pen_input -> dev .parent ,
1366
1416
"%s: received unknown report #%d\n" , __func__ , data [0 ]);
1367
1417
return 0 ;
1368
1418
}
1369
1419
1370
1420
wacom_intuos_pro2_bt_pen (wacom );
1371
- wacom_intuos_pro2_bt_touch (wacom );
1372
- wacom_intuos_pro2_bt_pad (wacom );
1373
- wacom_intuos_pro2_bt_battery (wacom );
1421
+ if (wacom -> features .type == INTUOSP2_BT ) {
1422
+ wacom_intuos_pro2_bt_touch (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
1429
return 0 ;
1375
1430
}
1376
1431
@@ -1660,7 +1715,8 @@ int wacom_equivalent_usage(int usage)
1660
1715
usage == WACOM_HID_WD_TOUCHSTRIP ||
1661
1716
usage == WACOM_HID_WD_TOUCHSTRIP2 ||
1662
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
1720
return usage ;
1665
1721
}
1666
1722
@@ -2017,15 +2073,15 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev,
2017
2073
}
2018
2074
2019
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
2078
struct wacom * wacom = hid_get_drvdata (hdev );
2023
2079
struct wacom_wac * wacom_wac = & wacom -> wacom_wac ;
2024
2080
struct input_dev * input = wacom_wac -> pad_input ;
2025
2081
bool active = wacom_wac -> hid_data .inrange_state != 0 ;
2026
2082
2027
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
2085
wacom_wac -> hid_data .pad_input_event_flag ) {
2030
2086
input_event (input , EV_ABS , ABS_MISC , active ? PAD_DEVICE_ID : 0 );
2031
2087
input_sync (input );
@@ -2144,6 +2200,9 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
2144
2200
struct input_dev * input = wacom_wac -> pen_input ;
2145
2201
unsigned equivalent_usage = wacom_equivalent_usage (usage -> hid );
2146
2202
2203
+ if (wacom_wac -> is_invalid_bt_frame )
2204
+ return ;
2205
+
2147
2206
switch (equivalent_usage ) {
2148
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
2299
features -> offset_bottom );
2241
2300
features -> offset_bottom = value ;
2242
2301
return ;
2302
+ case WACOM_HID_WD_REPORT_VALID :
2303
+ wacom_wac -> is_invalid_bt_frame = !value ;
2304
+ return ;
2243
2305
}
2244
2306
2245
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
2320
static void wacom_wac_pen_pre_report (struct hid_device * hdev ,
2259
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
2327
return ;
2262
2328
}
2263
2329
@@ -2270,6 +2336,9 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
2270
2336
bool range = wacom_wac -> hid_data .inrange_state ;
2271
2337
bool sense = wacom_wac -> hid_data .sense_state ;
2272
2338
2339
+ if (wacom_wac -> is_invalid_bt_frame )
2340
+ return ;
2341
+
2273
2342
if (!wacom_wac -> tool [0 ] && range ) { /* first in range */
2274
2343
/* Going into range select tool */
2275
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
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
2648
int r ;
2578
2649
2579
- for (r = 0 ; r < report -> maxfield ; r ++ ) {
2650
+ for (r = field_index ; r < report -> maxfield ; r ++ ) {
2580
2651
struct hid_field * field ;
2581
2652
unsigned count , n ;
2582
2653
@@ -2586,30 +2657,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo
2586
2657
if (!(HID_MAIN_ITEM_VARIABLE & field -> flags ))
2587
2658
continue ;
2588
2659
2589
- for (n = 0 ; n < count ; n ++ )
2590
- wacom_wac_event (hdev , field , & field -> usage [n ], field -> value [n ]);
2660
+ for (n = 0 ; n < count ; 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
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 )
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 );
2676
+ wacom_report_events (hdev , report , collection_index , field_index );
2613
2677
2614
2678
/*
2615
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
2683
* processing functions.
2620
2684
*/
2621
2685
if (report -> type != HID_INPUT_REPORT )
2622
- return ;
2623
-
2624
- wacom_wac_battery_report (hdev , report );
2686
+ return -1 ;
2625
2687
2626
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
2690
else if (WACOM_PEN_FIELD (field ) && wacom -> wacom_wac .pen_input )
2629
2691
wacom_wac_pen_report (hdev , report );
2630
2692
else if (WACOM_FINGER_FIELD (field ) && wacom -> wacom_wac .touch_input )
2631
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
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
3204
break ;
3094
3205
3095
3206
case INTUOSP2_BT :
3207
+ case INTUOSHT3_BT :
3096
3208
sync = wacom_intuos_pro2_bt_irq (wacom_wac , len );
3097
3209
break ;
3098
3210
@@ -3272,6 +3384,12 @@ void wacom_setup_device_quirks(struct wacom *wacom)
3272
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
3393
switch (features -> type ) {
3276
3394
case PL :
3277
3395
case DTU :
@@ -3466,7 +3584,9 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
3466
3584
case BAMBOO_PT :
3467
3585
case BAMBOO_PEN :
3468
3586
case INTUOSHT2 :
3469
- if (features -> type == INTUOSHT2 ) {
3587
+ case INTUOSHT3_BT :
3588
+ if (features -> type == INTUOSHT2 ||
3589
+ features -> type == INTUOSHT3_BT ) {
3470
3590
wacom_setup_basic_pro_pen (wacom_wac );
3471
3591
} else {
3472
3592
__clear_bit (ABS_MISC , input_dev -> absbit );
@@ -3887,6 +4007,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
3887
4007
input_set_abs_params (input_dev , ABS_WHEEL , 0 , 71 , 0 , 0 );
3888
4008
break ;
3889
4009
4010
+ case INTUOSHT3_BT :
3890
4011
case HID_GENERIC :
3891
4012
break ;
3892
4013
@@ -4415,6 +4536,12 @@ static const struct wacom_features wacom_features_0x360 =
4415
4536
static const struct wacom_features wacom_features_0x361 =
4416
4537
{ "Wacom Intuos Pro L" , 62200 , 43200 , 8191 , 63 ,
4417
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
4545
static const struct wacom_features wacom_features_0x37A =
4419
4546
{ "Wacom One by Wacom S" , 15200 , 9500 , 2047 , 63 ,
4420
4547
BAMBOO_PEN , WACOM_INTUOS_RES , WACOM_INTUOS_RES };
@@ -4589,6 +4716,8 @@ const struct hid_device_id wacom_ids[] = {
4589
4716
{ USB_DEVICE_WACOM (0x343 ) },
4590
4717
{ BT_DEVICE_WACOM (0x360 ) },
4591
4718
{ BT_DEVICE_WACOM (0x361 ) },
4719
+ { BT_DEVICE_WACOM (0x377 ) },
4720
+ { BT_DEVICE_WACOM (0x379 ) },
4592
4721
{ USB_DEVICE_WACOM (0x37A ) },
4593
4722
{ USB_DEVICE_WACOM (0x37B ) },
4594
4723
{ USB_DEVICE_WACOM (0x4001 ) },
0 commit comments