@@ -1190,6 +1190,161 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
1190
1190
return count ;
1191
1191
}
1192
1192
1193
+ static void wacom_intuos_pro2_bt_pen (struct wacom_wac * wacom )
1194
+ {
1195
+ const int pen_frame_len = 14 ;
1196
+ const int pen_frames = 7 ;
1197
+
1198
+ struct input_dev * pen_input = wacom -> pen_input ;
1199
+ unsigned char * data = wacom -> data ;
1200
+ int i ;
1201
+
1202
+ wacom -> serial [0 ] = get_unaligned_le64 (& data [99 ]);
1203
+ wacom -> id [0 ] = get_unaligned_le16 (& data [107 ]);
1204
+ if (wacom -> serial [0 ] >> 52 == 1 ) {
1205
+ /* Add back in missing bits of ID for non-USI pens */
1206
+ wacom -> id [0 ] |= (wacom -> serial [0 ] >> 32 ) & 0xFFFFF ;
1207
+ }
1208
+ wacom -> tool [0 ] = wacom_intuos_get_tool_type (wacom_intuos_id_mangle (wacom -> id [0 ]));
1209
+
1210
+ for (i = 0 ; i < pen_frames ; i ++ ) {
1211
+ unsigned char * frame = & data [i * pen_frame_len + 1 ];
1212
+
1213
+ if (!(frame [0 ] & 0x80 ))
1214
+ continue ;
1215
+
1216
+ input_report_abs (pen_input , ABS_X , get_unaligned_le16 (& frame [1 ]));
1217
+ input_report_abs (pen_input , ABS_Y , get_unaligned_le16 (& frame [3 ]));
1218
+ input_report_abs (pen_input , ABS_PRESSURE , get_unaligned_le16 (& frame [5 ]));
1219
+ input_report_abs (pen_input , ABS_TILT_X , frame [7 ]);
1220
+ input_report_abs (pen_input , ABS_TILT_Y , frame [8 ]);
1221
+ input_report_abs (pen_input , ABS_Z , get_unaligned_le16 (& frame [9 ]));
1222
+ input_report_abs (pen_input , ABS_WHEEL , get_unaligned_le16 (& frame [11 ]));
1223
+ input_report_abs (pen_input , ABS_DISTANCE , frame [13 ]);
1224
+
1225
+ input_report_key (pen_input , BTN_TOUCH , frame [0 ] & 0x01 );
1226
+ input_report_key (pen_input , BTN_STYLUS , frame [0 ] & 0x02 );
1227
+ input_report_key (pen_input , BTN_STYLUS2 , frame [0 ] & 0x04 );
1228
+
1229
+ input_report_key (pen_input , wacom -> tool [0 ], 1 );
1230
+ input_event (pen_input , EV_MSC , MSC_SERIAL , wacom -> serial [0 ]);
1231
+ input_report_abs (pen_input , ABS_MISC ,
1232
+ wacom_intuos_id_mangle (wacom -> id [0 ])); /* report tool id */
1233
+
1234
+ wacom -> shared -> stylus_in_proximity = frame [0 ] & 0x40 ;
1235
+
1236
+ input_sync (pen_input );
1237
+ }
1238
+ }
1239
+
1240
+ static void wacom_intuos_pro2_bt_touch (struct wacom_wac * wacom )
1241
+ {
1242
+ const int finger_touch_len = 8 ;
1243
+ const int finger_frames = 4 ;
1244
+ const int finger_frame_len = 43 ;
1245
+
1246
+ struct input_dev * touch_input = wacom -> touch_input ;
1247
+ unsigned char * data = wacom -> data ;
1248
+ int num_contacts_left = 5 ;
1249
+ int i , j ;
1250
+
1251
+ for (i = 0 ; i < finger_frames ; i ++ ) {
1252
+ unsigned char * frame = & data [i * finger_frame_len + 109 ];
1253
+ int current_num_contacts = frame [0 ] & 0x7F ;
1254
+ int contacts_to_send ;
1255
+
1256
+ if (!(frame [0 ] & 0x80 ))
1257
+ continue ;
1258
+
1259
+ /*
1260
+ * First packet resets the counter since only the first
1261
+ * packet in series will have non-zero current_num_contacts.
1262
+ */
1263
+ if (current_num_contacts )
1264
+ wacom -> num_contacts_left = current_num_contacts ;
1265
+
1266
+ contacts_to_send = min (num_contacts_left , wacom -> num_contacts_left );
1267
+
1268
+ for (j = 0 ; j < contacts_to_send ; j ++ ) {
1269
+ unsigned char * touch = & frame [j * finger_touch_len + 1 ];
1270
+ int slot = input_mt_get_slot_by_key (touch_input , touch [0 ]);
1271
+ int x = get_unaligned_le16 (& touch [2 ]);
1272
+ int y = get_unaligned_le16 (& touch [4 ]);
1273
+ int w = touch [6 ] * input_abs_get_res (touch_input , ABS_MT_POSITION_X );
1274
+ int h = touch [7 ] * input_abs_get_res (touch_input , ABS_MT_POSITION_Y );
1275
+
1276
+ if (slot < 0 )
1277
+ continue ;
1278
+
1279
+ input_mt_slot (touch_input , slot );
1280
+ input_mt_report_slot_state (touch_input , MT_TOOL_FINGER , touch [1 ] & 0x01 );
1281
+ input_report_abs (touch_input , ABS_MT_POSITION_X , x );
1282
+ input_report_abs (touch_input , ABS_MT_POSITION_Y , y );
1283
+ input_report_abs (touch_input , ABS_MT_TOUCH_MAJOR , max (w , h ));
1284
+ input_report_abs (touch_input , ABS_MT_TOUCH_MINOR , min (w , h ));
1285
+ input_report_abs (touch_input , ABS_MT_ORIENTATION , w > h );
1286
+ }
1287
+
1288
+ input_mt_sync_frame (touch_input );
1289
+
1290
+ wacom -> num_contacts_left -= contacts_to_send ;
1291
+ if (wacom -> num_contacts_left <= 0 ) {
1292
+ wacom -> num_contacts_left = 0 ;
1293
+ wacom -> shared -> touch_down = wacom_wac_finger_count_touches (wacom );
1294
+ }
1295
+ }
1296
+
1297
+ input_report_switch (touch_input , SW_MUTE_DEVICE , !(data [281 ] >> 7 ));
1298
+ input_sync (touch_input );
1299
+ }
1300
+
1301
+ static void wacom_intuos_pro2_bt_pad (struct wacom_wac * wacom )
1302
+ {
1303
+ struct input_dev * pad_input = wacom -> pad_input ;
1304
+ unsigned char * data = wacom -> data ;
1305
+
1306
+ int buttons = (data [282 ] << 1 ) | ((data [281 ] >> 6 ) & 0x01 );
1307
+ int ring = data [285 ];
1308
+ int prox = buttons | (ring & 0x80 );
1309
+
1310
+ wacom_report_numbered_buttons (pad_input , 9 , buttons );
1311
+
1312
+ input_report_abs (pad_input , ABS_WHEEL , (ring & 0x80 ) ? (ring & 0x7f ) : 0 );
1313
+
1314
+ input_report_key (pad_input , wacom -> tool [1 ], prox ? 1 : 0 );
1315
+ input_report_abs (pad_input , ABS_MISC , prox ? PAD_DEVICE_ID : 0 );
1316
+ input_event (pad_input , EV_MSC , MSC_SERIAL , 0xffffffff );
1317
+
1318
+ input_sync (pad_input );
1319
+ }
1320
+
1321
+ static void wacom_intuos_pro2_bt_battery (struct wacom_wac * wacom )
1322
+ {
1323
+ unsigned char * data = wacom -> data ;
1324
+
1325
+ bool chg = data [284 ] & 0x80 ;
1326
+ int battery_status = data [284 ] & 0x7F ;
1327
+
1328
+ wacom_notify_battery (wacom , battery_status , chg , 1 , chg );
1329
+ }
1330
+
1331
+ static int wacom_intuos_pro2_bt_irq (struct wacom_wac * wacom , size_t len )
1332
+ {
1333
+ unsigned char * data = wacom -> data ;
1334
+
1335
+ if (data [0 ] != 0x80 ) {
1336
+ dev_dbg (wacom -> pen_input -> dev .parent ,
1337
+ "%s: received unknown report #%d\n" , __func__ , data [0 ]);
1338
+ return 0 ;
1339
+ }
1340
+
1341
+ wacom_intuos_pro2_bt_pen (wacom );
1342
+ wacom_intuos_pro2_bt_touch (wacom );
1343
+ wacom_intuos_pro2_bt_pad (wacom );
1344
+ wacom_intuos_pro2_bt_battery (wacom );
1345
+ return 0 ;
1346
+ }
1347
+
1193
1348
static int wacom_24hdt_irq (struct wacom_wac * wacom )
1194
1349
{
1195
1350
struct input_dev * input = wacom -> touch_input ;
@@ -2667,6 +2822,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
2667
2822
sync = wacom_intuos_irq (wacom_wac );
2668
2823
break ;
2669
2824
2825
+ case INTUOSP2_BT :
2826
+ sync = wacom_intuos_pro2_bt_irq (wacom_wac , len );
2827
+ break ;
2828
+
2670
2829
case TABLETPC :
2671
2830
case TABLETPCE :
2672
2831
case TABLETPC2FG :
@@ -2838,6 +2997,13 @@ void wacom_setup_device_quirks(struct wacom *wacom)
2838
2997
if (features -> type == REMOTE )
2839
2998
features -> device_type = WACOM_DEVICETYPE_PAD ;
2840
2999
3000
+ if (features -> type == INTUOSP2_BT ) {
3001
+ features -> device_type |= WACOM_DEVICETYPE_PEN |
3002
+ WACOM_DEVICETYPE_PAD |
3003
+ WACOM_DEVICETYPE_TOUCH ;
3004
+ features -> quirks |= WACOM_QUIRK_BATTERY ;
3005
+ }
3006
+
2841
3007
switch (features -> type ) {
2842
3008
case PL :
2843
3009
case DTU :
@@ -2984,6 +3150,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
2984
3150
case INTUOSPL :
2985
3151
case INTUOS5S :
2986
3152
case INTUOSPS :
3153
+ case INTUOSP2_BT :
2987
3154
input_set_abs_params (input_dev , ABS_DISTANCE , 0 ,
2988
3155
features -> distance_max ,
2989
3156
features -> distance_fuzz , 0 );
@@ -3092,6 +3259,27 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
3092
3259
}
3093
3260
3094
3261
switch (features -> type ) {
3262
+ case INTUOSP2_BT :
3263
+ input_dev -> evbit [0 ] |= BIT_MASK (EV_SW );
3264
+ __set_bit (SW_MUTE_DEVICE , input_dev -> swbit );
3265
+
3266
+ if (wacom_wac -> shared -> touch -> product == 0x361 ) {
3267
+ input_set_abs_params (input_dev , ABS_MT_POSITION_X ,
3268
+ 0 , 12440 , 4 , 0 );
3269
+ input_set_abs_params (input_dev , ABS_MT_POSITION_Y ,
3270
+ 0 , 8640 , 4 , 0 );
3271
+ }
3272
+ else if (wacom_wac -> shared -> touch -> product == 0x360 ) {
3273
+ input_set_abs_params (input_dev , ABS_MT_POSITION_X ,
3274
+ 0 , 8960 , 4 , 0 );
3275
+ input_set_abs_params (input_dev , ABS_MT_POSITION_Y ,
3276
+ 0 , 5920 , 4 , 0 );
3277
+ }
3278
+ input_abs_set_res (input_dev , ABS_MT_POSITION_X , 40 );
3279
+ input_abs_set_res (input_dev , ABS_MT_POSITION_X , 40 );
3280
+
3281
+ /* fall through */
3282
+
3095
3283
case INTUOS5 :
3096
3284
case INTUOS5L :
3097
3285
case INTUOSPM :
@@ -3389,6 +3577,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
3389
3577
case INTUOSPL :
3390
3578
case INTUOS5S :
3391
3579
case INTUOSPS :
3580
+ case INTUOSP2_BT :
3392
3581
input_set_abs_params (input_dev , ABS_WHEEL , 0 , 71 , 0 , 0 );
3393
3582
break ;
3394
3583
@@ -3947,6 +4136,12 @@ static const struct wacom_features wacom_features_0x343 =
3947
4136
DTUS , WACOM_INTUOS_RES , WACOM_INTUOS_RES , 4 ,
3948
4137
WACOM_DTU_OFFSET , WACOM_DTU_OFFSET ,
3949
4138
WACOM_DTU_OFFSET , WACOM_DTU_OFFSET };
4139
+ static const struct wacom_features wacom_features_0x360 =
4140
+ { "Wacom Intuos Pro M" , 44800 , 29600 , 8191 , 63 ,
4141
+ INTUOSP2_BT , WACOM_INTUOS_RES , WACOM_INTUOS_RES , 9 , .touch_max = 10 };
4142
+ static const struct wacom_features wacom_features_0x361 =
4143
+ { "Wacom Intuos Pro L" , 62200 , 43200 , 8191 , 63 ,
4144
+ INTUOSP2_BT , WACOM_INTUOS_RES , WACOM_INTUOS_RES , 9 , .touch_max = 10 };
3950
4145
3951
4146
static const struct wacom_features wacom_features_HID_ANY_ID =
3952
4147
{ "Wacom HID" , .type = HID_GENERIC , .oVid = HID_ANY_ID , .oPid = HID_ANY_ID };
@@ -4113,6 +4308,8 @@ const struct hid_device_id wacom_ids[] = {
4113
4308
{ USB_DEVICE_WACOM (0x33D ) },
4114
4309
{ USB_DEVICE_WACOM (0x33E ) },
4115
4310
{ USB_DEVICE_WACOM (0x343 ) },
4311
+ { BT_DEVICE_WACOM (0x360 ) },
4312
+ { BT_DEVICE_WACOM (0x361 ) },
4116
4313
{ USB_DEVICE_WACOM (0x4001 ) },
4117
4314
{ USB_DEVICE_WACOM (0x4004 ) },
4118
4315
{ USB_DEVICE_WACOM (0x5000 ) },
0 commit comments