* [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode @ 2014-01-30 17:24 Frank Praznik 2014-01-30 17:24 ` [PATCH v2 1/6] HID: sony: Use low-level transport driver functions Frank Praznik ` (5 more replies) 0 siblings, 6 replies; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik This updated set of patches adds NULL pointer checking for the ll_driver functions and makes the battery calculation code more robust. The last patch from the first set that checked for duplicate controllers is on-hold for now as without a guaranteed way to retrieve the MAC address of a Bluetooth device from a module it has the potential to break. ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/6] HID: sony: Use low-level transport driver functions 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-02-03 16:26 ` David Herrmann 2014-01-30 17:24 ` [PATCH v2 2/6] HID: sony: Add modified Dualshock 4 Bluetooth HID descriptor Frank Praznik ` (4 subsequent siblings) 5 siblings, 1 reply; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Franz Frank Praznik From: Franz Frank Praznik <frank.praznik@oh.rr.com> Change the dualshock4_state_worker function to use the low-level output_report function. Remove sony_set_output_report since it is no longer used. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 58 ++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 40 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 2bd3f13..7a6d7c9 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -502,7 +502,6 @@ struct sony_sc { spinlock_t lock; struct hid_device *hdev; struct led_classdev *leds[MAX_LEDS]; - struct hid_report *output_report; unsigned long quirks; struct work_struct state_worker; struct power_supply battery; @@ -1053,21 +1052,26 @@ static void dualshock4_state_worker(struct work_struct *work) { struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); struct hid_device *hdev = sc->hdev; - struct hid_report *report = sc->output_report; - __s32 *value = report->field[0]->value; + int offset; + + __u8 buf[32] = { 0 }; - value[0] = 0x03; + buf[0] = 0x05; + buf[1] = 0x03; + offset = 4; #ifdef CONFIG_SONY_FF - value[3] = sc->right; - value[4] = sc->left; + buf[offset++] = sc->right; + buf[offset++] = sc->left; +#else + offset += 2; #endif - value[5] = sc->led_state[0]; - value[6] = sc->led_state[1]; - value[7] = sc->led_state[2]; + buf[offset++] = sc->led_state[0]; + buf[offset++] = sc->led_state[1]; + buf[offset++] = sc->led_state[2]; - hid_hw_request(hdev, report, HID_REQ_SET_REPORT); + hdev->ll_driver->output_report(hdev, buf, sizeof(buf)); } #ifdef CONFIG_SONY_FF @@ -1200,33 +1204,6 @@ static void sony_battery_remove(struct sony_sc *sc) sc->battery.name = NULL; } -static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) -{ - struct list_head *head, *list; - struct hid_report *report; - struct hid_device *hdev = sc->hdev; - - list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; - - list_for_each(head, list) { - report = list_entry(head, struct hid_report, list); - - if (report->id == req_id) { - if (report->size < req_size) { - hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n", - req_id, report->size, req_size); - return -EINVAL; - } - sc->output_report = report; - return 0; - } - } - - hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id); - - return -EINVAL; -} - static int sony_register_touchpad(struct sony_sc *sc, int touch_count, int w, int h) { @@ -1291,10 +1268,11 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) else if (sc->quirks & SIXAXIS_CONTROLLER_BT) ret = sixaxis_set_operational_bt(hdev); else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { - /* Report 5 (31 bytes) is used to send data to the controller via USB */ - ret = sony_set_output_report(sc, 0x05, 248); - if (ret < 0) + if (hdev->ll_driver->output_report == NULL) { + hid_err(hdev, "NULL output_report handler\n"); + ret = -EINVAL; goto err_stop; + } /* The Dualshock 4 touchpad supports 2 touches and has a * resolution of 1920x940. -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/6] HID: sony: Use low-level transport driver functions 2014-01-30 17:24 ` [PATCH v2 1/6] HID: sony: Use low-level transport driver functions Frank Praznik @ 2014-02-03 16:26 ` David Herrmann 0 siblings, 0 replies; 10+ messages in thread From: David Herrmann @ 2014-02-03 16:26 UTC (permalink / raw) To: Frank Praznik; +Cc: open list:HID CORE LAYER, Jiri Kosina Hi On Thu, Jan 30, 2014 at 6:24 PM, Frank Praznik <frank.praznik@oh.rr.com> wrote: > From: Franz Frank Praznik <frank.praznik@oh.rr.com> > > Change the dualshock4_state_worker function to use the low-level output_report > function. > > Remove sony_set_output_report since it is no longer used. > > Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> > --- > drivers/hid/hid-sony.c | 58 ++++++++++++++++---------------------------------- > 1 file changed, 18 insertions(+), 40 deletions(-) > > diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c > index 2bd3f13..7a6d7c9 100644 > --- a/drivers/hid/hid-sony.c > +++ b/drivers/hid/hid-sony.c > @@ -502,7 +502,6 @@ struct sony_sc { > spinlock_t lock; > struct hid_device *hdev; > struct led_classdev *leds[MAX_LEDS]; > - struct hid_report *output_report; > unsigned long quirks; > struct work_struct state_worker; > struct power_supply battery; > @@ -1053,21 +1052,26 @@ static void dualshock4_state_worker(struct work_struct *work) > { > struct sony_sc *sc = container_of(work, struct sony_sc, state_worker); > struct hid_device *hdev = sc->hdev; > - struct hid_report *report = sc->output_report; > - __s32 *value = report->field[0]->value; > + int offset; > + > + __u8 buf[32] = { 0 }; > > - value[0] = 0x03; > + buf[0] = 0x05; > + buf[1] = 0x03; > + offset = 4; > > #ifdef CONFIG_SONY_FF > - value[3] = sc->right; > - value[4] = sc->left; > + buf[offset++] = sc->right; > + buf[offset++] = sc->left; > +#else > + offset += 2; > #endif > > - value[5] = sc->led_state[0]; > - value[6] = sc->led_state[1]; > - value[7] = sc->led_state[2]; > + buf[offset++] = sc->led_state[0]; > + buf[offset++] = sc->led_state[1]; > + buf[offset++] = sc->led_state[2]; > > - hid_hw_request(hdev, report, HID_REQ_SET_REPORT); > + hdev->ll_driver->output_report(hdev, buf, sizeof(buf)); Ugh? You change SET_REPORT to output_report() here, which is not supposed to be identical. Are you sure that works? A correct HID device should accept both, but we're talking about gamepads here.. Thanks David > } > > #ifdef CONFIG_SONY_FF > @@ -1200,33 +1204,6 @@ static void sony_battery_remove(struct sony_sc *sc) > sc->battery.name = NULL; > } > > -static int sony_set_output_report(struct sony_sc *sc, int req_id, int req_size) > -{ > - struct list_head *head, *list; > - struct hid_report *report; > - struct hid_device *hdev = sc->hdev; > - > - list = &hdev->report_enum[HID_OUTPUT_REPORT].report_list; > - > - list_for_each(head, list) { > - report = list_entry(head, struct hid_report, list); > - > - if (report->id == req_id) { > - if (report->size < req_size) { > - hid_err(hdev, "Output report 0x%02x (%i bits) is smaller than requested size (%i bits)\n", > - req_id, report->size, req_size); > - return -EINVAL; > - } > - sc->output_report = report; > - return 0; > - } > - } > - > - hid_err(hdev, "Unable to locate output report 0x%02x\n", req_id); > - > - return -EINVAL; > -} > - > static int sony_register_touchpad(struct sony_sc *sc, int touch_count, > int w, int h) > { > @@ -1291,10 +1268,11 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) > else if (sc->quirks & SIXAXIS_CONTROLLER_BT) > ret = sixaxis_set_operational_bt(hdev); > else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { > - /* Report 5 (31 bytes) is used to send data to the controller via USB */ > - ret = sony_set_output_report(sc, 0x05, 248); > - if (ret < 0) > + if (hdev->ll_driver->output_report == NULL) { > + hid_err(hdev, "NULL output_report handler\n"); > + ret = -EINVAL; > goto err_stop; > + } > > /* The Dualshock 4 touchpad supports 2 touches and has a > * resolution of 1920x940. > -- > 1.8.5.3 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/6] HID: sony: Add modified Dualshock 4 Bluetooth HID descriptor 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik 2014-01-30 17:24 ` [PATCH v2 1/6] HID: sony: Use low-level transport driver functions Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-01-30 17:24 ` [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting Frank Praznik ` (3 subsequent siblings) 5 siblings, 0 replies; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik By default, the Dualshock 4 sends controller data via report 1. Once an output report is received the controller changes from sending data in report 1 to sending data in report 17, which is unmapped in the default descriptor. The mappings have to be moved to report 17 to let the HID driver properly process the incoming reports. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 7a6d7c9..52162a9 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -336,6 +336,216 @@ static u8 dualshock4_usb_rdesc[] = { 0xC0 /* End Collection */ }; +/* The default behavior of the Dualshock 4 is to send reports using report + * type 1 when running over Bluetooth. However, as soon as it receives a + * report of type 17 to set the LEDs or rumble it starts returning it's state + * in report 17 instead of 1. Since report 17 is undefined in the default HID + * descriptor the button and axis definitions must be moved to report 17 or + * the HID layer won't process the received input once a report is sent. + */ +static u8 dualshock4_bt_rdesc[] = { + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x05, /* Usage (Gamepad), */ + 0xA1, 0x01, /* Collection (Application), */ + 0x85, 0x01, /* Report ID (1), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x0A, /* Report Count (9), */ + 0x81, 0x02, /* Input (Variable), */ + 0x06, 0x04, 0xFF, /* Usage Page (FF04h), */ + 0x85, 0x02, /* Report ID (2), */ + 0x09, 0x24, /* Usage (24h), */ + 0x95, 0x24, /* Report Count (36), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xA3, /* Report ID (163), */ + 0x09, 0x25, /* Usage (25h), */ + 0x95, 0x30, /* Report Count (48), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x05, /* Report ID (5), */ + 0x09, 0x26, /* Usage (26h), */ + 0x95, 0x28, /* Report Count (40), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x06, /* Report ID (6), */ + 0x09, 0x27, /* Usage (27h), */ + 0x95, 0x34, /* Report Count (52), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x07, /* Report ID (7), */ + 0x09, 0x28, /* Usage (28h), */ + 0x95, 0x30, /* Report Count (48), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x08, /* Report ID (8), */ + 0x09, 0x29, /* Usage (29h), */ + 0x95, 0x2F, /* Report Count (47), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x06, 0x03, 0xFF, /* Usage Page (FF03h), */ + 0x85, 0x03, /* Report ID (3), */ + 0x09, 0x21, /* Usage (21h), */ + 0x95, 0x26, /* Report Count (38), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x04, /* Report ID (4), */ + 0x09, 0x22, /* Usage (22h), */ + 0x95, 0x2E, /* Report Count (46), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xF0, /* Report ID (240), */ + 0x09, 0x47, /* Usage (47h), */ + 0x95, 0x3F, /* Report Count (63), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xF1, /* Report ID (241), */ + 0x09, 0x48, /* Usage (48h), */ + 0x95, 0x3F, /* Report Count (63), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xF2, /* Report ID (242), */ + 0x09, 0x49, /* Usage (49h), */ + 0x95, 0x0F, /* Report Count (15), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x11, /* Report ID (17), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x09, 0x20, /* Usage (20h), */ + 0x95, 0x02, /* Report Count (2), */ + 0x81, 0x02, /* Input (Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x30, /* Usage (X), */ + 0x09, 0x31, /* Usage (Y), */ + 0x09, 0x32, /* Usage (Z), */ + 0x09, 0x35, /* Usage (Rz), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x04, /* Report Count (4), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x39, /* Usage (Hat Switch), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x25, 0x07, /* Logical Maximum (7), */ + 0x75, 0x04, /* Report Size (4), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x42, /* Input (Variable, Null State), */ + 0x05, 0x09, /* Usage Page (Button), */ + 0x19, 0x01, /* Usage Minimum (01h), */ + 0x29, 0x0E, /* Usage Maximum (0Eh), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x25, 0x01, /* Logical Maximum (1), */ + 0x75, 0x01, /* Report Size (1), */ + 0x95, 0x0E, /* Report Count (14), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x06, /* Report Size (6), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x01, /* Input (Constant), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x33, /* Usage (Rx), */ + 0x09, 0x34, /* Usage (Ry), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x02, /* Report Count (2), */ + 0x81, 0x02, /* Input (Variable), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x09, 0x20, /* Usage (20h), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x19, 0x40, /* Usage Minimum (40h), */ + 0x29, 0x42, /* Usage Maximum (42h), */ + 0x16, 0x00, 0x80, /* Logical Minimum (-32768), */ + 0x26, 0x00, 0x7F, /* Logical Maximum (32767), */ + 0x75, 0x10, /* Report Size (16), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Variable), */ + 0x19, 0x43, /* Usage Minimum (43h), */ + 0x29, 0x45, /* Usage Maximum (45h), */ + 0x16, 0xFF, 0xBF, /* Logical Minimum (-16385), */ + 0x26, 0x00, 0x40, /* Logical Maximum (16384), */ + 0x95, 0x03, /* Report Count (3), */ + 0x81, 0x02, /* Input (Variable), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x09, 0x20, /* Usage (20h), */ + 0x15, 0x00, /* Logical Minimum (0), */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x31, /* Report Count (51), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x21, /* Usage (21h), */ + 0x75, 0x08, /* Report Size (8), */ + 0x95, 0x4D, /* Report Count (77), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x12, /* Report ID (18), */ + 0x09, 0x22, /* Usage (22h), */ + 0x95, 0x8D, /* Report Count (141), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x23, /* Usage (23h), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x13, /* Report ID (19), */ + 0x09, 0x24, /* Usage (24h), */ + 0x95, 0xCD, /* Report Count (205), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x25, /* Usage (25h), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x14, /* Report ID (20), */ + 0x09, 0x26, /* Usage (26h), */ + 0x96, 0x0D, 0x01, /* Report Count (269), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x27, /* Usage (27h), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x15, /* Report ID (21), */ + 0x09, 0x28, /* Usage (28h), */ + 0x96, 0x4D, 0x01, /* Report Count (333), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x29, /* Usage (29h), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x16, /* Report ID (22), */ + 0x09, 0x2A, /* Usage (2Ah), */ + 0x96, 0x8D, 0x01, /* Report Count (397), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x2B, /* Usage (2Bh), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x17, /* Report ID (23), */ + 0x09, 0x2C, /* Usage (2Ch), */ + 0x96, 0xCD, 0x01, /* Report Count (461), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x2D, /* Usage (2Dh), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x18, /* Report ID (24), */ + 0x09, 0x2E, /* Usage (2Eh), */ + 0x96, 0x0D, 0x02, /* Report Count (525), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x2F, /* Usage (2Fh), */ + 0x91, 0x02, /* Output (Variable), */ + 0x85, 0x19, /* Report ID (25), */ + 0x09, 0x30, /* Usage (30h), */ + 0x96, 0x22, 0x02, /* Report Count (546), */ + 0x81, 0x02, /* Input (Variable), */ + 0x09, 0x31, /* Usage (31h), */ + 0x91, 0x02, /* Output (Variable), */ + 0x06, 0x80, 0xFF, /* Usage Page (FF80h), */ + 0x85, 0x82, /* Report ID (130), */ + 0x09, 0x22, /* Usage (22h), */ + 0x95, 0x3F, /* Report Count (63), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x83, /* Report ID (131), */ + 0x09, 0x23, /* Usage (23h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x84, /* Report ID (132), */ + 0x09, 0x24, /* Usage (24h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x90, /* Report ID (144), */ + 0x09, 0x30, /* Usage (30h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x91, /* Report ID (145), */ + 0x09, 0x31, /* Usage (31h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x92, /* Report ID (146), */ + 0x09, 0x32, /* Usage (32h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0x93, /* Report ID (147), */ + 0x09, 0x33, /* Usage (33h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xA0, /* Report ID (160), */ + 0x09, 0x40, /* Usage (40h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0x85, 0xA4, /* Report ID (164), */ + 0x09, 0x44, /* Usage (44h), */ + 0xB1, 0x02, /* Feature (Variable), */ + 0xC0 /* End Collection */ +}; + static __u8 ps3remote_rdesc[] = { 0x05, 0x01, /* GUsagePage Generic Desktop */ 0x09, 0x05, /* LUsage 0x05 [Game Pad] */ @@ -591,6 +801,10 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n"); rdesc = dualshock4_usb_rdesc; *rsize = sizeof(dualshock4_usb_rdesc); + } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) { + hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n"); + rdesc = dualshock4_bt_rdesc; + *rsize = sizeof(dualshock4_bt_rdesc); } /* The HID descriptor exposed over BT has a trailing zero byte */ -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik 2014-01-30 17:24 ` [PATCH v2 1/6] HID: sony: Use low-level transport driver functions Frank Praznik 2014-01-30 17:24 ` [PATCH v2 2/6] HID: sony: Add modified Dualshock 4 Bluetooth HID descriptor Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-02-03 16:29 ` David Herrmann 2014-01-30 17:24 ` [PATCH v2 4/6] HID: sony: Add Dualshock 4 Bluetooth battery and touchpad parsing Frank Praznik ` (2 subsequent siblings) 5 siblings, 1 reply; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik Add formatting and reporting for Dualshock 4 output reports on Bluetooth. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 52162a9..4d12b4e 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1268,11 +1268,18 @@ static void dualshock4_state_worker(struct work_struct *work) struct hid_device *hdev = sc->hdev; int offset; - __u8 buf[32] = { 0 }; + __u8 buf[78] = { 0 }; - buf[0] = 0x05; - buf[1] = 0x03; - offset = 4; + if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { + buf[0] = 0x05; + buf[1] = 0x03; + offset = 4; + } else { + buf[0] = 0x11; + buf[1] = 0xB0; + buf[3] = 0x0F; + offset = 6; + } #ifdef CONFIG_SONY_FF buf[offset++] = sc->right; @@ -1285,7 +1292,11 @@ static void dualshock4_state_worker(struct work_struct *work) buf[offset++] = sc->led_state[1]; buf[offset++] = sc->led_state[2]; - hdev->ll_driver->output_report(hdev, buf, sizeof(buf)); + if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) + hdev->ll_driver->output_report(hdev, buf, 32); + else + hdev->ll_driver->raw_request(hdev, 0x11, buf, 78, + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); } #ifdef CONFIG_SONY_FF @@ -1482,10 +1493,16 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) else if (sc->quirks & SIXAXIS_CONTROLLER_BT) ret = sixaxis_set_operational_bt(hdev); else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { - if (hdev->ll_driver->output_report == NULL) { + if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && + hdev->ll_driver->output_report == NULL) { hid_err(hdev, "NULL output_report handler\n"); ret = -EINVAL; goto err_stop; + } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && + hdev->ll_driver->raw_request == NULL) { + hid_err(hdev, "NULL raw_request handler\n"); + ret = -EINVAL; + goto err_stop; } /* The Dualshock 4 touchpad supports 2 touches and has a -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting 2014-01-30 17:24 ` [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting Frank Praznik @ 2014-02-03 16:29 ` David Herrmann 0 siblings, 0 replies; 10+ messages in thread From: David Herrmann @ 2014-02-03 16:29 UTC (permalink / raw) To: Frank Praznik; +Cc: open list:HID CORE LAYER, Jiri Kosina Hi On Thu, Jan 30, 2014 at 6:24 PM, Frank Praznik <frank.praznik@oh.rr.com> wrote: > Add formatting and reporting for Dualshock 4 output reports on Bluetooth. > > Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> > > --- > drivers/hid/hid-sony.c | 29 +++++++++++++++++++++++------ > 1 file changed, 23 insertions(+), 6 deletions(-) > > diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c > index 52162a9..4d12b4e 100644 > --- a/drivers/hid/hid-sony.c > +++ b/drivers/hid/hid-sony.c > @@ -1268,11 +1268,18 @@ static void dualshock4_state_worker(struct work_struct *work) > struct hid_device *hdev = sc->hdev; > int offset; > > - __u8 buf[32] = { 0 }; > + __u8 buf[78] = { 0 }; > > - buf[0] = 0x05; > - buf[1] = 0x03; > - offset = 4; > + if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { > + buf[0] = 0x05; > + buf[1] = 0x03; > + offset = 4; > + } else { > + buf[0] = 0x11; > + buf[1] = 0xB0; > + buf[3] = 0x0F; > + offset = 6; > + } > > #ifdef CONFIG_SONY_FF > buf[offset++] = sc->right; > @@ -1285,7 +1292,11 @@ static void dualshock4_state_worker(struct work_struct *work) > buf[offset++] = sc->led_state[1]; > buf[offset++] = sc->led_state[2]; > > - hdev->ll_driver->output_report(hdev, buf, sizeof(buf)); > + if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) > + hdev->ll_driver->output_report(hdev, buf, 32); > + else > + hdev->ll_driver->raw_request(hdev, 0x11, buf, 78, > + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); Ok, now I get it. The USB stuff takes output-reports and BT uses SET_REPORT. That's exactly the inverse of wiimotes. > } > > #ifdef CONFIG_SONY_FF > @@ -1482,10 +1493,16 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) > else if (sc->quirks & SIXAXIS_CONTROLLER_BT) > ret = sixaxis_set_operational_bt(hdev); > else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { > - if (hdev->ll_driver->output_report == NULL) { > + if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && > + hdev->ll_driver->output_report == NULL) { > hid_err(hdev, "NULL output_report handler\n"); > ret = -EINVAL; > goto err_stop; > + } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && > + hdev->ll_driver->raw_request == NULL) { > + hid_err(hdev, "NULL raw_request handler\n"); > + ret = -EINVAL; > + goto err_stop; If you rebase your patches on Benjamins series, you can use hid_hw_output_report() and hid_hw_raw_request() which already to the NULL check. So you can drop this stuff here. Thanks David > } > > /* The Dualshock 4 touchpad supports 2 touches and has a > -- > 1.8.5.3 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 4/6] HID: sony: Add Dualshock 4 Bluetooth battery and touchpad parsing 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik ` (2 preceding siblings ...) 2014-01-30 17:24 ` [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-01-30 17:24 ` [PATCH v2 5/6] HID: sony: Set initial battery level to 100% to avoid false low battery warnings Frank Praznik 2014-01-30 17:24 ` [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode Frank Praznik 5 siblings, 0 replies; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik Add offsets for retrieving the battery and touchpad data in Dualshock 4 Bluetooth reports. Adjust battery capacity calculations when in wireless mode. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 688da52..9aa20ff 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -861,25 +861,34 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) struct hid_input, list); struct input_dev *input_dev = hidinput->input; unsigned long flags; - int n, offset = 35; + int n, offset; __u8 cable_state, battery_capacity, battery_charging; + /* Battery and touchpad data starts at byte 30 in the USB report and + * 32 in Bluetooth report. + */ + offset = (sc->quirks & DUALSHOCK4_CONTROLLER_USB) ? 30 : 32; + /* The lower 4 bits of byte 30 contain the battery level * and the 5th bit contains the USB cable state. */ - cable_state = (rd[30] >> 4) & 0x01; - battery_capacity = rd[30] & 0x0F; + cable_state = (rd[offset] >> 4) & 0x01; + battery_capacity = rd[offset] & 0x0F; - /* On USB the Dualshock 4 battery level goes from 0 to 11. - * A battery level of 11 means fully charged. + /* When a USB power source is connected the battery level ranges from + * 0 to 10, and when running on battery power it ranges from 0 to 9. + * A battery level above 10 when plugged in means charge completed. */ - if (cable_state && battery_capacity == 11) + if (!cable_state || battery_capacity > 10) battery_charging = 0; else battery_charging = 1; + if (!cable_state) + battery_capacity++; if (battery_capacity > 10) - battery_capacity--; + battery_capacity = 10; + battery_capacity *= 10; spin_lock_irqsave(&sc->lock, flags); @@ -888,7 +897,10 @@ static void dualshock4_parse_report(struct sony_sc *sc, __u8 *rd, int size) sc->battery_charging = battery_charging; spin_unlock_irqrestore(&sc->lock, flags); - /* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB. + offset += 5; + + /* The Dualshock 4 multi-touch trackpad data starts at offset 35 on USB + * and 37 on Bluetooth. * The first 7 bits of the first byte is a counter and bit 8 is a touch * indicator that is 0 when pressed and 1 when not pressed. * The next 3 bytes are two 12 bit touch coordinates, X and Y. -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 5/6] HID: sony: Set initial battery level to 100% to avoid false low battery warnings 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik ` (3 preceding siblings ...) 2014-01-30 17:24 ` [PATCH v2 4/6] HID: sony: Add Dualshock 4 Bluetooth battery and touchpad parsing Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-01-30 17:24 ` [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode Frank Praznik 5 siblings, 0 replies; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik Set initial battery level to 100% to avoid false low battery warnings if a the battery level is polled before a report containing the battery information is received. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 9aa20ff..5564446 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1404,6 +1404,11 @@ static int sony_battery_probe(struct sony_sc *sc) struct hid_device *hdev = sc->hdev; int ret; + /* Set the default battery level to 100% to avoid low battery warnings + * if the battery is polled before the first device report is received. + */ + sc->battery_capacity = 100; + power_id = (unsigned long)atomic_inc_return(&power_id_seq); sc->battery.properties = sony_battery_props; -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik ` (4 preceding siblings ...) 2014-01-30 17:24 ` [PATCH v2 5/6] HID: sony: Set initial battery level to 100% to avoid false low battery warnings Frank Praznik @ 2014-01-30 17:24 ` Frank Praznik 2014-02-03 16:31 ` David Herrmann 5 siblings, 1 reply; 10+ messages in thread From: Frank Praznik @ 2014-01-30 17:24 UTC (permalink / raw) To: linux-input; +Cc: jkosina, dh.herrmann, Frank Praznik Add the necessary conditionals to enable battery reporting, rumble, LED settings and touchpad parsing. Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> --- drivers/hid/hid-sony.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index eee56d7..d920362 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -44,8 +44,10 @@ #define DUALSHOCK4_CONTROLLER_USB BIT(5) #define DUALSHOCK4_CONTROLLER_BT BIT(6) -#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) -#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_USB) +#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | \ + DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_BT) +#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | \ + DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_BT) #define MAX_LEDS 4 @@ -939,8 +941,9 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, swap(rd[47], rd[48]); sixaxis_parse_report(sc, rd, size); - } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && - size == 64) { + } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && + size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) + && rd[0] == 0x11 && size == 78)) { dualshock4_parse_report(sc, rd, size); } @@ -1079,7 +1082,8 @@ static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { buzz_set_leds(hdev, leds); } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) || - (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) { + (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) || + (drv_data->quirks & DUALSHOCK4_CONTROLLER_BT)) { for (n = 0; n < count; n++) drv_data->led_state[n] = leds[n]; schedule_work(&drv_data->state_worker); @@ -1184,7 +1188,8 @@ static int sony_leds_init(struct hid_device *hdev) /* Validate expected report characteristics. */ if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) return -ENODEV; - } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) { + } else if ((drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) || + (drv_data->quirks & DUALSHOCK4_CONTROLLER_BT)) { drv_data->led_count = 3; max_brightness = 255; use_colors = 1; @@ -1509,7 +1514,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) } else if (sc->quirks & SIXAXIS_CONTROLLER_BT) ret = sixaxis_set_operational_bt(hdev); - else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { + else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) || + (sc->quirks & DUALSHOCK4_CONTROLLER_BT)) { if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && hdev->ll_driver->output_report == NULL) { hid_err(hdev, "NULL output_report handler\n"); -- 1.8.5.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode 2014-01-30 17:24 ` [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode Frank Praznik @ 2014-02-03 16:31 ` David Herrmann 0 siblings, 0 replies; 10+ messages in thread From: David Herrmann @ 2014-02-03 16:31 UTC (permalink / raw) To: Frank Praznik; +Cc: open list:HID CORE LAYER, Jiri Kosina Hi On Thu, Jan 30, 2014 at 6:24 PM, Frank Praznik <frank.praznik@oh.rr.com> wrote: > Add the necessary conditionals to enable battery reporting, rumble, LED > settings and touchpad parsing. > > Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com> > > --- > drivers/hid/hid-sony.c | 20 +++++++++++++------- > 1 file changed, 13 insertions(+), 7 deletions(-) > > diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c > index eee56d7..d920362 100644 > --- a/drivers/hid/hid-sony.c > +++ b/drivers/hid/hid-sony.c > @@ -44,8 +44,10 @@ > #define DUALSHOCK4_CONTROLLER_USB BIT(5) > #define DUALSHOCK4_CONTROLLER_BT BIT(6) > > -#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | DUALSHOCK4_CONTROLLER_USB) > -#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | DUALSHOCK4_CONTROLLER_USB) > +#define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER_USB | BUZZ_CONTROLLER | \ > + DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_BT) > +#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT | \ > + DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_BT) How about adding: #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB | DUALSHOCK4_CONTROLLER_BT) and then simplifying the chunks below? Seems a bit redundant to always check for both, _USB and _BT in the dualshock4 case. Thanks David > > #define MAX_LEDS 4 > > @@ -939,8 +941,9 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, > swap(rd[47], rd[48]); > > sixaxis_parse_report(sc, rd, size); > - } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && > - size == 64) { > + } else if (((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && rd[0] == 0x01 && > + size == 64) || ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) > + && rd[0] == 0x11 && size == 78)) { > dualshock4_parse_report(sc, rd, size); > } > > @@ -1079,7 +1082,8 @@ static void sony_set_leds(struct hid_device *hdev, const __u8 *leds, int count) > if (drv_data->quirks & BUZZ_CONTROLLER && count == 4) { > buzz_set_leds(hdev, leds); > } else if ((drv_data->quirks & SIXAXIS_CONTROLLER_USB) || > - (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB)) { > + (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) || > + (drv_data->quirks & DUALSHOCK4_CONTROLLER_BT)) { > for (n = 0; n < count; n++) > drv_data->led_state[n] = leds[n]; > schedule_work(&drv_data->state_worker); > @@ -1184,7 +1188,8 @@ static int sony_leds_init(struct hid_device *hdev) > /* Validate expected report characteristics. */ > if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7)) > return -ENODEV; > - } else if (drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) { > + } else if ((drv_data->quirks & DUALSHOCK4_CONTROLLER_USB) || > + (drv_data->quirks & DUALSHOCK4_CONTROLLER_BT)) { > drv_data->led_count = 3; > max_brightness = 255; > use_colors = 1; > @@ -1509,7 +1514,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) > } > else if (sc->quirks & SIXAXIS_CONTROLLER_BT) > ret = sixaxis_set_operational_bt(hdev); > - else if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) { > + else if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) || > + (sc->quirks & DUALSHOCK4_CONTROLLER_BT)) { > if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && > hdev->ll_driver->output_report == NULL) { > hid_err(hdev, "NULL output_report handler\n"); > -- > 1.8.5.3 > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-02-03 16:31 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-01-30 17:24 [PATCH v2 0/6] HID: sony: Add full Dualshock 4 support in Bluetooth mode Frank Praznik 2014-01-30 17:24 ` [PATCH v2 1/6] HID: sony: Use low-level transport driver functions Frank Praznik 2014-02-03 16:26 ` David Herrmann 2014-01-30 17:24 ` [PATCH v2 2/6] HID: sony: Add modified Dualshock 4 Bluetooth HID descriptor Frank Praznik 2014-01-30 17:24 ` [PATCH v2 3/6] HID: sony: Add Bluetooth output report formatting Frank Praznik 2014-02-03 16:29 ` David Herrmann 2014-01-30 17:24 ` [PATCH v2 4/6] HID: sony: Add Dualshock 4 Bluetooth battery and touchpad parsing Frank Praznik 2014-01-30 17:24 ` [PATCH v2 5/6] HID: sony: Set initial battery level to 100% to avoid false low battery warnings Frank Praznik 2014-01-30 17:24 ` [PATCH v2 6/6] HID: sony: Add conditionals to enable all features in Bluetooth mode Frank Praznik 2014-02-03 16:31 ` David Herrmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).