HID: wiimote: Add write-register helpers
authorDavid Herrmann <dh.herrmann@googlemail.com>
Tue, 6 Sep 2011 11:50:35 +0000 (13:50 +0200)
committerJiri Kosina <jkosina@suse.cz>
Wed, 7 Sep 2011 11:25:17 +0000 (13:25 +0200)
Add helpers to synchronously write registers of the wiimote. This is heavily
used by initialization functions for wiimote peripherals.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/hid-wiimote.c

index 0a5e458820b2e2656d0285882a94fbb233fede60..59a08933c73c08e712165c104283b3aab12f6db1 100644 (file)
@@ -39,6 +39,9 @@ struct wiimote_state {
        struct completion ready;
        int cmd;
        __u32 opt;
+
+       /* results of synchronous requests */
+       __u8 cmd_err;
 };
 
 struct wiimote_data {
@@ -394,6 +397,25 @@ static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
        wiimote_queue(wdata, cmd, sizeof(cmd));
 }
 
+/* requries the cmd-mutex to be held */
+static int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
+                                               const __u8 *wmem, __u8 size)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&wdata->state.lock, flags);
+       wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0);
+       wiiproto_req_wreg(wdata, offset, wmem, size);
+       spin_unlock_irqrestore(&wdata->state.lock, flags);
+
+       ret = wiimote_cmd_wait(wdata);
+       if (!ret && wdata->state.cmd_err)
+               ret = -EIO;
+
+       return ret;
+}
+
 static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
 {
        struct wiimote_data *wdata;
@@ -635,9 +657,13 @@ static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
 
        handler_keys(wdata, payload);
 
-       if (err)
+       if (wiimote_cmd_pending(wdata, cmd, 0)) {
+               wdata->state.cmd_err = err;
+               wiimote_cmd_complete(wdata);
+       } else if (err) {
                hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
                                                                        cmd);
+       }
 }
 
 static void handler_drm_KA(struct wiimote_data *wdata, const __u8 *payload)