From a7de9b867be0662e72db69fd40a4f1d2aa80ecc0 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Mon, 16 Feb 2015 15:06:59 +0200 Subject: HID: sony: Enable Gasia third-party PS3 controllers Without this, my "Gasia Co.,Ltd PS(R) Gamepad" would not send any events. Now everything works including the leds. Based on work by Andrew Haines and Antonio Ospite. cc: Antonio Ospite cc: Andrew Haines Signed-off-by: Lauri Kasanen Reviewed-by: Antonio Ospite Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers/hid/hid-sony.c') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 31e9d2561106..f3d44e5266f0 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1139,9 +1139,29 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + if (ret < 0) { + hid_err(hdev, "can't set operational mode: step 1\n"); + goto out; + } + + /* + * Some compatible controllers like the Speedlink Strike FX and + * Gasia need another query plus an USB interrupt to get operational. + */ + ret = hid_hw_raw_request(hdev, 0xf5, buf, 8, HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); + + if (ret < 0) { + hid_err(hdev, "can't set operational mode: step 2\n"); + goto out; + } + + ret = hid_hw_output_report(hdev, buf, 1); + if (ret < 0) - hid_err(hdev, "can't set operational mode\n"); + hid_err(hdev, "can't set operational mode: step 3\n"); +out: kfree(buf); return ret; -- cgit v1.2.3 From 29b691a894f3964b26b8179423a45591fc071eea Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 16 Feb 2015 18:12:21 +0100 Subject: HID: sony: Use the minimum accepted size for feature report 0xf2 Sixaxis devices accept feature report 0xf2 when size is >= 17, not 18. Use the minimum accepted size. The change is mainly for documentation purposes, the code worked fine even before this change. Signed-off-by: Antonio Ospite Acked-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid/hid-sony.c') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index f3d44e5266f0..4d6376cac0bd 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -802,7 +802,7 @@ union sixaxis_output_report_01 { #define DS4_REPORT_0x05_SIZE 32 #define DS4_REPORT_0x11_SIZE 78 #define DS4_REPORT_0x81_SIZE 7 -#define SIXAXIS_REPORT_0xF2_SIZE 18 +#define SIXAXIS_REPORT_0xF2_SIZE 17 static spinlock_t sony_dev_list_lock; static LIST_HEAD(sony_device_list); -- cgit v1.2.3 From a85d67b545e9c1e178ecdb159cfa59a45405c22a Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 16 Feb 2015 18:12:22 +0100 Subject: HID: sony: Don't use magic numbers in sixaxis_set_operational_usb() Remove the magic numbers used in sixaxis_set_operational_usb(): - use the already defined SIXAXIS_REPORT_0xF2_SIZE; - define and use SIXAXIS_REPORT_0xF5_SIZE; - set the dummy buffer size to accommodate any report that is going to be requested. Signed-off-by: Antonio Ospite Acked-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/hid/hid-sony.c') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 4d6376cac0bd..64f2f51e6698 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -803,6 +803,7 @@ union sixaxis_output_report_01 { #define DS4_REPORT_0x11_SIZE 78 #define DS4_REPORT_0x81_SIZE 7 #define SIXAXIS_REPORT_0xF2_SIZE 17 +#define SIXAXIS_REPORT_0xF5_SIZE 8 static spinlock_t sony_dev_list_lock; static LIST_HEAD(sony_device_list); @@ -1131,13 +1132,15 @@ static void sony_input_configured(struct hid_device *hdev, static int sixaxis_set_operational_usb(struct hid_device *hdev) { int ret; - char *buf = kmalloc(18, GFP_KERNEL); + const int buf_size = + max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); + char *buf = kmalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = hid_hw_raw_request(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT, - HID_REQ_GET_REPORT); + ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret < 0) { hid_err(hdev, "can't set operational mode: step 1\n"); @@ -1148,8 +1151,8 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) * Some compatible controllers like the Speedlink Strike FX and * Gasia need another query plus an USB interrupt to get operational. */ - ret = hid_hw_raw_request(hdev, 0xf5, buf, 8, HID_FEATURE_REPORT, - HID_REQ_GET_REPORT); + ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); if (ret < 0) { hid_err(hdev, "can't set operational mode: step 2\n"); -- cgit v1.2.3 From dad89ad046b0a9cfad99fb30e27df2be5bf76b54 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 16 Feb 2015 18:12:23 +0100 Subject: HID: sony: Use __u8 * for the buffer in sixaxis_set_operational_usb() Use the same type declared in the prototypes of functions that are going to accept the buffer as parameter. Signed-off-by: Antonio Ospite Acked-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/hid/hid-sony.c') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 64f2f51e6698..ec542be818d5 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1134,7 +1134,7 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) int ret; const int buf_size = max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); - char *buf = kmalloc(buf_size, GFP_KERNEL); + __u8 *buf = kmalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; -- cgit v1.2.3 From 2e701a359ac2833381e5d226802bed8fd1946238 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Mon, 16 Feb 2015 18:12:24 +0100 Subject: HID: sony: Coding style cleanups in sixaxis_set_operational_usb() Don't mix declaration and allocation, remove some useless newlines between calling a function and checking its return value. Signed-off-by: Antonio Ospite Acked-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/hid/hid-sony.c') diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ec542be818d5..fa11930dfee2 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1131,17 +1131,17 @@ static void sony_input_configured(struct hid_device *hdev, */ static int sixaxis_set_operational_usb(struct hid_device *hdev) { - int ret; const int buf_size = max(SIXAXIS_REPORT_0xF2_SIZE, SIXAXIS_REPORT_0xF5_SIZE); - __u8 *buf = kmalloc(buf_size, GFP_KERNEL); + __u8 *buf; + int ret; + buf = kmalloc(buf_size, GFP_KERNEL); if (!buf) return -ENOMEM; ret = hid_hw_raw_request(hdev, 0xf2, buf, SIXAXIS_REPORT_0xF2_SIZE, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - if (ret < 0) { hid_err(hdev, "can't set operational mode: step 1\n"); goto out; @@ -1153,14 +1153,12 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) */ ret = hid_hw_raw_request(hdev, 0xf5, buf, SIXAXIS_REPORT_0xF5_SIZE, HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - if (ret < 0) { hid_err(hdev, "can't set operational mode: step 2\n"); goto out; } ret = hid_hw_output_report(hdev, buf, 1); - if (ret < 0) hid_err(hdev, "can't set operational mode: step 3\n"); -- cgit v1.2.3