All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 0/5] Wiimote fixes for 3.1
@ 2011-08-17  9:43 David Herrmann
  2011-08-17  9:43 ` [PATCH V2 1/5] HID: wiimote: Simplify synchronization David Herrmann
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

This contains few fixes for the current wiimote driver. Since HID core uses a
semaphore lock now, we can simplify the wiimote synchronization. This also adds
open/close callbacks, although bthid doesn't need that, but it makes the code
more consistent with other drivers.
As discussed on the mailinglist, this also removes the four LED sysfs attributes
in favor of four new led_classdev devices. I hope it is ok to remove an API as
long as 3.1 isn't released, yet.
The last two patches fix a bug that the driver didn't work when an extension was
plugged/unplugged. They simply reset the current DRM so the extension port is
ignored.

I've kept these fixes for 3.1 small. I will resend the other patches for 3.2
as RFC soon.

Cheers
David

David Herrmann (5):
  HID: wiimote: Simplify synchronization
  HID: wiimote: Correctly call HID open/close callbacks
  HID: wiimote: Register led class devices
  HID: wiimote: Add drm request
  HID: wiimote: Add status and return request handlers

 drivers/hid/Kconfig       |    1 +
 drivers/hid/hid-wiimote.c |  277 ++++++++++++++++++++++++++++++---------------
 2 files changed, 184 insertions(+), 94 deletions(-)

-- 
1.7.6


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH V2 1/5] HID: wiimote: Simplify synchronization
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
@ 2011-08-17  9:43 ` David Herrmann
  2011-08-17  9:43 ` [PATCH V2 2/5] HID: wiimote: Correctly call HID open/close callbacks David Herrmann
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

The new locking scheme in HID core allows us to remove a bit of synchronization.
Since the HID layer acts synchronously we simply register input core last and
there are no synchonization issues anymore.
Also register sysfs files after that to simplify the code.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
V2: Fix wiimote_destroy(): first stop worker, then stop hid hardware as
mentioned by Oliver.
Also remove atomic.h header as it is not used anymore.

 drivers/hid/hid-wiimote.c |   78 +++++++++++++++-----------------------------
 1 files changed, 27 insertions(+), 51 deletions(-)

diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index a594383..8a68bf5 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -10,7 +10,6 @@
  * any later version.
  */
 
-#include <linux/atomic.h>
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/input.h>
@@ -33,7 +32,6 @@ struct wiimote_state {
 };
 
 struct wiimote_data {
-	atomic_t ready;
 	struct hid_device *hdev;
 	struct input_dev *input;
 
@@ -200,9 +198,6 @@ static ssize_t wiifs_led_show_##num(struct device *dev,			\
 	unsigned long flags;						\
 	int state;							\
 									\
-	if (!atomic_read(&wdata->ready))				\
-		return -EBUSY;						\
-									\
 	spin_lock_irqsave(&wdata->state.lock, flags);			\
 	state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num);	\
 	spin_unlock_irqrestore(&wdata->state.lock, flags);		\
@@ -217,9 +212,6 @@ static ssize_t wiifs_led_set_##num(struct device *dev,			\
 	unsigned long flags;						\
 	__u8 state;							\
 									\
-	if (!atomic_read(&wdata->ready))				\
-		return -EBUSY;						\
-									\
 	spin_lock_irqsave(&wdata->state.lock, flags);			\
 									\
 	state = wdata->state.flags;					\
@@ -244,13 +236,6 @@ wiifs_led_show_set(4);
 static int wiimote_input_event(struct input_dev *dev, unsigned int type,
 						unsigned int code, int value)
 {
-	struct wiimote_data *wdata = input_get_drvdata(dev);
-
-	if (!atomic_read(&wdata->ready))
-		return -EBUSY;
-	/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
-	smp_rmb();
-
 	return 0;
 }
 
@@ -300,11 +285,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
 	int i;
 	unsigned long flags;
 
-	if (!atomic_read(&wdata->ready))
-		return -EBUSY;
-	/* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
-	smp_rmb();
-
 	if (size < 1)
 		return -EINVAL;
 
@@ -362,6 +342,15 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
 
 static void wiimote_destroy(struct wiimote_data *wdata)
 {
+	device_remove_file(&wdata->hdev->dev, &dev_attr_led1);
+	device_remove_file(&wdata->hdev->dev, &dev_attr_led2);
+	device_remove_file(&wdata->hdev->dev, &dev_attr_led3);
+	device_remove_file(&wdata->hdev->dev, &dev_attr_led4);
+
+	input_unregister_device(wdata->input);
+	cancel_work_sync(&wdata->worker);
+	hid_hw_stop(wdata->hdev);
+
 	kfree(wdata);
 }
 
@@ -377,19 +366,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
 		return -ENOMEM;
 	}
 
-	ret = device_create_file(&hdev->dev, &dev_attr_led1);
-	if (ret)
-		goto err;
-	ret = device_create_file(&hdev->dev, &dev_attr_led2);
-	if (ret)
-		goto err;
-	ret = device_create_file(&hdev->dev, &dev_attr_led3);
-	if (ret)
-		goto err;
-	ret = device_create_file(&hdev->dev, &dev_attr_led4);
-	if (ret)
-		goto err;
-
 	ret = hid_parse(hdev);
 	if (ret) {
 		hid_err(hdev, "HID parse failed\n");
@@ -408,9 +384,19 @@ static int wiimote_hid_probe(struct hid_device *hdev,
 		goto err_stop;
 	}
 
-	/* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
-	smp_wmb();
-	atomic_set(&wdata->ready, 1);
+	ret = device_create_file(&hdev->dev, &dev_attr_led1);
+	if (ret)
+		goto err_free;
+	ret = device_create_file(&hdev->dev, &dev_attr_led2);
+	if (ret)
+		goto err_free;
+	ret = device_create_file(&hdev->dev, &dev_attr_led3);
+	if (ret)
+		goto err_free;
+	ret = device_create_file(&hdev->dev, &dev_attr_led4);
+	if (ret)
+		goto err_free;
+
 	hid_info(hdev, "New device registered\n");
 
 	/* by default set led1 after device initialization */
@@ -420,15 +406,15 @@ static int wiimote_hid_probe(struct hid_device *hdev,
 
 	return 0;
 
+err_free:
+	wiimote_destroy(wdata);
+	return ret;
+
 err_stop:
 	hid_hw_stop(hdev);
 err:
 	input_free_device(wdata->input);
-	device_remove_file(&hdev->dev, &dev_attr_led1);
-	device_remove_file(&hdev->dev, &dev_attr_led2);
-	device_remove_file(&hdev->dev, &dev_attr_led3);
-	device_remove_file(&hdev->dev, &dev_attr_led4);
-	wiimote_destroy(wdata);
+	kfree(wdata);
 	return ret;
 }
 
@@ -437,16 +423,6 @@ static void wiimote_hid_remove(struct hid_device *hdev)
 	struct wiimote_data *wdata = hid_get_drvdata(hdev);
 
 	hid_info(hdev, "Device removed\n");
-
-	device_remove_file(&hdev->dev, &dev_attr_led1);
-	device_remove_file(&hdev->dev, &dev_attr_led2);
-	device_remove_file(&hdev->dev, &dev_attr_led3);
-	device_remove_file(&hdev->dev, &dev_attr_led4);
-
-	hid_hw_stop(hdev);
-	input_unregister_device(wdata->input);
-
-	cancel_work_sync(&wdata->worker);
 	wiimote_destroy(wdata);
 }
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V2 2/5] HID: wiimote: Correctly call HID open/close callbacks
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
  2011-08-17  9:43 ` [PATCH V2 1/5] HID: wiimote: Simplify synchronization David Herrmann
@ 2011-08-17  9:43 ` David Herrmann
  2011-08-17  9:43 ` [PATCH V2 3/5] HID: wiimote: Register led class devices David Herrmann
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

Even though the bluetooth hid backend does not react on open/close callbacks, we
should call them to be consistent with other hid drivers.

Also the new input open/close handlers will be used in future to prepare the
wiimote device for IR/extension input.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/hid/hid-wiimote.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 8a68bf5..d49f67c 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -239,6 +239,20 @@ static int wiimote_input_event(struct input_dev *dev, unsigned int type,
 	return 0;
 }
 
+static int wiimote_input_open(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+
+	return hid_hw_open(wdata->hdev);
+}
+
+static void wiimote_input_close(struct input_dev *dev)
+{
+	struct wiimote_data *wdata = input_get_drvdata(dev);
+
+	hid_hw_close(wdata->hdev);
+}
+
 static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
 {
 	input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT],
@@ -321,6 +335,8 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
 
 	input_set_drvdata(wdata->input, wdata);
 	wdata->input->event = wiimote_input_event;
+	wdata->input->open = wiimote_input_open;
+	wdata->input->close = wiimote_input_close;
 	wdata->input->dev.parent = &wdata->hdev->dev;
 	wdata->input->id.bustype = wdata->hdev->bus;
 	wdata->input->id.vendor = wdata->hdev->vendor;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V2 3/5] HID: wiimote: Register led class devices
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
  2011-08-17  9:43 ` [PATCH V2 1/5] HID: wiimote: Simplify synchronization David Herrmann
  2011-08-17  9:43 ` [PATCH V2 2/5] HID: wiimote: Correctly call HID open/close callbacks David Herrmann
@ 2011-08-17  9:43 ` David Herrmann
  2011-08-17  9:43 ` [PATCH V2 4/5] HID: wiimote: Add drm request David Herrmann
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

This registers 4 led devices to allow controlling the wiimote leds via standard
LED sysfs API. It removes the four sysfs attributes so we don't have two APIs
for one device.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
V2: Remove the four led sysfs attributes in favor of the led class devices.

 drivers/hid/Kconfig       |    1 +
 drivers/hid/hid-wiimote.c |  165 +++++++++++++++++++++++++++++----------------
 2 files changed, 107 insertions(+), 59 deletions(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 306b15f..1130a89 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -589,6 +589,7 @@ config HID_WACOM_POWER_SUPPLY
 config HID_WIIMOTE
 	tristate "Nintendo Wii Remote support"
 	depends on BT_HIDP
+	depends on LEDS_CLASS
 	---help---
 	Support for the Nintendo Wii Remote bluetooth device.
 
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index d49f67c..29edd55 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -13,6 +13,7 @@
 #include <linux/device.h>
 #include <linux/hid.h>
 #include <linux/input.h>
+#include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include "hid-ids.h"
@@ -34,6 +35,7 @@ struct wiimote_state {
 struct wiimote_data {
 	struct hid_device *hdev;
 	struct input_dev *input;
+	struct led_classdev *leds[4];
 
 	spinlock_t qlock;
 	__u8 head;
@@ -51,6 +53,9 @@ struct wiimote_data {
 #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
 					WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
 
+/* return flag for led \num */
+#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
+
 enum wiiproto_reqs {
 	WIIPROTO_REQ_LED = 0x11,
 	WIIPROTO_REQ_DRM_K = 0x30,
@@ -85,9 +90,6 @@ static __u16 wiiproto_keymap[] = {
 	BTN_MODE,	/* WIIPROTO_KEY_HOME */
 };
 
-#define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \
-									dev))
-
 static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
 								size_t count)
 {
@@ -190,48 +192,53 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
-#define wiifs_led_show_set(num)						\
-static ssize_t wiifs_led_show_##num(struct device *dev,			\
-			struct device_attribute *attr, char *buf)	\
-{									\
-	struct wiimote_data *wdata = dev_to_wii(dev);			\
-	unsigned long flags;						\
-	int state;							\
-									\
-	spin_lock_irqsave(&wdata->state.lock, flags);			\
-	state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num);	\
-	spin_unlock_irqrestore(&wdata->state.lock, flags);		\
-									\
-	return sprintf(buf, "%d\n", state);				\
-}									\
-static ssize_t wiifs_led_set_##num(struct device *dev,			\
-	struct device_attribute *attr, const char *buf, size_t count)	\
-{									\
-	struct wiimote_data *wdata = dev_to_wii(dev);			\
-	int tmp = simple_strtoul(buf, NULL, 10);			\
-	unsigned long flags;						\
-	__u8 state;							\
-									\
-	spin_lock_irqsave(&wdata->state.lock, flags);			\
-									\
-	state = wdata->state.flags;					\
-									\
-	if (tmp)							\
-		wiiproto_req_leds(wdata, state | WIIPROTO_FLAG_LED##num);\
-	else								\
-		wiiproto_req_leds(wdata, state & ~WIIPROTO_FLAG_LED##num);\
-									\
-	spin_unlock_irqrestore(&wdata->state.lock, flags);		\
-									\
-	return count;							\
-}									\
-static DEVICE_ATTR(led##num, S_IRUGO | S_IWUSR, wiifs_led_show_##num,	\
-						wiifs_led_set_##num)
-
-wiifs_led_show_set(1);
-wiifs_led_show_set(2);
-wiifs_led_show_set(3);
-wiifs_led_show_set(4);
+static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
+{
+	struct wiimote_data *wdata;
+	struct device *dev = led_dev->dev->parent;
+	int i;
+	unsigned long flags;
+	bool value = false;
+
+	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+
+	for (i = 0; i < 4; ++i) {
+		if (wdata->leds[i] == led_dev) {
+			spin_lock_irqsave(&wdata->state.lock, flags);
+			value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
+			spin_unlock_irqrestore(&wdata->state.lock, flags);
+			break;
+		}
+	}
+
+	return value ? LED_FULL : LED_OFF;
+}
+
+static void wiimote_leds_set(struct led_classdev *led_dev,
+						enum led_brightness value)
+{
+	struct wiimote_data *wdata;
+	struct device *dev = led_dev->dev->parent;
+	int i;
+	unsigned long flags;
+	__u8 state, flag;
+
+	wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
+
+	for (i = 0; i < 4; ++i) {
+		if (wdata->leds[i] == led_dev) {
+			flag = WIIPROTO_FLAG_LED(i + 1);
+			spin_lock_irqsave(&wdata->state.lock, flags);
+			state = wdata->state.flags;
+			if (value == LED_OFF)
+				wiiproto_req_leds(wdata, state & ~flag);
+			else
+				wiiproto_req_leds(wdata, state | flag);
+			spin_unlock_irqrestore(&wdata->state.lock, flags);
+			break;
+		}
+	}
+}
 
 static int wiimote_input_event(struct input_dev *dev, unsigned int type,
 						unsigned int code, int value)
@@ -315,6 +322,58 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
 	return 0;
 }
 
+static void wiimote_leds_destroy(struct wiimote_data *wdata)
+{
+	int i;
+	struct led_classdev *led;
+
+	for (i = 0; i < 4; ++i) {
+		if (wdata->leds[i]) {
+			led = wdata->leds[i];
+			wdata->leds[i] = NULL;
+			led_classdev_unregister(led);
+			kfree(led);
+		}
+	}
+}
+
+static int wiimote_leds_create(struct wiimote_data *wdata)
+{
+	int i, ret;
+	struct device *dev = &wdata->hdev->dev;
+	size_t namesz = strlen(dev_name(dev)) + 9;
+	struct led_classdev *led;
+	char *name;
+
+	for (i = 0; i < 4; ++i) {
+		led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
+		if (!led) {
+			ret = -ENOMEM;
+			goto err;
+		}
+		name = (void*)&led[1];
+		snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
+		led->name = name;
+		led->brightness = 0;
+		led->max_brightness = 1;
+		led->brightness_get = wiimote_leds_get;
+		led->brightness_set = wiimote_leds_set;
+
+		ret = led_classdev_register(dev, led);
+		if (ret) {
+			kfree(led);
+			goto err;
+		}
+		wdata->leds[i] = led;
+	}
+
+	return 0;
+
+err:
+	wiimote_leds_destroy(wdata);
+	return ret;
+}
+
 static struct wiimote_data *wiimote_create(struct hid_device *hdev)
 {
 	struct wiimote_data *wdata;
@@ -358,10 +417,7 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
 
 static void wiimote_destroy(struct wiimote_data *wdata)
 {
-	device_remove_file(&wdata->hdev->dev, &dev_attr_led1);
-	device_remove_file(&wdata->hdev->dev, &dev_attr_led2);
-	device_remove_file(&wdata->hdev->dev, &dev_attr_led3);
-	device_remove_file(&wdata->hdev->dev, &dev_attr_led4);
+	wiimote_leds_destroy(wdata);
 
 	input_unregister_device(wdata->input);
 	cancel_work_sync(&wdata->worker);
@@ -400,16 +456,7 @@ static int wiimote_hid_probe(struct hid_device *hdev,
 		goto err_stop;
 	}
 
-	ret = device_create_file(&hdev->dev, &dev_attr_led1);
-	if (ret)
-		goto err_free;
-	ret = device_create_file(&hdev->dev, &dev_attr_led2);
-	if (ret)
-		goto err_free;
-	ret = device_create_file(&hdev->dev, &dev_attr_led3);
-	if (ret)
-		goto err_free;
-	ret = device_create_file(&hdev->dev, &dev_attr_led4);
+	ret = wiimote_leds_create(wdata);
 	if (ret)
 		goto err_free;
 
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V2 4/5] HID: wiimote: Add drm request
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
                   ` (2 preceding siblings ...)
  2011-08-17  9:43 ` [PATCH V2 3/5] HID: wiimote: Register led class devices David Herrmann
@ 2011-08-17  9:43 ` David Herrmann
  2011-08-17  9:43 ` [PATCH V2 5/5] HID: wiimote: Add status and return request handlers David Herrmann
  2011-08-23  8:58 ` [PATCH V2 0/5] Wiimote fixes for 3.1 Jiri Kosina
  5 siblings, 0 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

The wiimote reports data in several data reporting modes (DRM). The DRM
request makes the wiimote send data in the requested drm.

The DRM mode can be set explicitely or can be chosen by the driver. To let
the driver choose the DRM mode, pass WIIPROTO_REQ_NULL placeholder to it. This
is no valid request and is replaced with an appropriate DRM.

Currently, the driver always sets the basic DRM_K mode, but this will be
extended when further peripherals like accelerometer and IR are supported.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/hid/hid-wiimote.c |   26 ++++++++++++++++++++++++++
 1 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 29edd55..84c9eb9 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -57,7 +57,9 @@ struct wiimote_data {
 #define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
 
 enum wiiproto_reqs {
+	WIIPROTO_REQ_NULL = 0x0,
 	WIIPROTO_REQ_LED = 0x11,
+	WIIPROTO_REQ_DRM = 0x12,
 	WIIPROTO_REQ_DRM_K = 0x30,
 };
 
@@ -192,6 +194,30 @@ static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
 	wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
+/*
+ * Check what peripherals of the wiimote are currently
+ * active and select a proper DRM that supports all of
+ * the requested data inputs.
+ */
+static __u8 select_drm(struct wiimote_data *wdata)
+{
+	return WIIPROTO_REQ_DRM_K;
+}
+
+static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
+{
+	__u8 cmd[3];
+
+	if (drm == WIIPROTO_REQ_NULL)
+		drm = select_drm(wdata);
+
+	cmd[0] = WIIPROTO_REQ_DRM;
+	cmd[1] = 0;
+	cmd[2] = drm;
+
+	wiimote_queue(wdata, cmd, sizeof(cmd));
+}
+
 static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
 {
 	struct wiimote_data *wdata;
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH V2 5/5] HID: wiimote: Add status and return request handlers
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
                   ` (3 preceding siblings ...)
  2011-08-17  9:43 ` [PATCH V2 4/5] HID: wiimote: Add drm request David Herrmann
@ 2011-08-17  9:43 ` David Herrmann
  2011-08-23  8:58 ` [PATCH V2 0/5] Wiimote fixes for 3.1 Jiri Kosina
  5 siblings, 0 replies; 7+ messages in thread
From: David Herrmann @ 2011-08-17  9:43 UTC (permalink / raw)
  To: linux-input; +Cc: oliver, jkosina, padovan, dh.herrmann

The wiimote resets the current drm when an extension is plugged in.
Fortunately, it also sends a status report in this situation so we just
reset the drm on every status report to keep the drm consistent.

Also handle return reports from the wiimote which indicate success and
failure of requests that we've sent.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
---
 drivers/hid/hid-wiimote.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 84c9eb9..85a02e5 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -60,6 +60,8 @@ enum wiiproto_reqs {
 	WIIPROTO_REQ_NULL = 0x0,
 	WIIPROTO_REQ_LED = 0x11,
 	WIIPROTO_REQ_DRM = 0x12,
+	WIIPROTO_REQ_STATUS = 0x20,
+	WIIPROTO_REQ_RETURN = 0x22,
 	WIIPROTO_REQ_DRM_K = 0x30,
 };
 
@@ -313,6 +315,26 @@ static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
 	input_sync(wdata->input);
 }
 
+static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
+{
+	handler_keys(wdata, payload);
+
+	/* on status reports the drm is reset so we need to resend the drm */
+	wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
+}
+
+static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
+{
+	__u8 err = payload[3];
+	__u8 cmd = payload[2];
+
+	handler_keys(wdata, payload);
+
+	if (err)
+		hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
+									cmd);
+}
+
 struct wiiproto_handler {
 	__u8 id;
 	size_t size;
@@ -320,6 +342,8 @@ struct wiiproto_handler {
 };
 
 static struct wiiproto_handler handlers[] = {
+	{ .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
+	{ .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return },
 	{ .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
 	{ .id = 0 }
 };
-- 
1.7.6


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH V2 0/5] Wiimote fixes for 3.1
  2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
                   ` (4 preceding siblings ...)
  2011-08-17  9:43 ` [PATCH V2 5/5] HID: wiimote: Add status and return request handlers David Herrmann
@ 2011-08-23  8:58 ` Jiri Kosina
  5 siblings, 0 replies; 7+ messages in thread
From: Jiri Kosina @ 2011-08-23  8:58 UTC (permalink / raw)
  To: David Herrmann; +Cc: linux-input, oliver, padovan

On Wed, 17 Aug 2011, David Herrmann wrote:

> This contains few fixes for the current wiimote driver. Since HID core uses a
> semaphore lock now, we can simplify the wiimote synchronization. This also adds
> open/close callbacks, although bthid doesn't need that, but it makes the code
> more consistent with other drivers.
> As discussed on the mailinglist, this also removes the four LED sysfs attributes
> in favor of four new led_classdev devices. I hope it is ok to remove an API as
> long as 3.1 isn't released, yet.
> The last two patches fix a bug that the driver didn't work when an extension was
> plugged/unplugged. They simply reset the current DRM so the extension port is
> ignored.
> 
> I've kept these fixes for 3.1 small. I will resend the other patches for 3.2
> as RFC soon.

Thanks. I have now queued the patchset.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-08-23  8:58 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-17  9:43 [PATCH V2 0/5] Wiimote fixes for 3.1 David Herrmann
2011-08-17  9:43 ` [PATCH V2 1/5] HID: wiimote: Simplify synchronization David Herrmann
2011-08-17  9:43 ` [PATCH V2 2/5] HID: wiimote: Correctly call HID open/close callbacks David Herrmann
2011-08-17  9:43 ` [PATCH V2 3/5] HID: wiimote: Register led class devices David Herrmann
2011-08-17  9:43 ` [PATCH V2 4/5] HID: wiimote: Add drm request David Herrmann
2011-08-17  9:43 ` [PATCH V2 5/5] HID: wiimote: Add status and return request handlers David Herrmann
2011-08-23  8:58 ` [PATCH V2 0/5] Wiimote fixes for 3.1 Jiri Kosina

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.