Re: [Patch-V2 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel
On Wed, January 6, 2016 6:47 pm, Dmitry Torokhov wrote: > It is wrong. Aside form the fact that IMO xpad.c is the wrong place for > this code to be in, why are we waiting for the input device to be opened by > userspace before we do the switch instead of doing it immediately? The 'send magic' might be better in a probe() call, but I don't believe that it requires userspace interaction as it stands. The wheel will disconnect almost immediately without me doing anything other than plug it in. -- Jan 6 21:18:50 speedster kernel: [ 439.604037] usb 5-1: new full-speed USB device number 2 using uhci_hcd Jan 6 21:18:50 speedster kernel: [ 439.791153] usb 5-1: New USB device found, idVendor=046d, idProduct=c261 Jan 6 21:18:50 speedster kernel: [ 439.791160] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 Jan 6 21:18:50 speedster kernel: [ 439.791164] usb 5-1: Product: G920 Driving Force Racing Wheel for Xbox One Jan 6 21:18:50 speedster kernel: [ 439.791167] usb 5-1: Manufacturer: Logitech Jan 6 21:18:50 speedster kernel: [ 439.791170] usb 5-1: SerialNumber: 5d1d5129cebe Jan 6 21:18:50 speedster mtp-probe: checking bus 5, device 2: "/sys/devices/pci:00/:00:1d.3/usb5/5-1" Jan 6 21:18:50 speedster mtp-probe: bus: 5, device: 2 was not an MTP device Jan 6 21:18:51 speedster kernel: [ 440.815191] input: Logitech G920 Driving Force Racing Wheel as /devices/pci:00/:00:1d.3/usb5/5-1/5-1:1.0/input/input4 Jan 6 21:18:51 speedster kernel: [ 440.815310] usbcore: registered new interface driver xpad Jan 6 21:18:52 speedster kernel: [ 441.340093] usb 5-1: USB disconnect, device number 2 Jan 6 21:18:52 speedster kernel: [ 442.052037] usb 5-1: new full-speed USB device number 3 using uhci_hcd Jan 6 21:18:52 speedster kernel: [ 442.239129] usb 5-1: New USB device found, idVendor=046d, idProduct=c262 Jan 6 21:18:52 speedster kernel: [ 442.239136] usb 5-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 Jan 6 21:18:52 speedster kernel: [ 442.239139] usb 5-1: Product: G920 Driving Force Racing Wheel for Xbox One Jan 6 21:18:52 speedster kernel: [ 442.239142] usb 5-1: Manufacturer: Logitech Jan 6 21:18:52 speedster kernel: [ 442.239145] usb 5-1: SerialNumber: 5d1d5129cebe Jan 6 21:18:52 speedster mtp-probe: checking bus 5, device 3: "/sys/devices/pci:00/:00:1d.3/usb5/5-1" Jan 6 21:18:52 speedster mtp-probe: bus: 5, device: 3 was not an MTP device Jan 6 21:18:52 speedster kernel: [ 442.267248] input: Logitech G920 Driving Force Racing Wheel for Xbox One as /devices/pci:00/:00:1d.3/usb5/5-1/5-1:1.0/0003:046D:C262.0002/input/input5 Jan 6 21:18:52 speedster kernel: [ 442.267510] logitech-hidpp-device 0003:046D:C262.0002: input,hiddev0,hidraw1: USB HID v1.11 Joystick [Logitech G920 Driving Force Racing Wheel for Xbox One] on usb-:00:1d.3-1/input0 Jan 6 21:18:53 speedster kernel: [ 442.322160] logitech-hidpp-device 0003:046D:C262.0002: HID++ 4.2 device connected. -- I also did a quick check with the 'send magic' disabled. Xpad creates the js0 and populates buttons, but pressing buttons/turning wheel does not result in any change in js0. I don't disagree to it being a seperate module, but don't have the time to implement/test at the moment. If some else does that would be good, can we make sure that the kconfig/makefile stuff uses same/sensible HID_CONFIGs? Simon -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch-V2 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel
On Thu, November 19, 2015 11:31 am, Dmitry Torokhov wrote: > On Thu, Nov 19, 2015 at 02:50:51PM +0100, Jiri Kosina wrote: > >> On Thu, 12 Nov 2015, Simon Wood wrote: >> >> >>> When plugged in the Logitech G920 wheel starts with USBID 046d:c261 >>> and behaviors as a vendor specific class. If a 'magic' byte sequence is >>> sent the wheel will detach and reconnect as a HID device with the >>> USBID 046d:c262. >>> >>> >>> Signed-off-by: Simon Wood <si...@mungewell.org> >>> >> >> Adding Dmitry to CC. >> >> >> Dmitry, I am planning to take this through my tree together with the >> rest of the actual HID support for that device if you Ack this. > > Hmm, I have an incoming series for xbox that night clash with this... If > you'll put it in a clean branch off 4.3 I'd pull it and then get more > changes on top. > > Can we also change the subject as it is not about adding a minimal > support. Something like "Input: xpad - switch Logitech G920 Wheel into HID > mode" Will spin a 'v3' with this and Benjamin's suggestion. Cheers, Simon. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V3 6/6] HID: hid-logitech-hidpp: G920 remove deadzones
Ensure that the G920 is not given the default deadzones. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index fc553e3..f2a4811 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1441,6 +1441,25 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + /* Ensure that Logitech G920 is not given a default fuzz/flat value */ + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + if (usage->type == EV_ABS && (usage->code == ABS_X || + usage->code == ABS_Y || usage->code == ABS_Z || + usage->code == ABS_RZ)) { + field->application = HID_GD_MULTIAXIS; + } + } + + return 0; +} + + static void hidpp_populate_input(struct hidpp_device *hidpp, struct input_dev *input, bool origin_is_hid_core) { @@ -1875,6 +1894,7 @@ static struct hid_driver hidpp_driver = { .raw_event = hidpp_raw_event, .input_configured = hidpp_input_configured, .input_mapping = hidpp_input_mapping, + .input_mapped = hidpp_input_mapped, }; module_hid_driver(hidpp_driver); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V3 3/6] HID: hid-logitech-hidpp: Add basic support for Logitech G920
This patch adds basic support for the Logitech G920 wheel when in HID mode. This wheel 'speaks' the HID++ protocol, and therefor is driven with hid-logitech-hidpp. At this stage the driver only shows that it can communicate with the wheel by outputting the name discovered over HID++. The normal HID functions work to give input functionality using joystick/event interface. Note: in 'hidpp_probe()' we have to start the hardware to get packets flowing, the same might apply in future for other devices which don't use the unifying protocol. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h| 1 + drivers/hid/hid-logitech-hidpp.c | 71 +++- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a69..190260c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1902,6 +1902,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ac1feea..269e758 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -619,6 +619,7 @@ #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_20xc219 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f +#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0f53dc8..98b8f09 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -49,11 +49,13 @@ MODULE_PARM_DESC(disable_tap_to_click, #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) #define HIDPP_QUIRK_CLASS_K400 BIT(2) +#define HIDPP_QUIRK_CLASS_G920 BIT(3) /* bits 2..20 are reserved for classes */ #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) #define HIDPP_QUIRK_NO_HIDINPUTBIT(23) +#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ HIDPP_QUIRK_CONNECT_EVENTS) @@ -146,8 +148,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp_dev); static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); int fields_count, ret; + hidpp = hid_get_drvdata(hdev); + switch (hidpp_report->report_id) { case REPORT_ID_HIDPP_SHORT: fields_count = HIDPP_REPORT_SHORT_LENGTH; @@ -168,9 +173,13 @@ static int __hidpp_send_report(struct hid_device *hdev, */ hidpp_report->device_index = 0xff; - ret = hid_hw_raw_request(hdev, hidpp_report->report_id, - (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); + if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { + ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count); + } else { + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + } return ret == fields_count ? 0 : -1; } @@ -1430,10 +1439,12 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) else name = hidpp_get_device_name(hidpp); - if (!name) + if (!name) { hid_err(hdev, "unable to retrieve the name of the device"); - else + } else { + dbg_hid("HID++: Got name: %s\n", name); snprintf(hdev->name, sizeof(hdev->name), "%s", name); + } kfree(name); } @@ -1596,6 +1607,25 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
[Patch-V3 5/6] HID: Add vendor specific usage pages for Logitech G920
The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft <elias@gmail.com> Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-input.c | 4 include/linux/hid.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2ba6bf6..f4eeb6b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -960,6 +960,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel goto ignore; case HID_UP_LOGIVENDOR: + /* intentional fallback */ + case HID_UP_LOGIVENDOR2: + /* intentional fallback */ + case HID_UP_LOGIVENDOR3: goto ignore; case HID_UP_PID: diff --git a/include/linux/hid.h b/include/linux/hid.h index 251a1d3..a6d7a3f 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR0xff00 #define HID_UP_CUSTOM 0x00ff #define HID_UP_LOGIVENDOR 0xffbc +#define HID_UP_LOGIVENDOR2 0xff09 +#define HID_UP_LOGIVENDOR3 0xff43 #define HID_UP_LNVENDOR0xffa0 #define HID_UP_SENSOR 0x0020 -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V3 4/6] HID: hid-logitech-hidpp: Add range sysfs for Logitech G920
The G920 can adjust the amount of 'turn' it permits, this patch adds a sysfs file 'range' to control this. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 140 ++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 98b8f09..fc553e3 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1295,6 +1295,133 @@ static int k400_connect(struct hid_device *hdev, bool connected) return k400_disable_tap_to_click(hidpp); } +/* - */ +/* Logitech G920 Driving Force Racing Wheel for Xbox One */ +/* - */ + +#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 + +/* Using session ID = 1 */ +#define CMD_G920_FORCE_GET_APERTURE0x51 +#define CMD_G920_FORCE_SET_APERTURE0x61 + +struct g920_private_data { + u8 force_feature; + u16 range; +}; + +#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) + +static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); +} + +static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + struct hidpp_report response; + u8 params[2]; + int ret; + u16 range = simple_strtoul(buf, NULL, 10); + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + if (range < 180) + range = 180; + else if (range > 900) + range = 900; + + params[0] = range >> 8; + params[1] = range & 0x00FF; + + ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, + CMD_G920_FORCE_SET_APERTURE, params, 2, ); + if (ret) + return ret; + + pdata->range = range; + return count; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); + +static int g920_allocate(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct g920_private_data *pdata; + + pdata = devm_kzalloc(>dev, sizeof(struct g920_private_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + hidpp->private_data = pdata; + + return 0; +} + +static int g920_get_config(struct hidpp_device *hidpp) +{ + struct g920_private_data *pdata = hidpp->private_data; + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hidpp->hid_dev, "Private driver data not found!\n"); + return -EINVAL; + } + + /* Find feature and store for later use */ + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, + _index, _type); + if (ret) + return ret; + + pdata->force_feature = feature_index; + + /* Read current Range */ + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_G920_FORCE_GET_APERTURE, NULL, 0, ); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } + if (ret) + return ret; + + pdata->range = get_unaligned_be16([0]); + + /* Create sysfs interface */ + ret = device_create_file(&(hidpp->hid_dev->dev), _attr_range); + if (ret) + hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); + + return 0; +} + /* -- */ /* Generic HID++ devices */ /* --
[Patch-V3 1/6] INPUT: xpad: switch Logitech G920 Wheel into HID mode
When plugged in the Logitech G920 wheel starts with USBID 046d:c261 and behaviors as a vendor specific class. If a 'magic' byte sequence is sent the wheel will detach and reconnect as a HID device with the USBID 046d:c262. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/input/joystick/xpad.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fd4100d..338a3a4 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,6 +93,7 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG(MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) +#define SWITCH_G920_TO_HID_MODE(1 << 3) #define XTYPE_XBOX0 #define XTYPE_XBOX360 1 @@ -134,6 +135,7 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -299,6 +301,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e),/* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e),/* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d),/* Logitech X-Box 360 style controllers */ + XPAD_XBOXONE_VENDOR(0x046d),/* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738),/* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f),/* 0x0e6f X-Box 360 controllers */ @@ -1048,6 +1051,19 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; + /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ + /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ + if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { + xpad->odata[0] = 0x0F; + xpad->odata[1] = 0x00; + xpad->odata[2] = 0x01; + xpad->odata[3] = 0x01; + xpad->odata[4] = 0x42; + xpad->irq_out->transfer_buffer_length = 5; + + return usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V3 2/6] HID: hid-logitech-hidpp: Add support for very long packets
Patch add support for the 'very long' HID++ packets, which are 64 bytes in length. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 59 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 5fd9786..0f53dc8 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -40,9 +40,11 @@ MODULE_PARM_DESC(disable_tap_to_click, #define REPORT_ID_HIDPP_SHORT 0x10 #define REPORT_ID_HIDPP_LONG 0x11 +#define REPORT_ID_HIDPP_VERY_LONG 0x12 #define HIDPP_REPORT_SHORT_LENGTH 7 #define HIDPP_REPORT_LONG_LENGTH 20 +#define HIDPP_REPORT_VERY_LONG_LENGTH 64 #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -81,13 +83,13 @@ MODULE_PARM_DESC(disable_tap_to_click, struct fap { u8 feature_index; u8 funcindex_clientid; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct rap { u8 sub_id; u8 reg_address; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct hidpp_report { @@ -153,6 +155,9 @@ static int __hidpp_send_report(struct hid_device *hdev, case REPORT_ID_HIDPP_LONG: fields_count = HIDPP_REPORT_LONG_LENGTH; break; + case REPORT_ID_HIDPP_VERY_LONG: + fields_count = HIDPP_REPORT_VERY_LONG_LENGTH; + break; default: return -ENODEV; } @@ -217,8 +222,9 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, goto exit; } - if (response->report_id == REPORT_ID_HIDPP_LONG && - response->fap.feature_index == HIDPP20_ERROR) { + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + response->fap.feature_index == HIDPP20_ERROR) { ret = response->fap.params[1]; dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); goto exit; @@ -243,7 +249,11 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); if (!message) return -ENOMEM; - message->report_id = REPORT_ID_HIDPP_LONG; + + if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) + message->report_id = REPORT_ID_HIDPP_VERY_LONG; + else + message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; memcpy(>fap.params, params, param_count); @@ -258,13 +268,23 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, struct hidpp_report *response) { struct hidpp_report *message; - int ret; + int ret, max_count; - if ((report_id != REPORT_ID_HIDPP_SHORT) && - (report_id != REPORT_ID_HIDPP_LONG)) + switch (report_id) { + case REPORT_ID_HIDPP_SHORT: + max_count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: + max_count = HIDPP_REPORT_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_VERY_LONG: + max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + default: return -EINVAL; + } - if (param_count > sizeof(message->rap.params)) + if (param_count > max_count) return -EINVAL; message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); @@ -508,10 +528,19 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, if (ret) return ret; - if (response.report_id == REPORT_ID_HIDPP_LONG) + switch (response.report_id) { + case REPORT_ID_HIDPP_VERY_LONG: + count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: count = HIDPP_REPORT_LONG_LENGTH - 4; - else + break; + case REPORT_ID_HIDPP_SHORT: count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + default: + return -EPROTO; + } if (len_buf < count) count = len_buf; @@ -1347,6 +1376,14 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, /* Generic HID++ processing. */ switch (data[0]) { + case REPORT_ID_HIDPP_VERY_LONG: + if (size != HIDPP_REP
[Patch-V3 0/6] HID: Support for the Logitech G920 Wheel
Patch-V3 tweaked as per Benjamin's and Dmitry's requests. This series of patches provide input support for the Logitech G920 gaming wheel. This wheel is internally different from the other Logitech wheels; when first connected it is in X-Box mode and can instructed to switch to HID with a 'magic command' (1st patch). Once the wheel reconnects in HID mode it can communicate with the HID++ protocol, but using a 'very long' packet size (2nd patch). Basic input operation is possible with adustment of the 'range' (the amount that the wheel turns) controlled via the '/sys' interface, same concept as the G25/G27/etc. We also discovered that wheel uses some vendor specific pages, which confuse the HID system resulting in lots of additional axis reported. This is prevented by ignoring these pages (5th patch, thank you Elias). The future... as the internals of the wheel are considerably more 'capable' we are working on implementing Force Feedback using the forth-coming KLGD system. Simon Wood (6): INPUT: xpad: switch Logitech G920 Wheel into HID mode HID: hid-logitech-hidpp: Add support for very long packets HID: hid-logitech-hidpp: Add basic support for Logitech G920 HID: hid-logitech-hidpp: Add range sysfs for Logitech G920 HID: Add vendor specific usage pages for Logitech G920 HID: hid-logitech-hidpp: G920 remove deadzones drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h| 1 + drivers/hid/hid-input.c | 4 + drivers/hid/hid-logitech-hidpp.c | 288 +++ drivers/input/joystick/xpad.c| 16 +++ include/linux/hid.h | 2 + 6 files changed, 285 insertions(+), 27 deletions(-) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Valve's "Steam Controller" behaves strangely
Just a heads up to anyone who wants to play with these on Linux. They do NOT behave as a normal gamepad, they don't present a JS0 interface and the events are a little wonky. They do present the axis/buttons data in the 'hidraw' stream, so there is some hope that we can support them. If anyone wants to collaborate, drop me a note. -- # hexdump -v -e '64/1 "%02x " "\n"' < /dev/hidraw1 01 00 01 3c 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 a7 c2 bc fa 9f 13 54 80 0a f6 df e5 3f 01 00 01 3c 23 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 47 a7 c2 bc fa 9f 13 54 80 0a f6 df e5 3f -- Attached are some quick notes from 15mins playing with the device. Cheers, Simon. Wireless Dongle Insert -- Nov 12 17:47:17 retrobox kernel: [ 2016.564082] usb 2-2: new full-speed USB device number 2 using uhci_hcd Nov 12 17:47:17 retrobox kernel: [ 2016.733096] usb 2-2: New USB device found, idVendor=28de, idProduct=1142 Nov 12 17:47:17 retrobox kernel: [ 2016.733108] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 Nov 12 17:47:17 retrobox kernel: [ 2016.733114] usb 2-2: Product: Steam Controller Nov 12 17:47:17 retrobox kernel: [ 2016.733121] usb 2-2: Manufacturer: Valve Software Nov 12 17:47:18 retrobox mtp-probe: checking bus 2, device 2: "/sys/devices/pci:00/:00:1d.0/usb2/2-2" Nov 12 17:47:18 retrobox mtp-probe: bus: 2, device: 2 was not an MTP device Nov 12 17:47:19 retrobox kernel: [ 2018.234725] hidraw: raw HID events driver (C) Jiri Kosina Nov 12 17:47:19 retrobox kernel: [ 2018.374556] usbcore: registered new interface driver usbhid Nov 12 17:47:19 retrobox kernel: [ 2018.374562] usbhid: USB HID core driver Nov 12 17:47:19 retrobox kernel: [ 2018.499064] input: Valve Software Steam Controller as /devices/pci:00/:00:1d.0/usb2/2-2/2-2:1.0/0003:28DE:1142.0001/input/input9 Nov 12 17:47:19 retrobox kernel: [ 2018.552665] hid-generic 0003:28DE:1142.0001: input,hidraw0: USB HID v1.11 Keyboard [Valve Software Steam Controller] on usb-:00:1d.0-2/input0 Nov 12 17:47:19 retrobox kernel: [ 2018.556660] hid-generic 0003:28DE:1142.0002: hiddev0,hidraw1: USB HID v1.11 Device [Valve Software Steam Controller] on usb-:00:1d.0-2/input1 Nov 12 17:47:19 retrobox kernel: [ 2018.560451] hid-generic 0003:28DE:1142.0003: hiddev0,hidraw2: USB HID v1.11 Device [Valve Software Steam Controller] on usb-:00:1d.0-2/input2 Nov 12 17:47:19 retrobox kernel: [ 2018.563159] hid-generic 0003:28DE:1142.0004: hiddev0,hidraw3: USB HID v1.11 Device [Valve Software Steam Controller] on usb-:00:1d.0-2/input3 Nov 12 17:47:19 retrobox kernel: [ 2018.566189] hid-generic 0003:28DE:1142.0005: hiddev0,hidraw4: USB HID v1.11 Device [Valve Software Steam Controller] on usb-:00:1d.0-2/input4 -- No events delivered, unless something is consuming hidraw (ie hexdump below). -- root@retrobox:/home/simon# evtest /dev/input/event8 Input driver version is 1.0.1 Input device ID: bus 0x3 vendor 0x28de product 0x1142 version 0x111 Input device name: "Valve Software Steam Controller" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 1 (KEY_ESC) Event code 2 (KEY_1) Event code 3 (KEY_2) Event code 4 (KEY_3) Event code 5 (KEY_4) Event code 6 (KEY_5) Event code 7 (KEY_6) Event code 8 (KEY_7) Event code 9 (KEY_8) Event code 10 (KEY_9) Event code 11 (KEY_0) Event code 12 (KEY_MINUS) Event code 13 (KEY_EQUAL) Event code 14 (KEY_BACKSPACE) Event code 15 (KEY_TAB) Event code 16 (KEY_Q) Event code 17 (KEY_W) Event code 18 (KEY_E) Event code 19 (KEY_R) Event code 20 (KEY_T) Event code 21 (KEY_Y) Event code 22 (KEY_U) Event code 23 (KEY_I) Event code 24 (KEY_O) Event code 25 (KEY_P) Event code 26 (KEY_LEFTBRACE) Event code 27 (KEY_RIGHTBRACE) Event code 28 (KEY_ENTER) Event code 29 (KEY_LEFTCTRL) Event code 30 (KEY_A) Event code 31 (KEY_S) Event code 32 (KEY_D) Event code 33 (KEY_F) Event code 34 (KEY_G) Event code 35 (KEY_H) Event code 36 (KEY_J) Event code 37 (KEY_K) Event code 38 (KEY_L) Event code 39 (KEY_SEMICOLON) Event code 40 (KEY_APOSTROPHE) Event code 41 (KEY_GRAVE) Event code 42 (KEY_LEFTSHIFT) Event code 43 (KEY_BACKSLASH) Event code 44 (KEY_Z) Event code 45 (KEY_X) Event code 46 (KEY_C) Event code 47 (KEY_V) Event code 48 (KEY_B) Event code 49 (KEY_N) Event code 50 (KEY_M) Event code 51 (KEY_COMMA) Event code 52 (KEY_DOT) Event code 53 (KEY_SLASH) Event code 54 (KEY_RIGHTSHIFT) Event code 55 (KEY_KPASTERISK) Event code 56 (KEY_LEFTALT) Event code 57 (KEY_SPACE) Event code 58 (KEY_CAPSLOCK) Event code 59 (KEY_F1)
[Patch-V2 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel
When plugged in the Logitech G920 wheel starts with USBID 046d:c261 and behaviors as a vendor specific class. If a 'magic' byte sequence is sent the wheel will detach and reconnect as a HID device with the USBID 046d:c262. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/input/joystick/xpad.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index fd4100d..338a3a4 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,6 +93,7 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG(MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) +#define SWITCH_G920_TO_HID_MODE(1 << 3) #define XTYPE_XBOX0 #define XTYPE_XBOX360 1 @@ -134,6 +135,7 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -299,6 +301,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e),/* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e),/* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d),/* Logitech X-Box 360 style controllers */ + XPAD_XBOXONE_VENDOR(0x046d),/* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738),/* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f),/* 0x0e6f X-Box 360 controllers */ @@ -1048,6 +1051,19 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; + /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ + /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ + if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { + xpad->odata[0] = 0x0F; + xpad->odata[1] = 0x00; + xpad->odata[2] = 0x01; + xpad->odata[3] = 0x01; + xpad->odata[4] = 0x42; + xpad->irq_out->transfer_buffer_length = 5; + + return usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V2 2/6] HID: hid-logitech-hidpp: Add support for very long packets
Patch add support for the 'very long' HID++ packets, which are 64 bytes in length. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 59 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 5fd9786..0f53dc8 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -40,9 +40,11 @@ MODULE_PARM_DESC(disable_tap_to_click, #define REPORT_ID_HIDPP_SHORT 0x10 #define REPORT_ID_HIDPP_LONG 0x11 +#define REPORT_ID_HIDPP_VERY_LONG 0x12 #define HIDPP_REPORT_SHORT_LENGTH 7 #define HIDPP_REPORT_LONG_LENGTH 20 +#define HIDPP_REPORT_VERY_LONG_LENGTH 64 #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -81,13 +83,13 @@ MODULE_PARM_DESC(disable_tap_to_click, struct fap { u8 feature_index; u8 funcindex_clientid; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct rap { u8 sub_id; u8 reg_address; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct hidpp_report { @@ -153,6 +155,9 @@ static int __hidpp_send_report(struct hid_device *hdev, case REPORT_ID_HIDPP_LONG: fields_count = HIDPP_REPORT_LONG_LENGTH; break; + case REPORT_ID_HIDPP_VERY_LONG: + fields_count = HIDPP_REPORT_VERY_LONG_LENGTH; + break; default: return -ENODEV; } @@ -217,8 +222,9 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, goto exit; } - if (response->report_id == REPORT_ID_HIDPP_LONG && - response->fap.feature_index == HIDPP20_ERROR) { + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + response->fap.feature_index == HIDPP20_ERROR) { ret = response->fap.params[1]; dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); goto exit; @@ -243,7 +249,11 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); if (!message) return -ENOMEM; - message->report_id = REPORT_ID_HIDPP_LONG; + + if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) + message->report_id = REPORT_ID_HIDPP_VERY_LONG; + else + message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; memcpy(>fap.params, params, param_count); @@ -258,13 +268,23 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, struct hidpp_report *response) { struct hidpp_report *message; - int ret; + int ret, max_count; - if ((report_id != REPORT_ID_HIDPP_SHORT) && - (report_id != REPORT_ID_HIDPP_LONG)) + switch (report_id) { + case REPORT_ID_HIDPP_SHORT: + max_count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: + max_count = HIDPP_REPORT_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_VERY_LONG: + max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + default: return -EINVAL; + } - if (param_count > sizeof(message->rap.params)) + if (param_count > max_count) return -EINVAL; message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); @@ -508,10 +528,19 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, if (ret) return ret; - if (response.report_id == REPORT_ID_HIDPP_LONG) + switch (response.report_id) { + case REPORT_ID_HIDPP_VERY_LONG: + count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: count = HIDPP_REPORT_LONG_LENGTH - 4; - else + break; + case REPORT_ID_HIDPP_SHORT: count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + default: + return -EPROTO; + } if (len_buf < count) count = len_buf; @@ -1347,6 +1376,14 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, /* Generic HID++ processing. */ switch (data[0]) { + case REPORT_ID_HIDPP_VERY_LONG: + if (size != HIDPP_REP
[Patch-V2 3/6] HID: hid-logitech-hidpp: Add basic support for Logitech G920
This patch adds basic support for the Logitech G920 wheel when in HID mode. This wheel 'speaks' the HID++ protocol, and therefor is driven with hid-logitech-hidpp. At this stage the driver only shows that it can communicate with the wheel by outputting the name discovered over HID++. The normal HID functions work to give input functionality using joystick/event interface. Note: in 'hidpp_probe()' we have to start the hardware to get packets flowing, the same might apply in future for other devices which don't use the unifying protocol. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h| 1 + drivers/hid/hid-logitech-hidpp.c | 71 +++- 3 files changed, 57 insertions(+), 16 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index c6f7a69..190260c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1902,6 +1902,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index ac1feea..269e758 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -619,6 +619,7 @@ #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_20xc219 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f +#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 0f53dc8..699a486 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -49,11 +49,13 @@ MODULE_PARM_DESC(disable_tap_to_click, #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) #define HIDPP_QUIRK_CLASS_K400 BIT(2) +#define HIDPP_QUIRK_CLASS_G920 BIT(3) /* bits 2..20 are reserved for classes */ #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) #define HIDPP_QUIRK_NO_HIDINPUTBIT(23) +#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ HIDPP_QUIRK_CONNECT_EVENTS) @@ -146,8 +148,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp_dev); static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); int fields_count, ret; + hidpp = hid_get_drvdata(hdev); + switch (hidpp_report->report_id) { case REPORT_ID_HIDPP_SHORT: fields_count = HIDPP_REPORT_SHORT_LENGTH; @@ -168,9 +173,13 @@ static int __hidpp_send_report(struct hid_device *hdev, */ hidpp_report->device_index = 0xff; - ret = hid_hw_raw_request(hdev, hidpp_report->report_id, - (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); + if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { + ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count); + } else { + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + } return ret == fields_count ? 0 : -1; } @@ -1430,10 +1439,12 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) else name = hidpp_get_device_name(hidpp); - if (!name) + if (!name) { hid_err(hdev, "unable to retrieve the name of the device"); - else + } else { + dbg_hid("HID++: Got name: %s\n", name); snprintf(hdev->name, sizeof(hdev->name), "%s", name); + } kfree(name); } @@ -1596,6 +1607,25 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
[Patch-V2 0/6] HID: Support for the Logitech G920 Wheel
Patch-V2 tweaked as per Benjamin's requests. This series of patches provide input support for the Logitech G920 gaming wheel. This wheel is internally different from the other Logitech wheels; when first connected it is in X-Box mode and can instructed to switch to HID with a 'magic command' (1st patch). Once the wheel reconnects in HID mode it can communicate with the HID++ protocol, but using a 'very long' packet size (2nd patch). Basic input operation is possible with adustment of the 'range' (the amount that the wheel turns) controlled via the '/sys' interface, same concept as the G25/G27/etc. We also discovered that wheel uses some vendor specific pages, which confuse the HID system resulting in lots of additional axis reported. This is prevented by ignoring these pages (5th patch, thank you Elias). Note: These patches are applied to Jiri's 'for-next' tree to work with the other HID++ changes already queued for 4.4. The future... as the internals of the wheel are considerably more 'capable' we are working on implementing Force Feedback using the forth-coming KLGD system. [Patch-V2 1/6] INPUT: xpad: Add minimal support for Logitech G920 [Patch-V2 2/6] HID: hid-logitech-hidpp: Add support for very long [Patch-V2 3/6] HID: hid-logitech-hidpp: Add basic support for [Patch-V2 4/6] HID: hid-logitech-hidpp: Add range sysfs for Logitech [Patch-V2 5/6] HID: Add vendor specific usage pages for Logitech G920 [Patch-V2 6/6] HID: hid-logitech-hidpp: G920 remove deadzones -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V2 6/6] HID: hid-logitech-hidpp: G920 remove deadzones
Ensure that the G920 is not given the default deadzones. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 80ebd1c..e235f3d 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1441,6 +1441,25 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + + /* Ensure that Logitech G920 is not given a default fuzz/flat value */ + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + if (usage->type == EV_ABS && (usage->code == ABS_X || + usage->code == ABS_Y || usage->code == ABS_Z || + usage->code == ABS_RZ)) { + field->application = HID_GD_MULTIAXIS; + } + } + + return 0; +} + + static void hidpp_populate_input(struct hidpp_device *hidpp, struct input_dev *input, bool origin_is_hid_core) { @@ -1875,6 +1894,7 @@ static struct hid_driver hidpp_driver = { .raw_event = hidpp_raw_event, .input_configured = hidpp_input_configured, .input_mapping = hidpp_input_mapping, + .input_mapped = hidpp_input_mapped, }; module_hid_driver(hidpp_driver); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V2 5/6] HID: Add vendor specific usage pages for Logitech G920
The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft <elias@gmail.com> Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-input.c | 4 include/linux/hid.h | 2 ++ 2 files changed, 6 insertions(+) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 2ba6bf6..f4eeb6b 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -960,6 +960,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel goto ignore; case HID_UP_LOGIVENDOR: + /* intentional fallback */ + case HID_UP_LOGIVENDOR2: + /* intentional fallback */ + case HID_UP_LOGIVENDOR3: goto ignore; case HID_UP_PID: diff --git a/include/linux/hid.h b/include/linux/hid.h index 251a1d3..a6d7a3f 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR0xff00 #define HID_UP_CUSTOM 0x00ff #define HID_UP_LOGIVENDOR 0xffbc +#define HID_UP_LOGIVENDOR2 0xff09 +#define HID_UP_LOGIVENDOR3 0xff43 #define HID_UP_LNVENDOR0xffa0 #define HID_UP_SENSOR 0x0020 -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[Patch-V2 4/6] HID: hid-logitech-hidpp: Add range sysfs for Logitech G920
The G920 can adjust the amount of 'turn' it permits, this patch adds a sysfs file 'range' to control this. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 140 ++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 699a486..80ebd1c 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1295,6 +1295,133 @@ static int k400_connect(struct hid_device *hdev, bool connected) return k400_disable_tap_to_click(hidpp); } +/* - */ +/* Logitech G920 Driving Force Racing Wheel for Xbox One */ +/* - */ + +#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 + +/* Using session ID = 1 */ +#define CMD_G920_FORCE_GET_APERTURE0x51 +#define CMD_G920_FORCE_SET_APERTURE0x61 + +struct g920_private_data { + u8 force_feature; + u16 range; +}; + +#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) + +static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); +} + +static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + struct hidpp_report response; + u8 params[2]; + int ret; + u16 range = simple_strtoul(buf, NULL, 10); + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + if (range < 180) + range = 180; + else if (range > 900) + range = 900; + + params[0] = range >> 8; + params[1] = range & 0x00FF; + + ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, + CMD_G920_FORCE_SET_APERTURE, params, 2, ); + if (ret) + return ret; + + pdata->range = range; + return count; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); + +static int g920_allocate(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct g920_private_data *pdata; + + pdata = devm_kzalloc(>dev, sizeof(struct g920_private_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + hidpp->private_data = pdata; + + return 0; +} + +static int g920_get_config(struct hidpp_device *hidpp) +{ + struct g920_private_data *pdata = hidpp->private_data; + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hidpp->hid_dev, "Private driver data not found!\n"); + return -EINVAL; + } + + /* Find feature and store for later use */ + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, + _index, _type); + if (ret) + return ret; + + pdata->force_feature = feature_index; + + /* Read current Range */ + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_G920_FORCE_GET_APERTURE, NULL, 0, ); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } + if (ret) + return ret; + + pdata->range = get_unaligned_be16([0]); + + /* Create sysfs interface */ + ret = device_create_file(&(hidpp->hid_dev->dev), _attr_range); + if (ret) + hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); + + return 0; +} + /* -- */ /* Generic HID++ devices */ /* --
Re: [Patch-V2 0/6] HID: Support for the Logitech G920 Wheel
> Note: These patches are applied to Jiri's 'for-next' tree to work with > the other HID++ changes already queued for 4.4. Whoops, left this note in by mistake. These patches are against 4.4 HEAD. Simon. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/6] HID: hid-logitech-hidpp: G920 remove deadzones
> With this change, and the nitpicks in the other patches, the series is: > Reviewed-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com> Have Patch-V2 in progress. Other build problems stopped in last night but trying again with new pull - hopefully they are fixed. Simon -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] HID: hid-logitech-hidpp: Add support for very long packets
Patch add support for the 'very long' HID++ packets, which are 64 bytes in length. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 59 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 452e5d5..08e65e8 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -40,9 +40,11 @@ MODULE_PARM_DESC(disable_tap_to_click, #define REPORT_ID_HIDPP_SHORT 0x10 #define REPORT_ID_HIDPP_LONG 0x11 +#define REPORT_ID_HIDPP_VERY_LONG 0x12 #define HIDPP_REPORT_SHORT_LENGTH 7 #define HIDPP_REPORT_LONG_LENGTH 20 +#define HIDPP_REPORT_VERY_LONG_LENGTH 64 #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -81,13 +83,13 @@ MODULE_PARM_DESC(disable_tap_to_click, struct fap { u8 feature_index; u8 funcindex_clientid; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct rap { u8 sub_id; u8 reg_address; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct hidpp_report { @@ -153,6 +155,9 @@ static int __hidpp_send_report(struct hid_device *hdev, case REPORT_ID_HIDPP_LONG: fields_count = HIDPP_REPORT_LONG_LENGTH; break; + case REPORT_ID_HIDPP_VERY_LONG: + fields_count = HIDPP_REPORT_VERY_LONG_LENGTH; + break; default: return -ENODEV; } @@ -217,8 +222,9 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, goto exit; } - if (response->report_id == REPORT_ID_HIDPP_LONG && - response->fap.feature_index == HIDPP20_ERROR) { + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + response->fap.feature_index == HIDPP20_ERROR) { ret = response->fap.params[1]; dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); goto exit; @@ -243,7 +249,11 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); if (!message) return -ENOMEM; - message->report_id = REPORT_ID_HIDPP_LONG; + + if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) + message->report_id = REPORT_ID_HIDPP_VERY_LONG; + else + message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; memcpy(>fap.params, params, param_count); @@ -258,13 +268,23 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, struct hidpp_report *response) { struct hidpp_report *message; - int ret; + int ret, max_count; - if ((report_id != REPORT_ID_HIDPP_SHORT) && - (report_id != REPORT_ID_HIDPP_LONG)) + switch (report_id) { + case REPORT_ID_HIDPP_SHORT: + max_count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: + max_count = HIDPP_REPORT_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_VERY_LONG: + max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + default: return -EINVAL; + } - if (param_count > sizeof(message->rap.params)) + if (param_count > max_count) return -EINVAL; message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); @@ -508,10 +528,19 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, if (ret) return ret; - if (response.report_id == REPORT_ID_HIDPP_LONG) + switch (response.report_id) { + case REPORT_ID_HIDPP_VERY_LONG: + count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: count = HIDPP_REPORT_LONG_LENGTH - 4; - else + break; + case REPORT_ID_HIDPP_SHORT: count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + default: + return -EPROTO; + } if (len_buf < count) count = len_buf; @@ -1345,6 +1374,14 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, /* Generic HID++ processing. */ switch (data[0]) { + case REPORT_ID_HIDPP_VERY_LONG: + if (size != HIDPP_REP
[PATCH 3/6] HID: hid-logitech-hidpp: Add basic support for Logitech G920
This patch adds basic support for the Logitech G920 wheel when in HID mode. This wheel 'speaks' the HID++ protocol, and therefor is driven with hid-logitech-hidpp. At this stage the driver only shows that it can communicate with the wheel by outputting the name discovered over HID++. The normal HID functions work to give input functionality using joystick/event interface. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h| 1 + drivers/hid/hid-logitech-hidpp.c | 69 +++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bcd914a..60d564d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f769208..d3500c4 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -614,6 +614,7 @@ #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_20xc219 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f +#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 08e65e8..dbb9ff3 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -49,11 +49,13 @@ MODULE_PARM_DESC(disable_tap_to_click, #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) #define HIDPP_QUIRK_CLASS_K400 BIT(2) +#define HIDPP_QUIRK_CLASS_G920 BIT(3) /* bits 2..20 are reserved for classes */ #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) #define HIDPP_QUIRK_NO_HIDINPUTBIT(23) +#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24) #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ HIDPP_QUIRK_CONNECT_EVENTS) @@ -146,8 +148,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp_dev); static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); int fields_count, ret; + hidpp = hid_get_drvdata(hdev); + switch (hidpp_report->report_id) { case REPORT_ID_HIDPP_SHORT: fields_count = HIDPP_REPORT_SHORT_LENGTH; @@ -168,9 +173,13 @@ static int __hidpp_send_report(struct hid_device *hdev, */ hidpp_report->device_index = 0xff; - ret = hid_hw_raw_request(hdev, hidpp_report->report_id, - (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); + if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { + ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count); + } else { + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + } return ret == fields_count ? 0 : -1; } @@ -1430,8 +1439,10 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) if (!name) hid_err(hdev, "unable to retrieve the name of the device"); - else + else { + dbg_hid("HID++: Got name: %s\n", name); snprintf(hdev->name, sizeof(hdev->name), "%s", name); + } kfree(name); } @@ -1594,6 +1605,25 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_parse_fail; } + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) + connect_mask &= ~HID_CONNECT_HIDINPUT; + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + ret = hid_hw_start(
[PATCH 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel
When plugged in the Logitech G920 wheel starts with USBID 046d:c261 and behaviors as a vendor specific class. If a 'magic' byte sequence is sent the wheel will detach and reconnect as a HID device with the USBID 046d:c262. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/input/joystick/xpad.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f8850f9..af83f7e 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,6 +93,7 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG(MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) +#define SWITCH_G920_TO_HID_MODE(1 << 3) #define XTYPE_XBOX0 #define XTYPE_XBOX360 1 @@ -133,6 +134,7 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -299,6 +301,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e),/* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e),/* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d),/* Logitech X-Box 360 style controllers */ + XPAD_XBOXONE_VENDOR(0x046d),/* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738),/* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f),/* 0x0e6f X-Box 360 controllers */ @@ -1021,6 +1024,19 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; + /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ + /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ + if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { + xpad->odata[0] = 0x0F; + xpad->odata[1] = 0x00; + xpad->odata[2] = 0x01; + xpad->odata[3] = 0x01; + xpad->odata[4] = 0x42; + xpad->irq_out->transfer_buffer_length = 5; + + return usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] HID: hid-logitech-hidpp: G920 remove deadzones
Ensure that the G920 is not given the default deadzones. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 03e01be..853b9c2 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1441,6 +1441,27 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int hidpp_input_mapped(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + /* Ensure that Logitech G920 is not given a default fuzz/flat value */ + if (usage->type == EV_ABS && (usage->code == ABS_X || + usage->code == ABS_Y || usage->code == ABS_Z || + usage->code == ABS_RZ)) { + switch (hdev->product) { + case USB_DEVICE_ID_LOGITECH_G920_WHEEL: + field->application = HID_GD_MULTIAXIS; + break; + default: + break; + } + } + + return 0; +} + + static void hidpp_populate_input(struct hidpp_device *hidpp, struct input_dev *input, bool origin_is_hid_core) { @@ -1873,6 +1894,7 @@ static struct hid_driver hidpp_driver = { .raw_event = hidpp_raw_event, .input_configured = hidpp_input_configured, .input_mapping = hidpp_input_mapping, + .input_mapped = hidpp_input_mapped, }; module_hid_driver(hidpp_driver); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] HID: Add vendor specific usage pages for Logitech G920
The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft <elias@gmail.com> Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-input.c | 2 +- include/linux/hid.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 53aeaf6..c120be5 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -959,7 +959,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel set_bit(EV_REP, input->evbit); goto ignore; - case HID_UP_LOGIVENDOR: + case HID_UP_LOGIVENDOR: case HID_UP_LOGIVENDOR2: case HID_UP_LOGIVENDOR3: goto ignore; case HID_UP_PID: diff --git a/include/linux/hid.h b/include/linux/hid.h index f17980d..ce1d883 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR0xff00 #define HID_UP_CUSTOM 0x00ff #define HID_UP_LOGIVENDOR 0xffbc +#define HID_UP_LOGIVENDOR2 0xff09 +#define HID_UP_LOGIVENDOR3 0xff43 #define HID_UP_LNVENDOR0xffa0 #define HID_UP_SENSOR 0x0020 -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
HID: Support for the Logitech G920 wheel
This series of patches provide input support for the Logitech G920 gaming wheel. This wheel is internally different from the other Logitech wheels; when first connected it is in X-Box mode and can instructed to switch to HID with a 'magic command' (1st patch). Once the wheel reconnects in HID mode it can communicate with the HID++ protocol, but using a 'very long' packet size (2nd patch). Basic input operation is possible with adustment of the 'range' (the amount that the wheel turns) controlled via the '/sys' interface, same concept as the G25/G27/etc. We also discovered that wheel uses some vendor specific pages, which confuse the HID system resulting in lots of additional axis reported. This is prevented by ignoring these pages (5th patch, thank you Elias). Note: These patches are applied to Jiri's 'for-next' tree to work with the other HID++ changes already queued for 4.4. [PATCH 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel [PATCH 2/6] HID: hid-logitech-hidpp: Add support for very long [PATCH 3/6] HID: hid-logitech-hidpp: Add basic support for Logitech [PATCH 4/6] HID: hid-logitech-hidpp: Add range sysfs for Logitech [PATCH 5/6] HID: Add vendor specific usage pages for Logitech G920 [PATCH 6/6] HID: hid-logitech-hidpp: G920 remove deadzones The future... as the internals of the wheel are considerably more 'capable' we are working on implementing Force Feedback using the forth-coming KLGD system. -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] HID: hid-logitech-hidpp: Add range sysfs for Logitech G920
The G920 can adjust the amount of 'turn' it permits, this patch adds a sysfs file 'range' to control this. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-logitech-hidpp.c | 140 ++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index dbb9ff3..03e01be 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1295,6 +1295,133 @@ static int k400_connect(struct hid_device *hdev, bool connected) return k400_disable_tap_to_click(hidpp); } +/* - */ +/* Logitech G920 Driving Force Racing Wheel for Xbox One */ +/* - */ + +#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 + +/* Using session ID = 1 */ +#define CMD_G920_FORCE_GET_APERTURE0x51 +#define CMD_G920_FORCE_SET_APERTURE0x61 + +struct g920_private_data { + u8 force_feature; + u16 range; +}; + +#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) + +static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); +} + +static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + struct hidpp_report response; + u8 params[2]; + int ret; + u16 range = simple_strtoul(buf, NULL, 10); + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + if (range < 180) + range = 180; + else if (range > 900) + range = 900; + + params[0] = range >> 8; + params[1] = range & 0x00FF; + + ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, + CMD_G920_FORCE_SET_APERTURE, params, 2, ); + if (ret) + return ret; + + pdata->range = range; + return count; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); + +static int g920_allocate(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct g920_private_data *pdata; + + pdata = devm_kzalloc(>dev, sizeof(struct g920_private_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + hidpp->private_data = pdata; + + return 0; +} + +static int g920_get_config(struct hidpp_device *hidpp) +{ + struct g920_private_data *pdata = hidpp->private_data; + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hidpp->hid_dev, "Private driver data not found!\n"); + return -EINVAL; + } + + /* Find feature and store for later use */ + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, + _index, _type); + if (ret) + return ret; + + pdata->force_feature = feature_index; + + /* Read current Range */ + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_G920_FORCE_GET_APERTURE, NULL, 0, ); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } + if (ret) + return ret; + + pdata->range = get_unaligned_be16([0]); + + /* Create sysfs interface */ + ret = device_create_file(&(hidpp->hid_dev->dev), _attr_range); + if (ret) + hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); + + return 0; +} + /* -- */ /* Generic HID++ devices */ /* --
[PATCH 1/2] HID: hid-logitech: Simplify wheel detection scheme
Simplfy how hid-logitech driver detects the native mode of the wheel, done by looking at the USB-ID revision and comparing bit mask. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-lg4ff.c | 70 - 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 02cec83..b363d88 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -114,16 +114,12 @@ struct lg4ff_compat_mode_switch { }; struct lg4ff_wheel_ident_info { + const u32 modes; const u16 mask; const u16 result; const u16 real_product_id; }; -struct lg4ff_wheel_ident_checklist { - const u32 count; - const struct lg4ff_wheel_ident_info *models[]; -}; - struct lg4ff_multimode_wheel { const u16 product_id; const u32 alternate_modes; @@ -174,36 +170,39 @@ static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = { /* Multimode wheel identificators */ static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { + LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 0xf000, 0x1000, USB_DEVICE_ID_LOGITECH_DFP_WHEEL }; static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { + LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 0xff00, 0x1200, USB_DEVICE_ID_LOGITECH_G25_WHEEL }; static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { + LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 0xfff0, 0x1230, USB_DEVICE_ID_LOGITECH_G27_WHEEL }; static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { + LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 0xff00, 0x1300, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL }; /* Multimode wheel identification checklists */ -static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = { - 4, - {_dfgt_ident_info, -_g27_ident_info, -_g25_ident_info, -_dfp_ident_info} +static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = { + _dfgt_ident_info, + _g27_ident_info, + _g25_ident_info, + _dfp_ident_info }; /* Compatibility mode switching commands */ @@ -1037,41 +1036,28 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) { - const struct lg4ff_wheel_ident_checklist *checklist; - int i, from_idx, to_idx; + u32 current_mode; + int i; - switch (reported_product_id) { - case USB_DEVICE_ID_LOGITECH_WHEEL: - case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: - checklist = _main_checklist; - from_idx = 0; - to_idx = checklist->count - 1; - break; - case USB_DEVICE_ID_LOGITECH_G25_WHEEL: - checklist = _main_checklist; - from_idx = 0; - to_idx = checklist->count - 2; /* End identity check at G25 */ - break; - case USB_DEVICE_ID_LOGITECH_G27_WHEEL: - checklist = _main_checklist; - from_idx = 1; /* Start identity check at G27 */ - to_idx = checklist->count - 3; /* End identity check at G27 */ - break; - case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: - checklist = _main_checklist; - from_idx = 0; - to_idx = checklist->count - 4; /* End identity check at DFGT */ - break; - default: - return 0; + /* identify current mode from USB PID */ + for (i = 1; i < ARRAY_SIZE(lg4ff_alternate_modes); i++) { + dbg_hid("Testing whether PID is %X\n", lg4ff_alternate_modes[i].product_id); + if (reported_product_id == lg4ff_alternate_modes[i].product_id) + break; } - for (i = from_idx; i <= to_idx; i++) { - const u16 mask = checklist->models[i]->mask; - const u16 result = checklist->models[i]->result; - const u16 real_product_id = checklist->models[i]->real_product_id; + if (i == ARRAY_SIZE(lg4ff_alternate_modes)) + return 0; + + current_mode = BIT(i); + + for (i = 0; i < ARRAY_SIZE(lg4ff_main_checklist); i++) { + const u16 mask = lg4ff_main_checklist[i]->mask; + const u16 result = lg4ff_main_checklist[i]->result; + const u16 real_product_id = lg4ff_main_checklist[i]->real_product_id; - if ((bcdDevice & mask) == result) { + if ((current_mode & lg4ff_main_checklist[i]->modes) && \ + (bcdDevice & mask) == result) {
[PATCH 2/2] HID: hid-logitech: Add support for G29
At present the G29 is mis-identified as a DFGT, this patch ensures that the wheel is correctly detected and allows setting the LEDs and turning range via the '/sys' interface. This wheel can also emulate other types of Logitech wheels. Signed-off-by: Simon Wood <si...@mungewell.org> --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-lg.c| 9 drivers/hid/hid-lg4ff.c | 57 + 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 70a11ac..949d804 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 5332fb7..c20ac76 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi, usage->code == ABS_Y || usage->code == ABS_Z || usage->code == ABS_RZ)) { switch (hdev->product) { + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: case USB_DEVICE_ID_LOGITECH_WHEEL: case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct hid_field *field, static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { + struct usb_interface *iface = to_usb_interface(hdev->dev.parent); + __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; + /* Only work with the 1st interface (G29 presents multiple) */ + if (iface_num != 0) { + dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); + return -ENODEV; + } + drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); if (!drv_data) { hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index b363d88..fbddcb3 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -45,7 +45,8 @@ #define LG4FF_MODE_G25_IDX 3 #define LG4FF_MODE_DFGT_IDX 4 #define LG4FF_MODE_G27_IDX 5 -#define LG4FF_MODE_MAX_IDX 6 +#define LG4FF_MODE_G29_IDX 6 +#define LG4FF_MODE_MAX_IDX 7 #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) @@ -53,6 +54,7 @@ #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) #define LG4FF_DFEX_TAG "DF-EX" #define LG4FF_DFEX_NAME "Driving Force / Formula EX" @@ -62,6 +64,8 @@ #define LG4FF_G25_NAME "G25 Racing Wheel" #define LG4FF_G27_TAG "G27" #define LG4FF_G27_NAME "G27 Racing Wheel" +#define LG4FF_G29_TAG "G29" +#define LG4FF_G29_NAME "G29 Racing Wheel" #define LG4FF_DFGT_TAG "DFGT" #define LG4FF_DFGT_NAME "Driving Force GT" @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = { {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL}, {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} }; @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = { {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, LG4FF_G27_TAG, LG4FF_G27_NAME}, + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, +LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 |
[RFC 4/5] HID: hid-logitech-hidpp: Add range sysfs for Logitech G920
The G920 can adjust the amount of 'turn' it permits, this patch adds a sysfs file 'range' to control this. --- drivers/hid/hid-logitech-hidpp.c | 140 ++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 76d7267..db05f55 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1170,6 +1170,133 @@ static int m560_input_mapping(struct hid_device *hdev, struct hid_input *hi, return -1; } +/* - */ +/* Logitech G920 Driving Force Racing Wheel for Xbox One */ +/* - */ + +#define HIDPP_PAGE_G920_FORCE_FEEDBACK 0x8123 + +/* Using session ID = 1 */ +#define CMD_G920_FORCE_GET_APERTURE0x51 +#define CMD_G920_FORCE_SET_APERTURE0x61 + +struct g920_private_data { + u8 force_feature; + u16 range; +}; + +#define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) + +static ssize_t g920_range_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + return scnprintf(buf, PAGE_SIZE, "%u\n", pdata->range); +} + +static ssize_t g920_range_store(struct device *dev, struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hid_device *hid = to_hid_device(dev); + struct hidpp_device *hidpp = hid_get_drvdata(hid); + struct g920_private_data *pdata; + struct hidpp_report response; + u8 params[2]; + int ret; + u16 range = simple_strtoul(buf, NULL, 10); + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hid, "Private driver data not found!\n"); + return -EINVAL; + } + + if (range < 180) + range = 180; + else if (range > 900) + range = 900; + + params[0] = range >> 8; + params[1] = range & 0x00FF; + + ret = hidpp_send_fap_command_sync(hidpp, pdata->force_feature, + CMD_G920_FORCE_SET_APERTURE, params, 2, ); + if (ret) + return ret; + + pdata->range = range; + return count; +} + +static DEVICE_ATTR(range, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH, g920_range_show, g920_range_store); + +static int g920_allocate(struct hid_device *hdev) +{ + struct hidpp_device *hidpp = hid_get_drvdata(hdev); + struct g920_private_data *pdata; + + pdata = devm_kzalloc(>dev, sizeof(struct g920_private_data), + GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + hidpp->private_data = pdata; + + return 0; +} + +static int g920_get_config(struct hidpp_device *hidpp) +{ + struct g920_private_data *pdata = hidpp->private_data; + struct hidpp_report response; + u8 feature_type; + u8 feature_index; + int ret; + + pdata = hidpp->private_data; + if (!pdata) { + hid_err(hidpp->hid_dev, "Private driver data not found!\n"); + return -EINVAL; + } + + /* Find feature and store for later use */ + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_G920_FORCE_FEEDBACK, + _index, _type); + if (ret) + return ret; + + pdata->force_feature = feature_index; + + /* Read current Range */ + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_G920_FORCE_GET_APERTURE, NULL, 0, ); + if (ret > 0) { + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", + __func__, ret); + return -EPROTO; + } + if (ret) + return ret; + + pdata->range = get_unaligned_be16([0]); + + /* Create sysfs interface */ + ret = device_create_file(&(hidpp->hid_dev->dev), _attr_range); + if (ret) + hid_warn(hidpp->hid_dev, "Unable to create sysfs interface for \"range\", errno %d\n", ret); + + return 0; +} + /* -- */ /* Generic HID++ devices */ /* -- */ @@ -1456,6 +1583,10 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = m560_allocate(hdev); if (ret)
[RFC 1/5] INPUT: xpad: Add minimal support for Logitech G920 Wheel
When plugged in the Logitech G920 wheel starts with USBID 046d:c261 and behaviors as a vendor specific class. If a 'magic' byte sequence is sent the wheel will detach and reconnect as a HID device with the USBID 046d:c262. --- drivers/input/joystick/xpad.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f8850f9..af83f7e 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -93,6 +93,7 @@ #define MAP_STICKS_TO_NULL (1 << 2) #define DANCEPAD_MAP_CONFIG(MAP_DPAD_TO_BUTTONS | \ MAP_TRIGGERS_TO_BUTTONS | MAP_STICKS_TO_NULL) +#define SWITCH_G920_TO_HID_MODE(1 << 3) #define XTYPE_XBOX0 #define XTYPE_XBOX360 1 @@ -133,6 +134,7 @@ static const struct xpad_device { { 0x046d, 0xc21e, "Logitech Gamepad F510", 0, XTYPE_XBOX360 }, { 0x046d, 0xc21f, "Logitech Gamepad F710", 0, XTYPE_XBOX360 }, { 0x046d, 0xc242, "Logitech Chillstream Controller", 0, XTYPE_XBOX360 }, + { 0x046d, 0xc261, "Logitech G920 Driving Force Racing Wheel", SWITCH_G920_TO_HID_MODE, XTYPE_XBOXONE }, { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", 0, XTYPE_XBOX }, { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", 0, XTYPE_XBOX }, { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", 0, XTYPE_XBOX }, @@ -299,6 +301,7 @@ static struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x045e),/* Microsoft X-Box 360 controllers */ XPAD_XBOXONE_VENDOR(0x045e),/* Microsoft X-Box One controllers */ XPAD_XBOX360_VENDOR(0x046d),/* Logitech X-Box 360 style controllers */ + XPAD_XBOXONE_VENDOR(0x046d),/* Logitech X-Box One style controllers */ XPAD_XBOX360_VENDOR(0x0738),/* Mad Catz X-Box 360 controllers */ { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f),/* 0x0e6f X-Box 360 controllers */ @@ -1021,6 +1024,19 @@ static int xpad_open(struct input_dev *dev) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) return -EIO; + /* Logitect G920 wheel starts in XBOX mode, but is reconfigured to be HID */ + /* device with USBID of 046D:C262. Wheel will detach when 'magic' is sent. */ + if (xpad->mapping & SWITCH_G920_TO_HID_MODE) { + xpad->odata[0] = 0x0F; + xpad->odata[1] = 0x00; + xpad->odata[2] = 0x01; + xpad->odata[3] = 0x01; + xpad->odata[4] = 0x42; + xpad->irq_out->transfer_buffer_length = 5; + + return usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + if (xpad->xtype == XTYPE_XBOXONE) { /* Xbox one controller needs to be initialized. */ xpad->odata[0] = 0x05; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 5/5] HID: Add vendor specific usage pages for Logitech G920
The Logitech G920 uses a couple of vendor specific usage pages, which results in incorrect number of axis/buttons being detected. This patch adds these pages to the 'ignore' list. Reported-by: Elias Vanderstuyft--- drivers/hid/hid-input.c | 2 +- include/linux/hid.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 53aeaf6..c120be5 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -959,7 +959,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel set_bit(EV_REP, input->evbit); goto ignore; - case HID_UP_LOGIVENDOR: + case HID_UP_LOGIVENDOR: case HID_UP_LOGIVENDOR2: case HID_UP_LOGIVENDOR3: goto ignore; case HID_UP_PID: diff --git a/include/linux/hid.h b/include/linux/hid.h index f17980d..ce1d883 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -168,6 +168,8 @@ struct hid_item { #define HID_UP_MSVENDOR0xff00 #define HID_UP_CUSTOM 0x00ff #define HID_UP_LOGIVENDOR 0xffbc +#define HID_UP_LOGIVENDOR2 0xff09 +#define HID_UP_LOGIVENDOR3 0xff43 #define HID_UP_LNVENDOR0xffa0 #define HID_UP_SENSOR 0x0020 -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC 2/5] HID: hid-logitech-hidpp: Add support for very long packets
Patch add support for the 'very long' HID++ packets, which are 64 bytes in length. --- drivers/hid/hid-logitech-hidpp.c | 59 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 4841964..c343b23 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -35,9 +35,11 @@ MODULE_PARM_DESC(disable_raw_mode, #define REPORT_ID_HIDPP_SHORT 0x10 #define REPORT_ID_HIDPP_LONG 0x11 +#define REPORT_ID_HIDPP_VERY_LONG 0x12 #define HIDPP_REPORT_SHORT_LENGTH 7 #define HIDPP_REPORT_LONG_LENGTH 20 +#define HIDPP_REPORT_VERY_LONG_LENGTH 64 #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) @@ -71,13 +73,13 @@ MODULE_PARM_DESC(disable_raw_mode, struct fap { u8 feature_index; u8 funcindex_clientid; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct rap { u8 sub_id; u8 reg_address; - u8 params[HIDPP_REPORT_LONG_LENGTH - 4U]; + u8 params[HIDPP_REPORT_VERY_LONG_LENGTH - 4U]; }; struct hidpp_report { @@ -143,6 +145,9 @@ static int __hidpp_send_report(struct hid_device *hdev, case REPORT_ID_HIDPP_LONG: fields_count = HIDPP_REPORT_LONG_LENGTH; break; + case REPORT_ID_HIDPP_VERY_LONG: + fields_count = HIDPP_REPORT_VERY_LONG_LENGTH; + break; default: return -ENODEV; } @@ -207,8 +212,9 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, goto exit; } - if (response->report_id == REPORT_ID_HIDPP_LONG && - response->fap.feature_index == HIDPP20_ERROR) { + if ((response->report_id == REPORT_ID_HIDPP_LONG || + response->report_id == REPORT_ID_HIDPP_VERY_LONG) && + response->fap.feature_index == HIDPP20_ERROR) { ret = response->fap.params[1]; dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); goto exit; @@ -233,7 +239,11 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); if (!message) return -ENOMEM; - message->report_id = REPORT_ID_HIDPP_LONG; + + if (param_count > (HIDPP_REPORT_LONG_LENGTH - 4)) + message->report_id = REPORT_ID_HIDPP_VERY_LONG; + else + message->report_id = REPORT_ID_HIDPP_LONG; message->fap.feature_index = feat_index; message->fap.funcindex_clientid = funcindex_clientid; memcpy(>fap.params, params, param_count); @@ -248,13 +258,23 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, struct hidpp_report *response) { struct hidpp_report *message; - int ret; + int ret, max_count; - if ((report_id != REPORT_ID_HIDPP_SHORT) && - (report_id != REPORT_ID_HIDPP_LONG)) + switch (report_id) { + case REPORT_ID_HIDPP_SHORT: + max_count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: + max_count = HIDPP_REPORT_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_VERY_LONG: + max_count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + default: return -EINVAL; + } - if (param_count > sizeof(message->rap.params)) + if (param_count > max_count) return -EINVAL; message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); @@ -498,10 +518,19 @@ static int hidpp_devicenametype_get_device_name(struct hidpp_device *hidpp, if (ret) return ret; - if (response.report_id == REPORT_ID_HIDPP_LONG) + switch (response.report_id) { + case REPORT_ID_HIDPP_VERY_LONG: + count = HIDPP_REPORT_VERY_LONG_LENGTH - 4; + break; + case REPORT_ID_HIDPP_LONG: count = HIDPP_REPORT_LONG_LENGTH - 4; - else + break; + case REPORT_ID_HIDPP_SHORT: count = HIDPP_REPORT_SHORT_LENGTH - 4; + break; + default: + return -EPROTO; + } if (len_buf < count) count = len_buf; @@ -1220,6 +1249,14 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report, /* Generic HID++ processing. */ switch (data[0]) { + case REPORT_ID_HIDPP_VERY_LONG: + if (size != HIDPP_REPORT_VERY_LONG_LENGTH) { + hid_err(hdev, "received hid++ report of bad size (%d)", + size); +
[RFC 3/5] HID: hid-logitech-hidpp: Add basic support for Logitech G920
This patch adds basic support for the Logitech G920 wheel when in HID mode. This wheel 'speaks' the HID++ protocol, and therefor is driven with hid-logitech-hidpp. At this stage the driver only shows that it can communicate with the wheel by outputting the name discovered over HID++. The normal HID functions work to give input functionality using joystick/event interface. --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h| 1 + drivers/hid/hid-logitech-hidpp.c | 69 +++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 70a11ac..fe53b0a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1896,6 +1896,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f769208..d3500c4 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -614,6 +614,7 @@ #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_20xc219 #define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f +#define USB_DEVICE_ID_LOGITECH_G920_WHEEL 0xc262 #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index c343b23..76d7267 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -43,10 +43,12 @@ MODULE_PARM_DESC(disable_raw_mode, #define HIDPP_QUIRK_CLASS_WTP BIT(0) #define HIDPP_QUIRK_CLASS_M560 BIT(1) +#define HIDPP_QUIRK_CLASS_G920 BIT(2) /* bits 2..20 are reserved for classes */ #define HIDPP_QUIRK_DELAYED_INIT BIT(21) #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) +#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(23) /* * There are two hidpp protocols in use, the first version hidpp10 is known @@ -136,8 +138,11 @@ static void hidpp_connect_event(struct hidpp_device *hidpp_dev); static int __hidpp_send_report(struct hid_device *hdev, struct hidpp_report *hidpp_report) { + struct hidpp_device *hidpp = hid_get_drvdata(hdev); int fields_count, ret; + hidpp = hid_get_drvdata(hdev); + switch (hidpp_report->report_id) { case REPORT_ID_HIDPP_SHORT: fields_count = HIDPP_REPORT_SHORT_LENGTH; @@ -158,9 +163,13 @@ static int __hidpp_send_report(struct hid_device *hdev, */ hidpp_report->device_index = 0xff; - ret = hid_hw_raw_request(hdev, hidpp_report->report_id, - (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, - HID_REQ_SET_REPORT); + if (hidpp->quirks & HIDPP_QUIRK_FORCE_OUTPUT_REPORTS) { + ret = hid_hw_output_report(hdev, (u8 *)hidpp_report, fields_count); + } else { + ret = hid_hw_raw_request(hdev, hidpp_report->report_id, + (u8 *)hidpp_report, fields_count, HID_OUTPUT_REPORT, + HID_REQ_SET_REPORT); + } return ret == fields_count ? 0 : -1; } @@ -1305,8 +1314,10 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) if (!name) hid_err(hdev, "unable to retrieve the name of the device"); - else + else { + dbg_hid("HID++: Got name: %s\n", name); snprintf(hdev->name, sizeof(hdev->name), "%s", name); + } kfree(name); } @@ -1457,6 +1468,25 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_parse_fail; } + if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) + connect_mask &= ~HID_CONNECT_HIDINPUT; + + if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) { + ret = hid_hw_start(hdev, connect_mask); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto hid_hw_start_fail; + } + ret = hid_hw_open(hdev); + if (ret < 0) { + dev_err(>dev, "%s:hid_hw_open returned error:%d\n", +
Re: [PATCH] HID: hid-lg: Add USBID for Logitech G29 Wheel
> I was able to get some more information, but as yet have not been able to > get time on the real hardware. Attached is a 2nd patch which should > improve the support, I'll formally submit it next week But if anyone > can test it first that would be great. Obviously the 'submit next week' never happened... but I now have one of these wheels to work on. The bad news is that the information we got does not appear to be complete. At present the wheel is mis-recognised as a G27 and forced into an emulation state, it is somewhat usable in that mode. If we send the 'G29 mode' command the wheel comes back with a device with 2x HID interfaces and that appears to screw up the probe (full log attached). -- Sep 28 12:30:33 retrobox kernel: [11079.944056] usb 2-1: new full-speed USB device number 3 using uhci_hcd Sep 28 12:30:33 retrobox kernel: [11080.113102] usb 2-1: New USB device found, idVendor=046d, idProduct=c24f Sep 28 12:30:33 retrobox kernel: [11080.113113] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 Sep 28 12:30:33 retrobox kernel: [11080.113120] usb 2-1: Product: G29 Driving Force Racing Wheel Sep 28 12:30:33 retrobox kernel: [11080.113125] usb 2-1: Manufacturer: Logitech Sep 28 12:30:33 retrobox kernel: [11080.124431] input: Logitech G29 Driving Force Racing Wheel as /devices/pci:00/:00:1d.0/usb2/2-1/2-1:1.0/0003:046D:C24F.0002/input/input10 Sep 28 12:30:33 retrobox kernel: [11080.125134] logitech 0003:046D:C24F.0002: input,hidraw0: USB HID v1.11 Joystick [Logitech G29 Driving Force Racing Wheel] on usb-:00:1d.0-1/input0 Sep 28 12:30:33 retrobox kernel: [11080.126094] logitech 0003:046D:C24F.0002: Force feedback support for Logitech Gaming Wheels Sep 28 12:30:33 retrobox kernel: [11080.134307] logitech 0003:046D:C24F.0003: hiddev0,hidraw1: USB HID v1.11 Device [Logitech G29 Driving Force Racing Wheel] on usb-:00:1d.0-1/input1 Sep 28 12:30:33 retrobox kernel: [11080.134319] logitech 0003:046D:C24F.0003: not enough values in HID_OUTPUT_REPORT 0 field 0 Sep 28 12:30:33 retrobox kernel: [11080.134339] logitech: probe of 0003:046D:C24F.0003 failed with error -1 -- Any suggestions as to how we can 'ignore' or unbind the 2nd interface in order to only work with the 1st? Simon G29 connected, appears as DFEX then we send command to get it to reconnect -- Sep 28 12:30:32 retrobox kernel: [11078.904047] usb 2-1: new full-speed USB device number 2 using uhci_hcd Sep 28 12:30:32 retrobox kernel: [11079.077104] usb 2-1: New USB device found, idVendor=046d, idProduct=c294 Sep 28 12:30:32 retrobox kernel: [11079.077115] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 Sep 28 12:30:32 retrobox kernel: [11079.077122] usb 2-1: Product: G29 Driving Force Racing Wheel Sep 28 12:30:32 retrobox kernel: [11079.077128] usb 2-1: Manufacturer: Logitech Sep 28 12:30:32 retrobox mtp-probe: checking bus 2, device 2: "/sys/devices/pci:00/:00:1d.0/usb2/2-1" Sep 28 12:30:32 retrobox mtp-probe: bus: 2, device: 2 was not an MTP device Sep 28 12:30:32 retrobox kernel: [11079.266693] input: Logitech G29 Driving Force Racing Wheel as /devices/pci:00/:00:1d.0/usb2/2-1/2-1:1.0/0003:046D:C294.0001/input/input9 Sep 28 12:30:32 retrobox kernel: [11079.267441] logitech 0003:046D:C294.0001: input,hidraw0: USB HID v1.00 Joystick [Logitech G29 Driving Force Racing Wheel] on usb-:00:1d.0-1/input0 Sep 28 12:30:32 retrobox kernel: [11079.276117] usbcore: registered new interface driver usbhid Sep 28 12:30:32 retrobox kernel: [11079.276127] usbhid: USB HID core driver Sep 28 12:30:32 retrobox kernel: [11079.320193] usb 2-1: USB disconnect, device number 2 Sep 28 12:30:32 retrobox systemd-udevd[243]: error opening USB device 'descriptors' file Sep 28 12:30:33 retrobox kernel: [11079.944056] usb 2-1: new full-speed USB device number 3 using uhci_hcd Sep 28 12:30:33 retrobox kernel: [11080.113102] usb 2-1: New USB device found, idVendor=046d, idProduct=c24f Sep 28 12:30:33 retrobox kernel: [11080.113113] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 Sep 28 12:30:33 retrobox kernel: [11080.113120] usb 2-1: Product: G29 Driving Force Racing Wheel Sep 28 12:30:33 retrobox kernel: [11080.113125] usb 2-1: Manufacturer: Logitech Sep 28 12:30:33 retrobox kernel: [11080.124431] input: Logitech G29 Driving Force Racing Wheel as /devices/pci:00/:00:1d.0/usb2/2-1/2-1:1.0/0003:046D:C24F.0002/input/input10 Sep 28 12:30:33 retrobox kernel: [11080.125134] logitech 0003:046D:C24F.0002: input,hidraw0: USB HID v1.11 Joystick [Logitech G29 Driving Force Racing Wheel] on usb-:00:1d.0-1/input0 Sep 28 12:30:33 retrobox kernel: [11080.126094] logitech 0003:046D:C24F.0002: Force feedback support for Logitech Gaming Wheels Sep 28 12:30:33 retrobox kernel: [11080.134307] logitech 0003:046D:C24F.0003: hiddev0,hidraw1: USB HID v1.11 Device [Logitech G29 Driving Force Racing Wheel] on usb-:00:1d.0-1/input1 Sep 28 12
Re: [PATCH 0/2] HID: logitech-hidpp: allow to disable tap to click on the K400
> The first patch might conflict with Simon's current work in progress, so > that's why Simon is CC-ed to it. Thanks for the 'heads-up', I think that the HID++ stuff I have in progress won't be ready until the 4.4 cycle, Cheers, Simon -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: hid-lg: Add USBID for Logitech G29 Wheel
> I do not have this wheel to test with, but this should at least get it > working in emulation mode. > > Note: There is probably more work required for adjust HID descriptor and > handle switching between emulation and native modes. I was able to get some more information, but as yet have not been able to get time on the real hardware. Attached is a 2nd patch which should improve the support, I'll formally submit it next week But if anyone can test it first that would be great. There's a pre-built Debian/Ubuntu kernel here: https://dl.dropboxusercontent.com/u/34518077/linux-headers-4.2.0-g29%2B_20150831_i386.deb https://dl.dropboxusercontent.com/u/34518077/linux-image-4.2.0-g29%2B_20150831_i386.deb The wheel will need to be in PS3 mode set with switch behind LEDs, and should connect first as a DF-EX (220' turn) and then automatically reconnect as G29 (900' turn). The mode should be selectable something like -- root@retrobox:/home/simon# cd /sys/bus/hid/devices/0003\:046D\:C29B.0002 root@retrobox:/sys/bus/hid/devices/0003:046D:C29B.0002# ls alternate_modes country driver hidraw input leds modalias power range real_id report_descriptor subsystem uevent root@retrobox:/sys/bus/hid/devices/0003:046D:C29B.0002# cat alternate_modes native: G27 Racing Wheel * DF-EX: Driving Force / Formula EX DFP: Driving Force Pro G25: G25 Racing Wheel G27: G27 Racing Wheel * root@retrobox:/sys/bus/hid/devices/0003:046D:C29B.0002# echo G25 > alternate_modes -- The LEDs should also work -- root@retrobox:/home/simon/linux-git# cd /sys/class/leds/ root@retrobox:/sys/class/leds# ls 0003:046D:C29B.0005::RPM1 0003:046D:C29B.0005::RPM4 input3::numlock tpacpi::power tpacpi::thinkvantage 0003:046D:C29B.0005::RPM2 0003:046D:C29B.0005::RPM5 input3::scrolllock tpacpi::standby 0003:046D:C29B.0005::RPM3 input3::capslock phy0-led tpacpi::thinklight root@retrobox:/sys/class/leds# echo 1 > 0003\:046D\:C29B.0005\:\:RPM1/brightness -- Cheers, Simondiff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e6fce23..2e9c706 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1874,6 +1874,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 02cec83..d0c3da5 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -45,7 +45,8 @@ #define LG4FF_MODE_G25_IDX 3 #define LG4FF_MODE_DFGT_IDX 4 #define LG4FF_MODE_G27_IDX 5 -#define LG4FF_MODE_MAX_IDX 6 +#define LG4FF_MODE_G29_IDX 6 +#define LG4FF_MODE_MAX_IDX 7 #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) @@ -53,6 +54,7 @@ #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) #define LG4FF_DFEX_TAG "DF-EX" #define LG4FF_DFEX_NAME "Driving Force / Formula EX" @@ -62,6 +64,8 @@ #define LG4FF_G25_NAME "G25 Racing Wheel" #define LG4FF_G27_TAG "G27" #define LG4FF_G27_NAME "G27 Racing Wheel" +#define LG4FF_G29_TAG "G29" +#define LG4FF_G29_NAME "G29 Racing Wheel" #define LG4FF_DFGT_TAG "DFGT" #define LG4FF_DFGT_NAME "Driving Force GT" @@ -144,6 +148,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = { {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL}, {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} }; @@ -161,6 +166,9 @@ static const struct lg4ff_multimode_wheel lg4ff_multimode_wheels[] = { {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, LG4FF_G27_TAG, LG4FF_G27_NAME}, + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, + LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP, + LG4FF_G29_TAG, LG4FF_G29_NAME}, }; static const struct lg4ff_alternate_mode
Re: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific compatible property
On Fri, Aug 14, 2015 at 12:31:09AM +0300, Laurent Pinchart wrote: On Thursday 13 August 2015 11:26:32 Geert Uytterhoeven wrote: On Thu, Aug 13, 2015 at 2:05 AM, Simon Horman ho...@verge.net.au wrote: On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote: On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote: On Tuesday 07 July 2015 09:26:21 Simon Horman wrote: On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote: On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote: Replace the deprecated generic adi,adxl34x compatible value by the adxl345-specific adi,adxl345 value, cfr. commit e465bf6fc55d5ce2 (DT: i2c: Deprecate adi,adxl34x compatible string). Signed-off-by: Geert Uytterhoeven geert+rene...@glider.be Acked-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- Depends on commit 3a38958d2477b718 (Input: adxl34x - add OF match support), which is in v4.2-rc1. This is v2 of ARM: shmobile: kzm9g dts: Add adxl345-specific compatible property. It appears to me that this will cause a regression when booting old kernels with new dts blobs. For that reason think we should consider v1 of this change coupled with a schedule to remove use of the deprecated compat string. That's the forward compatibility that Geert mentioned, is that really an issue, especially on this board ? I think it would be best to provide backwards compatibility unless there is a compelling reason not to. I would like to revisit this discussion with a view to getting some version of this patch queued up (yes I know I pushed back on it earlier in this thread). I'm fine with applying v1. And I'm quite unsurprisingly not, as I've asked for a v2. The adi,adxl34x compatible string is deprecated. That means we still support it in the driver for device trees that haven't been updated, but it shouldn't be used forward by new device trees. That's why the device tree sources contained in the kernel shouldn't use it, especially given that they often serve as references for device trees shipped out of tree. Thanks, I see your point now. I have queued up v2. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific compatible property
On Wed, Jul 08, 2015 at 09:51:49AM +0900, Simon Horman wrote: On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote: Hi Simon, On Tuesday 07 July 2015 09:26:21 Simon Horman wrote: On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote: On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote: Replace the deprecated generic adi,adxl34x compatible value by the adxl345-specific adi,adxl345 value, cfr. commit e465bf6fc55d5ce2 (DT: i2c: Deprecate adi,adxl34x compatible string). Signed-off-by: Geert Uytterhoeven geert+rene...@glider.be Acked-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- Depends on commit 3a38958d2477b718 (Input: adxl34x - add OF match support), which is in v4.2-rc1. This is v2 of ARM: shmobile: kzm9g dts: Add adxl345-specific compatible property. It appears to me that this will cause a regression when booting old kernels with new dts blobs. For that reason think we should consider v1 of this change coupled with a schedule to remove use of the deprecated compat string. That's the forward compatibility that Geert mentioned, is that really an issue, especially on this board ? I think it would be best to provide backwards compatibility unless there is a compelling reason not to. I would like to revisit this discussion with a view to getting some version of this patch queued up (yes I know I pushed back on it earlier in this thread). -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] hid: sony: Drop invalid Sixaxis input reports
When connected via Bluetooth the sixaxis periodically sends reports with an ID of 1, the second byte 0xff and the rest zeroed. These reports are not related to the controller state and must be dropped to avoid generating false input events. These 'problem reports' were reported (*) over the on Bluetooth list, and appear in both the HID and the HCI streams (suggesting that they are really sent from device). They are not seen on the USB connection. Dropping them in 'raw_event()' seems a sensible approach, Simon. * http://www.spinics.net/lists/linux-bluetooth/msg63028.html Signed-off-by: Frank Praznik frank.praz...@oh.rr.com --- drivers/hid/hid-sony.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ed2f008..beb2b02 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1270,6 +1270,17 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, * has to be BYTE_SWAPPED before passing up to joystick interface */ if ((sc-quirks SIXAXIS_CONTROLLER) rd[0] == 0x01 size == 49) { + /* + * When connected via Bluetooth the Sixaxis occasionally sends + * a report with the second byte 0xff and the rest zeroed. + * + * This report does not reflect the actual state of the + * controller must be ignored to avoid generating false input + * events. + */ + if (rd[1] == 0xff) + return -EINVAL; + swap(rd[41], rd[42]); swap(rd[43], rd[44]); swap(rd[45], rd[46]); -- 2.4.3 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: hid-lg: Add USBID for Logitech G29 Wheel
Since this wheel is now available, and the USBID is listed on their website, this patch adds it to allow the hid-lg4ff force feedback driver to find it. I do not have this wheel to test with, but this should at least get it working in emulation mode. Note: There is probably more work required for adjust HID descriptor and handle switching between emulation and native modes. Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-lg.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b04b082..653bfd4 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -599,6 +599,7 @@ #define USB_DEVICE_ID_LOGITECH_DUAL_ACTION 0xc216 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_20xc219 +#define USB_DEVICE_ID_LOGITECH_G29_WHEEL 0xc24f #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D 0xc283 #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO 0xc286 #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940 0xc287 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 429340d..5332fb7 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -776,6 +776,8 @@ static const struct hid_device_id lg_devices[] = { .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), .driver_data = LG_FF }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL), + .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO), -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: hid-sony: Navigator Axis for L1 button
Patch HID report descriptor to add joystick axis for the L1 button (previously missing). Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ed2f008..69586b3 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -296,7 +296,14 @@ static __u8 navigation_rdesc[] = { 0x09, 0x01, /* Usage (Pointer),*/ 0x81, 0x02, /* Input (Variable), */ 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ - 0x95, 0x20, /* Report Count (26), */ + 0x95, 0x01, /* Report Count (1), */ + 0x81, 0x02, /* Input (Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x95, 0x01, /* Report Count (1), */ + 0x09, 0x01, /* Usage (Pointer),*/ + 0x81, 0x02, /* Input (Variable), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x95, 0x1E, /* Report Count (24), */ 0x81, 0x02, /* Input (Variable), */ 0x75, 0x08, /* Report Size (8),*/ 0x95, 0x30, /* Report Count (48), */ -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] ARM: shmobile: kzm9g dts: Use adxl345-specific compatible property
On Tue, Jul 07, 2015 at 09:56:29AM +0300, Laurent Pinchart wrote: Hi Simon, On Tuesday 07 July 2015 09:26:21 Simon Horman wrote: On Mon, Jul 06, 2015 at 04:29:33PM +0300, Laurent Pinchart wrote: On Monday 06 July 2015 12:55:32 Geert Uytterhoeven wrote: Replace the deprecated generic adi,adxl34x compatible value by the adxl345-specific adi,adxl345 value, cfr. commit e465bf6fc55d5ce2 (DT: i2c: Deprecate adi,adxl34x compatible string). Signed-off-by: Geert Uytterhoeven geert+rene...@glider.be Acked-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- Depends on commit 3a38958d2477b718 (Input: adxl34x - add OF match support), which is in v4.2-rc1. This is v2 of ARM: shmobile: kzm9g dts: Add adxl345-specific compatible property. It appears to me that this will cause a regression when booting old kernels with new dts blobs. For that reason think we should consider v1 of this change coupled with a schedule to remove use of the deprecated compat string. That's the forward compatibility that Geert mentioned, is that really an issue, especially on this board ? I think it would be best to provide backwards compatibility unless there is a compelling reason not to. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC_v2 0/4] HID: hid-sony: Add IIO Suport for Motion Controllers
the SixAxis also have a gyroscope, I don't know how useful/reliable it is, but it's there. I had a recollection that there was a gyro, but didn't see it when looking at the 'hidraw' stream. It might be affected by the 'multi-touch axes' bug. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC_v2 1/4] HID: hid-sony: Add basic IIO support for SixAxis Controller
+case IIO_CHAN_INFO_SCALE: +switch (chan-type) { +case IIO_ACCEL: +*val = 0; /* 9.80665/117 = 0.084540086 */ +*val2 = 84540; I guess 9.80665 is 'g', but is the 117 taken from the accelerometer datasheet? What is it? And BTW I get 9.80665/117 = 0.083817521 The '117' was taken from experimentation, average value accessed across all accelerometer axis on a stationary device. It does appear however that I can not use a calculator ;-) (...must have been a prior value left there). Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC_v2 3/4] HID: hid-sony: Add IIO trigger support for SixAxis Controller
--- drivers/hid/hid-sony.c | 71 -- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index b7a7f0d..ce0526d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -39,9 +39,11 @@ #include linux/iio/iio.h #include linux/iio/sysfs.h #include linux/iio/buffer.h +#include linux/iio/trigger.h #include linux/iio/trigger_consumer.h #include linux/iio/triggered_buffer.h #include linux/interrupt.h +#include linux/irq_work.h #include hid-ids.h @@ -855,9 +857,14 @@ enum sony_iio_axis { AXIS_ACC_Z, }; +static void sony_iio_trigger_work(struct irq_work *work); + struct sony_iio { struct sony_sc *sc; + struct iio_trigger *trig; + u8 buff[16];/* 3x 16-bit + padding + timestamp */ + struct irq_work work; #endif }; @@ -1076,6 +1083,13 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, sc-last_data[AXIS_ACC_X] = (rd[42] 8) + rd[41]; sc-last_data[AXIS_ACC_Y] = (rd[44] 8) + rd[43]; sc-last_data[AXIS_ACC_Z] = (rd[46] 8) + rd[45]; + + if (sc-indio_dev) { + struct sony_iio *data; + + data = iio_priv(sc-indio_dev); + sony_iio_trigger_work(data-work); + } #endif sixaxis_parse_report(sc, rd, size); } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 @@ -1869,6 +1883,28 @@ static const struct iio_info sony_iio_info = { .driver_module = THIS_MODULE, }; +static void sony_iio_trigger_work(struct irq_work *work) +{ + struct sony_iio *data = container_of(work, struct sony_iio, work); + + iio_trigger_poll(data-trig); +} + +static ssize_t sony_iio_trigger_poll(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct iio_trigger *trig = to_iio_trigger(dev); + struct sony_iio *data = iio_trigger_get_drvdata(trig); + + irq_work_queue(data-work); + + return count; +} + +static const struct iio_trigger_ops sony_iio_trigger_ops = { + .owner = THIS_MODULE, +}; + static irqreturn_t sony_iio_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; @@ -1910,11 +1946,29 @@ static int sony_iio_probe(struct sony_sc *sc) indio_dev-channels = sony_sixaxis_channels; indio_dev-num_channels = ARRAY_SIZE(sony_sixaxis_channels); + data-trig = iio_trigger_alloc(%s-dev%d, indio_dev-name, + indio_dev-id); + if (!data-trig) { + ret = -ENOMEM; + goto err; + } + + data-trig-dev.parent = hdev-dev; + data-trig-ops = sony_iio_trigger_ops; + iio_trigger_set_drvdata(data-trig, indio_dev); + indio_dev-trig = iio_trigger_get(data-trig); + + init_irq_work(data-work, sony_iio_trigger_work); + + ret = iio_trigger_register(data-trig); + if (ret) + goto err_trigger_free; + ret = iio_triggered_buffer_setup(indio_dev, NULL, sony_iio_trigger_handler, NULL); if (ret 0) { dev_err(hdev-dev, unable to setup iio triggered buffer\n); - goto err; + goto err_trigger_unregister; } ret = iio_device_register(indio_dev); @@ -1926,6 +1980,11 @@ static int sony_iio_probe(struct sony_sc *sc) err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); +err_trigger_unregister: + if (data-trig) + iio_trigger_unregister(data-trig); +err_trigger_free: + iio_trigger_free(data-trig); err: kfree(indio_dev); sc-indio_dev = NULL; @@ -1934,11 +1993,19 @@ err: static void sony_iio_remove(struct sony_sc *sc) { + struct sony_iio *data; + if (!sc-indio_dev) return; - iio_device_unregister(sc-indio_dev); + data = iio_priv(sc-indio_dev); + iio_triggered_buffer_cleanup(sc-indio_dev); + if (data-trig) + iio_trigger_unregister(data-trig); + iio_trigger_free(data-trig); + iio_device_unregister(sc-indio_dev); + kfree(sc-indio_dev); sc-indio_dev = NULL; } -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC_v2 2/4] HID: hid-sony: Add IIO buffer support for SixAxis Controller
--- drivers/hid/hid-sony.c | 50 +++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index c4686e3..b7a7f0d 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -37,6 +37,11 @@ #include linux/idr.h #include linux/input/mt.h #include linux/iio/iio.h +#include linux/iio/sysfs.h +#include linux/iio/buffer.h +#include linux/iio/trigger_consumer.h +#include linux/iio/triggered_buffer.h +#include linux/interrupt.h #include hid-ids.h @@ -852,6 +857,7 @@ enum sony_iio_axis { struct sony_iio { struct sony_sc *sc; + u8 buff[16];/* 3x 16-bit + padding + timestamp */ #endif }; @@ -861,6 +867,7 @@ static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, *rsize = sizeof(sixaxis_rdesc); return sixaxis_rdesc; } + static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { @@ -1841,12 +1848,20 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev, .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_OFFSET), \ .address = AXIS_ACC_##_axis,\ + .scan_index = AXIS_ACC_##_axis, \ + .scan_type = { \ + .sign = 's',\ + .realbits = 16, \ + .storagebits = 16, \ + .shift = 0, \ + }, \ } static const struct iio_chan_spec sony_sixaxis_channels[] = { SONY_ACC_CHANNEL(X), SONY_ACC_CHANNEL(Y), SONY_ACC_CHANNEL(Z), + IIO_CHAN_SOFT_TIMESTAMP(3), }; static const struct iio_info sony_iio_info = { @@ -1854,6 +1869,25 @@ static const struct iio_info sony_iio_info = { .driver_module = THIS_MODULE, }; +static irqreturn_t sony_iio_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf-indio_dev; + struct sony_iio *data = iio_priv(indio_dev); + int64_t time_ns = iio_get_time_ns(); + int bit, i = 0; + + for_each_set_bit(bit, indio_dev-active_scan_mask, +indio_dev-masklength) { + ((u16 *)data-buff)[i++] = data-sc-last_data[bit]; + } + + iio_push_to_buffers_with_timestamp(indio_dev, data-buff, time_ns); + iio_trigger_notify_done(indio_dev-trig); + + return IRQ_HANDLED; +} + static int sony_iio_probe(struct sony_sc *sc) { struct hid_device *hdev = sc-hdev; @@ -1871,18 +1905,27 @@ static int sony_iio_probe(struct sony_sc *sc) indio_dev-dev.parent = hdev-dev; indio_dev-name = dev_name(hdev-dev); - indio_dev-modes = INDIO_DIRECT_MODE; + indio_dev-modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED; indio_dev-info = sony_iio_info; indio_dev-channels = sony_sixaxis_channels; - indio_dev-num_channels = 3; + indio_dev-num_channels = ARRAY_SIZE(sony_sixaxis_channels); + + ret = iio_triggered_buffer_setup(indio_dev, NULL, + sony_iio_trigger_handler, NULL); + if (ret 0) { + dev_err(hdev-dev, unable to setup iio triggered buffer\n); + goto err; + } ret = iio_device_register(indio_dev); if (ret 0) { hid_err(hdev, Unable to register iio device\n); - goto err; + goto err_buffer_cleanup; } return 0; +err_buffer_cleanup: + iio_triggered_buffer_cleanup(indio_dev); err: kfree(indio_dev); sc-indio_dev = NULL; @@ -1895,6 +1938,7 @@ static void sony_iio_remove(struct sony_sc *sc) return; iio_device_unregister(sc-indio_dev); + iio_triggered_buffer_cleanup(sc-indio_dev); kfree(sc-indio_dev); sc-indio_dev = NULL; } -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC_v2 0/4] HID: hid-sony: Add IIO Suport for Motion Controllers
This series of patches is a RFC for the idea of connecting motion capability controllers to the IIO subsystem, initially targeting the Sony SixAxis controller. In the future I hope that this can be used for sensor packs used in VR headset/devices. The advantage of the IIO subsystem is that the data is presented in SI units, although it is noted that the current API requires root level access - this is really a distribution requirement (UDEV rules can make '/dev/iiodevice0' accessible). The RFC is in 4 parts, split into logical steps: [PATCH 1/4] HID: hid-sony: Add basic IIO support for SixAxis Controller [PATCH 2/4] HID: hid-sony: Add IIO buffer support for SixAxis Controller [PATCH 3/4] HID: hid-sony: Add IIO trigger support for SixAxis Controller [PATCH 4/4] HID: hid-sony: Add IIO support for DualShock4 Controller The SixAxis contains accelerometers, the DS4 contains accelerometers and gyros. The next stage would be support the PS Move controller, which contains accelerometers, gyros and magnetometers. As an example of IIO usage I would point to RTIMULib, which recently showed a full 9-dof IMU fusion via IIO. (1) Known Bug: At present the 3rd patch introduces the issue that once loaded and a device connects, the module can not be unloaded (even after device disconnects). It seems that the refcount is being increased, but not decreased. -- $ cat /sys/module/hid_sony/refcnt 2 -- (1) https://richardstechnotes.wordpress.com/2015/06/17/rteiioimu-driving-a-9-dof-imu-via-industrial-io-iio/ -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC_v2 4/4] HID: hid-sony: Add IIO support for DualShock4 Controller
--- drivers/hid/hid-sony.c | 87 +- 1 file changed, 79 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index ce0526d..f1c1a16 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -62,7 +62,7 @@ DUALSHOCK4_CONTROLLER) #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) -#define SONY_IIO_SUPPORT SIXAXIS_CONTROLLER +#define SONY_IIO_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) #define MAX_LEDS 4 @@ -848,13 +848,16 @@ struct sony_sc { #if IS_BUILTIN(CONFIG_IIO) || \ (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) struct iio_dev *indio_dev; - __u16 last_data[3]; + __s16 last_data[6]; }; enum sony_iio_axis { AXIS_ACC_X, AXIS_ACC_Y, AXIS_ACC_Z, + AXIS_GYRO_X, + AXIS_GYRO_Y, + AXIS_GYRO_Z, }; static void sony_iio_trigger_work(struct irq_work *work); @@ -863,7 +866,7 @@ struct sony_iio { struct sony_sc *sc; struct iio_trigger *trig; - u8 buff[16];/* 3x 16-bit + padding + timestamp */ + u8 buff[24];/* 6x 16-bit + padding + timestamp */ struct irq_work work; #endif }; @@ -1095,6 +1098,25 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 size == 64) || ((sc-quirks DUALSHOCK4_CONTROLLER_BT) rd[0] == 0x11 size == 78)) { +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + int offset = (sc-quirks DUALSHOCK4_CONTROLLER_USB) ? 13 : 15; + + sc-last_data[AXIS_ACC_X] = (rd[offset+7] 8) + rd[offset+6]; + sc-last_data[AXIS_ACC_Y] = (rd[offset+9] 8) + rd[offset+8]; + sc-last_data[AXIS_ACC_Z] = (rd[offset+11] 8) + rd[offset+10]; + + sc-last_data[AXIS_GYRO_X] = (rd[offset+1] 8) + rd[offset]; + sc-last_data[AXIS_GYRO_Y] = (rd[offset+3] 8) + rd[offset+2]; + sc-last_data[AXIS_GYRO_Z] = (rd[offset+5] 8) + rd[offset+4]; + + if (sc-indio_dev) { + struct sony_iio *data; + + data = iio_priv(sc-indio_dev); + sony_iio_trigger_work(data-work); + } +#endif dualshock4_parse_report(sc, rd, size); } @@ -1827,6 +1849,7 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: switch (chan-type) { case IIO_ACCEL: + case IIO_ANGL_VEL: *val = data-sc-last_data[chan-address]; return IIO_VAL_INT; default: @@ -1835,8 +1858,17 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: switch (chan-type) { case IIO_ACCEL: - *val = 0; /* 9.80665/117 = 0.084540086 */ - *val2 = 84540; + if (data-sc-quirks SIXAXIS_CONTROLLER) { + *val = 0; /* 9.80665/117 = 0.084540086 */ + *val2 = 84540; + } else if (data-sc-quirks DUALSHOCK4_CONTROLLER) { + *val = 0; /* 9.80665/8192 = 0.001197101 */ + *val2 = 1197; + } + return IIO_VAL_INT_PLUS_MICRO; + case IIO_ANGL_VEL: + *val = 0; /* 0.001 */ + *val2 = 1000; return IIO_VAL_INT_PLUS_MICRO; default: return -EINVAL; @@ -1844,7 +1876,13 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_OFFSET: switch (chan-type) { case IIO_ACCEL: - *val = -512; + if (data-sc-quirks SIXAXIS_CONTROLLER) + *val = -512; + else if (data-sc-quirks DUALSHOCK4_CONTROLLER) + *val = 0; + return IIO_VAL_INT; + case IIO_ANGL_VEL: + *val = 0; return IIO_VAL_INT; default: return -EINVAL; @@ -1871,6 +1909,23 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev, }, \ } +#define SONY_GYRO_CHANNEL(_axis) { \ + .type = IIO_ANGL_VEL, \ + .modified = 1,
[RFC_v2 1/4] HID: hid-sony: Add basic IIO support for SixAxis Controller
--- drivers/hid/hid-sony.c | 153 - 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 6ca96ce..c4686e3 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -36,6 +36,7 @@ #include linux/list.h #include linux/idr.h #include linux/input/mt.h +#include linux/iio/iio.h #include hid-ids.h @@ -54,6 +55,7 @@ DUALSHOCK4_CONTROLLER) #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) +#define SONY_IIO_SUPPORT SIXAXIS_CONTROLLER #define MAX_LEDS 4 @@ -835,6 +837,22 @@ struct sony_sc { __u8 led_delay_on[MAX_LEDS]; __u8 led_delay_off[MAX_LEDS]; __u8 led_count; + +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + struct iio_dev *indio_dev; + __u16 last_data[3]; +}; + +enum sony_iio_axis { + AXIS_ACC_X, + AXIS_ACC_Y, + AXIS_ACC_Z, +}; + +struct sony_iio { + struct sony_sc *sc; +#endif }; static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -843,7 +861,6 @@ static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, *rsize = sizeof(sixaxis_rdesc); return sixaxis_rdesc; } - static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { @@ -1047,6 +1064,12 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, swap(rd[45], rd[46]); swap(rd[47], rd[48]); +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + sc-last_data[AXIS_ACC_X] = (rd[42] 8) + rd[41]; + sc-last_data[AXIS_ACC_Y] = (rd[44] 8) + rd[43]; + sc-last_data[AXIS_ACC_Z] = (rd[46] 8) + rd[45]; +#endif sixaxis_parse_report(sc, rd, size); } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 size == 64) || ((sc-quirks DUALSHOCK4_CONTROLLER_BT) @@ -1769,6 +1792,114 @@ static void sony_battery_remove(struct sony_sc *sc) sc-battery_desc.name = NULL; } +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + +static int sony_iio_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct sony_iio *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan-type) { + case IIO_ACCEL: + *val = data-sc-last_data[chan-address]; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan-type) { + case IIO_ACCEL: + *val = 0; /* 9.80665/117 = 0.084540086 */ + *val2 = 84540; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + switch (chan-type) { + case IIO_ACCEL: + *val = -512; + return IIO_VAL_INT; + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +#define SONY_ACC_CHANNEL(_axis) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis,\ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ + .address = AXIS_ACC_##_axis,\ +} + +static const struct iio_chan_spec sony_sixaxis_channels[] = { + SONY_ACC_CHANNEL(X), + SONY_ACC_CHANNEL(Y), + SONY_ACC_CHANNEL(Z), +}; + +static const struct iio_info sony_iio_info = { + .read_raw = sony_iio_read_raw, + .driver_module = THIS_MODULE, +}; + +static int sony_iio_probe(struct sony_sc *sc) +{ + struct hid_device *hdev = sc-hdev; + struct iio_dev *indio_dev; + struct sony_iio *data; + int ret; + + indio_dev = iio_device_alloc(sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + sc-indio_dev = indio_dev; + data = iio_priv(indio_dev); + data-sc = sc; + + indio_dev-dev.parent = hdev-dev; + indio_dev-name =
Re: [RFC] HID: hid-sony: Add basic iio-subsystem reading of SixAxis Accelerometers
I have further advanced the patch to include reading via buffer, but I'm having trigger 'conceptual' problems getting my head around the HID device issuing an interrupt when a input report is received. Looking at iio_dummy_event and iios_sysfs for inspiration You can skip the triggers. It's not obligatory, you can push directly into a buffer. Triggers are nice for 'data ready' type signals (which is closest to what we have here) if you might want to hang other sensors off the timing (so read on demand ADCs etc. They aren't actually 'required' as such. After a bit of poking around I got the triggers working as well, I can self trigger and even trigger another (iio-dummy) device. However I couldn't trigger two devices at the same time from a single trigger, is this normal for IIO? Next is a little code clean-up and I'll post what I have for some more comments, Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] HID: hid-sony: Fix report descriptor for Navigation Controller
Patch report descriptor to remove unused and ramdomly changing axis. Original report descriptor (via BT) was as follows: 05 01 09 04 a1 01 a1 02 85 01 75 08 95 01 15 00 |..u.| 0010 26 ff 00 81 03 75 01 95 13 15 00 25 01 35 00 45 |u.%.5.E| 0020 01 05 09 19 01 29 13 81 02 75 01 95 0d 06 00 ff |.)...u..| 0030 81 03 15 00 26 ff 00 05 01 09 01 a1 00 75 08 95 |u..| 0040 04 35 00 46 ff 00 09 30 09 31 09 32 09 35 81 02 |.5.F...0.1.2.5..| 0050 c0 05 01 75 08 95 27 09 01 81 02 75 08 95 30 09 |...u..'u..0.| 0060 01 91 02 75 08 95 30 09 01 b1 02 c0 a1 02 85 02 |...u..0.| 0070 75 08 95 30 09 01 b1 02 c0 a1 02 85 ee 75 08 95 |u..0.u..| 0080 30 09 01 b1 02 c0 a1 02 85 ef 75 08 95 30 09 01 |0.u..0..| 0090 b1 02 c0 c0 00|.| 0095 Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 91 +- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index af02139..ed2f008 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -248,6 +248,88 @@ static __u8 motion_rdesc[] = { 0xC0/* End Collection */ }; +/* PS/3 Navigation controller */ +static __u8 navigation_rdesc[] = { + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x04, /* Usage (Joystik),*/ + 0xA1, 0x01, /* Collection (Application), */ + 0xA1, 0x02, /* Collection (Logical), */ + 0x85, 0x01, /* Report ID (1), */ + 0x75, 0x08, /* Report Size (8),*/ + 0x95, 0x01, /* Report Count (1), */ + 0x15, 0x00, /* Logical Minimum (0),*/ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x75, 0x01, /* Report Size (1),*/ + 0x95, 0x13, /* Report Count (19), */ + 0x15, 0x00, /* Logical Minimum (0),*/ + 0x25, 0x01, /* Logical Maximum (1),*/ + 0x35, 0x00, /* Physical Minimum (0), */ + 0x45, 0x01, /* Physical Maximum (1), */ + 0x05, 0x09, /* Usage Page (Button),*/ + 0x19, 0x01, /* Usage Minimum (01h),*/ + 0x29, 0x13, /* Usage Maximum (13h),*/ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x01, /* Report Size (1),*/ + 0x95, 0x0D, /* Report Count (13), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x15, 0x00, /* Logical Minimum (0),*/ + 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x09, 0x01, /* Usage (Pointer),*/ + 0xA1, 0x00, /* Collection (Physical), */ + 0x75, 0x08, /* Report Size (8),*/ + 0x95, 0x02, /* Report Count (2), */ + 0x35, 0x00, /* Physical Minimum (0), */ + 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ + 0x09, 0x30, /* Usage (X), */ + 0x09, 0x31, /* Usage (Y), */ + 0x81, 0x02, /* Input (Variable), */ + 0xC0, /* End Collection, */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x95, 0x06, /* Report Count (6), */ + 0x81, 0x03, /* Input (Constant, Variable), */ + 0x05, 0x01, /* Usage Page (Desktop), */ + 0x75, 0x08, /* Report Size (8),*/ + 0x95, 0x05, /* Report Count (5), */ + 0x09, 0x01, /* Usage (Pointer),*/ + 0x81, 0x02, /* Input (Variable), */ + 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ + 0x95, 0x20, /* Report Count (26), */ + 0x81, 0x02, /* Input (Variable), */ + 0x75, 0x08, /* Report Size (8),*/ + 0x95, 0x30, /* Report Count (48
[PATCH 2/3] HID: hid-sony: Navigation controller only has 1 LED and no rumble
Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 41 + 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 3fba2dca..af02139 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -48,15 +48,20 @@ #define DUALSHOCK4_CONTROLLER_BT BIT(6) #define MOTION_CONTROLLER_USB BIT(7) #define MOTION_CONTROLLER_BT BIT(8) +#define NAVIGATION_CONTROLLER_USB BIT(9) +#define NAVIGATION_CONTROLLER_BT BIT(10) #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) +#define NAVIGATION_CONTROLLER (NAVIGATION_CONTROLLER_USB |\ + NAVIGATION_CONTROLLER_BT) #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ DUALSHOCK4_CONTROLLER_BT) #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ - DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER) + DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER |\ + NAVIGATION_CONTROLLER) #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ - MOTION_CONTROLLER_BT) + MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ MOTION_CONTROLLER) @@ -1052,6 +1057,9 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (sc-quirks MOTION_CONTROLLER) return motion_fixup(hdev, rdesc, rsize); + if (sc-quirks NAVIGATION_CONTROLLER) + return sixaxis_fixup(hdev, rdesc, rsize); + if (sc-quirks PS3REMOTE) return ps3remote_fixup(hdev, rdesc, rsize); @@ -1181,6 +1189,9 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, sixaxis_parse_report(sc, rd, size); } else if ((sc-quirks MOTION_CONTROLLER_BT) rd[0] == 0x01 size == 49) { sixaxis_parse_report(sc, rd, size); + } else if ((sc-quirks NAVIGATION_CONTROLLER) rd[0] == 0x01 + size == 49) { + sixaxis_parse_report(sc, rd, size); } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 size == 64) || ((sc-quirks DUALSHOCK4_CONTROLLER_BT) rd[0] == 0x11 size == 78)) { @@ -1591,6 +1602,15 @@ static int sony_leds_init(struct sony_sc *sc) use_ds4_names = 1; name_len = 0; name_fmt = %s:%s; + } else if (sc-quirks NAVIGATION_CONTROLLER) { + static const __u8 navigation_leds[4] = {0x01, 0x00, 0x00, 0x00}; + + memcpy(sc-led_state, navigation_leds, sizeof(navigation_leds)); + sc-led_count = 1; + memset(use_hw_blink, 1, 4); + use_ds4_names = 0; + name_len = strlen(::sony#); + name_fmt = %s::sony%d; } else { sixaxis_set_leds_from_id(sc); sc-led_count = 4; @@ -1782,7 +1802,8 @@ static void motion_state_worker(struct work_struct *work) static int sony_allocate_output_report(struct sony_sc *sc) { - if (sc-quirks SIXAXIS_CONTROLLER) + if ((sc-quirks SIXAXIS_CONTROLLER) || + (sc-quirks NAVIGATION_CONTROLLER)) sc-output_report_dmabuf = kmalloc(sizeof(union sixaxis_output_report_01), GFP_KERNEL); @@ -2001,6 +2022,7 @@ static int sony_check_add(struct sony_sc *sc) if ((sc-quirks DUALSHOCK4_CONTROLLER_BT) || (sc-quirks MOTION_CONTROLLER_BT) || + (sc-quirks NAVIGATION_CONTROLLER_BT) || (sc-quirks SIXAXIS_CONTROLLER_BT)) { /* * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC @@ -2033,7 +2055,8 @@ static int sony_check_add(struct sony_sc *sc) } memcpy(sc-mac_address, buf[1], sizeof(sc-mac_address)); - } else if (sc-quirks SIXAXIS_CONTROLLER_USB) { + } else if ((sc-quirks SIXAXIS_CONTROLLER_USB) || + (sc-quirks NAVIGATION_CONTROLLER_USB)) { buf = kmalloc(SIXAXIS_REPORT_0xF2_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -2167,7 +2190,8 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_stop; } - if (sc-quirks SIXAXIS_CONTROLLER_USB) { + if ((sc-quirks SIXAXIS_CONTROLLER_USB) || + (sc-quirks NAVIGATION_CONTROLLER_USB)) { /* * The Sony Sixaxis does not handle HID Output Reports
[PATCH 1/3] HID: hid-sony: Add BT support for Navigation Controller
Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-sony.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 044e96a..a64f862 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1962,6 +1962,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 2ce0295..3fba2dca 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2287,6 +2287,8 @@ static const struct hid_device_id sony_devices[] = { .driver_data = SIXAXIS_CONTROLLER_USB }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_USB }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), + .driver_data = SIXAXIS_CONTROLLER_BT }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), .driver_data = MOTION_CONTROLLER_USB }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] HID: hid-sony: Add basic iio-subsystem reading of SixAxis Accelerometers
Thank you for your comments, I'm just getting started with IIO so it's all good stuff... + Hmm. This driver is already a substantial mash up of a number of different types of driver (as far as linux is concerned), with input, battery and led drivers. Might be worth considering a more formal MFD approach as it'll break the driver up into a number of sub components that will then sit in the various subsystems in a cleaner fashion. Just a thought! Might be, but that sounds like more work ;-) If pushing some ideas around prompts that, it can't be a bad thing right? +case IIO_CHAN_INFO_SCALE: +switch (chan-type) { If the scale really is 1 then don't export it. Note the units would have to be in m/s^2 which seems unlikely though. I'm guessing this is a placeholder.. Yes place holder, different controllers (SixAxis, DS4 and PSMove) have different values. In the far future I'd hope to use the per-device calibration stored on the PSMove. https://github.com/nitsch/moveonpc/wiki/Calibration-data +static const struct iio_chan_spec sony_sixaxis_channels[] = { +SONY_ACC_CHANNEL(X), +SONY_ACC_CHANNEL(Y), +SONY_ACC_CHANNEL(Z), No gyro channels yet? Just to note, if the gyro frequency etc is different from the accelerometer (pretty common) then you'll want to register two IIO devices rather than just the one so that the control and buffers are separate. I have a vague memory that the SixAxis has a 1-ch gyro but this is not showing on hidraw (might be 'hidden' behind MultiTouch ID/Bug). The DS4 has Accel/Gyros, and the PSMove has Accel/Gyro/Mag. I didn't expose the mags over input/joystick axis as I didn't want to corrupt stream the PSMoveAPI (it needs to be re-ordered) and it's unlikely anyone would actually use via joystick. The PSMove's report actually contains 2 frames assumed to be 1/2 sample rate apart for the Accel/Gyro, but only one Mag reading. I have further advanced the patch to include reading via buffer, but I'm having trigger 'conceptual' problems getting my head around the HID device issuing an interrupt when a input report is received. Looking at iio_dummy_event and iios_sysfs for inspiration On the assumption that there will be multiple devices (either same type or with different HID drivers) all trying to issue triggers, we'd need to be a little careful. Is there a 'short-cut' we can use if a HID device is only required to trigger itself (and not other iio devices)? ie. not need true interrupt system. Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC] HID: hid-sony: Add basic iio-subsystem reading of SixAxis Accelerometers
[resent as I screwed up addressing... sorry] This patch is a RFC/POC for the idea of using the iio-subsystem as the 'proper' way to communicate the state of motion enabled controllers to the Linux internals. I have started with the hid-sony driver, with support for the SixAxis's 3 Accelerometers. Proper trigger/buffer support will follow shortly, along with support for the DS4 and PSMove controllers (which have a much more extensive set of motion hardware). Once the sensor data is available (over iio) I envision that it will be considerably easier to write motion tracking, flight control and AHRS software in a consistant manner. Hopefully this will become the standard way of connecting controllers, motion controls and head mounted displays. --- drivers/hid/hid-sony.c | 175 + 1 file changed, 175 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 6ca96ce..79afae6 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -36,6 +36,7 @@ #include linux/list.h #include linux/idr.h #include linux/input/mt.h +#include linux/iio/iio.h #include hid-ids.h @@ -54,6 +55,7 @@ DUALSHOCK4_CONTROLLER) #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) +#define SONY_IIO_SUPPORT SIXAXIS_CONTROLLER #define MAX_LEDS 4 @@ -835,6 +837,23 @@ struct sony_sc { __u8 led_delay_on[MAX_LEDS]; __u8 led_delay_off[MAX_LEDS]; __u8 led_count; + +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + struct iio_dev *indio_dev; + __u16 last_acc[3]; + __u16 last_gyro[3]; +}; + +enum sony_iio_axis { + AXIS_X, + AXIS_Y, + AXIS_Z, +}; + +struct sony_iio { + struct sony_sc *sc; +#endif }; static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -1047,6 +1066,12 @@ static int sony_raw_event(struct hid_device *hdev, struct hid_report *report, swap(rd[45], rd[46]); swap(rd[47], rd[48]); +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + sc-last_acc[0] = (rd[42] 8) + rd[41]; + sc-last_acc[1] = (rd[44] 8) + rd[43]; + sc-last_acc[2] = (rd[46] 8) + rd[45]; +#endif sixaxis_parse_report(sc, rd, size); } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 size == 64) || ((sc-quirks DUALSHOCK4_CONTROLLER_BT) @@ -1769,6 +1794,136 @@ static void sony_battery_remove(struct sony_sc *sc) sc-battery_desc.name = NULL; } +#if IS_BUILTIN(CONFIG_IIO) || \ + (IS_MODULE(CONFIG_IIO) IS_MODULE(CONFIG_HID_SONY)) + +static int sony_iio_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct sony_iio *data = iio_priv(indio_dev); + int ret; + u32 temp; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan-type) { + case IIO_ACCEL: + *val = data-sc-last_acc[chan-scan_index]; + return IIO_VAL_INT; + case IIO_ANGL_VEL: + *val = data-sc-last_gyro[chan-scan_index]; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SCALE: + switch (chan-type) { + case IIO_ACCEL: + *val = 1; + return IIO_VAL_INT; + case IIO_ANGL_VEL: + *val = 1; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + switch (chan-type) { + case IIO_ACCEL: + *val = 512; + return IIO_VAL_INT; + case IIO_ANGL_VEL: + *val = 512; + return IIO_VAL_INT; + default: + return -EINVAL; + } + } + + return -EINVAL; +} + +#define SONY_ACC_CHANNEL(_axis) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis,\ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET),
Re: Handling Controllers with Acc/Gyro/Mag via HID system
The IIO subsystem's user-space API is awful, and root only. I said as much here: http://thread.gmane.org/gmane.linux.kernel.iio/14421 Just getting started with this idea, and found this which might waylay some of the pain https://github.com/analogdevicesinc/libiio I wrote this for accelerometers that are in tablets/convertibles: https://github.com/hadess/iio-sensor-proxy/ Thanks I'll check it out. Thinking more of a AHRS rather than 'just' rotating the screen. ;-) Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] HID_ hid-sony_ Add support PS3 Move Battery via BT
Add support for the battery charge level and state to be read via BT. This is not support via USB as there is no know way to get the device sending 'input' reports over USB. Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 28dba6c..d9fa804 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -55,7 +55,8 @@ DUALSHOCK4_CONTROLLER_BT) #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ DUALSHOCK4_CONTROLLER | MOTION_CONTROLLER) -#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER) +#define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ + MOTION_CONTROLLER_BT) #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER |\ MOTION_CONTROLLER) @@ -1041,6 +1042,7 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) { static const __u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; unsigned long flags; + int offset; __u8 cable_state, battery_capacity, battery_charging; /* @@ -1049,12 +1051,14 @@ static void sixaxis_parse_report(struct sony_sc *sc, __u8 *rd, int size) * It does not report the actual level while charging so it * is set to 100% while charging is in progress. */ - if (rd[30] = 0xee) { + offset = (sc-quirks MOTION_CONTROLLER) ? 12 : 30; + + if (rd[offset] = 0xee) { battery_capacity = 100; - battery_charging = !(rd[30] 0x01); + battery_charging = !(rd[offset] 0x01); cable_state = 1; } else { - __u8 index = rd[30] = 5 ? rd[30] : 5; + __u8 index = rd[offset] = 5 ? rd[offset] : 5; battery_capacity = sixaxis_battery_capacity[index]; battery_charging = 0; cable_state = 0; @@ -1155,6 +1159,8 @@ 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 MOTION_CONTROLLER_BT) rd[0] == 0x01 size == 49) { + sixaxis_parse_report(sc, rd, size); } else if (((sc-quirks DUALSHOCK4_CONTROLLER_USB) rd[0] == 0x01 size == 64) || ((sc-quirks DUALSHOCK4_CONTROLLER_BT) rd[0] == 0x11 size == 78)) { @@ -1976,6 +1982,7 @@ static int sony_check_add(struct sony_sc *sc) int n, ret; if ((sc-quirks DUALSHOCK4_CONTROLLER_BT) || + (sc-quirks MOTION_CONTROLLER_BT) || (sc-quirks SIXAXIS_CONTROLLER_BT)) { /* * sony_get_bt_devaddr() attempts to parse the Bluetooth MAC -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] HID: hid-sony: PS3 Move enable LEDs and Rumble via BT
The LED and Rumble control only function via BT if the full output report is sent. The large report still functions via USB. Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index d9fa804..51cb1ac 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -902,6 +902,7 @@ struct motion_output_report_02 { #define DS4_REPORT_0x81_SIZE 7 #define SIXAXIS_REPORT_0xF2_SIZE 17 #define SIXAXIS_REPORT_0xF5_SIZE 8 +#define MOTION_REPORT_0x02_SIZE 49 static DEFINE_SPINLOCK(sony_dev_list_lock); static LIST_HEAD(sony_device_list); @@ -1746,7 +1747,7 @@ static void motion_state_worker(struct work_struct *work) struct motion_output_report_02 *report = (struct motion_output_report_02 *)sc-output_report_dmabuf; - memset(report, 0, sizeof(struct motion_output_report_02)); + memset(report, 0, MOTION_REPORT_0x02_SIZE); report-type = 0x02; /* set leds */ report-r = sc-led_state[0]; @@ -1757,8 +1758,7 @@ static void motion_state_worker(struct work_struct *work) report-rumble = max(sc-right, sc-left); #endif - hid_hw_output_report(hdev, (__u8 *)report, - sizeof(struct motion_output_report_02)); + hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE); } static int sony_allocate_output_report(struct sony_sc *sc) @@ -1774,9 +1774,8 @@ static int sony_allocate_output_report(struct sony_sc *sc) sc-output_report_dmabuf = kmalloc(DS4_REPORT_0x05_SIZE, GFP_KERNEL); else if (sc-quirks MOTION_CONTROLLER) - sc-output_report_dmabuf = - kmalloc(sizeof(struct motion_output_report_02), - GFP_KERNEL); + sc-output_report_dmabuf = kmalloc(MOTION_REPORT_0x02_SIZE, + GFP_KERNEL); else return 0; -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] HID: hid-sony: Add quirk for MOTION_CONTROLLER_BT
Split quirk for PS Move Controller as it has to be treated differently when connected via BT. Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-sony.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 6fcc2b4..28dba6c 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -46,9 +46,11 @@ #define PS3REMOTE BIT(4) #define DUALSHOCK4_CONTROLLER_USB BIT(5) #define DUALSHOCK4_CONTROLLER_BT BIT(6) -#define MOTION_CONTROLLER BIT(7) +#define MOTION_CONTROLLER_USB BIT(7) +#define MOTION_CONTROLLER_BT BIT(8) #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) +#define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) #define DUALSHOCK4_CONTROLLER (DUALSHOCK4_CONTROLLER_USB |\ DUALSHOCK4_CONTROLLER_BT) #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ @@ -2261,9 +2263,9 @@ static const struct hid_device_id sony_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_USB }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), - .driver_data = MOTION_CONTROLLER }, + .driver_data = MOTION_CONTROLLER_USB }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), - .driver_data = MOTION_CONTROLLER }, + .driver_data = MOTION_CONTROLLER_BT }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_BT }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Handling Controllers with Acc/Gyro/Mag via HID system
Hi all, I'm in the process of fixing the HID descriptor for the PS3 Move Controller. which has a particularly convoluted layout for it's Accelormeters, Gyros and Magnetometers involving 2 sets of data per output report. https://github.com/nitsch/moveonpc/wiki/Input-report The plan is/was to massage the HID descriptor so the first set of Accels/Gyro/Mag appear in a set a axis, as a simple way of getting to this data. [snip] Given that more controllers are coming with 'motion' controls, is there a framework in place for unifying support? A little more poking around has got me looking at the IIO subsystem, which seems to be everything Accel/Gyro/Mag... I note that there are a few 'HID'ish things there too, although I'm not sure whether they are useful to us, or just intended for connecting motion devices via the HID bus and then onto IIO. -- drivers/iio/accel/hid-sensor-accel-3d.c drivers/iio/gyro/hid-sensor-gyro-3d.c drivers/iio/magnetometer/hid-sensor-magn-3d.c drivers/iio/orientation/hid-sensor-rotation.c -- Does the idea of the drivers for the HID (gaming) controllers opening up a connection to IIO system and pushing the Accel/Gyro/Mag values there (rather than exposing them on the joystick interface) make sense? Are there any examples of other devices doing this, so I can re-use the code? Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Handling Controllers with Acc/Gyro/Mag via HID system
Hi all, I'm in the process of fixing the HID descriptor for the PS3 Move Controller. which has a particularly convoluted layout for it's Accelormeters, Gyros and Magnetometers involving 2 sets of data per output report. https://github.com/nitsch/moveonpc/wiki/Input-report The plan is/was to massage the HID descriptor so the first set of Accels/Gyro/Mag appear in a set a axis, as a simple way of getting to this data. The Magnetometers are only 12 bits, and if 'we' want the HID system to be able to process these as an axis the data needs to be shuffled. Previously for the Sony SixAxis Accels was done in 'sony_raw_event'. https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-sony.c?id=refs/tags/v4.1-rc7#n1035 My reshuffle would be: --- /* Need to fix order and shared nibble of 12bit Temp/Mags */ /* 8e 4. .. .. .. .. - Temp = 0x08E4 */ /* .. .1 51 .. .. .. - MagX = 0x0151 */ /* .. .. .. 02 1. .. - MagZ = 0x0021 */ /* .. .. .. .. .2 98 - MagY = 0x0298 */ __u8 tmp; tmp = rd[38]; rd[38] = (((rd[37] 0xF0) 4) | ((rd[39] 0x0F) 4)); rd[37] = (((tmp 0xF0) 4) | ((rd[37] 0x0F) 4)); rd[39] = (((rd[39] 0xF0) 4) | ((tmp 0x0F) 4)); tmp = rd[41]; rd[41] = (((rd[40] 0xF0) 4) | ((rd[42] 0x0F) 4)); rd[40] = (((tmp 0xF0) 4) | ((rd[40] 0x0F) 4)); rd[42] = (((rd[42] 0xF0) 4) | ((tmp 0x0F) 4)); --- This works, however I have noticed that this affects/reshuffles the output of '/dev/hidraw0', which would 'corrupt' the data going into the existing user-mode drivers (such as psmoveapi). Is there a 'better' place/way to reshuffle this data, or is this just how it needs to be? Given that more controllers are coming with 'motion' controls, is there a framework in place for unifying support? Cheers, Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID: hid-sony: Support PS3 Move Controller when connected via Bluetooth
Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-sony.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index aefb248..044e96a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1960,6 +1960,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index aeb8b41..6fcc2b4 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -2262,6 +2262,8 @@ static const struct hid_device_id sony_devices[] = { .driver_data = SIXAXIS_CONTROLLER_USB }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), .driver_data = MOTION_CONTROLLER }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER), + .driver_data = MOTION_CONTROLLER }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), .driver_data = SIXAXIS_CONTROLLER_BT }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), -- 2.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/6] hid: sony: Add support for the Sony Motion Controller
Add a fixed-up HID descriptor for the Sony motion controller and enable controls for the LED light as well as force-feedback. Hi, I think that a mistake has been made here with the report descriptor, it looks like it is an exact duplicate of the one for the six-axis and it does not match the documented layout from the psmove-api guys. https://github.com/nitsch/moveonpc/wiki/Input-report The document above shows that there are two copies of axis data (frame1 and frame2) for many of them, what is the best way of handling this in kernel? Should we just ignore the 2nd? I have attached the 'original' reports (ie. with hid-sony changing them) for reference. Note the BT one has a trailing zero (like the DS4 has) which prevents decoding... I just cropped it off to decode. Simon. psmove_bt_report_orig.bin Description: Binary data psmove_bt_report_orig.code Description: Binary data psmove_usb_report_orig.bin Description: Binary data psmove_usb_report_orig.code Description: Binary data
Re: [PATCH v2 0/5] Support for the Sony Motion Controller and other cleanups
This set of patches adds initial support for the Sony Motion Controller via cleaned-up initial patches from Pavel Machek, streamlines LED initialization and state updates, adds a comment to explain why the Sixaxis has so many axes and why they spill over into the multi-touch space and makes some general cosmetic corrections. Maybe a little pointless as Jiri as already accepted, but I wanted to confirm that these patches appear work OK on my 3rd party (Intec) controller which has been problematic in the past. I have also acquired a PS Move Motion controller and note that LED settings work, but are then overridden (LED goes dark) after ~5s when connected with USB. I believe that this is a 'feature' of the controller with USB connection (and note there is no HID stream coming from the device). Does any one know of a trigger/command which will enable full USB operation? Simon. PS. I did not try BT connection as that apparently requires Bluez 5.0, which is a pain on _that_ machine. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] input: adxl34x: Add OF match support
On Thu, May 21, 2015 at 01:42:26PM +0200, Geert Uytterhoeven wrote: From: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com The I2C subsystem can match devices without explicit OF support based on the part of their compatible property after the comma. However, this mechanism uses the first compatible value only. For adxl34x OF device nodes the compatible property will contain the more specific adi,adxl345 or adi,adxl346 value first. This prevents the device node from being matched with the adxl34x driver. Fix this by adding an OF match table with an adi,adxl345 compatible entry. There's no need to add the adi,adxl346 entry as the ADXL346 is backward-compatible with the ADXL345 with differences handled by runtime detection of the device model. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com Reviewed-by: Wolfram Sang wsa+rene...@sang-engineering.com Signed-off-by: Geert Uytterhoeven geert+rene...@glider.be --- v2: - Add Reviewed-by. Reviewed-by: Simon Horman horms+rene...@verge.net.au -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/2] DT: i2c: Deprecate adi,adxl34x compatible string
On Thu, May 21, 2015 at 01:42:25PM +0200, Geert Uytterhoeven wrote: From: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com DT nodes should use the more specific adi,adxl345 and adi,adxl346 compatible values instead. As the ADXL346 is backward-compatible with the ADXL345, ADXL346 nodes must list both adi,adxl346 and adi,adxl345, in that order. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com Acked-by: Wolfram Sang w...@the-dreams.de Signed-off-by: Geert Uytterhoeven geert+rene...@glider.be --- v2: - Add Acked-by. Reviewed-by: Simon Horman horms+rene...@verge.net.au -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: Add driver for acer keybard with broken rdesc
On 27.02.2015 15:28, Florian Echtler wrote: Just as a quick side note, Simon's hack compiled as a standalone module fixes the issue for me on stock kernel 3.16.0 - keyboard works perfectly now. So device 06CB:2991 has exactly the same broken descriptor and should probably included in any future solution. Okay, i will include it. Many thanks to everyone involved! Best, Florian On 27.02.2015 15:16, Benjamin Tissoires wrote: [adding Florian to the thread, he is also affected by this] On Tue, Feb 17, 2015 at 9:01 PM, Andrew Dugganadug...@synaptics.com wrote: On 02/17/2015 04:30 AM, Jiri Kosina wrote: On Thu, 29 Jan 2015,li...@simon-woerner.de wrote: From: Simon Wörnerm...@simon-woerner.de HID: Add driver for acer keybard with broken rdesc Hi Simon, to make sure proper device - driver binding is performed, you also have to add device ID to the hid_have_special_driver[] array. To the cost of an error in the kernel log, the proper binding will be done even if if there is no entry in hid_have_special_driver :) See Florian's log: [3.153892] hid-generic 0003:06CB:2991.0003: usage index exceeded [3.153896] hid-generic 0003:06CB:2991.0003: item 0 2 2 2 parsing failed [3.153921] hid-generic: probe of 0003:06CB:2991.0003 failed with error -22 So hid-generic will fail to bind the device, so normally hid-acer should bind it, fix the report descriptor and the keyboard should be working. Not very clean, but it should work :) The other solutions looks like more work and at least some other problems. So this best and preferred solution, or did i got any thing wrong? I have been meaning to respond to this patch. Unfortunately, simply adding this driver to the hid_have_special_driver[] list will prevent hid-multitouch from binding to the touchpad which shares the same vid and pid. My suggestion would be to create a new scan_flag for GD_KEYBOARD and to add to the code in hid_scan_collection() which scans the GENDESK usages. Similar to the code which is searching for HID_GD_POINTER. Then in hid_scan_report() we could assign a group for this driver based on the pid and the GD_KEYBOARD scan flag in the vendor handling code. This could work, but that means that the list of special quirks after the parsing is going to explode :( Plus we have to be sure that the scan_report doesn't fail or we will not be able to tag the device correctly. I can help out with implementing this part of the patch if there aren't any other suggestions. Adding a new group and more code to the hid_scan_report() vendor handling code is definately not ideal. But, I am not sure of a better way of binding different sub drivers to devices with the same vid and pid. An alternative would be to have hid-rmi handle all Synaptics touchpads, even the ones which currently use hid-multitouch. Then the keyboard report descriptor fixup could just be handled in hid-rmi. Accessing the finger data via rmi mode would also have the benefit of being able to report events which are currently not supported by the PTP collection (ie ABS_MT_PRESSURE, ABS_MT_TOUCH_MAJOR/MINOR). The touchpads which currently use hid-multitouch report finger data a little differently then the ones currently using hid-rmi so there is some work which would need to be done to add support for them in hid-rmi. I am not sure we want to do that. Because we don't want hid-rmi to fix all crappy keyboards around when the OEM reuses the synaptics PID. Maybe a better way of handling such situation is to provide a generic mechanism to overwrite/patch the report descriptor so that we could get rid of the drivers which just fix the report descriptor. I have on a branch a version where I look into /lib/firmware/hid if there is a matching device and a matching report descriptor. Then, I read this firmware dynamically and patch the report descriptor. This however requires that the hid modules are not included directly in the kernel, or the /lib/firmware dir is not available and the device doesn't bind. Cheers, Benjamin -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message tomajord...@vger.kernel.org More majordomo info athttp://vger.kernel.org/majordomo-info.html Is there any point i missed or we're good to go now? (expect the new device id) Greets, Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: HID: usbhid: Check HID report descriptor contents after device reset
Hi Dan The patch dc3c78e43469: HID: usbhid: Check HID report descriptor contents after device reset from Apr 3, 2012, leads to the following static checker warning: drivers/hid/usbhid/hid-core.c:1591 hid_reset_resume() warn: bool comparison is always 'true' drivers/hid/usbhid/hid-core.c 1421 static int hid_post_reset(struct usb_interface *intf) 1422 { 1423 struct usb_device *dev = interface_to_usbdev (intf); 1424 struct hid_device *hid = usb_get_intfdata(intf); 1425 struct usbhid_device *usbhid = hid-driver_data; 1426 struct usb_host_interface *interface = intf-cur_altsetting; 1427 int status; 1428 char *rdesc; 1429 1430 /* Fetch and examine the HID report descriptor. If this 1431 * has changed, then rebind. Since usbcore's check of the 1432 * configuration descriptors passed, we already know that 1433 * the size of the HID report descriptor has not changed. 1434 */ 1435 rdesc = kmalloc(hid-dev_rsize, GFP_KERNEL); 1436 if (!rdesc) { 1437 dbg_hid(couldn't allocate rdesc memory (post_reset)\n); 1438 return 1; We return 1 on error now in this function. I can't figure out if this is intentional. Originally, this was intentional. The thinking was that if we're stopped from determining whether or not the report descriptor contents have changed, we should act as though they have and indicate to usb_reset_device() that a rebind should occur. snip 1463 1464 return 0; 1465 } [ snip ] 1589 clear_bit(HID_SUSPENDED, usbhid-iofl); 1590 status = hid_post_reset(intf); 1591 if (status = 0 hid-driver hid-driver-reset_resume) { ^^^ This condition is always true. 1592 int ret = hid-driver-reset_resume(hid); 1593 if (ret 0) 1594 status = ret; Maybe the -reset_resume() can succeed even though hid_post_reset() failed? In that case, we return the 1 error code and print it in dmesg in usb_resume_interface(). Strange and uncommented. Yes, it does look like hid_post_reset() should be returning proper error codes on failure, to allow correct behaviour here. usb_reset_device() should still interpret such error code returns as a need to attempt a rebind. 1595 } 1596 return status; 1597 } regards, dan carpenter Many thanks Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RESEND] HID: Stop hiding options with !EXPERT
I can't really comment on the overall situation (Jiri replied to your last thread), but... The HID_LOGITECH option is even worse than the others. Sub-options depend on it, and this causes menuconfig and friends to display the option even though the user can't change its value. The help page for HID_LOGITECH will not explain why the value can't be changed. It only says, for example: Perhaps the Kconfig for Logitech does need some TLC. It should be remembered that it supports a wide range of devices from Unifying, to game controllers and wheels. In total it knows about 30 USB-IDs. Depends on: INPUT [=y] HID [=y] and that leaves the user puzzled about why the option is forced to y. You might argue that this is a Kconfig bug, but that doesn't make it less annoying for the user. Even worse is that some of the sub-options of HID_LOGITECH select INPUT_FF_MEMLESS, which in turn gets out of control for the user. So, if you set INPUT=y and HID=y (something most general purpose distributions would do these days, as both modules would get loaded on a vast majority of systems otherwise), and you want support for force-feedback game controllers, you can't have that as a module, it has to be built-in, regardless of how rare these devices are. It make sense to remain as a module (if modules are enabled) when 'INPUT=y and HID=y', and should not force 'FF_MEMLESS=Y' (just leave that as module too). There is also the 'LEDS CLASS' which is required for G27 support. IIRC there was some 'magic' done with hid-steelseries to tweak problems with LEDs. I'd be open to helping this happen, given some guidance. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: hid-sony: Prevent LED overrun
On Feb 18, 2015 12:32 AM, si...@mungewell.org wrote: I think this was a bug in the LED system itself fixed by this commit: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/leds/leds.h?id=56d06fdee534124f79b51ff92232373b783cddc2 In kernel 3.19 the brightness values are clamped correctly and I can't replicate your bug. I guess it's possible, I am running 3.19.0rc5. I'll build 3.19 and see if it's showing the bug. Ah, my mistake. That fix wasn't pulled in until 3.20 so you'll need to grab the latest working version to try it. Well I did a 'git pull' and left it building overnight, and only just saw this email... A quick test this morning shows that the bug does not occur with the new build, so it looks like my patch is not required after all (and fixing in LED subsystem makes far more sense). I am, however, confused about what I pulled and built. It definately had the patch (I looked in drivers/leds/leds.h before building) but built as 3.19 guess I'll just have a confused expression for the rest of the day. https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/log/drivers/leds/leds.h Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: hid-lg4ff: Fix undefined reference build issue with CONFIG_USB disabled.
Fix undefined reference build issue with CONFIG_USB disabled. Just a newbie question... for a family of devices (the wheels) which can only be attached via USB, wouldn't the better approach be to fix the dependancy? Are there any other devices provided for by 'hid-logitech' which use any other transport (HID over Bluetooth or the like)? Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 0/4] HID: hid-lg4ff: Improve handling of Logitech multimode gaming wheels
This patch series improves handling of various Logitech gaming wheels and allows switching between various compatibility modes which might be useful to improve compatibility with very old games and testing purposes. Signed-off-by: Michal Malý madcatxs...@devoid-pointer.net v2: - Rebased against latest linux-next - Document the newly introduced sysfs interfaces in appropriate commits - Assume that we are targeting kernel version 4.1 - Fix a misleading error message regarding unsupported wheel mode This version looks good to me; tested with WiiWheel, DFP and G27. Thanks, Simon -- tested-by: Simon Wood si...@mungewell.org -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: hid-sony: Prevent LED overrun
I think this was a bug in the LED system itself fixed by this commit: http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/drivers/leds/leds.h?id=56d06fdee534124f79b51ff92232373b783cddc2 In kernel 3.19 the brightness values are clamped correctly and I can't replicate your bug. I guess it's possible, I am running 3.19.0rc5. I'll build 3.19 and see if it's showing the bug. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] HID: Improve handling of multimode Logitech handling wheels
Hi all, I tested this with a DFP, G27 and WiiWheell was looking good, but then I found a small bug. It seems that the requested mode is case sensitive. 'G25' works, but 'g25' is seen as a request for a 'DF-GT' and causes and error. Sorry I didn't see this earlier. I'd be happy to apply and fix later, but I suspect Jiri will say fix it first. Simon PS. Resent via Gmail as my hosting is having issues. On Fri, 6 Feb 2015 10:27:21 -0700, si...@mungewell.org wrote: This patch series improves handling of various Logitech gaming wheels and allows switching between various compatibility modes which might be useful to improve compatibility with very old games and testing purposes. Hi all, We should note that part 1 performs a very important function of identify the wheels as per Logitech's schema. At present our (old detection) uses USB Revision to identify 'fancy' wheels which can be placed into native mode. This means when Logitech updates the hardware we are playing catch-up (this has happened 3 times with the DF-GT wheel so far). This newer code should automatically cope with new wheels in the future. Thanks to Michal for undertaking this work. I have been testing the code over the past weeks and believe it to be working, I will confirm mid-next week when I can gain access to my wheels. Simon Got this while testing -- Feb 12 19:52:00 bigbox kernel: [ 966.044022] usb 8-2: new full-speed USB device number 16 using uhci_hcd Feb 12 19:52:00 bigbox kernel: [ 966.215031] usb 8-2: New USB device found, idVendor=046d, idProduct=c298 Feb 12 19:52:00 bigbox kernel: [ 966.215035] usb 8-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0 Feb 12 19:52:00 bigbox kernel: [ 966.215038] usb 8-2: Product: G27 Racing Wheel Feb 12 19:52:00 bigbox kernel: [ 966.218081] drivers/hid/usbhid/hid-core.c: HID probe called for ifnum 0 Feb 12 19:52:00 bigbox kernel: [ 966.225084] logitech 0003:046D:C298.0012: fixing up Logitech Driving Force Pro report descri ptor Feb 12 19:52:00 bigbox kernel: [ 966.225545] input: G27 Racing Wheel as /devices/pci:00/:00:1d.3/usb8/8-2/8-2:1.0/000 3:046D:C298.0012/input/input24 Feb 12 19:52:00 bigbox mtp-probe: checking bus 8, device 16: /sys/devices/pci:00/:00:1d.3/usb8/8-2 Feb 12 19:52:00 bigbox mtp-probe: bus: 8, device: 16 was not an MTP device Feb 12 19:52:00 bigbox kernel: [ 966.280150] logitech 0003:046D:C298.0012: input,hidraw2: USB HID v1.00 Joystick [G27 Racing Wheel] on usb-:00:1d.3-2/input0 Feb 12 19:52:00 bigbox kernel: [ 966.280155] drivers/hid/hid-lg4ff.c: Found wheel with real PID C29B whose reported PID is C2 98 Feb 12 19:52:00 bigbox kernel: [ 966.280158] drivers/hid/hid-lg4ff.c: Found compatible device, product ID C298 Feb 12 19:52:00 bigbox kernel: [ 966.280166] drivers/hid/usbhid/hid-core.c: submitting out urb Feb 12 19:52:00 bigbox kernel: [ 966.280174] drivers/hid/hid-lg4ff.c: sysfs interface created Feb 12 19:52:00 bigbox kernel: [ 966.280176] drivers/hid/hid-lg4ff.c: Driving Force Pro: setting range to 900 Feb 12 19:52:00 bigbox kernel: [ 966.280179] logitech 0003:046D:C298.0012: Force feedback support for Logitech Gaming Wheels Feb 12 19:52:00 bigbox kernel: [ 966.286030] drivers/hid/usbhid/hid-core.c: submitting out urb Feb 12 19:52:00 bigbox kernel: [ 966.294030] drivers/hid/usbhid/hid-core.c: submitting out urb Feb 12 19:52:26 bigbox kernel: [ 992.162555] drivers/hid/hid-lg4ff.c: Alternate mode DFGT not supported by the device -- Note I don't have a DFGT, and didn't ask for a fake one Unplug and replug -- Feb 12 20:05:15 bigbox kernel: [ 1761.104019] usb 8-2: new full-speed USB device number 23 using uhci_hcd Feb 12 20:05:15 bigbox kernel: [ 1761.275032] usb 8-2: New USB device found, idVendor=046d, idProduct=c294 Feb 12 20:05:15 bigbox kernel: [ 1761.275037] usb 8-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0 Feb 12 20:05:15 bigbox kernel: [ 1761.275040] usb 8-2: Product: G27 Racing Wheel Feb 12 20:05:15 bigbox kernel: [ 1761.278091] drivers/hid/usbhid/hid-core.c: HID probe called for ifnum 0 Feb 12 20:05:15 bigbox kernel: [ 1761.286543] input: G27 Racing Wheel as /devices/pci:00/:00:1d.3/usb8/8-2/8-2:1.0/0003:046D:C294.0019/input/input31 Feb 12 20:05:15 bigbox mtp-probe: checking bus 8, device 23: /sys/devices/pci:00/:00:1d.3/usb8/8-2 Feb 12 20:05:15 bigbox mtp-probe: bus: 8, device: 23 was not an MTP device Feb 12 20:05:15 bigbox kernel: [ 1761.340180] logitech 0003:046D:C294.0019: input,hidraw2: USB HID v1.00 Joystick [G27 Racing Wheel] on usb-:00:1d.3-2/input0 Feb 12 20:05:15 bigbox kernel: [ 1761.340186] drivers/hid/hid-lg4ff.c: Found wheel with real PID C29B whose reported PID is C294 Feb 12 20:05:15 bigbox kernel: [ 1761.340188] drivers/hid/hid-lg4ff.c: Found compatible device, product ID C294 Feb 12 20:05:15 bigbox kernel: [ 1761.340197] drivers/hid/usbhid/hid-core.c: submitting out urb Feb 12 20:05:15 bigbox kernel
Re: [PATCH 0/4] HID: Improve handling of multimode Logitech handling wheels
This patch series improves handling of various Logitech gaming wheels and allows switching between various compatibility modes which might be useful to improve compatibility with very old games and testing purposes. Hi all, We should note that part 1 performs a very important function of identify the wheels as per Logitech's schema. At present our (old detection) uses USB Revision to identify 'fancy' wheels which can be placed into native mode. This means when Logitech updates the hardware we are playing catch-up (this has happened 3 times with the DF-GT wheel so far). This newer code should automatically cope with new wheels in the future. Thanks to Michal for undertaking this work. I have been testing the code over the past weeks and believe it to be working, I will confirm mid-next week when I can gain access to my wheels. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
EPERM instead of EINVAL?
Hi all, Michal is working on another round of changes for the Logitech wheel (hid-lg4ff), and we are including code to switch between different modes - thus allowing a G27 wheel (for example) to emulate a simpler wheel. At present we automatically 'upgrade' wheel to the best mode they can handle, we then allow the user to 'downgrade' as they wish. However, we have to prevent them downgrading to the simplest (USB_DEVICE_ID_LOGITECH_WHEEL) as when the devices does the USB detach/attach it would then just upgrade automatically. We have a module parameter which prevents the automatic upgrade if the user _really_ wants their expensive wheel to behave like the cheapest. The code does this: -- /* Automatic switching has to be disabled for the switch to DF-EX mode to work correctly */ if (target_product_id == USB_DEVICE_ID_LOGITECH_WHEEL !lg4ff_no_autoswitch) { hid_info(hid, \%s\ cannot be switched to \DF-EX\ mode. Load the \hid_logitech\ module with \lg4ff_no_autoswitch=1\ parameter set and try again.\n, entry-real_name); return -EINVAL; } -- So it throws an EINVAL if you try to set simplest when auto-switch is enabled. The message on the console is a little confusing, but hid debug explains. -- root@bigbox:/storage/linux-git# echo DF-EX /sys/bus/hid/devices/0003\:046D\:C298.000F/alternate_modes bash: echo: write error: Invalid argument -- Feb 4 22:21:01 bigbox kernel: [ 7715.452435] logitech 0003:046D:C298.000F: G27 Racing Wheel cannot be switched to DF-EX mode. Load the hid_logitech module with lg4ff_no_autoswitch=1 parameter set and try again. -- Would it make more sense to use EPERM, or is there another error code we can throw to be more informative. Thanks, Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: Add driver for synaptics keybard with broken rdesc
Thanks for the feedback, this is my first commit to the linux kernel so I don't know much about how the input / hid is working. I will add the changelog to the patch email, just need to find out how this works. Am 27.01.15 um 15:16 schrieb Benjamin Tissoires: On Fri, Jan 23, 2015 at 2:03 PM, Simon Wörner li...@simon-woerner.de wrote: From: Simon Wörner m...@simon-woerner.de Signed-off-by: Simon Wörner m...@simon-woerner.de --- drivers/hid/Kconfig | 6 ++ drivers/hid/Makefile| 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-synaptics.c | 190 4 files changed, 198 insertions(+) create mode 100644 drivers/hid/hid-synaptics.c I am pretty sure you are missing a change in hid-core.c to add your device to hid_have_special_driver. So I need to add this? static const struct hid_device_id hid_have_special_driver[] = { ... { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_VENDOR_ID_SYNAPTICS_KBD) }, ... do I also need to add #if IS_ENABLED(HID_SYNAPTICS) ... #endif or will hid-core handle that for me? Other than that (and the 2comments Jiri made), I am not very happy with adding a hid-synaptics while we already have a hid-rmi for synaptics devices. However, the keyboard must not follow the rmi spec, so this might be just fine. I have seen the rmi module and haven't found anything they have in common. The USB device of the keyboard has also attached a mouse / trackpad, but it also doens't make use of the rmi module. I don't see any reason for putting both together, e.g. hid-holtek-* has also two modules for keyboard rdesc fix and mouse rdesc fix. Maybe hid-synaptics-kbd would better fit? Few more comments: diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dfdc269..9f4124e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -708,6 +708,12 @@ config HID_SUNPLUS ---help--- Support for Sunplus wireless desktop. +config HID_SYNAPTICS + tristate Synaptics keyboard support + depends on HID + ---help--- + Support for Synaptics keyboard with invalid rdesc + config HID_RMI tristate Synaptics RMI4 device support depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index debd15b..01bda39 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_HID_SONY) += hid-sony.o obj-$(CONFIG_HID_SPEEDLINK)+= hid-speedlink.o obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o +obj-$(CONFIG_HID_SYNAPTICS)+= hid-synaptics.o obj-$(CONFIG_HID_GREENASIA)+= hid-gaff.o obj-$(CONFIG_HID_THINGM) += hid-thingm.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9243359..976ab39 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -873,6 +873,7 @@ #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD0x1ac3 +#define USB_VENDOR_ID_SYNAPTICS_KBD0x2968 #define USB_DEVICE_ID_SYNAPTICS_TP_V1030x5710 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS0x2047 diff --git a/drivers/hid/hid-synaptics.c b/drivers/hid/hid-synaptics.c new file mode 100644 index 000..3dab405 --- /dev/null +++ b/drivers/hid/hid-synaptics.c @@ -0,0 +1,190 @@ +/* + * HID driver for synaptics devices + * + * Copyright (c) 2015 Simon Wörner + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include linux/device.h +#include linux/hid.h +#include linux/module.h +#include linux/usb.h Please avoid using usb.h in HID drivers. HID should be transport agnostic. Okay. + +#include hid-ids.h + +/* Synaptics keyboards (USB ID 06cb:2968) e.g. in Acer SW5-012 + * have the following issue: + * - The report descriptor specifies an excessively large number of consumer + * usages (2^15), which is more than HID_MAX_USAGES. This prevents proper + * parsing of the report descriptor. + * + * The replacement descriptor below fixes the number of consumer usages. + */ + +static __u8 synaptics_kbd_rdesc_fixed[] = { + /* Application Collection */ + 0x06, 0x85, 0xFF, /* (GLOBAL) USAGE_PAGE (Vendor-defined) */ + 0x09, 0x95, /* (LOCAL) USAGE (0xFF850095) */ + 0xA1, 0x01, /* (MAIN) COLLECTION (Application) */ + 0x85, 0x5A, /* (GLOBAL) REPORT_ID (0x5A (90) 'Z') */ + 0x09, 0x01, /* (LOCAL) USAGE (0xFF850001) */ + 0x26
Re: [PATCH] HID: Add driver for synaptics keybard with broken rdesc
The new version is nearly finished, I will send it later today. See below for additional changes not in the other mails. Am 28.01.15 um 00:46 schrieb Andrew Duggan: On Tue, Jan 27, 2015 at 8:13 AM, Benjamin Tissoires benjamin.tissoi...@gmail.com wrote: On Tue, Jan 27, 2015 at 10:10 AM, Simon Wörner li...@simon-woerner.de wrote: Thanks for the feedback, this is my first commit to the linux kernel so I don't know much about how the input / hid is working. I will add the changelog to the patch email, just need to find out how this works. Am 27.01.15 um 15:16 schrieb Benjamin Tissoires: On Fri, Jan 23, 2015 at 2:03 PM, Simon Wörner li...@simon-woerner.de wrote: From: Simon Wörner m...@simon-woerner.de Signed-off-by: Simon Wörner m...@simon-woerner.de --- drivers/hid/Kconfig | 6 ++ drivers/hid/Makefile| 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-synaptics.c | 190 4 files changed, 198 insertions(+) create mode 100644 drivers/hid/hid-synaptics.c This isn't actually a Synaptics keyboard. The product id matches a touchpad so it appears that this is another situation where a vendor is using our touchpad's VID and PID to describe a composite USB device in a dock, even though our touchpad is only one of the devices in the dock. This is similar to what happened on the Dell Venue Pro 11. I think Synaptics should be removed from the name since it will be confusing should Synaptics release a keyboard. Thanks for pointing this out. I disassembled it and it seems to be a acer keyboard, at least there is a acer part number on it and acer assembled it with the stolen USB ID. So I renamed the module to 'hid_acer'. I am pretty sure you are missing a change in hid-core.c to add your device to hid_have_special_driver. So I need to add this? static const struct hid_device_id hid_have_special_driver[] = { ... { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_VENDOR_ID_SYNAPTICS_KBD) }, ... yep, seems fine. Adding the VID and PID to the hid_have_special_driver will cause the touchpad to stop working since it will prevent hid-multitouch from binding to it. Maybe in hid-core.c add a new hid group and a new scan flag for HID_GD_KEYBOARD and look for it in hid_scan_report()? But, this would also match the keyboard in the Dell Venue Pro 11 and potentially others, so the driver would need to check to see if the report descriptor needs this fix or not. I removed it from 'hid_have_special_driver' as in the first patch mail. If the USB ID isn't reliable and used by multiple devices then letting hid-core fail (on the acer keyboards) and claim the device afterwards with a check for the defect rdesc would have minimum impact on other devices and seems the be an acceptable solution to me. do I also need to add #if IS_ENABLED(HID_SYNAPTICS) ... #endif or will hid-core handle that for me? no, the rule here is that we just blacklist the device, and if the module is not compiled, then... too bad :) Other than that (and the 2comments Jiri made), I am not very happy with adding a hid-synaptics while we already have a hid-rmi for synaptics devices. However, the keyboard must not follow the rmi spec, so this might be just fine. I have seen the rmi module and haven't found anything they have in common. The USB device of the keyboard has also attached a mouse / trackpad, but it also doens't make use of the rmi module. I don't see any reason for putting both together, e.g. hid-holtek-* has also two modules for keyboard rdesc fix and mouse rdesc fix. Maybe hid-synaptics-kbd would better fit? no hid-synaptics will be fine. Few more comments: diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dfdc269..9f4124e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -708,6 +708,12 @@ config HID_SUNPLUS ---help--- Support for Sunplus wireless desktop. +config HID_SYNAPTICS + tristate Synaptics keyboard support + depends on HID + ---help--- + Support for Synaptics keyboard with invalid rdesc + config HID_RMI tristate Synaptics RMI4 device support depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index debd15b..01bda39 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_HID_SONY) += hid-sony.o obj-$(CONFIG_HID_SPEEDLINK)+= hid-speedlink.o obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o +obj-$(CONFIG_HID_SYNAPTICS)+= hid-synaptics.o obj-$(CONFIG_HID_GREENASIA)+= hid-gaff.o obj-$(CONFIG_HID_THINGM) += hid-thingm.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9243359..976ab39 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -873,6
[PATCH] HID: Add driver for synaptics keybard with broken rdesc
From: Simon Wörner m...@simon-woerner.de Signed-off-by: Simon Wörner m...@simon-woerner.de --- drivers/hid/Kconfig | 6 ++ drivers/hid/Makefile| 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-synaptics.c | 190 4 files changed, 198 insertions(+) create mode 100644 drivers/hid/hid-synaptics.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index dfdc269..9f4124e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -708,6 +708,12 @@ config HID_SUNPLUS ---help--- Support for Sunplus wireless desktop. +config HID_SYNAPTICS + tristate Synaptics keyboard support + depends on HID + ---help--- + Support for Synaptics keyboard with invalid rdesc + config HID_RMI tristate Synaptics RMI4 device support depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index debd15b..01bda39 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -109,6 +109,7 @@ obj-$(CONFIG_HID_SONY) += hid-sony.o obj-$(CONFIG_HID_SPEEDLINK)+= hid-speedlink.o obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o +obj-$(CONFIG_HID_SYNAPTICS)+= hid-synaptics.o obj-$(CONFIG_HID_GREENASIA)+= hid-gaff.o obj-$(CONFIG_HID_THINGM) += hid-thingm.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 9243359..976ab39 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -873,6 +873,7 @@ #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD0x1ac3 +#define USB_VENDOR_ID_SYNAPTICS_KBD0x2968 #define USB_DEVICE_ID_SYNAPTICS_TP_V1030x5710 #define USB_VENDOR_ID_TEXAS_INSTRUMENTS0x2047 diff --git a/drivers/hid/hid-synaptics.c b/drivers/hid/hid-synaptics.c new file mode 100644 index 000..3dab405 --- /dev/null +++ b/drivers/hid/hid-synaptics.c @@ -0,0 +1,190 @@ +/* + * HID driver for synaptics devices + * + * Copyright (c) 2015 Simon Wörner + */ + +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include linux/device.h +#include linux/hid.h +#include linux/module.h +#include linux/usb.h + +#include hid-ids.h + +/* Synaptics keyboards (USB ID 06cb:2968) e.g. in Acer SW5-012 + * have the following issue: + * - The report descriptor specifies an excessively large number of consumer + * usages (2^15), which is more than HID_MAX_USAGES. This prevents proper + * parsing of the report descriptor. + * + * The replacement descriptor below fixes the number of consumer usages. + */ + +static __u8 synaptics_kbd_rdesc_fixed[] = { + /* Application Collection */ + 0x06, 0x85, 0xFF, /* (GLOBAL) USAGE_PAGE (Vendor-defined) */ + 0x09, 0x95, /* (LOCAL) USAGE (0xFF850095)*/ + 0xA1, 0x01, /* (MAIN) COLLECTION (Application) */ + 0x85, 0x5A, /* (GLOBAL) REPORT_ID (0x5A (90) 'Z') */ + 0x09, 0x01, /* (LOCAL) USAGE (0xFF850001) */ + 0x26, 0xFF, 0x00, /* (GLOBAL) LOGICAL_MAXIMUM 0x00FF (255)*/ + 0x75, 0x08, /* (GLOBAL) REPORT_SIZE 0x08 (8)*/ + 0x95, 0x10, /* (GLOBAL) REPORT_COUNT 0x10 (16) */ + 0xB1, 0x00, /* (MAIN) FEATURE 0x00*/ + 0xC0, /* (MAIN) END_COLLECTION (Application) */ + + /* Application Collection */ + 0x05, 0x01, /* (GLOBAL) USAGE_PAGE (Desktop) */ + 0x09, 0x06, /* (LOCAL) USAGE 0x06 (Keyboard) */ + 0xA1, 0x01, /* (MAIN) COLLECTION (Application) */ + 0x85, 0x01, /* (GLOBAL) REPORT_ID 0x01 (1) */ + 0x75, 0x01, /* (GLOBAL) REPORT_SIZE 0x01 (1)*/ + 0x95, 0x08, /* (GLOBAL) REPORT_COUNT 0x08 (8) */ + 0x05, 0x07, /* (GLOBAL) USAGE_PAGE 0x07 (Keyboard) */ + 0x19, 0xE0, /* (LOCAL) USAGE_MINIMUM 0xE0 */ + 0x29, 0xE7, /* (LOCAL) USAGE_MAXIMUM 0xE7 */ + 0x25, 0x01, /* (GLOBAL) LOGICAL_MAXIMUM 0x01 (1)*/ + 0x81, 0x02, /* (MAIN) INPUT 0x02 */ + 0x95, 0x01, /* (GLOBAL) REPORT_COUNT 0x01 (1) */ + 0x75, 0x08, /* (GLOBAL) REPORT_SIZE 0x08 (8)*/ + 0x81, 0x03, /* (MAIN) INPUT 0x03
HID: Add driver for synaptics keybard with broken rdesc
Synaptics keyboards (USB ID 06cb:2968) e.g. in Acer SW5-012 have the following issue: - The report descriptor specifies an excessively large number of consumer usages (2^15), which is more than HID_MAX_USAGES. This prevents proper parsing of the report descriptor. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] HID: add new gamepad LED constants
Even if I did add the plumbing for HID over into the LED subsystem, is there an easy way to correlate input devices and their LEDs from userspace? You can follow the symlinks through the '/sys' filesystem. For example the following all point to the same LED. -- simon@womble:~$ ls /sys/class/input/js0/device/device/leds/0003\:054C\:0268.0001\:\:sony1 brightness device max_brightness power subsystem trigger uevent simon@womble:~$ ls /sys/class/leds/0003\:054C\:0268.0001\:\:sony1/ brightness device max_brightness power subsystem trigger uevent simon@womble:~$ ls /sys/bus/hid/devices/0003\:054C\:0268.0001/leds/0003\:054C\:0268.0001\:\:sony1/ brightness device max_brightness power subsystem trigger uevent -- One problem that exists is that many HID devices don't have an (embedded) serial number, so identification can be confused if you have more that one identical device. Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
From Jiri Kosina jkos...@suse.cz, Wed, Sep 03, 2014 at 09:29:07AM +0200: On Tue, 2 Sep 2014, Dylan Alex Simon wrote: Some combination of kernel debugging options and killing processes let it survive long enough to write the backtrace to disk. A simple modprobe/rmmod wasn't enough, though, it required a few tries removing the device and then rmmod (though has definitely happend on just one removal before). Let me know if there's anything else I can try. Alright, this supports my original hunch. I think I see the race. Could you please try the patch below? Thanks. diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 134be89..743a517 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -208,7 +208,7 @@ unregister_red: static void thingm_remove_rgb(struct thingm_rgb *rgb) { - flush_work(rgb-work); + cancel_work_sync(rgb-work); led_classdev_unregister(rgb-red.ldev); led_classdev_unregister(rgb-green.ldev); led_classdev_unregister(rgb-blue.ldev); Same problem (only rmmod this time, no write error, but still doesn't happen every time): [ 213.180726] thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 rmmod [ 217.399934] BUG: unable to handle kernel paging request at a00aa0cf [ 217.400034] IP: [ 217.400038] [a00aa0cf] 0xa00aa0cf [ 217.400039] PGD 1814067 [ 217.400040] PUD 1815063 [ 217.400044] PMD 42c266067 PTE 0 [ 217.400048] Oops: 0010 [#1] SMP [ 217.400057] Modules linked in: led_class cuse fuse snd_emu10k1 snd_hwdep snd_util_mem snd_ac97_codec ac97_bus snd_rawmidi snd_seq_device snd_pcm snd_timer ipt_ULOG [last unloaded: hid_thingm] [ 217.400061] CPU: 1 PID: 749 Comm: kworker/1:2 Not tainted 3.16.1-1-g98fed6d-dirty #146 [ 217.400063] Hardware name: empty empty/S8010-LE, BIOS 'V2.03B ' 03/15/2012 [ 217.400066] Workqueue: events 0xa00aa040 [ 217.400068] task: 88042df88790 ti: 8800bb9e4000 task.ti: 8800bb9e4000 [ 217.400072] RIP: 0010:[a00aa0cf] [a00aa0cf] 0xa00aa0cf [ 217.400073] RSP: 0018:8800bb9e7dd0 EFLAGS: 00010286 [ 217.400075] RAX: 0009 RBX: 88042c285af0 RCX: 0302 [ 217.400077] RDX: 0078 RSI: 0286 RDI: 88042d0e1a80 [ 217.400078] RBP: 8800bb9e7df0 R08: 8804ad0e1a80 R09: 0282 [ 217.400079] R10: 0001 R11: 2c95c8ba R12: 88042c8b0580 [ 217.400081] R13: R14: 88043ec54e00 R15: 88043ec513c0 [ 217.400087] FS: 7f02217fc700() GS:88043ec4() knlGS: [ 217.400089] CS: 0010 DS: ES: CR0: 8005003b [ 217.400091] CR2: a00aa0cf CR3: 00042af9 CR4: 000407e0 [ 217.400091] Stack: [ 217.400096] 0100a000 00010063 0ba997f6 88042c285af0 [ 217.400099] 8800bb9e7e38 81052c2f 88043ec513c0 3ec513c0 [ 217.400104] 88043ec513c0 88043ec513e8 88042df88790 88042c8b05b0 [ 217.400105] Call Trace: [ 217.400114] [81052c2f] process_one_work+0x14f/0x400 [ 217.400120] [81053423] worker_thread+0x63/0x540 [ 217.400125] [810533c0] ? create_and_start_worker+0x60/0x60 [ 217.400130] [81059038] kthread+0xe8/0x100 [ 217.400136] [8152de24] ? schedule+0x24/0x60 [ 217.400144] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 217.400149] [815323ec] ret_from_fork+0x7c/0xb0 [ 217.400153] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 217.400159] Code: Bad RIP value. [ 217.400163] RIP [a00aa0cf] 0xa00aa0cf [ 217.400164] RSP 8800bb9e7dd0 [ 217.400165] CR2: a00aa0cf [ 217.400168] ---[ end trace 9bd9c9db3e942a93 ]--- -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
I sent you wrong version of the patch, sorry for that. Could you please try the one below instead? diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 134be89..dffc50d 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -208,7 +208,7 @@ unregister_red: static void thingm_remove_rgb(struct thingm_rgb *rgb) { - flush_work(rgb-work); + cancel_work_sync(rgb-work); led_classdev_unregister(rgb-red.ldev); led_classdev_unregister(rgb-green.ldev); led_classdev_unregister(rgb-blue.ldev); @@ -286,10 +286,10 @@ static void thingm_remove(struct hid_device *hdev) struct thingm_device *tdev = hid_get_drvdata(hdev); int i; + hid_hw_stop(hdev); + for (i = 0; i tdev-fwinfo-numrgb; ++i) thingm_remove_rgb(tdev-rgb + i); - - hid_hw_stop(hdev); } static const struct hid_device_id thingm_table[] = { Still no luck (it really is using the new module, even though it didn't rebuild the kernel). I should also mention this is gcc 4.9.1. I can rebuild with 4.8.3 if there's a reason to suspect that, though I haven't seen any other issues. [ 145.571979] thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 [ 149.151153] BUG: unable to handle kernel paging request at a00aa0cf [ 149.151246] IP: [ 149.151251] [a00aa0cf] 0xa00aa0cf [ 149.151257] PGD 1814067 PUD 1815063 PMD 42ba9e067 PTE 0 [ 149.151262] Oops: 0010 [#1] SMP [ 149.151273] Modules linked in: led_class cuse fuse snd_emu10k1 snd_hwdep snd_util_mem snd_ac97_codec ac97_bus snd_rawmidi snd_seq_device snd_pcm snd_timer ipt_ULOG [last unloaded: hid_thingm] [ 149.151279] CPU: 7 PID: 664 Comm: kworker/7:2 Not tainted 3.16.1-1-g98fed6d-dirty #146 [ 149.151280] Hardware name: empty empty/S8010-LE, BIOS 'V2.03B ' 03/15/2012 [ 149.151286] Workqueue: events 0xa00aa040 [ 149.151288] task: 88042de12010 ti: 8800bb96c000 task.ti: 8800bb96c000 [ 149.151294] RIP: 0010:[a00aa0cf] [a00aa0cf] 0xa00aa0cf [ 149.151296] RSP: 0018:8800bb96fdd0 EFLAGS: 00010286 [ 149.151298] RAX: 0009 RBX: 88042ba612f0 RCX: 0302 [ 149.151300] RDX: 0049 RSI: 0286 RDI: 88042aa95d80 [ 149.151302] RBP: 8800bb96fdf0 R08: 8804aaa95d80 R09: 0282 [ 149.151303] R10: 00716d515080 R11: 0026 R12: 88042d189940 [ 149.151305] R13: R14: 88043edd4e00 R15: 88043edd13c0 [ 149.151308] FS: 7f383d7a3700() GS:88043edc() knlGS: [ 149.151311] CS: 0010 DS: ES: CR0: 8005003b [ 149.151315] CR2: a00aa0cf CR3: 01813000 CR4: 000407e0 [ 149.151316] Stack: [ 149.151321] 0100a000 00010063 f7ea6138 88042ba612f0 [ 149.151325] 8800bb96fe38 81052c2f 88043edd13c0 3edd13c0 [ 149.151329] 88043edd13c0 88043edd13e8 88042de12010 88042d189970 [ 149.151330] Call Trace: [ 149.151341] [81052c2f] process_one_work+0x14f/0x400 [ 149.151349] [81053423] worker_thread+0x63/0x540 [ 149.151354] [810533c0] ? create_and_start_worker+0x60/0x60 [ 149.151359] [81059038] kthread+0xe8/0x100 [ 149.151364] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 149.151370] [815323ec] ret_from_fork+0x7c/0xb0 [ 149.151374] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 149.151382] Code: Bad RIP value. [ 149.151386] RIP [a00aa0cf] 0xa00aa0cf [ 149.151387] RSP 8800bb96fdd0 [ 149.151389] CR2: a00aa0cf [ 149.151392] ---[ end trace 0d9114b619b5b2dc ]--- [ 149.151442] BUG: unable to handle kernel paging request at ffc8 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
Hrm, what we really want is to first destroy the LED interface, otherwise someone might have re-queued the workqueue through thingm_led_set() after it has been flushed / cancelled already. Could you please give it one more shot with the patch below? Thanks for your prompt testing. diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 134be89..3d8cf5e 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -208,10 +208,10 @@ unregister_red: static void thingm_remove_rgb(struct thingm_rgb *rgb) { - flush_work(rgb-work); led_classdev_unregister(rgb-red.ldev); led_classdev_unregister(rgb-green.ldev); led_classdev_unregister(rgb-blue.ldev); + cancel_work_sync(rgb-work); } static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) @@ -286,10 +286,10 @@ static void thingm_remove(struct hid_device *hdev) struct thingm_device *tdev = hid_get_drvdata(hdev); int i; + hid_hw_stop(hdev); + for (i = 0; i tdev-fwinfo-numrgb; ++i) thingm_remove_rgb(tdev-rgb + i); - - hid_hw_stop(hdev); } static const struct hid_device_id thingm_table[] = { I think that did the trick. I've run through the whole cycle about 20 times in various conditions, and it seems solid so far. Thanks! -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
From Jiri Kosina jkos...@suse.cz, Wed, Sep 03, 2014 at 04:37:05PM +0200: On Wed, 3 Sep 2014, Dylan Alex Simon wrote: I think that did the trick. I've run through the whole cycle about 20 times in various conditions, and it seems solid so far. Thanks! Thanks. I actually think that the minimal necessary fix is below. Could you please do a (hopefully last) round of testing with just this patch applied? diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c index 134be89..c1d21fa 100644 --- a/drivers/hid/hid-thingm.c +++ b/drivers/hid/hid-thingm.c @@ -208,10 +208,10 @@ unregister_red: static void thingm_remove_rgb(struct thingm_rgb *rgb) { - flush_work(rgb-work); led_classdev_unregister(rgb-red.ldev); led_classdev_unregister(rgb-green.ldev); led_classdev_unregister(rgb-blue.ldev); + flush_work(rgb-work); } static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) (Sorry, didn't get a chance back at the machine until now.) This seems to be working fine, as well. I now do get the failed to write color messages again when unplugging, which didn't show up with the other patch, but no panics. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
hid-thingm: kernel panic on remove
Whenever either disconnecting the USB device or simply rmmod'ing the module (even when not in use), I get a kernel panic. I haven't managed to capture a backtrace, but at least the first two lines were saved after an rmmod: 18:53:17 kernel: thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 snip, rmmod hid-thingm: 08:38:42 kernel: BUG: unable to handle kernel paging request at fffb8a80aaf8 08:38:42 kernel: IP: [8106e30c] osq_lock+0x3c/0x110 Let me know if you'd like me to try to capture more info, but this problem seems very reproducible (at least with a mk2 device; I never had the problem on older kernels with a mk1). I do direct write()s to the hidraw device, but don't otherwise use the driver while it's loaded. Also at https://bugzilla.kernel.org/show_bug.cgi?id=83751 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
From Benjamin Tissoires benjamin.tissoi...@gmail.com, Tue, Sep 02, 2014 at 03:58:08PM -0400: Hi, On 09/02/2014 01:46 PM, Dylan Alex Simon wrote: Whenever either disconnecting the USB device or simply rmmod'ing the module (even when not in use), I get a kernel panic. I haven't managed to capture a backtrace, but at least the first two lines were saved after an rmmod. Let me know if you'd like me to try to capture more info, but this problem seems very reproducible (at least with a mk2 device; I never had the problem on older kernels with a mk1). I do direct write()s to the hidraw device, but don't otherwise use the driver while it's loaded. Also at https://bugzilla.kernel.org/show_bug.cgi?id=83751 Do you happen to see a unsupported firmware error when plugging your device? If so, then the following patch should help with the panic (but you will an other one to be able to use again your device). No, no unsupported firmware messages. The device and driver work fine otherwise. It registers (and unregisters) all the devices. Hotplug events: 18:53:17 kernel: thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 18:53:17 hotplug: 694 add module path:/module/hid_thingm 18:53:17 hotplug: 695 add hidraw path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/hidraw/hidraw3 18:53:17 hotplug: 696 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:red:led1 18:53:17 hotplug: 698 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:blue:led1 18:53:17 hotplug: 697 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:green:led1 18:53:17 hotplug: 699 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:red:led2 18:53:17 hotplug: 700 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:green:led2 18:53:17 hotplug: 701 add leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:blue:led2 18:53:17 hotplug: 702 add drivers path:/bus/hid/drivers/thingm snip, rmmod: 08:38:42 hotplug: 710 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:red:led1 08:38:42 hotplug: 712 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:blue:led1 08:38:42 hotplug: 711 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:green:led1 08:38:42 hotplug: 714 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:green:led2 08:38:42 hotplug: 713 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:red:led2 08:38:42 hotplug: 715 remove leds path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/leds/thingm3:blue:led2 08:38:42 hotplug: 716 remove hidraw path:/devices/pci:00/:00:12.2/usb1/1-3/1-3.1/1-3.1.4/1-3.1.4:1.0/0003:27B8:01ED.0004/hidraw/hidraw3 08:38:42 kernel: BUG: unable to handle kernel paging request at fffb8a80aaf8 08:38:42 kernel: IP: [8106e30c] osq_lock+0x3c/0x110 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: hid-thingm: kernel panic on remove
From Jiri Kosina jkos...@suse.cz, Tue, Sep 02, 2014 at 11:32:30PM +0200: On Tue, 2 Sep 2014, Benjamin Tissoires wrote: Whenever either disconnecting the USB device or simply rmmod'ing the module (even when not in use), I get a kernel panic. I haven't managed to capture a backtrace, but at least the first two lines were saved after an rmmod: 18:53:17 kernel: thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 snip, rmmod hid-thingm: 08:38:42 kernel: BUG: unable to handle kernel paging request at fffb8a80aaf8 08:38:42 kernel: IP: [8106e30c] osq_lock+0x3c/0x110 Hmm, so the only lock that is taken in thingm driver itself is rgb-tdev-lock, which is thingm_device-lock, properly initialized in _probe(). So my first thought was that the work is not cancelled properly, causing use-after-free on the lock with the workqueue firing at the time the drvier has cleaned up everything, but that doesn't seem to be the case, as thingm_remove() - thingm_remove_rgb() seems to be doing the right thing. Dylan, is there any chance for you to capture more complete backtrace from the oops? serial console, netconsole, anything? Some combination of kernel debugging options and killing processes let it survive long enough to write the backtrace to disk. A simple modprobe/rmmod wasn't enough, though, it required a few tries removing the device and then rmmod (though has definitely happend on just one removal before). Let me know if there's anything else I can try. insmod [ 28.855960] thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 rmmod;insmod [ 147.037008] thingm 0003:27B8:01ED.0004: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 unplug [ 218.496688] usb 1-3.1.4: USB disconnect, device number 7 [ 218.502278] hid : failed to write color [ 218.506131] hid : failed to write color plug [ 233.557300] usb 1-3.1.4: new full-speed USB device number 8 using ehci-pci [ 233.657195] usb 1-3.1.4: config 1 interface 0 altsetting 0 has 2 endpoint descriptors, different from the interface descriptor's value: 1 [ 233.660402] thingm 0003:27B8:01ED.0005: hidraw3: USB HID v1.01 Device [ThingM blink(1) mk2] on usb-:00:12.2-3.1.4/input0 rmmod [ 253.682724] BUG: unable to handle kernel paging request at a00af0cf [ 253.682807] IP: [ 253.682812] [a00af0cf] 0xa00af0cf [ 253.682817] PGD 1814067 PUD 1815063 PMD 42cace067 PTE 0 [ 253.682820] Oops: 0010 [#1] SMP [ 253.682830] Modules linked in: led_class cuse fuse snd_emu10k1 snd_hwdep snd_util_mem snd_ac97_codec ac97_bus snd_rawmidi snd_seq_device snd_pcm snd_timer ipt_ULOG [last unloaded: hid_thingm] [ 253.682833] CPU: 0 PID: 849 Comm: kworker/0:2 Not tainted 3.16.1-1-g98fed6d #145 [ 253.682835] Hardware name: empty empty/S8010-LE, BIOS 'V2.03B ' 03/15/2012 [ 253.682838] Workqueue: events 0xa00af040 [ 253.682840] task: 88042e330050 ti: 880429d8c000 task.ti: 880429d8c000 [ 253.682844] RIP: 0010:[a00af0cf] [a00af0cf] 0xa00af0cf [ 253.682846] RSP: 0018:880429d8fdd0 EFLAGS: 00010286 [ 253.682847] RAX: 0009 RBX: 88042ca83af0 RCX: 0302 [ 253.682849] RDX: 0078 RSI: 0286 RDI: 88042caaade0 [ 253.682850] RBP: 880429d8fdf0 R08: 8804acaaade0 R09: 0282 [ 253.682852] R10: 88042c93dbc0 R11: 001f R12: 88042c885e80 [ 253.682853] R13: R14: 88043ec14e00 R15: 88043ec113c0 [ 253.682856] FS: 7f58ebcec700() GS:88043ec0() knlGS: [ 253.682857] CS: 0010 DS: ES: CR0: 8005003b [ 253.682859] CR2: a00af0cf CR3: 01813000 CR4: 000407f0 [ 253.682859] Stack: [ 253.682863] 0100a000 00010063 8867f918 88042ca83af0 [ 253.682866] 880429d8fe38 81052c2f 88043ec113c0 3ec113c0 [ 253.682869] 88043ec113c0 88043ec113e8 88042e330050 88042c885eb0 [ 253.682870] Call Trace: [ 253.682878] [81052c2f] process_one_work+0x14f/0x400 [ 253.682882] [81053423] worker_thread+0x63/0x540 [ 253.682886] [810533c0] ? create_and_start_worker+0x60/0x60 [ 253.682889] [81059038] kthread+0xe8/0x100 [ 253.682893] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 253.682897] [815323ec] ret_from_fork+0x7c/0xb0 [ 253.682900] [81058f50] ? kthread_create_on_node+0x1b0/0x1b0 [ 253.682906] Code: Bad RIP value. [ 253.682908] RIP [a00af0cf] 0xa00af0cf [ 253.682909] RSP 880429d8fdd0 [ 253.682910] CR2: a00af0cf [ 253.682913] ---[ end trace 38f1b789201cd967 ]--- [ 253.682946] BUG: unable to handle kernel paging request at ffc8 [
[RFC 3/4] HID:hid-logitech: Use new native switch method
--- drivers/hid/hid-lg4ff.c | 126 +--- 1 file changed, 55 insertions(+), 71 deletions(-) diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index eda07a2..0ba0838 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -32,21 +32,10 @@ #include hid-lg.h #include hid-ids.h -#define DFGT_REV_MAJ 0x13 -#define DFGT_REV_MIN 0x22 -#define DFGT2_REV_MIN 0x26 -#define DFP_REV_MAJ 0x11 -#define DFP_REV_MIN 0x06 -#define FFEX_REV_MAJ 0x21 -#define FFEX_REV_MIN 0x00 -#define G25_REV_MAJ 0x12 -#define G25_REV_MIN 0x22 -#define G27_REV_MAJ 0x12 -#define G27_REV_MIN 0x38 -#define G27_2_REV_MIN 0x39 - #define to_hid_device(pdev) container_of(pdev, struct hid_device, dev) +#define LG4FF_FFEX_BCDDEVICE 0x2100 + static void hid_lg4ff_set_range_dfp(struct hid_device *hid, u16 range); static void hid_lg4ff_set_range_g25(struct hid_device *hid, u16 range); static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf); @@ -89,48 +78,6 @@ static const struct lg4ff_mode_switcher lg4ff_mode_switchers[] = { /* Note: Orde {0x1000, 0xf000, LG4FF_MSW_DFP, USB_DEVICE_ID_LOGITECH_DFP_WHEEL, hid_lg4ff_set_range_dfp}, }; -struct lg4ff_native_cmd { - const __u8 cmd_num; /* Number of commands to send */ - const __u8 cmd[]; -}; - -struct lg4ff_usb_revision { - const __u16 rev_maj; - const __u16 rev_min; - const struct lg4ff_native_cmd *command; -}; - -static const struct lg4ff_native_cmd native_dfp = { - 1, - {0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -static const struct lg4ff_native_cmd native_dfgt = { - 2, - {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */ -0xf8, 0x09, 0x03, 0x01, 0x00, 0x00, 0x00} /* 2nd command */ -}; - -static const struct lg4ff_native_cmd native_g25 = { - 1, - {0xf8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00} -}; - -static const struct lg4ff_native_cmd native_g27 = { - 2, - {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1st command */ -0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00} /* 2nd command */ -}; - -static const struct lg4ff_usb_revision lg4ff_revs[] = { - {DFGT_REV_MAJ, DFGT_REV_MIN, native_dfgt}, /* Driving Force GT */ - {DFGT_REV_MAJ, DFGT2_REV_MIN, native_dfgt},/* Driving Force GT v2 */ - {DFP_REV_MAJ, DFP_REV_MIN, native_dfp}, /* Driving Force Pro */ - {G25_REV_MAJ, G25_REV_MIN, native_g25}, /* G25 */ - {G27_REV_MAJ, G27_REV_MIN, native_g27}, /* G27 */ - {G27_REV_MAJ, G27_2_REV_MIN, native_g27},/* G27 v2 */ -}; - /* Recalculates X axis value accordingly to currently selected range */ static __s32 lg4ff_adjust_dfp_x_axis(__s32 value, __u16 range) { @@ -397,19 +344,63 @@ static void hid_lg4ff_set_range_dfp(struct hid_device *hid, __u16 range) hid_hw_request(hid, report, HID_REQ_SET_REPORT); } -static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd) +static int lg4ff_switch_mode(struct hid_device *hid, __u16 type, int mode) { struct list_head *report_list = hid-report_enum[HID_OUTPUT_REPORT].report_list; struct hid_report *report = list_entry(report_list-next, struct hid_report, list); - __u8 i, j; + __s32 *value = report-field[0]-value; + + if (mode = LG4FF_MSW_MAX || mode = LG4FF_MSW_NAT) mode = type; + + if (type == LG4FF_MSW_G25 mode == LG4FF_MSW_G25) { + value[0] = 0xf8; + value[1] = 0x10; + value[2] = 0x00; + value[3] = 0x00; + value[4] = 0x00; + value[5] = 0x00; + value[6] = 0x00; + + hid_hw_request(hid, report, HID_REQ_SET_REPORT); + return 0; + } - j = 0; - while (j 7*cmd-cmd_num) { - for (i = 0; i 7; i++) - report-field[0]-value[i] = cmd-cmd[j++]; + if (mode == LG4FF_MSW_DFP) { + value[0] = 0xf8; + value[1] = 0x01; + value[2] = 0x00; + value[3] = 0x00; + value[4] = 0x00; + value[5] = 0x00; + value[6] = 0x00; hid_hw_request(hid, report, HID_REQ_SET_REPORT); + return 0; } + + /* Prevent compat mode on USB reset */ + if (type == LG4FF_MSW_DFGT || type == LG4FF_MSW_G27) { + value[0] = 0xf8; + value[1] = 0x0a; + value[2] = 0x00; + value[3] = 0x00; + value[4] = 0x00; + value[5] = 0x00; + value[6] = 0x00; + + hid_hw_request(hid, report, HID_REQ_SET_REPORT); + } + + value[0] = 0xf8; + value[1] = 0x09; + value[2] = mode; + value[3] = 0x01; + value[4] = 0x00; + value[5] = 0x00; + value[6] = 0x00; +
Re: PATCH hid: Implement mode switching on Logitech gaming wheels accordingly to the documentation
Simon mailed me his revised patchset which has the changes broken out into four separate patches and allows to switch extended compatibility modes on the fly through sysfs. I looked them over and I they seem fine to me. I suppose he'll submit them for review very soon. Whilst it is my intention to submit them, I might not achieve the 'very soon' part earliest I think would be mid next week as they still need a little tweaking. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] HID:hid-logitech: Prevent possibility of infinite loop when using /sys interface
If the device data is not accessible for some reason, returning 0 will cause the call to be continuously called again as none of the string has been 'consumed'. Signed-off-by: Simon Wood si...@mungewell.org --- drivers/hid/hid-lg4ff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index cc2bd20..7835717 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at drv_data = hid_get_drvdata(hid); if (!drv_data) { hid_err(hid, Private driver data not found!\n); - return 0; + return -EINVAL; } entry = drv_data-device_props; if (!entry) { hid_err(hid, Device properties not found!\n); - return 0; + return -EINVAL; } if (range == 0) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] HID:hid-logitech: Prevent possibility of infinite loop when using /sys interface
If the device data is not accessible for some reason, returning 0 will cause the call to be continuously called again as none of the string has been 'consumed'. --- drivers/hid/hid-lg4ff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index cc2bd20..7835717 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at drv_data = hid_get_drvdata(hid); if (!drv_data) { hid_err(hid, Private driver data not found!\n); - return 0; + return -EINVAL; } entry = drv_data-device_props; if (!entry) { hid_err(hid, Device properties not found!\n); - return 0; + return -EINVAL; } if (range == 0) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: PATCH hid: Implement mode switching on Logitech gaming wheels accordingly to the documentation
+#define LG4FF_MSW_MIN 0 +#define LG4FF_MSW_NATIVE 0 /* Switch device to its native mode (if applicable) */ +#define LG4FF_MSW_DONTSWITCH 1 /* Leave device in its current mode */ +#define LG4FF_MSW_DFP 2 /* Switch device so that it emulates Driving Force Pro (only G25, G27, DFGT) */ +#define LG4FF_MSW_G25 3 /* Switch device so that it emulates G25 (only G27) */ +#define LG4FF_MSW_MAX 3 Just to let everyone know I am looking at this patch, and have emailed Michal some questions on whether it covers all options for control. Cheers, Simon. -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [v2] input: drv260x: Add TI drv260x haptics driver
The initial driver supports the devices real time playback mode. But the device has additional wave patterns in ROM. As it presented the device appears to be a memoryless device, however you present it to the rest of the system as if it can support playback of multiple effects simultaneously, which is incorrect. My guess that you need to engage the memoryless input library to schedule handling multiple effects for your device, including ramping up, ramping down, stopping playback when effects runs out, etc. Hi Dan, Elias and Michal (cc'ed) are working on a kernel/userland library to handle sending multiple force feedback signals to 'simple' devices, perhaps you should engage with them. Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] edt-ft5x06 - cannot see IRQ Qfrom device after DT probe
On 22/07/14 12:40, Markus Niebel wrote: Am 16.07.2014 12:01, wrote Simon Budig: On 15/07/14 19:43, Markus Niebel wrote: - when adding an int-gpios node to devicetree and parsing this gpio the gpio will be configured as input - IRQ can be seen by CPU Question: - shall we add an int-gpio property to enable gpio pin config as input or Shouldn't it be possible to configure the pin as input directly from the device tree, indepently from the touch driver section? I don't see, how to do that, maybe I did miss the right point. Try looking at Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt There you have the input-enable generic property. Global question is: how can we make sure, that the driver that request the IRQ requests also the GPIO (implicit or like in the old platfrom data days explicit)? But thats beyond input devices and my knowledge. The driver does not depend on the IRQ coming from a real CPU gpio. It *could* be an external gpio expander or whatever (whether that is a good idea is debatable of course). When I submitted the first version of the driver it had bits in it to configure the pin properly. The feedback basically was to remove that, because it made some assumptions that you can map the IRQ to the relevant GPIO, which is not always possible. I hope that helps. (But really, your bootloader really should have a *very* good reason to configure the touch irq pin as output - I have the impression that right now there are two outputs driving against each other in your setup - not healthy for the hardware). Bye, Simon -- Simon Budigkernel concepts GmbH simon.bu...@kernelconcepts.de Sieghuetter Hauptweg 48 +49-271-771091-17 D-57072 Siegen signature.asc Description: OpenPGP digital signature
Re: [RFC] edt-ft5x06 - cannot see IRQ Qfrom device after DT probe
On 15/07/14 19:43, Markus Niebel wrote: - when adding an int-gpios node to devicetree and parsing this gpio the gpio will be configured as input - IRQ can be seen by CPU Question: - shall we add an int-gpio property to enable gpio pin config as input or Shouldn't it be possible to configure the pin as input directly from the device tree, indepently from the touch driver section? Bye, Simon -- Simon Budigkernel concepts GmbH simon.bu...@kernelconcepts.de Sieghuetter Hauptweg 48 +49-271-771091-17 D-57072 Siegen signature.asc Description: OpenPGP digital signature
Re: [PATCH v2 10/10] mfd: cros_ec: move EC interrupt to cros_ec_keyb
On 18 June 2014 12:14, Doug Anderson diand...@chromium.org wrote: From: Andrew Bresticker abres...@chromium.org If we receive EC interrupts after the cros_ec driver has probed, but before the cros_ec_keyb driver has probed, the cros_ec IRQ handler will not run the cros_ec_keyb notifier and the EC will leave the IRQ line asserted. The cros_ec IRQ handler then returns IRQ_HANDLED and the resulting flood of interrupts causes the machine to hang. Since the EC interrupt is currently only used for the keyboard, move the setup and handling of the EC interrupt to the cros_ec_keyb driver. Signed-off-by: Andrew Bresticker abres...@chromium.org Signed-off-by: Doug Anderson diand...@chromium.org Reviewed-by: Simon Glass s...@chromium.org We never needed an EC-level interrupt, and have shipped at least three products now that use this code, so I think it is safe enough to declare that we won't need it. Regards, Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/10] mfd: cros_ec: cleanup: Remove EC wrapper functions
a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 2b0c598..60c0880 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -63,9 +63,10 @@ struct cros_ec_command { * @was_wake_device: true if this device was set to wake the system from * sleep at the last suspend * @event_notifier: interrupt event notifier for transport devices - * @command_send: send a command - * @command_recv: receive a response - * @command_sendrecv: send a command and receive a response + * @cmd_xfer: send command to EC and get response + * Returns 0 if the communication succeeded, but that doesn't mean the EC + * was happy with the command it got. Caller should check msg.result for + * the EC's result code. * * @priv: Private data * @irq: Interrupt to use @@ -83,7 +84,6 @@ struct cros_ec_command { * @parent: pointer to parent device (e.g. i2c or spi device) * @wake_enabled: true if this device can wake the system from sleep * @lock: one transaction at a time - * @cmd_xfer: low-level channel to the EC */ struct cros_ec_device { @@ -94,13 +94,8 @@ struct cros_ec_device { bool was_wake_device; struct class *cros_class; struct blocking_notifier_head event_notifier; - int (*command_send)(struct cros_ec_device *ec, - uint16_t cmd, void *out_buf, int out_len); - int (*command_recv)(struct cros_ec_device *ec, - uint16_t cmd, void *in_buf, int in_len); - int (*command_sendrecv)(struct cros_ec_device *ec, - uint16_t cmd, void *out_buf, int out_len, - void *in_buf, int in_len); + int (*cmd_xfer)(struct cros_ec_device *ec, + struct cros_ec_command *msg); /* These are used to implement the platform-specific interface */ void *priv; @@ -112,8 +107,6 @@ struct cros_ec_device { struct device *parent; bool wake_enabled; struct mutex lock; - int (*cmd_xfer)(struct cros_ec_device *ec, - struct cros_ec_command *msg); Seems odd - maybe this line move of cmd_xfer() should be in an earlier patch? Regards, Simon -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 08/10] mfd: cros_ec: cleanup: Remove EC wrapper functions
Hi Doug, On 17 June 2014 21:27, Doug Anderson diand...@chromium.org wrote: Simon, On Tue, Jun 17, 2014 at 8:42 PM, Simon Glass s...@chromium.org wrote: diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 4083796..dc37b6b 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -191,8 +191,18 @@ static void cros_ec_keyb_close(struct input_dev *dev) static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) { - return ckdev-ec-command_recv(ckdev-ec, EC_CMD_MKBP_STATE, - kb_state, ckdev-cols); + int ret; + struct cros_ec_command msg = { + .version = 0, + .command = EC_CMD_MKBP_STATE, + .outdata = NULL, + .outsize = 0, + .indata = kb_state, + .insize = ckdev-cols, + }; + + ret = ckdev-ec-cmd_xfer(ckdev-ec, msg); Do we need ret? No. If you wish I will spin without it. Let me know. Note that locally this code includes a comment between the above and the return: /* FIXME: This assumes msg.result == EC_RES_SUCCESS */ It's not important to me, and you've explained the other question. Reviewed-by: Simon Glass s...@chromium.org -- To unsubscribe from this list: send the line unsubscribe linux-input in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch] Input: edt-ft5x06 - fix an i2c write for M09 support
Hi all. I received notice from Robert Wörle who spotted a bug in the ft5x06 driver (M09 support) which can result in bogus values being written into the configuration registers. Paul wrote: I think i found the problem, as the driver sends 3 bytes instead of 2 when accessing a register on the M09 firmware. Therefore , writing to gain seems to overflow into the offset register. This seems to be even in the lastet upstream driver so i created a patch for this driver which you find attached. @Simon Budig Find attached a patch to fix this edt driver bug, feel free to comment , test and commit upstream ;-) He is right, his fix is correct. Please include his patch into the repository. Acked-By: Simon Budig simon.bu...@kernelconcepts.de Thanks, Simon -- Simon Budigkernel concepts GmbH simon.bu...@kernelconcepts.de Sieghuetter Hauptweg 48 +49-271-771091-17 D-57072 Siegen From 36b9ac0e8206efefc8795c925b0f3b63ab29fd08 Mon Sep 17 00:00:00 2001 From: Robert Woerle rob...@linuxdevelopment.de Date: Wed, 28 May 2014 13:22:09 +0200 Subject: [PATCH] Input: edt-ft5x06 - fix i2c writes to 2 bytes on M09 firmware Signed-off-by: Robert Woerle rob...@linuxdevelopment.de --- drivers/input/touchscreen/edt-ft5x06.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index f8815be..d4f3399 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -271,7 +271,7 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata, wrbuf[0] = addr; wrbuf[1] = value; - return edt_ft5x06_ts_readwrite(tsdata-client, 3, + return edt_ft5x06_ts_readwrite(tsdata-client, 2, wrbuf, 0, NULL); default: -- 1.7.9.5 signature.asc Description: OpenPGP digital signature