diff options
author | Aaron Armstrong Skomra <skomra@gmail.com> | 2018-03-06 13:48:33 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-03-07 09:21:44 -0500 |
commit | 87046b6c995c50c11c8bd4a71877df83f99b3516 (patch) | |
tree | 0db4d673a7a9f4e236f6136c4cc5fe3875d80856 | |
parent | 183b6366cf473ff0e706a6751adc082faa44843d (diff) |
HID: wacom: Add support for 3rd generation Intuos BT
Use the code path that predates generic device support.
Signed-off-by: Aaron Armstrong Skomra <skomra@gmail.com>
Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r-- | drivers/hid/wacom_wac.c | 113 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.h | 1 |
2 files changed, 94 insertions, 20 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 90c38a0523e9..d532c1ebf2ee 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 | ||
@@ -3093,6 +3148,7 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len) | |||
3093 | break; | 3148 | break; |
3094 | 3149 | ||
3095 | case INTUOSP2_BT: | 3150 | case INTUOSP2_BT: |
3151 | case INTUOSHT3_BT: | ||
3096 | sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); | 3152 | sync = wacom_intuos_pro2_bt_irq(wacom_wac, len); |
3097 | break; | 3153 | break; |
3098 | 3154 | ||
@@ -3272,6 +3328,12 @@ void wacom_setup_device_quirks(struct wacom *wacom) | |||
3272 | features->quirks |= WACOM_QUIRK_BATTERY; | 3328 | features->quirks |= WACOM_QUIRK_BATTERY; |
3273 | } | 3329 | } |
3274 | 3330 | ||
3331 | if (features->type == INTUOSHT3_BT) { | ||
3332 | features->device_type |= WACOM_DEVICETYPE_PEN | | ||
3333 | WACOM_DEVICETYPE_PAD; | ||
3334 | features->quirks |= WACOM_QUIRK_BATTERY; | ||
3335 | } | ||
3336 | |||
3275 | switch (features->type) { | 3337 | switch (features->type) { |
3276 | case PL: | 3338 | case PL: |
3277 | case DTU: | 3339 | case DTU: |
@@ -3466,7 +3528,9 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, | |||
3466 | case BAMBOO_PT: | 3528 | case BAMBOO_PT: |
3467 | case BAMBOO_PEN: | 3529 | case BAMBOO_PEN: |
3468 | case INTUOSHT2: | 3530 | case INTUOSHT2: |
3469 | if (features->type == INTUOSHT2) { | 3531 | case INTUOSHT3_BT: |
3532 | if (features->type == INTUOSHT2 || | ||
3533 | features->type == INTUOSHT3_BT) { | ||
3470 | wacom_setup_basic_pro_pen(wacom_wac); | 3534 | wacom_setup_basic_pro_pen(wacom_wac); |
3471 | } else { | 3535 | } else { |
3472 | __clear_bit(ABS_MISC, input_dev->absbit); | 3536 | __clear_bit(ABS_MISC, input_dev->absbit); |
@@ -3887,6 +3951,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); | 3951 | input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); |
3888 | break; | 3952 | break; |
3889 | 3953 | ||
3954 | case INTUOSHT3_BT: | ||
3890 | case HID_GENERIC: | 3955 | case HID_GENERIC: |
3891 | break; | 3956 | break; |
3892 | 3957 | ||
@@ -4415,6 +4480,12 @@ static const struct wacom_features wacom_features_0x360 = | |||
4415 | static const struct wacom_features wacom_features_0x361 = | 4480 | static const struct wacom_features wacom_features_0x361 = |
4416 | { "Wacom Intuos Pro L", 62200, 43200, 8191, 63, | 4481 | { "Wacom Intuos Pro L", 62200, 43200, 8191, 63, |
4417 | INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 }; | 4482 | INTUOSP2_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 9, .touch_max = 10 }; |
4483 | static const struct wacom_features wacom_features_0x377 = | ||
4484 | { "Wacom Intuos BT S", 15200, 9500, 4095, 63, | ||
4485 | INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; | ||
4486 | static const struct wacom_features wacom_features_0x379 = | ||
4487 | { "Wacom Intuos BT M", 21600, 13500, 4095, 63, | ||
4488 | INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 }; | ||
4418 | static const struct wacom_features wacom_features_0x37A = | 4489 | static const struct wacom_features wacom_features_0x37A = |
4419 | { "Wacom One by Wacom S", 15200, 9500, 2047, 63, | 4490 | { "Wacom One by Wacom S", 15200, 9500, 2047, 63, |
4420 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 4491 | BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -4589,6 +4660,8 @@ const struct hid_device_id wacom_ids[] = { | |||
4589 | { USB_DEVICE_WACOM(0x343) }, | 4660 | { USB_DEVICE_WACOM(0x343) }, |
4590 | { BT_DEVICE_WACOM(0x360) }, | 4661 | { BT_DEVICE_WACOM(0x360) }, |
4591 | { BT_DEVICE_WACOM(0x361) }, | 4662 | { BT_DEVICE_WACOM(0x361) }, |
4663 | { BT_DEVICE_WACOM(0x377) }, | ||
4664 | { BT_DEVICE_WACOM(0x379) }, | ||
4592 | { USB_DEVICE_WACOM(0x37A) }, | 4665 | { USB_DEVICE_WACOM(0x37A) }, |
4593 | { USB_DEVICE_WACOM(0x37B) }, | 4666 | { USB_DEVICE_WACOM(0x37B) }, |
4594 | { USB_DEVICE_WACOM(0x4001) }, | 4667 | { USB_DEVICE_WACOM(0x4001) }, |
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 15d9c14fbdf7..827d8fc4a3f2 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h | |||
@@ -213,6 +213,7 @@ enum { | |||
213 | INTUOSPM, | 213 | INTUOSPM, |
214 | INTUOSPL, | 214 | INTUOSPL, |
215 | INTUOSP2_BT, | 215 | INTUOSP2_BT, |
216 | INTUOSHT3_BT, | ||
216 | WACOM_21UX2, | 217 | WACOM_21UX2, |
217 | WACOM_22HD, | 218 | WACOM_22HD, |
218 | DTK, | 219 | DTK, |