Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH v4 7/7] HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
From: Frank Praznik @ 2014-04-04 18:37 UTC (permalink / raw)
  To: simon, Frank Praznik; +Cc: HID CORE LAYER, Jiri Kosina
In-Reply-To: <9eabb4ae4fb93b4c51816953fc453e4f.squirrel@mungewell.org>

On 4/4/2014 12:11, simon@mungewell.org wrote:
> Why not make the triggers/etc apply across the board, so it doesn't matter
> which led the command is sent to - it's just registered/copied to the
> first (red?) led data[].

Unfortunately, it's not that simple.  There is no API for setting 
triggers from within the module and from looking at the code for these 
triggers, some set the hardware blink rate which will blink the whole 
light bar and some just use their own software timers and send 
brightness commands which will only effect the LED they are set on which 
results in unpredictable behavior depending on how the trigger is 
implemented.

These software-only triggers are why I'm thinking it would be good to 
have an extra global control for controlling the whole light bar 
synchronously.  Even if you set all the LEDs to the same software 
trigger the colors may not flash in sync if the trigger starts a 
separate timer for each LED and in some cases the trigger may mangle the 
user defined brightness settings (ie. the heartbeat trigger doesn't read 
the current brightness and just uses the maximum).

With an extra global switch, you can set the desired brightness levels 
for each color, then just use the global control to set the on/off state 
and get consistent blink behavior even if the trigger uses software 
timers or doesn't care about the user's brightness settings.  Plus, if 
for some reason you do want to flash individual colors, setting the 
blink rate of an individual color will always blink only that color 
instead of potentially blinking the whole light bar if the trigger tries 
to set the hardware blink rate.

I think it will be more functional, more predictable and less confusing.

>
>>> 3rd Party Intec - Was unable to get any controlled blinking.
>> It sounds like this controller just doesn't implement all of the
>> behavior of the official controller.  I'm not sure how to fix it if it's
>> not obeying the instructions in valid output reports and I don't have
>> one to test personally.  Do the lights flash properly when the
>> controller is used with a PS3?
> I presume that they just reversed engineered what they thought to be
> correct, I don't have a Playstation so can't confirm for certain.
>
> In my testing from a year ago or so, I could make the blink work via
> sending data with python. The script can be found here:
> http://www.spinics.net/lists/linux-input/msg28271.html
>
> Note: "Which LED to enable(LED1..4 << 1, 0x20=none)"
>
> Cheers,
> Simon
>

I'll take a look, but without having that particular controller all I 
can do is take a shot in the dark.

^ permalink raw reply

* [PATCH 3/4] HID: microsoft: added Sidewinder X4 / X6 sysfs support
From: Tolga Cakir @ 2014-04-04 17:07 UTC (permalink / raw)
  To: Benjamin Tissoires, Derya, Jiri Kosina, Reyad Attiyat
  Cc: linux-input, linux-kernel, Tolga Cakir

This patch enables us to set the profile, LEDs and read the key mask via sysfs. Documentation is included in this patch.

Signed-off-by: Tolga Cakir <tolga@cevel.net>
---
 .../ABI/testing/sysfs-driver-hid-microsoft         |  30 +++
 drivers/hid/hid-microsoft.c                        | 231 +++++++++++++++++++++
 2 files changed, 261 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-microsoft

diff --git a/Documentation/ABI/testing/sysfs-driver-hid-microsoft b/Documentation/ABI/testing/sysfs-driver-hid-microsoft
new file mode 100644
index 0000000..9fdfad7
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-microsoft
@@ -0,0 +1,30 @@
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/auto_led
+Date:		April 2014
+Contact:	Tolga Cakir <tolga@cevel.net>
+Description:	This file allows you to set and view the Auto LED status.
+		Valid values are 0 and 1.
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/profile
+Date:		April 2014
+Contact:	Tolga Cakir <tolga@cevel.net>
+Description:	Both, the Sidewinder X4 and the X6 can handle profiles.
+		They can be switched by writing to this file. Profile LEDs will be
+		set accordingly.
+		Valid values are 1 - 3.
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/key_mask
+Date:		April 2014
+Contact:	Tolga Cakir <tolga@cevel.net>
+Description:	This file is read-only and outputs an unsigned long integer.
+		Every bit represents one of the S1 - S6 extra keys on the Sidewinder
+		X4 and S1 - S30 on the Sidewinder X6. The least significant bit
+		represents S1 on both gaming keyboards, the most significant bit
+		represents the Bank switch button on both keyboards. Multiple
+		special keys can be pressed at the same time.
+
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/record_led
+Date:		April 2014
+Contact:	Tolga Cakir <tolga@cevel.net>
+Description:	This file allows you to set and view the Record LED status.
+		Valid values are 0 - 2. 0 stands for off, 1 for solid mode and 2
+		for blinking mode.
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 5b5d40f..5674c0c 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -19,6 +19,8 @@
 #include <linux/input.h>
 #include <linux/hid.h>
 #include <linux/module.h>
+#include <linux/sysfs.h>
+#include <linux/usb.h>
 
 #include "hid-ids.h"
 
@@ -209,6 +211,219 @@ static int ms_sidewinder_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
 	return 1;
 }
 
+static int ms_sidewinder_control(struct hid_device *hdev, __u8 setup)
+{
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+	struct hid_report *report =
+			hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[7];
+
+	/*
+	 * LEDs 1 - 3 should not be set simultaneously, however
+	 * they can be set in any combination with Auto or Record LEDs.
+	 */
+	report->field[0]->value[0] = (setup & 0x01) ? 0x01 : 0x00;	/* X6 only: Macro Pad toggle */
+	report->field[0]->value[1] = (setup & 0x02) ? 0x01 : 0x00;	/* LED Auto */
+	report->field[0]->value[2] = (setup & 0x04) ? 0x01 : 0x00;	/* LED 1 */
+	report->field[0]->value[3] = (setup & 0x08) ? 0x01 : 0x00;	/* LED 2 */
+	report->field[0]->value[4] = (setup & 0x10) ? 0x01 : 0x00;	/* LED 3 */
+	report->field[1]->value[0] = 0x00;	/* Clear Record LED */
+
+	switch (setup & 0x60) {
+	case 0x40: report->field[1]->value[0] = 0x02;	break;	/* Record LED Blink */
+	case 0x20: report->field[1]->value[0] = 0x03;	break;	/* Record LED Solid */
+	}
+
+	hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+	sidewinder->status = setup;
+
+	return 0;
+}
+
+/*
+ * Sidewinder sysfs
+ * @key_mask: show pressed special keys
+ * @profile: show and set profile count and LED status
+ * @auto_led: show and set LED Auto
+ * @record_led: show and set Record LED
+ */
+static ssize_t ms_sidewinder_key_mask_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+
+	return snprintf(buf, PAGE_SIZE, "%lu\n", sidewinder->key_mask);
+}
+
+static struct device_attribute dev_attr_ms_sidewinder_key_mask = {
+	.attr = { .name = __stringify(key_mask), .mode = S_IRUGO },
+	.show = ms_sidewinder_key_mask_show
+};
+
+static ssize_t ms_sidewinder_profile_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+
+	return snprintf(buf, PAGE_SIZE, "%1u\n", sidewinder->profile);
+}
+
+static ssize_t ms_sidewinder_profile_store(struct device *dev,
+		struct device_attribute *attr, char const *buf, size_t count)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+	__u8 setup = sidewinder->status & ~(0x1c);	/* Clear Profile LEDs */
+
+	if (sscanf(buf, "%1u", &sidewinder->profile) != 1)
+		return -EINVAL;
+
+	if (sidewinder->profile < 1 || sidewinder->profile > 3) {
+		return -EINVAL;
+	} else {
+		setup |= 0x02 << sidewinder->profile;
+		ms_sidewinder_control(hdev, setup);
+		return strnlen(buf, PAGE_SIZE);
+	}
+}
+
+static struct device_attribute dev_attr_ms_sidewinder_profile =
+	__ATTR(profile, S_IWUSR | S_IRUGO,
+		ms_sidewinder_profile_show,
+		ms_sidewinder_profile_store);
+
+static ssize_t ms_sidewinder_macro_pad_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+
+	return snprintf(buf, PAGE_SIZE, "%1u\n", (sidewinder->status & 0x01));
+}
+
+static ssize_t ms_sidewinder_macro_pad_store(struct device *dev,
+		struct device_attribute *attr, char const *buf, size_t count)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+	unsigned int value;
+	__u8 setup;
+
+	if (sscanf(buf, "%1u", &value) != 1)
+		return -EINVAL;
+
+	if (value < 0 || value > 1) {
+		return -EINVAL;
+	} else {
+		setup = sidewinder->status & ~(0x01);	/* Clear Macro Pad */
+		if (value)
+			setup |= 0x01;
+		ms_sidewinder_control(hdev, setup);
+		return strnlen(buf, PAGE_SIZE);
+	}
+}
+
+static struct device_attribute dev_attr_ms_sidewinder_macro_pad =
+	__ATTR(macro_pad, S_IWUSR | S_IRUGO,
+		ms_sidewinder_macro_pad_show,
+		ms_sidewinder_macro_pad_store);
+
+static ssize_t ms_sidewinder_record_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+
+	return snprintf(buf, PAGE_SIZE, "%1d\n", (sidewinder->status & 0x60) >> 5);
+}
+
+static ssize_t ms_sidewinder_record_store(struct device *dev,
+		struct device_attribute *attr, char const *buf, size_t count)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+	unsigned int value;
+	__u8 setup;
+
+	if (sscanf(buf, "%1u", &value) != 1)
+		return -EINVAL;
+
+	if (value < 0 || value > 2) {
+		return -EINVAL;
+	} else {
+		setup = sidewinder->status & ~(0xe0);	/* Clear Record LED */
+		if (value)
+			setup |= 0x10 << value;
+		ms_sidewinder_control(hdev, setup);
+		return strnlen(buf, PAGE_SIZE);
+	}
+}
+
+static struct device_attribute dev_attr_ms_sidewinder_record =
+	__ATTR(record_led, S_IWUSR | S_IRUGO,
+		ms_sidewinder_record_show,
+		ms_sidewinder_record_store);
+
+static ssize_t ms_sidewinder_auto_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+
+	return snprintf(buf, PAGE_SIZE, "%1d\n", (sidewinder->status & 0x02) >> 1);
+}
+
+static ssize_t ms_sidewinder_auto_store(struct device *dev,
+		struct device_attribute *attr, char const *buf, size_t count)
+{
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
+	struct ms_sidewinder_extra *sidewinder = sc->extra;
+	unsigned int value;
+	__u8 setup;
+
+	if (sscanf(buf, "%1d", &value) != 1)
+		return -EINVAL;
+
+	if (value < 0 || value > 1) {
+		return -EINVAL;
+	} else {
+		setup = sidewinder->status & ~(0x02);	/* Clear Auto LED */
+		if (value)
+			setup |= 0x02;
+		ms_sidewinder_control(hdev, setup);
+		return strnlen(buf, PAGE_SIZE);
+	}
+}
+
+static struct device_attribute dev_attr_ms_sidewinder_auto =
+	__ATTR(auto_led, S_IWUSR | S_IRUGO,
+		ms_sidewinder_auto_show,
+		ms_sidewinder_auto_store);
+
+static struct attribute *ms_attributes[] = {
+	&dev_attr_ms_sidewinder_key_mask.attr,
+	&dev_attr_ms_sidewinder_profile.attr,
+	&dev_attr_ms_sidewinder_macro_pad.attr,
+	&dev_attr_ms_sidewinder_record.attr,
+	&dev_attr_ms_sidewinder_auto.attr,
+	NULL
+};
+
+static const struct attribute_group ms_attr_group = {
+	.attrs = ms_attributes,
+};
+
 static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
@@ -357,6 +572,13 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 			return -ENOMEM;
 		}
 		sc->extra = sidewinder;
+
+		/* Create sysfs files for the Consumer Control Device only */
+		if (hdev->type == 2) {
+			if (sysfs_create_group(&hdev->dev.kobj, &ms_attr_group)) {
+				hid_warn(hdev, "Could not create sysfs group\n");
+			}
+		}
 	}
 
 	ret = hid_parse(hdev);
@@ -377,6 +599,14 @@ err_free:
 	return ret;
 }
 
+static void ms_remove(struct hid_device *hdev)
+{
+	sysfs_remove_group(&hdev->dev.kobj,
+		&ms_attr_group);
+
+	hid_hw_stop(hdev);
+}
+
 static const struct hid_device_id ms_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
 		.driver_data = MS_HIDINPUT },
@@ -419,6 +649,7 @@ static struct hid_driver ms_driver = {
 	.input_mapped = ms_input_mapped,
 	.event = ms_event,
 	.probe = ms_probe,
+	.remove = ms_remove,
 };
 module_hid_driver(ms_driver);
 
-- 
1.9.1


^ permalink raw reply related

* [PATCH 1/4] HID: microsoft: moving quirks to struct
From: Tolga Cakir @ 2014-04-04 17:06 UTC (permalink / raw)
  To: Benjamin Tissoires, Derya, Jiri Kosina, Reyad Attiyat
  Cc: linux-input, linux-kernel, Tolga Cakir

This will give us the opportunity to easily implement extra features
for new devices.

Signed-off-by: Tolga Cakir <tolga@cevel.net>
---
 drivers/hid/hid-microsoft.c | 44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 6fd5817..0a61403 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -30,23 +30,28 @@
 #define MS_DUPLICATE_USAGES	0x20
 #define MS_RDESC_3K		0x40
 
+struct ms_data {
+	unsigned long quirks;
+	void *extra;
+};
+
 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
 
 	/*
 	 * Microsoft Wireless Desktop Receiver (Model 1028) has
 	 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
 	 */
-	if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
+	if ((sc->quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
 			rdesc[559] == 0x29) {
 		hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
 		rdesc[557] = 0x35;
 		rdesc[559] = 0x45;
 	}
 	/* the same as above (s/usage/physical/) */
-	if ((quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 &&
+	if ((sc->quirks & MS_RDESC_3K) && *rsize == 106 && rdesc[94] == 0x19 &&
 			rdesc[95] == 0x00 && rdesc[96] == 0x29 &&
 			rdesc[97] == 0xff) {
 		rdesc[94] = 0x35;
@@ -142,15 +147,15 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
 
-	if (quirks & MS_ERGONOMY) {
+	if (sc->quirks & MS_ERGONOMY) {
 		int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
 		if (ret)
 			return ret;
 	}
 
-	if ((quirks & MS_PRESENTER) &&
+	if ((sc->quirks & MS_PRESENTER) &&
 			ms_presenter_8k_quirk(hi, usage, bit, max))
 		return 1;
 
@@ -161,9 +166,9 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
 
-	if (quirks & MS_DUPLICATE_USAGES)
+	if (sc->quirks & MS_DUPLICATE_USAGES)
 		clear_bit(usage->code, *bit);
 
 	return 0;
@@ -172,7 +177,7 @@ static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
 static int ms_event(struct hid_device *hdev, struct hid_field *field,
 		struct hid_usage *usage, __s32 value)
 {
-	unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
+	struct ms_data *sc = hid_get_drvdata(hdev);
 	struct input_dev *input;
 
 	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
@@ -182,7 +187,7 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
 	input = field->hidinput->input;
 
 	/* Handling MS keyboards special buttons */
-	if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
+	if (sc->quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
 		/* Special keypad keys */
 		input_report_key(input, KEY_KPEQUAL, value & 0x01);
 		input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
@@ -190,7 +195,7 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
 		return 1;
 	}
 
-	if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
+	if (sc->quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
 		/* Scroll wheel */
 		int step = ((value & 0x60) >> 5) + 1;
 
@@ -205,7 +210,7 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
 		return 1;
 	}
 
-	if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
+	if (sc->quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
 		static unsigned int last_key = 0;
 		unsigned int key = 0;
 		switch (value) {
@@ -229,12 +234,19 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
 
 static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 {
-	unsigned long quirks = id->driver_data;
+	struct ms_data *sc;
 	int ret;
 
-	hid_set_drvdata(hdev, (void *)quirks);
+	sc = devm_kzalloc(&hdev->dev, sizeof(struct ms_data), GFP_KERNEL);
+	if (!sc) {
+		hid_err(hdev, "can't alloc microsoft descriptor\n");
+		return -ENOMEM;
+	}
+
+	sc->quirks = id->driver_data;
+	hid_set_drvdata(hdev, sc);
 
-	if (quirks & MS_NOGET)
+	if (sc->quirks & MS_NOGET)
 		hdev->quirks |= HID_QUIRK_NOGET;
 
 	ret = hid_parse(hdev);
@@ -243,7 +255,7 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		goto err_free;
 	}
 
-	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ?
+	ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((sc->quirks & MS_HIDINPUT) ?
 				HID_CONNECT_HIDINPUT_FORCE : 0));
 	if (ret) {
 		hid_err(hdev, "hw start failed\n");
-- 
1.9.1


^ permalink raw reply related

* [PATCH 4/4] HID: microsoft: undefining ms_map_key_clear after usage
From: Tolga Cakir @ 2014-04-04 17:07 UTC (permalink / raw)
  To: Benjamin Tissoires, Derya, Jiri Kosina, Reyad Attiyat
  Cc: linux-input, linux-kernel, Tolga Cakir

This is inspired by various other hid drivers.

Signed-off-by: Tolga Cakir <tolga@cevel.net>
---
 drivers/hid/hid-microsoft.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 5674c0c..5281d2d 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -211,6 +211,8 @@ static int ms_sidewinder_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
 	return 1;
 }
 
+#undef ms_map_key_clear
+
 static int ms_sidewinder_control(struct hid_device *hdev, __u8 setup)
 {
 	struct ms_data *sc = hid_get_drvdata(hdev);
-- 
1.9.1


^ permalink raw reply related

* [PATCH 2/4] HID: microsoft: initial support for Microsoft Sidewinder X4 / X6 keyboards
From: Tolga Cakir @ 2014-04-04 17:06 UTC (permalink / raw)
  To: Benjamin Tissoires, Derya, Jiri Kosina, Reyad Attiyat
  Cc: linux-input, linux-kernel, Tolga Cakir

This patch will let hid-microsoft handle the Microsoft Sidewinder X4 and X6 keyboards.

Signed-off-by: Tolga Cakir <tolga@cevel.net>
---
 drivers/hid/hid-core.c      |   2 +
 drivers/hid/hid-ids.h       |   2 +
 drivers/hid/hid-microsoft.c | 114 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 118 insertions(+)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index dbe548b..5de5ba1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1815,6 +1815,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_X6) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_X4) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 548c1a5..21be65d 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -626,6 +626,8 @@
 #define USB_DEVICE_ID_MS_PRESENTER_8K_BT	0x0701
 #define USB_DEVICE_ID_MS_PRESENTER_8K_USB	0x0713
 #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K	0x0730
+#define USB_DEVICE_ID_SIDEWINDER_X6	0x074b
+#define USB_DEVICE_ID_SIDEWINDER_X4	0x0768
 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500	0x076c
 #define USB_DEVICE_ID_MS_TOUCH_COVER_2	0x07a7
 #define USB_DEVICE_ID_MS_TYPE_COVER_2	0x07a9
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 0a61403..5b5d40f 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -29,12 +29,28 @@
 #define MS_NOGET		0x10
 #define MS_DUPLICATE_USAGES	0x20
 #define MS_RDESC_3K		0x40
+#define MS_SIDEWINDER	0x80
 
 struct ms_data {
 	unsigned long quirks;
 	void *extra;
 };
 
+/*
+ * For Sidewinder X4 / X6 devices.
+ * @profile: for storing profile status.
+ * @status: holds information about LED states and numpad mode (X6
+ * only). The 1st bit is for numpad mode, bits 2 - 7 are reserved for
+ * LED configuration and the last bit is currently unused.
+ * @key_mask: holds information about pressed special keys. It's
+ * readable via sysfs, so user-space tools can handle keys.
+ */
+struct ms_sidewinder_extra {
+	unsigned profile;
+	__u8 status;
+	unsigned long key_mask;
+};
+
 static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		unsigned int *rsize)
 {
@@ -143,6 +159,56 @@ static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
 	return 1;
 }
 
+static int ms_sidewinder_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
+		unsigned long **bit, int *max)
+{
+	set_bit(EV_REP, hi->input->evbit);
+	switch (usage->hid & HID_USAGE) {
+	/*
+	 * Registering Sidewinder X4 / X6 special keys. S1 - S6 macro keys
+	 * are shared between Sidewinder X4 & X6 and are programmable.
+	 */
+	case 0xfb01: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S1 */
+	case 0xfb02: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S2 */
+	case 0xfb03: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S3 */
+	case 0xfb04: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S4 */
+	case 0xfb05: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S5 */
+	case 0xfb06: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S6 */
+	/* S7 - S30 macro keys are only present on the Sidewinder X6 */
+	case 0xfb07: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S7 */
+	case 0xfb08: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S8 */
+	case 0xfb09: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S9 */
+	case 0xfb0a: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S10 */
+	case 0xfb0b: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S11 */
+	case 0xfb0c: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S12 */
+	case 0xfb0d: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S13 */
+	case 0xfb0e: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S14 */
+	case 0xfb0f: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S15 */
+	case 0xfb10: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S16 */
+	case 0xfb11: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S17 */
+	case 0xfb12: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S18 */
+	case 0xfb13: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S19 */
+	case 0xfb14: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S20 */
+	case 0xfb15: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S21 */
+	case 0xfb16: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S22 */
+	case 0xfb17: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S23 */
+	case 0xfb18: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S24 */
+	case 0xfb19: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S25 */
+	case 0xfb1a: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S26 */
+	case 0xfb1b: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S27 */
+	case 0xfb1c: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S28 */
+	case 0xfb1d: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S29 */
+	case 0xfb1e: ms_map_key_clear(KEY_UNKNOWN);	break;	/* S30 */
+	/* Not programmable keys: Profile, Game Center (X6 only) and Macro */
+	case 0xfd11: ms_map_key_clear(KEY_GAMES);	break;	/* X6: Game Center*/
+	case 0xfd12: ms_map_key_clear(KEY_MACRO);	break;	/* Macro */
+	case 0xfd15: ms_map_key_clear(KEY_UNKNOWN);	break;	/* Profile */
+	default:
+		return 0;
+	}
+	return 1;
+}
+
 static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 		struct hid_field *field, struct hid_usage *usage,
 		unsigned long **bit, int *max)
@@ -159,6 +225,10 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 			ms_presenter_8k_quirk(hi, usage, bit, max))
 		return 1;
 
+	if ((sc->quirks & MS_SIDEWINDER) &&
+			ms_sidewinder_kb_quirk(hi, usage, bit, max))
+		return 1;
+
 	return 0;
 }
 
@@ -229,6 +299,34 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
 		return 1;
 	}
 
+	/*
+	 * Sidewinder special button handling & profile switching
+	 *
+	 * Pressing S1 - S30 macro keys will not send out any keycodes, but
+	 * set bits on key_mask (readable via sysfs). It's possible to press
+	 * multiple special keys at the same time.
+	 */
+	if (sc->quirks & MS_SIDEWINDER) {
+		struct input_dev *input = field->hidinput->input;
+		struct ms_sidewinder_extra *sidewinder = sc->extra;
+		int i;
+
+		for (i = 0; i <= 29; i++) {	/* Run through S1 - S30 keys */
+			if ((usage->hid & HID_USAGE) == (0xfb01 + i)) {
+				value ? set_bit(i, &sidewinder->key_mask) : clear_bit(i, &sidewinder->key_mask);
+				break;	/* Exit loop, when correct hid usage has been found */
+			}
+		}
+
+		switch (usage->hid & HID_USAGE) {
+		case 0xfd11: input_event(input, usage->type, KEY_GAMES, value);	break;
+		case 0xfd12: input_event(input, usage->type, KEY_MACRO, value);	break;
+		case 0xfd15: value ? set_bit(30, &sidewinder->key_mask) : clear_bit(30, &sidewinder->key_mask);	break;
+		}
+
+		return 1;
+	}
+
 	return 0;
 }
 
@@ -249,6 +347,18 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	if (sc->quirks & MS_NOGET)
 		hdev->quirks |= HID_QUIRK_NOGET;
 
+	if (sc->quirks & MS_SIDEWINDER) {
+		struct ms_sidewinder_extra *sidewinder;
+
+		sidewinder = devm_kzalloc(&hdev->dev, sizeof(struct ms_sidewinder_extra),
+					GFP_KERNEL);
+		if (!sidewinder) {
+			hid_err(hdev, "can't alloc microsoft descriptor\n");
+			return -ENOMEM;
+		}
+		sc->extra = sidewinder;
+	}
+
 	ret = hid_parse(hdev);
 	if (ret) {
 		hid_err(hdev, "parse failed\n");
@@ -270,6 +380,10 @@ err_free:
 static const struct hid_device_id ms_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
 		.driver_data = MS_HIDINPUT },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_X6),
+		.driver_data = MS_SIDEWINDER },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_X4),
+		.driver_data = MS_SIDEWINDER },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
 		.driver_data = MS_ERGONOMY },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
-- 
1.9.1

^ permalink raw reply related

* Re: [PATCH v4 7/7] HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
From: simon @ 2014-04-04 16:11 UTC (permalink / raw)
  Cc: HID CORE LAYER, Jiri Kosina, Frank Praznik
In-Reply-To: <533EBE48.5010100@oh.rr.com>

DS3:
>> blinking sometimes got confused, setting trigger to none and back to
>> timer resolved.

> Could you elaborate on how the blinking became confused?

When blink was enabled the led would turn off (from being statically on),
but never turn on/blink... I'll try to do some more 'structured' testing
over the weekend. Seen on the 3rd led, which might be a clue.

DS4:
> Yeah, if you set different LEDs to different triggers the light can get
> stuck since the triggers will constantly override each other. I'm
> thinking that an extra "blink" LED just to control the global blink rate
> would be a better solution since the hardware blink setting isn't really
> LED specific.

Why not make the triggers/etc apply across the board, so it doesn't matter
which led the command is sent to - it's just registered/copied to the
first (red?) led data[].

IIRC the weirdness I saw was:
--
cd red
echo 80 > brightness # now red
cd blue
echo 80 > brightness # now purple
cd red
echo timer > trigger # now flashing blue....
--

>> 3rd Party Intec - Was unable to get any controlled blinking.

> It sounds like this controller just doesn't implement all of the
> behavior of the official controller.  I'm not sure how to fix it if it's
> not obeying the instructions in valid output reports and I don't have
> one to test personally.  Do the lights flash properly when the
> controller is used with a PS3?

I presume that they just reversed engineered what they thought to be
correct, I don't have a Playstation so can't confirm for certain.

In my testing from a year ago or so, I could make the blink work via
sending data with python. The script can be found here:
http://www.spinics.net/lists/linux-input/msg28271.html

Note: "Which LED to enable(LED1..4 << 1, 0x20=none)"

Cheers,
Simon


^ permalink raw reply

* [PATCH] HID: add missing hid usages
From: Olivier Gay @ 2014-04-04 15:02 UTC (permalink / raw)
  To: linux-input
  Cc: Jiri Kosina, Nestor Lopez Casado, Olivier Gay, Mathieu Meisser

Add some missing hid usages from consumer page, add
display brightness control usages from approved hid usage
table request HUTTR41:
http://www.usb.org/developers/hidpage/HUTRR41.pdf
and add voice command usage from approved request HUTTR45:
http://www.usb.org/developers/hidpage/Voice_Command_Usage.pdf

Signed-off-by: Olivier Gay <ogay@logitech.com>
Signed-off-by: Mathieu Meisser <mmeisser@logitech.com>
---

Hi all,

with this patch we add some missing hid usages to the hid system.
Those missing hid usages are already used by some Logitech
products as well as some future ones.

(Note: checkpatch.pl shows some errors but I didn't want to
break the current code style in hid-input.c)

Best regards,

Olivier

 drivers/hid/hid-debug.c    | 14 ++++++++++++++
 drivers/hid/hid-input.c    | 15 +++++++++++++++
 include/uapi/linux/input.h | 16 ++++++++++++++++
 3 files changed, 45 insertions(+)

diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 53b771d..742d78b 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -855,6 +855,20 @@ static const char *keys[KEY_MAX + 1] = {
 	[KEY_KBDILLUMDOWN] = "KbdIlluminationDown",
 	[KEY_KBDILLUMUP] = "KbdIlluminationUp",
 	[KEY_SWITCHVIDEOMODE] = "SwitchVideoMode",
+	[KEY_BUTTONCONFIG] = "ButtonConfig",
+	[KEY_TASKMANAGER] = "TaskManager",
+	[KEY_JOURNAL] = "Journal",
+	[KEY_CONTROLPANEL] = "ControlPanel",
+	[KEY_APPSELECT] = "AppSelect",
+	[KEY_SCREENSAVER] = "ScreenSaver",
+	[KEY_VOICECOMMAND] = "VoiceCommand",
+	[KEY_BRIGHTNESS_INC] = "BrightnessInc",
+	[KEY_BRIGHTNESS_DEC] = "BrightnessDec",
+	[KEY_BRIGHTNESS] = "Brightness",
+	[KEY_BRIGHTNESS_TOGGLE] = "BrightnessToggle",
+	[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
+	[KEY_BRIGHTNESS_MAX] = "BrightnessMax",
+	[KEY_BRIGHTNESS_AUTO] = "BrightnessAuto",
 };
 
 static const char *relatives[REL_MAX + 1] = {
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 930382e..e1409da 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -721,6 +721,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		case 0x06c: map_key_clear(KEY_YELLOW);		break;
 		case 0x06d: map_key_clear(KEY_ZOOM);		break;
 
+		case 0x06f: map_key_clear(KEY_BRIGHTNESS_INC);		break;
+		case 0x070: map_key_clear(KEY_BRIGHTNESS_DEC);		break;
+		case 0x071: map_key_clear(KEY_BRIGHTNESS);		break;
+		case 0x072: map_key_clear(KEY_BRIGHTNESS_TOGGLE);	break;
+		case 0x073: map_key_clear(KEY_BRIGHTNESS_MIN);		break;
+		case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX);		break;
+		case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO);		break;
+
 		case 0x082: map_key_clear(KEY_VIDEO_NEXT);	break;
 		case 0x083: map_key_clear(KEY_LAST);		break;
 		case 0x084: map_key_clear(KEY_ENTER);		break;
@@ -761,6 +769,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		case 0x0bf: map_key_clear(KEY_SLOW);		break;
 
 		case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
+		case 0x0cf: map_key_clear(KEY_VOICECOMMAND);	break;
 		case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
 		case 0x0e2: map_key_clear(KEY_MUTE);		break;
 		case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
@@ -768,6 +777,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
 		case 0x0f5: map_key_clear(KEY_SLOW);		break;
 
+		case 0x181: map_key_clear(KEY_BUTTONCONFIG);	break;
 		case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
 		case 0x183: map_key_clear(KEY_CONFIG);		break;
 		case 0x184: map_key_clear(KEY_WORDPROCESSOR);	break;
@@ -781,6 +791,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		case 0x18c: map_key_clear(KEY_VOICEMAIL);	break;
 		case 0x18d: map_key_clear(KEY_ADDRESSBOOK);	break;
 		case 0x18e: map_key_clear(KEY_CALENDAR);	break;
+		case 0x18f: map_key_clear(KEY_TASKMANAGER);	break;
+		case 0x190: map_key_clear(KEY_JOURNAL);		break;
 		case 0x191: map_key_clear(KEY_FINANCE);		break;
 		case 0x192: map_key_clear(KEY_CALC);		break;
 		case 0x193: map_key_clear(KEY_PLAYER);		break;
@@ -789,12 +801,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
 		case 0x199: map_key_clear(KEY_CHAT);		break;
 		case 0x19c: map_key_clear(KEY_LOGOFF);		break;
 		case 0x19e: map_key_clear(KEY_COFFEE);		break;
+		case 0x19f: map_key_clear(KEY_CONTROLPANEL);		break;
+		case 0x1a2: map_key_clear(KEY_APPSELECT);		break;
 		case 0x1a3: map_key_clear(KEY_NEXT);		break;
 		case 0x1a4: map_key_clear(KEY_PREVIOUS);	break;
 		case 0x1a6: map_key_clear(KEY_HELP);		break;
 		case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
 		case 0x1ab: map_key_clear(KEY_SPELLCHECK);	break;
 		case 0x1ae: map_key_clear(KEY_KEYBOARD);	break;
+		case 0x1b1: map_key_clear(KEY_SCREENSAVER);		break;
 		case 0x1b4: map_key_clear(KEY_FILE);		break;
 		case 0x1b6: map_key_clear(KEY_IMAGES);		break;
 		case 0x1b7: map_key_clear(KEY_AUDIO);		break;
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index bd24470..d82454f 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -722,6 +722,22 @@ struct input_keymap_entry {
 
 #define KEY_ALS_TOGGLE		0x230	/* Ambient light sensor */
 
+#define KEY_BUTTONCONFIG		0x240	/* AL Button Configuration */
+#define KEY_TASKMANAGER		0x241	/* AL Task/Project Manager */
+#define KEY_JOURNAL		0x242	/* AL Log/Journal/Timecard */
+#define KEY_CONTROLPANEL		0x243	/* AL Control Panel */
+#define KEY_APPSELECT		0x244	/* AL Select Task/Application */
+#define KEY_SCREENSAVER		0x245	/* AL Screen Saver */
+#define KEY_VOICECOMMAND		0x246	/* Listening Voice Command */
+
+#define KEY_BRIGHTNESS_INC		KEY_BRIGHTNESSUP
+#define KEY_BRIGHTNESS_DEC		KEY_BRIGHTNESSDOWN
+#define KEY_BRIGHTNESS		0x250	/* Display Brightness */
+#define KEY_BRIGHTNESS_TOGGLE		0x251	/* Backlight Toggle */
+#define KEY_BRIGHTNESS_MIN		0x252	/* Set Brightness to Minimum */
+#define KEY_BRIGHTNESS_MAX		0x253	/* Set Brightness to Maximum */
+#define KEY_BRIGHTNESS_AUTO		0x254	/* Set Auto Brightness */
+
 #define BTN_TRIGGER_HAPPY		0x2c0
 #define BTN_TRIGGER_HAPPY1		0x2c0
 #define BTN_TRIGGER_HAPPY2		0x2c1
-- 
1.9.0


^ permalink raw reply related

* Re: ti_am33x_adc sampling bugs
From: gmane-G/ASJRsgvFgvW+L+VdN226ESeJV5RFUqQQ4Iyu8u01E @ 2014-04-04 13:41 UTC (permalink / raw)
  To: Zubair Lutfullah :
  Cc: Jonathan Cameron, Rob Mosher, Sebastian Andrzej Siewior,
	robertcnelson-Re5JQEeQqe8AvxtiuMwx3w, Samuel Ortiz,
	Dmitry Torokhov, Felipe Balbi, linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA, Lee Jones
In-Reply-To: <20140401054158.GA3261-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Hi,

On 2014-04-01 00:42, Zubair Lutfullah : wrote:
> Sorry for taking this long to reply.
> 
> The confusion here is due to vendor/mainline trees for the kernel.
> 
> This discussion should have been carried out on
> https://github.com/beagleboard/kernel/issues
> instead of the kernel mailing lists.

Sorry for jumping in here.

I use a more recent kernel 3.13.x and currently try to move to 3.14.x.
The sampling seems to work, but I would like to use the generic_buffer
test [1].

The kernel used here [1] is a 3.13.6 stable plus those patches [2] 
(from
Rob Nelson)

Can someone please tell me what's the status with beagle bone black and
iio (and maybe whom to talk to about it).

Regards,

Robert

[1] http://thread.gmane.org/gmane.linux.kernel.iio/11631
[2]
https://github.com/RobertBerger/meta-mainline/blob/dora-training-v3.13.x/beagle-bone-black-ml/recipes-kernel/linux/linux-yocto-custom/beagle-bone-black-ml-user-patches.scc


...do it-do it right-do it right now- Bobby Riggs

My public pgp key is available,at:
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x90320BF1

^ permalink raw reply

* Re: [PATCH v4 7/7] HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
From: simon @ 2014-04-04  5:55 UTC (permalink / raw)
  Cc: linux-input, jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-8-git-send-email-frank.praznik@oh.rr.com>

> Add support for setting the blink rate of the LEDs.  The Sixaxis allows
> control
> over each individual LED, but the Dualshock 4 only has one global control
> for
> the light bar so changing any individual color changes the global blink
> rate.

I was able to build this and test on the controllers I have. After
modprobing 'ledtrig-timer', I was able to 'echo timer > trigger' in the
appropriate led directory and confirm that leds blinked without additional
USB traffic seen by USBMON.

DS3 SixAxis - mostly worked, although I hade to set a led to 0, before I
could set to 1 (otherwise all leds just did automatic blinking). I was
able to:
blink single led
blink led while other was statically on
blink multiple leds with different timing
blinking sometimes got confused, setting trigger to none and back to timer
resolved.

DS4 - Worked as descibed in patch, but I feel behaviour is confusing. I
was able to:
blink single led
unable adjust other led whilst blinking (blinking stopped, or wrong colour
started blinking)

3rd Party Intec - Was unable to get any controlled blinking. As previously
mentioned all leds flash (automatic, as if first plugged in) whenever all
leds are turned off.
I can control all leds in a static on/off mode, but can't set any
blinking/timer behaviour

Let me know if there's any other testing I can do,
Simon.



^ permalink raw reply

* Re: [PATCH] Add sensor hub quirk for ThinkPad Helix
From: Jiri Kosina @ 2014-04-03 20:54 UTC (permalink / raw)
  To: Stephen Chandler Paul
  Cc: linux-input, linux-kernel, Benjamin Tissoires,
	Srinivas Pandruvada, Adam Williamson
In-Reply-To: <1396556875-31108-1-git-send-email-thatslyude@gmail.com>

On Thu, 3 Apr 2014, Stephen Chandler Paul wrote:

> Just like some of the other laptops/tablets on the market with ultrabook
> sensors, the ThinkPad Helix's sensor hub requires a special quirk in
> order for it to power on properly. Without it the sensors are detected
> by the kernel and set up as usual, but they won't output any data. This
> will also fix the sensors on any other laptops with the same model of
> sensor hub.
> 
> Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>

Queued for 3.15, thanks.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCH] Add sensor hub quirk for ThinkPad Helix
From: Srinivas Pandruvada @ 2014-04-03 20:39 UTC (permalink / raw)
  To: Stephen Chandler Paul, Jiri Kosina, linux-input, linux-kernel
  Cc: Benjamin Tissoires, Srinivas Pandruvada, Adam Williamson
In-Reply-To: <1396556875-31108-1-git-send-email-thatslyude@gmail.com>


On 04/03/2014 01:27 PM, Stephen Chandler Paul wrote:
> Just like some of the other laptops/tablets on the market with ultrabook
> sensors, the ThinkPad Helix's sensor hub requires a special quirk in
> order for it to power on properly. Without it the sensors are detected
> by the kernel and set up as usual, but they won't output any data. This
> will also fix the sensors on any other laptops with the same model of
> sensor hub.
>
> Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>
> ---
>   drivers/hid/hid-ids.h        | 3 ++-
>   drivers/hid/hid-sensor-hub.c | 7 +++++--
>   2 files changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index bd22126..3312f1b5 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -455,7 +455,8 @@
>   
>   #define USB_VENDOR_ID_INTEL_0		0x8086
>   #define USB_VENDOR_ID_INTEL_1		0x8087
> -#define USB_DEVICE_ID_INTEL_HID_SENSOR	0x09fa
> +#define USB_DEVICE_ID_INTEL_HID_SENSOR_0	0x09fa
> +#define USB_DEVICE_ID_INTEL_HID_SENSOR_1	0x0a04
>   
>   #define USB_VENDOR_ID_STM_0             0x0483
>   #define USB_DEVICE_ID_STM_HID_SENSOR    0x91d1
> diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
> index 5182031..af8244b 100644
> --- a/drivers/hid/hid-sensor-hub.c
> +++ b/drivers/hid/hid-sensor-hub.c
> @@ -697,10 +697,13 @@ static void sensor_hub_remove(struct hid_device *hdev)
>   
>   static const struct hid_device_id sensor_hub_devices[] = {
>   	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
> -			USB_DEVICE_ID_INTEL_HID_SENSOR),
> +			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
>   			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
>   	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
> -			USB_DEVICE_ID_INTEL_HID_SENSOR),
> +			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
> +			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
> +	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
> +			USB_DEVICE_ID_INTEL_HID_SENSOR_1),
>   			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
>   	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
>   			USB_DEVICE_ID_STM_HID_SENSOR),

Acked-by: Srinivas Pandruvada<srinivas.pandruvada@linux.intel.com>


Thanks,
Srinivas


^ permalink raw reply

* [PATCH] Add sensor hub quirk for ThinkPad Helix
From: Stephen Chandler Paul @ 2014-04-03 20:27 UTC (permalink / raw)
  To: Jiri Kosina, linux-input, linux-kernel
  Cc: Benjamin Tissoires, Srinivas Pandruvada, Adam Williamson

Just like some of the other laptops/tablets on the market with ultrabook
sensors, the ThinkPad Helix's sensor hub requires a special quirk in
order for it to power on properly. Without it the sensors are detected
by the kernel and set up as usual, but they won't output any data. This
will also fix the sensors on any other laptops with the same model of
sensor hub.

Signed-off-by: Stephen Chandler Paul <thatslyude@gmail.com>
---
 drivers/hid/hid-ids.h        | 3 ++-
 drivers/hid/hid-sensor-hub.c | 7 +++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index bd22126..3312f1b5 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -455,7 +455,8 @@
 
 #define USB_VENDOR_ID_INTEL_0		0x8086
 #define USB_VENDOR_ID_INTEL_1		0x8087
-#define USB_DEVICE_ID_INTEL_HID_SENSOR	0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_0	0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_1	0x0a04
 
 #define USB_VENDOR_ID_STM_0             0x0483
 #define USB_DEVICE_ID_STM_HID_SENSOR    0x91d1
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 5182031..af8244b 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -697,10 +697,13 @@ static void sensor_hub_remove(struct hid_device *hdev)
 
 static const struct hid_device_id sensor_hub_devices[] = {
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
-			USB_DEVICE_ID_INTEL_HID_SENSOR),
+			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
 			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
-			USB_DEVICE_ID_INTEL_HID_SENSOR),
+			USB_DEVICE_ID_INTEL_HID_SENSOR_0),
+			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
+	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
+			USB_DEVICE_ID_INTEL_HID_SENSOR_1),
 			.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
 			USB_DEVICE_ID_STM_HID_SENSOR),
-- 
1.8.3.2


^ permalink raw reply related

* [git pull] Input updates for 3.15-rc0
From: Dmitry Torokhov @ 2014-04-03 17:07 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel, linux-input

[-- Attachment #1: Type: text/plain, Size: 6741 bytes --]

Hi Linus,

Please pull from:

	git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
	master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive first round of updates for the input subsystem. Just new
drivers and existing driver fixes, no core changes except for the new
uinput IOCTL to allow userspace to fetch sysfs name of the input device
that was created.

Changelog:
---------

Alexander Shiyan (1):
      Input: add new driver for ARM CLPS711X keypad

Alexey Khoroshilov (1):
      Input: gtco - fix usb_dev leak

Andrey Smirnov (1):
      Input: ims-pcu - add commands supported by the new version of the FW

Anthony Olech (1):
      Input: da9052_onkey - use correct register bit for key status

Arnd Bergmann (1):
      Input: remove obsolete tnetv107x drivers

Barry Song (2):
      Input: sirfsoc-onkey - drop the IRQF_SHARED flag
      Input: sirfsoc-onkey - update copyright years to 2014

Benjamin Tissoires (1):
      Input: uinput - add UI_GET_SYSNAME ioctl to retrieve the sysfs path

Benjamin Tisssoires (1):
      Input: uinput - breaks by goto out in uinput_ioctl_handler

Clinton Sprain (3):
      Input: appletouch - dial back fuzz setting
      Input: appletouch - implement sensor data smoothing
      Input: appletouch - fix jumps when additional fingers are detected

Dan Carpenter (1):
      Input: edt-ft5x06 - add a missing condition

Dmitry Torokhov (2):
      Input: ims-pcu - fix error unwinding path in application mode
      Input: sirfsoc-onkey - implement open and close methods

Fabio Estevam (1):
      Input: imx_keypad - Propagate the real error code on platform_get_irq() failure

Heiko Stübner (2):
      Input: zforce - use internal pdata pointer instead of dev_get_platdata
      Input: zforce - add devicetree support

Jakub Bogusz (1):
      Input: wistron_btns - add FS AMILO Pro 8210 support

Jean Delvare (2):
      Input: olpc_apsp - fix dependencies of OLPC AP-SP driver
      Input: wistron_btns - simplify dependencies

Lejun Zhu (1):
      Input: add driver for SOC button array

Lothar Waßmann (5):
      Input: edt-ft5x06 - several cleanups; no functional change
      Input: edt-ft5x06 - add DT support
      Input: edt-ft5x06 - adjust delays to conform datasheet
      Input: edt-ft5x06 - ignore touchdown events
      Input: edt-ft5x06 - add support for M09 firmware version

Luis Ortega (4):
      Input: zforce - fix spelling errors
      Input: zforce - fix lines exceeding 80 columns
      Input: zforce - remove unnecessary payload data checks
      Input: zforce - reduce stack memory allocated to frames

Sachin Kamat (1):
      Input: s3c2410 - trivial cleanup in header file

Stephen Boyd (6):
      Input: pmic8xxx-keypad - fix build by removing gpio configuration
      Input: pmic8xxx-keypad - migrate to devm_* APIs
      Input: pmic8xxx-keypad - migrate to regmap APIs
      Input: pmic8xxx-keypad - migrate to DT
      Input: pmic8xxx-pwrkey - migrate to DT
      Input: pm8xxx-vibrator - add DT match table

Thomas Gleixner (1):
      Input: hp_sdc - use del_timer_sync() in exit path

Xianglong Du (4):
      Input: sirfsoc-onkey - fix namespace pwrc_resume function
      Input: sirfsoc-onkey - use dev_get_drvdata instead of platform_get_drvdata
      Input: sirfsoc-onkey - report release event by detecting pin status
      Input: sirfsoc-onkey - set the capability of reporting KEY_POWER


Diffstat:
--------

 .../devicetree/bindings/input/clps711x-keypad.txt  |  27 ++
 .../bindings/input/qcom,pm8xxx-keypad.txt          |  89 ++++
 .../bindings/input/qcom,pm8xxx-pwrkey.txt          |  46 ++
 .../devicetree/bindings/input/qcom,pm8xxx-vib.txt  |  22 +
 .../bindings/input/touchscreen/edt-ft5x06.txt      |  55 +++
 .../bindings/input/touchscreen/zforce_ts.txt       |  30 ++
 drivers/input/keyboard/Kconfig                     |  22 +-
 drivers/input/keyboard/Makefile                    |   2 +-
 drivers/input/keyboard/clps711x-keypad.c           | 207 ++++++++
 drivers/input/keyboard/imx_keypad.c                |   4 +-
 drivers/input/keyboard/pmic8xxx-keypad.c           | 348 ++++++--------
 drivers/input/keyboard/tnetv107x-keypad.c          | 329 -------------
 drivers/input/misc/Kconfig                         |  12 +-
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/ims-pcu.c                       | 258 +++++++++-
 drivers/input/misc/pm8xxx-vibrator.c               |   9 +-
 drivers/input/misc/pmic8xxx-pwrkey.c               |  33 +-
 drivers/input/misc/sirfsoc-onkey.c                 | 111 +++--
 drivers/input/misc/soc_button_array.c              | 218 +++++++++
 drivers/input/misc/uinput.c                        |  97 ++--
 drivers/input/misc/wistron_btns.c                  |  19 +
 drivers/input/mouse/appletouch.c                   | 143 ++++--
 drivers/input/serio/Kconfig                        |   2 +-
 drivers/input/serio/hp_sdc.c                       |   2 +-
 drivers/input/tablet/gtco.c                        |   2 +-
 drivers/input/touchscreen/Kconfig                  |   9 -
 drivers/input/touchscreen/Makefile                 |   1 -
 drivers/input/touchscreen/edt-ft5x06.c             | 519 ++++++++++++++++-----
 drivers/input/touchscreen/tnetv107x-ts.c           | 384 ---------------
 drivers/input/touchscreen/zforce_ts.c              |  95 +++-
 include/linux/input/pmic8xxx-keypad.h              |  52 ---
 include/linux/input/pmic8xxx-pwrkey.h              |  31 --
 include/linux/platform_data/touchscreen-s3c2410.h  |  17 +-
 include/linux/uinput.h                             |   2 +
 include/uapi/linux/uinput.h                        |  13 +-
 35 files changed, 1910 insertions(+), 1301 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/input/clps711x-keypad.txt
 create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt
 create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt
 create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/zforce_ts.txt
 create mode 100644 drivers/input/keyboard/clps711x-keypad.c
 delete mode 100644 drivers/input/keyboard/tnetv107x-keypad.c
 create mode 100644 drivers/input/misc/soc_button_array.c
 delete mode 100644 drivers/input/touchscreen/tnetv107x-ts.c
 delete mode 100644 include/linux/input/pmic8xxx-keypad.h
 delete mode 100644 include/linux/input/pmic8xxx-pwrkey.h

-- 
Dmitry


[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: HID vendor access from user space
From: Jiri Kosina @ 2014-04-03 13:57 UTC (permalink / raw)
  To: Nestor Lopez Casado
  Cc: David Herrmann, Dmitry Torokhov, Andrew de los Reyes,
	open list:HID CORE LAYER, Olivier Gay, Benjamin Tissoires
In-Reply-To: <CAE7qMrpO_yEtUGQEg5+8k4gU5=7Hxu03_Y0Uov+vJf5pM0ozkA@mail.gmail.com>

On Wed, 2 Apr 2014, Nestor Lopez Casado wrote:

> >> If a user wants to configure/control the device there are two choices,
> >> either write a hid-specific driver to deal with the vendor specific
> >> collection, or open the corresponding /hidraw node from userspace.
> >>
> >> But a hidraw node that carries system input data requires root priviledges.
> >>
> >> I'm interested in hearing your opinions on how to add the capability
> >> for a normal user process to control/configure a HID device via
> >> reports exchanged with a vendor collection.
> >>
> >> I have one proposal, which is to create, say  "/dev/hidvendorX", nodes
> >> for all top level HID collections which are today ignored by hid-input
> >> and/or other subsystems.
> >>
> >> These nodes would not require root priviledge by default and thus,
> >> users could control/reconfigure their devices from a standard
> >> application while keeping the "standard" input functionality intact.
> >
> > Why not write a kernel driver? We have a pretty nice infrastructure
> > for all this.
>
> Do you mean a "hid-specific" driver for certain vid & pid devices ?

I indeed believe that it's what David was proposing. Writing in-kernel 
drivers that handle just specific collections/usages, and let the rest 
be handled by the core infrastructure, is super-easy these days.

Also, if you need users to be able to trigger particular actions being 
perfomed by the driver, sysfs knobs should be a reasonable way to doing 
this.

As an example of such interface -- creating a sysfs trigger for 
hid-logitech-dj that will send the pairing command to the unified 
receiver, has been on my TODO list for quite some time already (and was 
even suggested by Linus).

> > If it's a license-issue, I recommend using udev rules to change
> > permissions on the requested devices directly during setup. You can
> > then use hidraw.
> It is not a license issue, it is a security issue.
> 
> Every hid class interface, (either usb, bluetooth, i2c, etc) has an
> associated hidraw node, and that node aggregates all reports sent from
> the device.
> 
> Say that for example, the device has a keyboard collection and a
> vendor collection, then changing permissions on the associated hidraw
> node (so as to give any desktop user unrestricted access to the vendor
> collection) would open the door to malicious code that could log the
> keyboard activity (as both the vendor reports and input reports are
> seen on the same hidraw node)

I think I am missing the point here. If you own the credentials of the 
session owner, you can log keystrokes anyway even now, just use

	xinput list
	xinput test <id>

and see the result :) Admittedly, this is a little bit more difficult when 
you are outside X11 session, but I am not sure how much concerned you are 
about such scenario anyway.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCH v4 1/7] HID: sony: Fix cancel_work_sync mismerge
From: Jiri Kosina @ 2014-04-03 12:24 UTC (permalink / raw)
  To: Frank Praznik; +Cc: linux-input
In-Reply-To: <1396456285-23755-2-git-send-email-frank.praznik@oh.rr.com>

On Wed, 2 Apr 2014, Frank Praznik wrote:

> Remove redundant cancel_work_sync() call caused by mismerge.
> 
> Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>

Queued for 3.15, thanks for spotting it, Frank.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCH 00/22] atmel_mxt_ts patches, already signed-off
From: Nick Dyer @ 2014-04-03 10:41 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Hi Dmitry-

Nick Dyer <nick.dyer@itdev.co.uk> wrote:
> Here is a set of patches for atmel_mxt_ts that you've already
> signed-off. I've rebased them against the most recent mainline and made
> some very minor changes such as INIT_COMPLETION->reinit_completion.

It would be useful to have some feedback about this patchset if you have time.

Nick

^ permalink raw reply

* Re: [patch v2] Input: edt-ft5x06 - add a missing condition
From: Lothar Waßmann @ 2014-04-03  6:40 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Dmitry Torokhov, Henrik Rydberg, Grant Likely, Rob Herring,
	Fugang Duan, Jingoo Han, linux-input, kernel-janitors
In-Reply-To: <20140403013712.GA28270@mwanda>

Hi,

Dan Carpenter wrote:
> The if condition was accidentally deleted here so we return every time
> instead of returning on error.
> 
> Fixes: fd335ab04b3f ('Input: edt-ft5x06 - add support for M09 firmware version')
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> ---
> v2: removed a stray tab character
> 
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index 75b666b..9d0b324 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -291,9 +291,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
>  		wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
>  		wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
>  
> -		error = edt_ft5x06_ts_readwrite(tsdata->client,
> -						2, wrbuf, 2, rdbuf);
> -		return error;
> +		error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
> +						rdbuf);
> +		if (error)
> +			return error;
>  
>  		if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
>  			dev_err(&tsdata->client->dev,
> 
Acked-By: Lothar Waßmann <LW@KARO-electronics.de>


Lothar Waßmann
-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [patch v2] Input: edt-ft5x06 - add a missing condition
From: Jingoo Han @ 2014-04-03  2:18 UTC (permalink / raw)
  To: 'Dan Carpenter', 'Dmitry Torokhov'
  Cc: 'Lothar Waßmann', 'Henrik Rydberg',
	'Grant Likely', 'Rob Herring',
	'Fugang Duan', linux-input, kernel-janitors,
	'Jingoo Han'
In-Reply-To: <20140403013712.GA28270@mwanda>

On Thursday, April 03, 2014 10:37 AM, Dan Carpenter wrote:
> 
> The if condition was accidentally deleted here so we return every time
> instead of returning on error.
> 
> Fixes: fd335ab04b3f ('Input: edt-ft5x06 - add support for M09 firmware version')
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

Reviewed-by: Jingoo Han <jg1.han@samsung.com>

Best regards,
Jingoo Han

> ---
> v2: removed a stray tab character
> 
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index 75b666b..9d0b324 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -291,9 +291,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
>  		wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
>  		wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
> 
> -		error = edt_ft5x06_ts_readwrite(tsdata->client,
> -						2, wrbuf, 2, rdbuf);
> -		return error;
> +		error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
> +						rdbuf);
> +		if (error)
> +			return error;
> 
>  		if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
>  			dev_err(&tsdata->client->dev,


^ permalink raw reply

* [patch v2] Input: edt-ft5x06 - add a missing condition
From: Dan Carpenter @ 2014-04-03  1:37 UTC (permalink / raw)
  To: Dmitry Torokhov, Lothar Waßmann
  Cc: Henrik Rydberg, Grant Likely, Rob Herring, Fugang Duan,
	Jingoo Han, linux-input, kernel-janitors
In-Reply-To: <002101cf4eda$184e85b0$48eb9110$%han@samsung.com>

The if condition was accidentally deleted here so we return every time
instead of returning on error.

Fixes: fd335ab04b3f ('Input: edt-ft5x06 - add support for M09 firmware version')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
---
v2: removed a stray tab character

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 75b666b..9d0b324 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -291,9 +291,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
 		wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
 		wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
 
-		error = edt_ft5x06_ts_readwrite(tsdata->client,
-						2, wrbuf, 2, rdbuf);
-		return error;
+		error = edt_ft5x06_ts_readwrite(tsdata->client, 2, wrbuf, 2,
+						rdbuf);
+		if (error)
+			return error;
 
 		if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
 			dev_err(&tsdata->client->dev,


^ permalink raw reply related

* Re: [patch] Input: edt-ft5x06 - add a missing condition
From: Jingoo Han @ 2014-04-03  1:14 UTC (permalink / raw)
  To: 'Dan Carpenter'
  Cc: 'Dmitry Torokhov', 'Lothar Waßmann',
	'Henrik Rydberg', 'Grant Likely',
	'Rob Herring', 'Fugang Duan', linux-input,
	kernel-janitors, 'Jingoo Han'
In-Reply-To: <20140402165354.GA9970@mwanda>

On Thursday, April 03, 2014 1:54 AM, Dan Carpenter wrote:
> 
> The if condition was accidentally deleted here so we return every time
> instead of returning on error.
> 
> Fixes: fd335ab04b3f ('Input: edt-ft5x06 - add support for M09 firmware version')
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> 
> diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
> index 75b666b..9d0b324 100644
> --- a/drivers/input/touchscreen/edt-ft5x06.c
> +++ b/drivers/input/touchscreen/edt-ft5x06.c
> @@ -291,9 +291,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
>  		wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
>  		wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
> 
> -		error = edt_ft5x06_ts_readwrite(tsdata->client,
> -						2, wrbuf, 2, rdbuf);
> -		return error;
> +		error = edt_ft5x06_ts_readwrite(tsdata->client,	2, wrbuf, 2,
                                                                                 ^^^^^^
I think that 'tab' is not necessary between "client," and "2,".
Others look good.

Best regards,
Jingoo Han

> +						rdbuf);
> +		if (error)
> +			return error;
> 
>  		if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
>  			dev_err(&tsdata->client->dev,


^ permalink raw reply

* Re: [PATCH v4 0/7] HID: sony: More Sony controller fixes and improvements.
From: Jiri Kosina @ 2014-04-02 22:36 UTC (permalink / raw)
  To: Frank Praznik; +Cc: linux-input
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>

On Wed, 2 Apr 2014, Frank Praznik wrote:

> v4 of this series has been rebased against jikos/hid.git/for-linus
> 
> There was another bit of mismerge code duplication in for-linus that caused
> merge conflicts with patches 3 and above in v3 of the series.
> 
> The first patch in v4 fixes the mismerge and the remaining patches now apply
> cleanly.
> 
> Patch 1 should be queued for 3.15 as soon as possible.

Hmm, you are right indeed. This conflict resolution is not something I'd 
be proud of.

Will be queuing the first patch shortly after Linus pulls, and will review 
the rest after merge window is closed.

Thanks,

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* [patch] Input: edt-ft5x06 - add a missing condition
From: Dan Carpenter @ 2014-04-02 16:53 UTC (permalink / raw)
  To: Dmitry Torokhov, Lothar Waßmann
  Cc: Henrik Rydberg, Grant Likely, Rob Herring, Fugang Duan,
	Jingoo Han, linux-input, kernel-janitors

The if condition was accidentally deleted here so we return every time
instead of returning on error.

Fixes: fd335ab04b3f ('Input: edt-ft5x06 - add support for M09 firmware version')
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 75b666b..9d0b324 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -291,9 +291,10 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
 		wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
 		wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
 
-		error = edt_ft5x06_ts_readwrite(tsdata->client,
-						2, wrbuf, 2, rdbuf);
-		return error;
+		error = edt_ft5x06_ts_readwrite(tsdata->client,	2, wrbuf, 2,
+						rdbuf);
+		if (error)
+			return error;
 
 		if ((wrbuf[0] ^ wrbuf[1] ^ rdbuf[0]) != rdbuf[1]) {
 			dev_err(&tsdata->client->dev,

^ permalink raw reply related

* [PATCH v4 5/7] HID: sony: Use the controller Bluetooth MAC address as the unique value in the battery name string
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
  To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>

Use the controller Bluetooth MAC address as the unique identifier in the
battery name string instead of the atomic integer that was used before.

Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---

 drivers/hid/hid-sony.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index a86542a..c709161 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1413,8 +1413,6 @@ static int sony_battery_get_property(struct power_supply *psy,
 
 static int sony_battery_probe(struct sony_sc *sc)
 {
-	static atomic_t power_id_seq = ATOMIC_INIT(0);
-	unsigned long power_id;
 	struct hid_device *hdev = sc->hdev;
 	int ret;
 
@@ -1424,15 +1422,13 @@ static int sony_battery_probe(struct sony_sc *sc)
 	 */
 	sc->battery_capacity = 100;
 
-	power_id = (unsigned long)atomic_inc_return(&power_id_seq);
-
 	sc->battery.properties = sony_battery_props;
 	sc->battery.num_properties = ARRAY_SIZE(sony_battery_props);
 	sc->battery.get_property = sony_battery_get_property;
 	sc->battery.type = POWER_SUPPLY_TYPE_BATTERY;
 	sc->battery.use_for_apm = 0;
-	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%lu",
-				     power_id);
+	sc->battery.name = kasprintf(GFP_KERNEL, "sony_controller_battery_%pMR",
+				     sc->mac_address);
 	if (!sc->battery.name)
 		return -ENOMEM;
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v4 7/7] HID: sony: Add blink support to the Sixaxis and DualShock 4 LEDs
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
  To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>

Add support for setting the blink rate of the LEDs.  The Sixaxis allows control
over each individual LED, but the Dualshock 4 only has one global control for
the light bar so changing any individual color changes the global blink rate.

Setting the brightness cancels the blinking as per the LED class specifications.

The Sixaxis and Dualshock 4 controllers accept delays in decisecond increments
from 0 to 255 (2550 milliseconds).

The value at index 1 of the DualShock 4 USB output report must be 0xFF or the
light bar won't blink.

Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---

 drivers/hid/hid-sony.c | 113 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 104 insertions(+), 9 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index f26f8fa..aa5ece5 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -773,6 +773,8 @@ struct sony_sc {
 	__u8 battery_charging;
 	__u8 battery_capacity;
 	__u8 led_state[MAX_LEDS];
+	__u8 led_delay_on[MAX_LEDS];
+	__u8 led_delay_off[MAX_LEDS];
 	__u8 led_count;
 };
 
@@ -1167,7 +1169,7 @@ static void sony_led_set_brightness(struct led_classdev *led,
 	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
 	struct sony_sc *drv_data;
 
-	int n;
+	int n, blink_index;
 
 	drv_data = hid_get_drvdata(hdev);
 	if (!drv_data) {
@@ -1176,14 +1178,31 @@ static void sony_led_set_brightness(struct led_classdev *led,
 	}
 
 	for (n = 0; n < drv_data->led_count; n++) {
-		if (led == drv_data->leds[n]) {
-			if (value != drv_data->led_state[n]) {
-				drv_data->led_state[n] = value;
-				sony_set_leds(drv_data, drv_data->led_state,
-						drv_data->led_count);
-			}
+		if (led == drv_data->leds[n])
 			break;
-		}
+	}
+
+	/* This LED is not registered on this device */
+	if (n >= drv_data->led_count)
+		return;
+
+	/* The DualShock 4 has a global blink setting and always uses index 0 */
+	if (drv_data->quirks & DUALSHOCK4_CONTROLLER)
+		blink_index = 0;
+	else
+		blink_index = n;
+
+	if ((value != drv_data->led_state[n]) ||
+		drv_data->led_delay_on[blink_index] ||
+		drv_data->led_delay_off[blink_index]) {
+		drv_data->led_state[n] = value;
+
+		/* Setting the brightness stops the blinking */
+		drv_data->led_delay_on[blink_index] = 0;
+		drv_data->led_delay_off[blink_index] = 0;
+
+		sony_set_leds(drv_data, drv_data->led_state,
+				drv_data->led_count);
 	}
 }
 
@@ -1209,6 +1228,58 @@ static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
 	return LED_OFF;
 }
 
+static int sony_led_blink_set(struct led_classdev *led, unsigned long *delay_on,
+				unsigned long *delay_off)
+{
+	struct device *dev = led->dev->parent;
+	struct hid_device *hdev = container_of(dev, struct hid_device, dev);
+	struct sony_sc *drv_data = hid_get_drvdata(hdev);
+	int n;
+	__u8 new_on, new_off;
+
+	if (!drv_data) {
+		hid_err(hdev, "No device data\n");
+		return -EINVAL;
+	}
+
+	/* Max delay is 255 deciseconds or 2550 milliseconds */
+	if (*delay_on > 2550)
+		*delay_on = 2550;
+	if (*delay_off > 2550)
+		*delay_off = 2550;
+
+	/* Blink at 1 Hz if both values are zero */
+	if (!*delay_on && !*delay_off)
+		*delay_on = *delay_off = 1000;
+
+	new_on = *delay_on / 10;
+	new_off = *delay_off / 10;
+
+	/* The DualShock 4 has a global blink setting and always uses index 0 */
+	if (drv_data->quirks & DUALSHOCK4_CONTROLLER) {
+		n = 0;
+	} else {
+		for (n = 0; n < drv_data->led_count; n++) {
+			if (led == drv_data->leds[n])
+				break;
+		}
+	}
+
+	/* This LED is not registered on this device */
+	if (n >= drv_data->led_count)
+		return -EINVAL;
+
+	/* Don't schedule work if the values didn't change */
+	if (new_on != drv_data->led_delay_on[n] ||
+		new_off != drv_data->led_delay_off[n]) {
+		drv_data->led_delay_on[n] = new_on;
+		drv_data->led_delay_off[n] = new_off;
+		schedule_work(&drv_data->state_worker);
+	}
+
+	return 0;
+}
+
 static void sony_leds_remove(struct sony_sc *sc)
 {
 	struct led_classdev *led;
@@ -1301,6 +1372,9 @@ static int sony_leds_init(struct sony_sc *sc)
 		led->brightness_get = sony_led_get_brightness;
 		led->brightness_set = sony_led_set_brightness;
 
+		if (!(sc->quirks & BUZZ_CONTROLLER))
+			led->blink_set = sony_led_blink_set;
+
 		sc->leds[n] = led;
 
 		ret = led_classdev_register(&hdev->dev, led);
@@ -1325,6 +1399,7 @@ error_leds:
 static void sixaxis_state_worker(struct work_struct *work)
 {
 	struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
+	int n;
 	union sixaxis_output_report_01 report = {
 		.buf = {
 			0x01,
@@ -1348,6 +1423,22 @@ static void sixaxis_state_worker(struct work_struct *work)
 	report.data.leds_bitmap |= sc->led_state[2] << 3;
 	report.data.leds_bitmap |= sc->led_state[3] << 4;
 
+	/*
+	 * The LEDs in the report are indexed in reverse order to their
+	 * corresponding light on the controller.
+	 * Index 0 = LED 4, index 1 = LED 3, etc...
+	 *
+	 * In the case of both delay values being zero (blinking disabled) the
+	 * default report values should be used or the controller LED will be
+	 * always off.
+	 */
+	for (n = 0; n < 4; n++) {
+		if (sc->led_delay_on[n] || sc->led_delay_off[n]) {
+			report.data.led[3 - n].duty_off = sc->led_delay_off[n];
+			report.data.led[3 - n].duty_on = sc->led_delay_on[n];
+		}
+	}
+
 	hid_hw_raw_request(sc->hdev, report.data.report_id, report.buf,
 			sizeof(report), HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
 }
@@ -1362,7 +1453,7 @@ static void dualshock4_state_worker(struct work_struct *work)
 
 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
 		buf[0] = 0x05;
-		buf[1] = 0x03;
+		buf[1] = 0xFF;
 		offset = 4;
 	} else {
 		buf[0] = 0x11;
@@ -1382,6 +1473,10 @@ static void dualshock4_state_worker(struct work_struct *work)
 	buf[offset++] = sc->led_state[1];
 	buf[offset++] = sc->led_state[2];
 
+	/* If both delay values are zero the DualShock 4 disables blinking. */
+	buf[offset++] = sc->led_delay_on[0];
+	buf[offset++] = sc->led_delay_off[0];
+
 	if (sc->quirks & DUALSHOCK4_CONTROLLER_USB)
 		hid_hw_output_report(hdev, buf, 32);
 	else
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH v4 6/7] HID: sony: Initialize the controller LEDs with a device ID value
From: Frank Praznik @ 2014-04-02 16:31 UTC (permalink / raw)
  To: linux-input; +Cc: jkosina, Frank Praznik
In-Reply-To: <1396456285-23755-1-git-send-email-frank.praznik@oh.rr.com>

Add an IDA id allocator to assign unique, sequential device ids to Sixaxis and
DualShock 4 controllers.

Use the device ID to initialize the Sixaxis and DualShock 4 controller LEDs to
default values.  The number or color of the controller is set relative to other
connected Sony controllers.

Set the LED class brightness values to the initial values and add the new led to
the array before calling led_classdev_register so that the correct brightness
value shows up in the LED sysfs entry.

Use explicit module init and exit functions since the IDA allocator must be
manually destroyed when the module is unloaded.

Signed-off-by: Frank Praznik <frank.praznik@oh.rr.com>
---

 drivers/hid/hid-sony.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 114 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c709161..f26f8fa 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -33,6 +33,7 @@
 #include <linux/power_supply.h>
 #include <linux/spinlock.h>
 #include <linux/list.h>
+#include <linux/idr.h>
 #include <linux/input/mt.h>
 
 #include "hid-ids.h"
@@ -749,6 +750,7 @@ union sixaxis_output_report_01 {
 
 static spinlock_t sony_dev_list_lock;
 static LIST_HEAD(sony_device_list);
+static DEFINE_IDA(sony_device_id_allocator);
 
 struct sony_sc {
 	spinlock_t lock;
@@ -758,6 +760,7 @@ struct sony_sc {
 	unsigned long quirks;
 	struct work_struct state_worker;
 	struct power_supply battery;
+	int device_id;
 
 #ifdef CONFIG_SONY_FF
 	__u8 left;
@@ -1078,6 +1081,52 @@ static int dualshock4_set_operational_bt(struct hid_device *hdev)
 				HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
 }
 
+static void sixaxis_set_leds_from_id(int id, __u8 values[MAX_LEDS])
+{
+	static const __u8 sixaxis_leds[10][4] = {
+				{ 0x01, 0x00, 0x00, 0x00 },
+				{ 0x00, 0x01, 0x00, 0x00 },
+				{ 0x00, 0x00, 0x01, 0x00 },
+				{ 0x00, 0x00, 0x00, 0x01 },
+				{ 0x01, 0x00, 0x00, 0x01 },
+				{ 0x00, 0x01, 0x00, 0x01 },
+				{ 0x00, 0x00, 0x01, 0x01 },
+				{ 0x01, 0x00, 0x01, 0x01 },
+				{ 0x00, 0x01, 0x01, 0x01 },
+				{ 0x01, 0x01, 0x01, 0x01 }
+	};
+
+	BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0]));
+
+	if (id < 0)
+		return;
+
+	id %= 10;
+	memcpy(values, sixaxis_leds[id], sizeof(sixaxis_leds[id]));
+}
+
+static void dualshock4_set_leds_from_id(int id, __u8 values[MAX_LEDS])
+{
+	/* The first 4 color/index entries match what the PS4 assigns */
+	static const __u8 color_code[7][3] = {
+			/* Blue   */	{ 0x00, 0x00, 0x01 },
+			/* Red	  */	{ 0x01, 0x00, 0x00 },
+			/* Green  */	{ 0x00, 0x01, 0x00 },
+			/* Pink   */	{ 0x02, 0x00, 0x01 },
+			/* Orange */	{ 0x02, 0x01, 0x00 },
+			/* Teal   */	{ 0x00, 0x01, 0x01 },
+			/* White  */	{ 0x01, 0x01, 0x01 }
+	};
+
+	BUG_ON(MAX_LEDS < ARRAY_SIZE(color_code[0]));
+
+	if (id < 0)
+		return;
+
+	id %= 7;
+	memcpy(values, color_code[id], sizeof(color_code[id]));
+}
+
 static void buzz_set_leds(struct hid_device *hdev, const __u8 *leds)
 {
 	struct list_head *report_list =
@@ -1191,7 +1240,7 @@ static int sony_leds_init(struct sony_sc *sc)
 	size_t name_len;
 	const char *name_fmt;
 	static const char * const color_str[] = { "red", "green", "blue" };
-	static const __u8 initial_values[MAX_LEDS] = { 0x00, 0x00, 0x00, 0x00 };
+	__u8 initial_values[MAX_LEDS] = { 0 };
 
 	BUG_ON(!(sc->quirks & SONY_LED_SUPPORT));
 
@@ -1205,12 +1254,14 @@ static int sony_leds_init(struct sony_sc *sc)
 		if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 0, 0, 7))
 			return -ENODEV;
 	} else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
+		dualshock4_set_leds_from_id(sc->device_id, initial_values);
 		sc->led_count = 3;
 		max_brightness = 255;
 		use_colors = 1;
 		name_len = 0;
 		name_fmt = "%s:%s";
 	} else {
+		sixaxis_set_leds_from_id(sc->device_id, initial_values);
 		sc->led_count = 4;
 		max_brightness = 1;
 		use_colors = 0;
@@ -1245,14 +1296,17 @@ static int sony_leds_init(struct sony_sc *sc)
 		else
 			snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1);
 		led->name = name;
-		led->brightness = 0;
+		led->brightness = initial_values[n];
 		led->max_brightness = max_brightness;
 		led->brightness_get = sony_led_get_brightness;
 		led->brightness_set = sony_led_set_brightness;
 
+		sc->leds[n] = led;
+
 		ret = led_classdev_register(&hdev->dev, led);
 		if (ret) {
 			hid_err(hdev, "Failed to register LED %d\n", n);
+			sc->leds[n] = NULL;
 			kfree(led);
 			goto error_leds;
 		}
@@ -1603,6 +1657,38 @@ static int sony_check_add(struct sony_sc *sc)
 	return sony_check_add_dev_list(sc);
 }
 
+static int sony_set_device_id(struct sony_sc *sc)
+{
+	int ret;
+
+	/*
+	 * Only DualShock 4 or Sixaxis controllers get an id.
+	 * All others are set to -1.
+	 */
+	if ((sc->quirks & SIXAXIS_CONTROLLER) ||
+	    (sc->quirks & DUALSHOCK4_CONTROLLER)) {
+		ret = ida_simple_get(&sony_device_id_allocator, 0, 0,
+					GFP_KERNEL);
+		if (ret < 0) {
+			sc->device_id = -1;
+			return ret;
+		}
+		sc->device_id = ret;
+	} else {
+		sc->device_id = -1;
+	}
+
+	return 0;
+}
+
+static void sony_release_device_id(struct sony_sc *sc)
+{
+	if (sc->device_id >= 0) {
+		ida_simple_remove(&sony_device_id_allocator, sc->device_id);
+		sc->device_id = -1;
+	}
+}
+
 static inline void sony_init_work(struct sony_sc *sc,
 					void(*worker)(struct work_struct *))
 {
@@ -1654,6 +1740,12 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		return ret;
 	}
 
+	ret = sony_set_device_id(sc);
+	if (ret < 0) {
+		hid_err(hdev, "failed to allocate the device id\n");
+		goto err_stop;
+	}
+
 	if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
 		/*
 		 * The Sony Sixaxis does not handle HID Output Reports on the
@@ -1745,6 +1837,7 @@ err_stop:
 		sony_battery_remove(sc);
 	sony_cancel_work_sync(sc);
 	sony_remove_dev_list(sc);
+	sony_release_device_id(sc);
 	hid_hw_stop(hdev);
 	return ret;
 }
@@ -1765,6 +1858,8 @@ static void sony_remove(struct hid_device *hdev)
 
 	sony_remove_dev_list(sc);
 
+	sony_release_device_id(sc);
+
 	hid_hw_stop(hdev);
 }
 
@@ -1809,6 +1904,22 @@ static struct hid_driver sony_driver = {
 	.report_fixup  = sony_report_fixup,
 	.raw_event     = sony_raw_event
 };
-module_hid_driver(sony_driver);
+
+static int __init sony_init(void)
+{
+	dbg_hid("Sony:%s\n", __func__);
+
+	return hid_register_driver(&sony_driver);
+}
+
+static void __exit sony_exit(void)
+{
+	dbg_hid("Sony:%s\n", __func__);
+
+	ida_destroy(&sony_device_id_allocator);
+	hid_unregister_driver(&sony_driver);
+}
+module_init(sony_init);
+module_exit(sony_exit);
 
 MODULE_LICENSE("GPL");
-- 
1.8.3.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox