Re: [Patch-V2 1/6] INPUT: xpad: Add minimal support for Logitech G920 Wheel

2016-01-06 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-19 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
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

2015-11-12 Thread Simon Wood
> 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

2015-11-10 Thread Simon Wood

> 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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-07 Thread Simon Wood
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

2015-11-02 Thread Simon Wood
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

2015-11-02 Thread Simon Wood
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

2015-10-23 Thread Simon Wood
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

2015-10-23 Thread Simon Wood
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

2015-10-23 Thread Simon Wood
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

2015-10-23 Thread Simon Wood
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

2015-10-23 Thread Simon Wood
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

2015-09-28 Thread Simon Wood
> 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

2015-09-03 Thread simon

> 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

2015-09-02 Thread simon
> 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

2015-08-13 Thread Simon Horman
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

2015-08-12 Thread Simon Horman
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

2015-07-23 Thread simon
 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

2015-07-23 Thread Simon Wood
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

2015-07-10 Thread Simon Wood
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

2015-07-07 Thread Simon Horman
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

2015-06-24 Thread simon
 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

2015-06-24 Thread simon

 +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

2015-06-23 Thread Simon Wood
---
 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

2015-06-23 Thread Simon Wood
---
 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

2015-06-23 Thread Simon Wood

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

2015-06-23 Thread Simon Wood
---
 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

2015-06-23 Thread Simon Wood
---
 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

2015-06-18 Thread simon

 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

2015-06-17 Thread Simon Wood
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

2015-06-17 Thread Simon Wood
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

2015-06-17 Thread Simon Wood
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

2015-06-14 Thread simon
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

2015-06-11 Thread Simon Wood
[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

2015-06-09 Thread simon

 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

2015-06-09 Thread Simon Wood
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

2015-06-09 Thread Simon Wood
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

2015-06-09 Thread Simon Wood
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

2015-06-08 Thread simon
 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

2015-06-08 Thread simon
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

2015-06-03 Thread Simon Wood
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

2015-06-03 Thread simon
 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

2015-05-27 Thread simon
 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

2015-05-21 Thread Simon Horman
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

2015-05-21 Thread Simon Horman
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

2015-03-24 Thread Simon Wörner

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

2015-02-27 Thread Simon Haggett

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

2015-02-20 Thread simon
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

2015-02-18 Thread simon
 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.

2015-02-18 Thread simon
 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

2015-02-17 Thread simon
 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

2015-02-17 Thread simon

 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

2015-02-13 Thread Simon Wood
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

2015-02-06 Thread simon
 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?

2015-02-05 Thread simon
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

2015-01-27 Thread Simon Wörner
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

2015-01-27 Thread Simon Wörner
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

2015-01-23 Thread Simon Wörner
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

2015-01-23 Thread Simon Wörner
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

2014-09-15 Thread simon

 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

2014-09-03 Thread Dylan Alex Simon
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

2014-09-03 Thread Dylan Alex Simon
 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

2014-09-03 Thread Dylan Alex Simon
 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

2014-09-03 Thread Dylan Alex Simon
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

2014-09-02 Thread Dylan Alex Simon
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

2014-09-02 Thread Dylan Alex Simon
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

2014-09-02 Thread Dylan Alex Simon
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

2014-08-20 Thread Simon Wood
---
 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

2014-08-14 Thread simon

 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

2014-08-14 Thread Simon Wood
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

2014-08-06 Thread Simon Wood
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

2014-07-31 Thread simon

 +#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

2014-07-28 Thread simon

 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

2014-07-22 Thread Simon Budig
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

2014-07-16 Thread 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?

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

2014-06-19 Thread Simon Glass
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

2014-06-17 Thread Simon Glass
 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

2014-06-17 Thread Simon Glass
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

2014-06-07 Thread Simon Budig
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


  1   2   3   >