aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2018-04-05 07:28:34 -0400
committerJiri Kosina <jkosina@suse.cz>2018-04-05 07:28:34 -0400
commit108ff0e8012ae10708168940c7474318fb343751 (patch)
tree57b8936d4ec961d62c90af3c2a4c764a1b2d50c0
parentaf73686e7bfe49fbbccc099995be8c78ce5bfe9a (diff)
parentb7289cb1cf99d432c894b9da7a54e24f73ae4c93 (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.h3
-rw-r--r--drivers/hid/hid-quirks.c2
-rw-r--r--drivers/hid/hid-sony.c131
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
1107static 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
1101static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, 1181static 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
1265static int sony_register_touchpad(struct sony_sc *sc, int touch_count, 1349static 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};
2974MODULE_DEVICE_TABLE(hid, sony_devices); 3093MODULE_DEVICE_TABLE(hid, sony_devices);