@@ -1190,6 +1190,161 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom)
11901190 return count ;
11911191}
11921192
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+
11931348static int wacom_24hdt_irq (struct wacom_wac * wacom )
11941349{
11951350 struct input_dev * input = wacom -> touch_input ;
@@ -2667,6 +2822,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
26672822 sync = wacom_intuos_irq (wacom_wac );
26682823 break ;
26692824
2825+ case INTUOSP2_BT :
2826+ sync = wacom_intuos_pro2_bt_irq (wacom_wac , len );
2827+ break ;
2828+
26702829 case TABLETPC :
26712830 case TABLETPCE :
26722831 case TABLETPC2FG :
@@ -2838,6 +2997,13 @@ void wacom_setup_device_quirks(struct wacom *wacom)
28382997 if (features -> type == REMOTE )
28392998 features -> device_type = WACOM_DEVICETYPE_PAD ;
28402999
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+
28413007 switch (features -> type ) {
28423008 case PL :
28433009 case DTU :
@@ -2984,6 +3150,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
29843150 case INTUOSPL :
29853151 case INTUOS5S :
29863152 case INTUOSPS :
3153+ case INTUOSP2_BT :
29873154 input_set_abs_params (input_dev , ABS_DISTANCE , 0 ,
29883155 features -> distance_max ,
29893156 features -> distance_fuzz , 0 );
@@ -3092,6 +3259,27 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
30923259 }
30933260
30943261 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+
30953283 case INTUOS5 :
30963284 case INTUOS5L :
30973285 case INTUOSPM :
@@ -3389,6 +3577,7 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
33893577 case INTUOSPL :
33903578 case INTUOS5S :
33913579 case INTUOSPS :
3580+ case INTUOSP2_BT :
33923581 input_set_abs_params (input_dev , ABS_WHEEL , 0 , 71 , 0 , 0 );
33933582 break ;
33943583
@@ -3947,6 +4136,12 @@ static const struct wacom_features wacom_features_0x343 =
39474136 DTUS , WACOM_INTUOS_RES , WACOM_INTUOS_RES , 4 ,
39484137 WACOM_DTU_OFFSET , WACOM_DTU_OFFSET ,
39494138 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 };
39504145
39514146static const struct wacom_features wacom_features_HID_ANY_ID =
39524147 { "Wacom HID" , .type = HID_GENERIC , .oVid = HID_ANY_ID , .oPid = HID_ANY_ID };
@@ -4113,6 +4308,8 @@ const struct hid_device_id wacom_ids[] = {
41134308 { USB_DEVICE_WACOM (0x33D ) },
41144309 { USB_DEVICE_WACOM (0x33E ) },
41154310 { USB_DEVICE_WACOM (0x343 ) },
4311+ { BT_DEVICE_WACOM (0x360 ) },
4312+ { BT_DEVICE_WACOM (0x361 ) },
41164313 { USB_DEVICE_WACOM (0x4001 ) },
41174314 { USB_DEVICE_WACOM (0x4004 ) },
41184315 { USB_DEVICE_WACOM (0x5000 ) },
0 commit comments