diff options
author | Jiri Kosina <jkosina@suse.cz> | 2018-04-05 07:28:34 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2018-04-05 07:28:34 -0400 |
commit | 108ff0e8012ae10708168940c7474318fb343751 (patch) | |
tree | 57b8936d4ec961d62c90af3c2a4c764a1b2d50c0 | |
parent | af73686e7bfe49fbbccc099995be8c78ce5bfe9a (diff) | |
parent | b7289cb1cf99d432c894b9da7a54e24f73ae4c93 (diff) |
Merge branch 'for-4.17/sony' into for-linus
Pull support for NSG-MR5U and NSG-MR7U devices.
-rw-r--r-- | drivers/hid/hid-ids.h | 3 | ||||
-rw-r--r-- | drivers/hid/hid-quirks.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 131 |
3 files changed, 130 insertions, 6 deletions
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 18933074e59a..77814cbe2d4c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -964,6 +964,9 @@ | |||
964 | 964 | ||
965 | #define USB_VENDOR_ID_SMK 0x0609 | 965 | #define USB_VENDOR_ID_SMK 0x0609 |
966 | #define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306 | 966 | #define USB_DEVICE_ID_SMK_PS3_BDREMOTE 0x0306 |
967 | #define USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE 0x0368 | ||
968 | #define USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE 0x0369 | ||
969 | |||
967 | 970 | ||
968 | #define USB_VENDOR_ID_SONY 0x054c | 971 | #define USB_VENDOR_ID_SONY 0x054c |
969 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b | 972 | #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b |
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 0176a927070a..c691d332f549 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c | |||
@@ -614,6 +614,8 @@ static const struct hid_device_id hid_have_special_driver[] = { | |||
614 | #if IS_ENABLED(CONFIG_HID_SONY) | 614 | #if IS_ENABLED(CONFIG_HID_SONY) |
615 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, | 615 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, |
616 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, | 616 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, |
617 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) }, | ||
618 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) }, | ||
617 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, | 619 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, |
618 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, | 620 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, |
619 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, | 621 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ccdc5f2d01b1..e475c5073c99 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * Copyright (c) 2006-2013 Jiri Kosina | 9 | * Copyright (c) 2006-2013 Jiri Kosina |
10 | * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> | 10 | * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com> |
11 | * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com> | 11 | * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com> |
12 | * Copyright (c) 2018 Todd Kelner | ||
12 | */ | 13 | */ |
13 | 14 | ||
14 | /* | 15 | /* |
@@ -55,6 +56,8 @@ | |||
55 | #define NAVIGATION_CONTROLLER_BT BIT(11) | 56 | #define NAVIGATION_CONTROLLER_BT BIT(11) |
56 | #define SINO_LITE_CONTROLLER BIT(12) | 57 | #define SINO_LITE_CONTROLLER BIT(12) |
57 | #define FUTUREMAX_DANCE_MAT BIT(13) | 58 | #define FUTUREMAX_DANCE_MAT BIT(13) |
59 | #define NSG_MR5U_REMOTE_BT BIT(14) | ||
60 | #define NSG_MR7U_REMOTE_BT BIT(15) | ||
58 | 61 | ||
59 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) | 62 | #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) |
60 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) | 63 | #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) |
@@ -72,8 +75,11 @@ | |||
72 | MOTION_CONTROLLER) | 75 | MOTION_CONTROLLER) |
73 | #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\ | 76 | #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_BT |\ |
74 | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) | 77 | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) |
78 | #define NSG_MRXU_REMOTE (NSG_MR5U_REMOTE_BT | NSG_MR7U_REMOTE_BT) | ||
75 | 79 | ||
76 | #define MAX_LEDS 4 | 80 | #define MAX_LEDS 4 |
81 | #define NSG_MRXU_MAX_X 1667 | ||
82 | #define NSG_MRXU_MAX_Y 1868 | ||
77 | 83 | ||
78 | 84 | ||
79 | /* PS/3 Motion controller */ | 85 | /* PS/3 Motion controller */ |
@@ -1098,6 +1104,80 @@ static void dualshock4_parse_report(struct sony_sc *sc, u8 *rd, int size) | |||
1098 | } | 1104 | } |
1099 | } | 1105 | } |
1100 | 1106 | ||
1107 | static void nsg_mrxu_parse_report(struct sony_sc *sc, u8 *rd, int size) | ||
1108 | { | ||
1109 | int n, offset, relx, rely; | ||
1110 | u8 active; | ||
1111 | |||
1112 | /* | ||
1113 | * The NSG-MRxU multi-touch trackpad data starts at offset 1 and | ||
1114 | * the touch-related data starts at offset 2. | ||
1115 | * For the first byte, bit 0 is set when touchpad button is pressed. | ||
1116 | * Bit 2 is set when a touch is active and the drag (Fn) key is pressed. | ||
1117 | * This drag key is mapped to BTN_LEFT. It is operational only when a | ||
1118 | * touch point is active. | ||
1119 | * Bit 4 is set when only the first touch point is active. | ||
1120 | * Bit 6 is set when only the second touch point is active. | ||
1121 | * Bits 5 and 7 are set when both touch points are active. | ||
1122 | * The next 3 bytes are two 12 bit X/Y coordinates for the first touch. | ||
1123 | * The following byte, offset 5, has the touch width and length. | ||
1124 | * Bits 0-4=X (width), bits 5-7=Y (length). | ||
1125 | * A signed relative X coordinate is at offset 6. | ||
1126 | * The bytes at offset 7-9 are the second touch X/Y coordinates. | ||
1127 | * Offset 10 has the second touch width and length. | ||
1128 | * Offset 11 has the relative Y coordinate. | ||
1129 | */ | ||
1130 | offset = 1; | ||
1131 | |||
1132 | input_report_key(sc->touchpad, BTN_LEFT, rd[offset] & 0x0F); | ||
1133 | active = (rd[offset] >> 4); | ||
1134 | relx = (s8) rd[offset+5]; | ||
1135 | rely = ((s8) rd[offset+10]) * -1; | ||
1136 | |||
1137 | offset++; | ||
1138 | |||
1139 | for (n = 0; n < 2; n++) { | ||
1140 | u16 x, y; | ||
1141 | u8 contactx, contacty; | ||
1142 | |||
1143 | x = rd[offset] | ((rd[offset+1] & 0x0F) << 8); | ||
1144 | y = ((rd[offset+1] & 0xF0) >> 4) | (rd[offset+2] << 4); | ||
1145 | |||
1146 | input_mt_slot(sc->touchpad, n); | ||
1147 | input_mt_report_slot_state(sc->touchpad, MT_TOOL_FINGER, active & 0x03); | ||
1148 | |||
1149 | if (active & 0x03) { | ||
1150 | contactx = rd[offset+3] & 0x0F; | ||
1151 | contacty = rd[offset+3] >> 4; | ||
1152 | input_report_abs(sc->touchpad, ABS_MT_TOUCH_MAJOR, | ||
1153 | max(contactx, contacty)); | ||
1154 | input_report_abs(sc->touchpad, ABS_MT_TOUCH_MINOR, | ||
1155 | min(contactx, contacty)); | ||
1156 | input_report_abs(sc->touchpad, ABS_MT_ORIENTATION, | ||
1157 | (bool) (contactx > contacty)); | ||
1158 | input_report_abs(sc->touchpad, ABS_MT_POSITION_X, x); | ||
1159 | input_report_abs(sc->touchpad, ABS_MT_POSITION_Y, | ||
1160 | NSG_MRXU_MAX_Y - y); | ||
1161 | /* | ||
1162 | * The relative coordinates belong to the first touch | ||
1163 | * point, when present, or to the second touch point | ||
1164 | * when the first is not active. | ||
1165 | */ | ||
1166 | if ((n == 0) || ((n == 1) && (active & 0x01))) { | ||
1167 | input_report_rel(sc->touchpad, REL_X, relx); | ||
1168 | input_report_rel(sc->touchpad, REL_Y, rely); | ||
1169 | } | ||
1170 | } | ||
1171 | |||
1172 | offset += 5; | ||
1173 | active >>= 2; | ||
1174 | } | ||
1175 | |||
1176 | input_mt_sync_frame(sc->touchpad); | ||
1177 | |||
1178 | input_sync(sc->touchpad); | ||
1179 | } | ||
1180 | |||
1101 | static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | 1181 | static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, |
1102 | u8 *rd, int size) | 1182 | u8 *rd, int size) |
1103 | { | 1183 | { |
@@ -1206,6 +1286,10 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, | |||
1206 | } | 1286 | } |
1207 | 1287 | ||
1208 | dualshock4_parse_report(sc, rd, size); | 1288 | dualshock4_parse_report(sc, rd, size); |
1289 | |||
1290 | } else if ((sc->quirks & NSG_MRXU_REMOTE) && rd[0] == 0x02) { | ||
1291 | nsg_mrxu_parse_report(sc, rd, size); | ||
1292 | return 1; | ||
1209 | } | 1293 | } |
1210 | 1294 | ||
1211 | if (sc->defer_initialization) { | 1295 | if (sc->defer_initialization) { |
@@ -1263,7 +1347,7 @@ static int sony_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
1263 | } | 1347 | } |
1264 | 1348 | ||
1265 | static int sony_register_touchpad(struct sony_sc *sc, int touch_count, | 1349 | static int sony_register_touchpad(struct sony_sc *sc, int touch_count, |
1266 | int w, int h) | 1350 | int w, int h, int touch_major, int touch_minor, int orientation) |
1267 | { | 1351 | { |
1268 | size_t name_sz; | 1352 | size_t name_sz; |
1269 | char *name; | 1353 | char *name; |
@@ -1294,10 +1378,6 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count, | |||
1294 | snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); | 1378 | snprintf(name, name_sz, "%s" DS4_TOUCHPAD_SUFFIX, sc->hdev->name); |
1295 | sc->touchpad->name = name; | 1379 | sc->touchpad->name = name; |
1296 | 1380 | ||
1297 | ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER); | ||
1298 | if (ret < 0) | ||
1299 | goto err; | ||
1300 | |||
1301 | /* We map the button underneath the touchpad to BTN_LEFT. */ | 1381 | /* We map the button underneath the touchpad to BTN_LEFT. */ |
1302 | __set_bit(EV_KEY, sc->touchpad->evbit); | 1382 | __set_bit(EV_KEY, sc->touchpad->evbit); |
1303 | __set_bit(BTN_LEFT, sc->touchpad->keybit); | 1383 | __set_bit(BTN_LEFT, sc->touchpad->keybit); |
@@ -1306,6 +1386,25 @@ static int sony_register_touchpad(struct sony_sc *sc, int touch_count, | |||
1306 | input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0); | 1386 | input_set_abs_params(sc->touchpad, ABS_MT_POSITION_X, 0, w, 0, 0); |
1307 | input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0); | 1387 | input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0); |
1308 | 1388 | ||
1389 | if (touch_major > 0) { | ||
1390 | input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR, | ||
1391 | 0, touch_major, 0, 0); | ||
1392 | if (touch_minor > 0) | ||
1393 | input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR, | ||
1394 | 0, touch_minor, 0, 0); | ||
1395 | if (orientation > 0) | ||
1396 | input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION, | ||
1397 | 0, orientation, 0, 0); | ||
1398 | } | ||
1399 | |||
1400 | if (sc->quirks & NSG_MRXU_REMOTE) { | ||
1401 | __set_bit(EV_REL, sc->touchpad->evbit); | ||
1402 | } | ||
1403 | |||
1404 | ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER); | ||
1405 | if (ret < 0) | ||
1406 | goto err; | ||
1407 | |||
1309 | ret = input_register_device(sc->touchpad); | 1408 | ret = input_register_device(sc->touchpad); |
1310 | if (ret < 0) | 1409 | if (ret < 0) |
1311 | goto err; | 1410 | goto err; |
@@ -2690,7 +2789,7 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2690 | * The Dualshock 4 touchpad supports 2 touches and has a | 2789 | * The Dualshock 4 touchpad supports 2 touches and has a |
2691 | * resolution of 1920x942 (44.86 dots/mm). | 2790 | * resolution of 1920x942 (44.86 dots/mm). |
2692 | */ | 2791 | */ |
2693 | ret = sony_register_touchpad(sc, 2, 1920, 942); | 2792 | ret = sony_register_touchpad(sc, 2, 1920, 942, 0, 0, 0); |
2694 | if (ret) { | 2793 | if (ret) { |
2695 | hid_err(sc->hdev, | 2794 | hid_err(sc->hdev, |
2696 | "Unable to initialize multi-touch slots: %d\n", | 2795 | "Unable to initialize multi-touch slots: %d\n", |
@@ -2721,6 +2820,20 @@ static int sony_input_configured(struct hid_device *hdev, | |||
2721 | } | 2820 | } |
2722 | 2821 | ||
2723 | sony_init_output_report(sc, dualshock4_send_output_report); | 2822 | sony_init_output_report(sc, dualshock4_send_output_report); |
2823 | } else if (sc->quirks & NSG_MRXU_REMOTE) { | ||
2824 | /* | ||
2825 | * The NSG-MRxU touchpad supports 2 touches and has a | ||
2826 | * resolution of 1667x1868 | ||
2827 | */ | ||
2828 | ret = sony_register_touchpad(sc, 2, | ||
2829 | NSG_MRXU_MAX_X, NSG_MRXU_MAX_Y, 15, 15, 1); | ||
2830 | if (ret) { | ||
2831 | hid_err(sc->hdev, | ||
2832 | "Unable to initialize multi-touch slots: %d\n", | ||
2833 | ret); | ||
2834 | goto err_stop; | ||
2835 | } | ||
2836 | |||
2724 | } else if (sc->quirks & MOTION_CONTROLLER) { | 2837 | } else if (sc->quirks & MOTION_CONTROLLER) { |
2725 | sony_init_output_report(sc, motion_send_output_report); | 2838 | sony_init_output_report(sc, motion_send_output_report); |
2726 | } else { | 2839 | } else { |
@@ -2969,6 +3082,12 @@ static const struct hid_device_id sony_devices[] = { | |||
2969 | /* Nyko Core Controller for PS3 */ | 3082 | /* Nyko Core Controller for PS3 */ |
2970 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), | 3083 | { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER), |
2971 | .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, | 3084 | .driver_data = SIXAXIS_CONTROLLER_USB | SINO_LITE_CONTROLLER }, |
3085 | /* SMK-Link NSG-MR5U Remote Control */ | ||
3086 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE), | ||
3087 | .driver_data = NSG_MR5U_REMOTE_BT }, | ||
3088 | /* SMK-Link NSG-MR7U Remote Control */ | ||
3089 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE), | ||
3090 | .driver_data = NSG_MR7U_REMOTE_BT }, | ||
2972 | { } | 3091 | { } |
2973 | }; | 3092 | }; |
2974 | MODULE_DEVICE_TABLE(hid, sony_devices); | 3093 | MODULE_DEVICE_TABLE(hid, sony_devices); |