aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-11-17 08:12:00 -0500
committerJiri Kosina <jkosina@suse.cz>2011-11-22 17:08:09 -0500
commitfad8c0e34323eb7789f93750258a2cf02dc6cf69 (patch)
treebb2b0f3b89fa751702dec42681cdb1bf206d0259
parent7e274400629fbf8eab294fef39c3efde463966a9 (diff)
HID: wiimote: Add read-mem helpers
Add helper functions similar to the write-mem helpers but for reading wiimote memory and eeprom. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-wiimote-core.c77
-rw-r--r--drivers/hid/hid-wiimote.h4
2 files changed, 81 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index c955d500c81f..f7f8b7ff7dec 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -312,6 +312,37 @@ static void wiiproto_req_wmem(struct wiimote_data *wdata, bool eeprom,
312 wiimote_queue(wdata, cmd, sizeof(cmd)); 312 wiimote_queue(wdata, cmd, sizeof(cmd));
313} 313}
314 314
315#define wiiproto_req_rreg(wdata, os, sz) \
316 wiiproto_req_rmem((wdata), false, (os), (sz))
317
318#define wiiproto_req_reeprom(wdata, os, sz) \
319 wiiproto_req_rmem((wdata), true, (os), (sz))
320
321static void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom,
322 __u32 offset, __u16 size)
323{
324 __u8 cmd[7];
325
326 if (size == 0) {
327 hid_warn(wdata->hdev, "Invalid length %d rmem request\n", size);
328 return;
329 }
330
331 cmd[0] = WIIPROTO_REQ_RMEM;
332 cmd[1] = 0;
333 cmd[2] = (offset >> 16) & 0xff;
334 cmd[3] = (offset >> 8) & 0xff;
335 cmd[4] = offset & 0xff;
336 cmd[5] = (size >> 8) & 0xff;
337 cmd[6] = size & 0xff;
338
339 if (!eeprom)
340 cmd[1] |= 0x04;
341
342 wiiproto_keep_rumble(wdata, &cmd[1]);
343 wiimote_queue(wdata, cmd, sizeof(cmd));
344}
345
315/* requries the cmd-mutex to be held */ 346/* requries the cmd-mutex to be held */
316int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, 347int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
317 const __u8 *wmem, __u8 size) 348 const __u8 *wmem, __u8 size)
@@ -331,6 +362,36 @@ int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
331 return ret; 362 return ret;
332} 363}
333 364
365/* requries the cmd-mutex to be held */
366ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, __u8 *rmem,
367 __u8 size)
368{
369 unsigned long flags;
370 ssize_t ret;
371
372 spin_lock_irqsave(&wdata->state.lock, flags);
373 wdata->state.cmd_read_size = size;
374 wdata->state.cmd_read_buf = rmem;
375 wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff);
376 wiiproto_req_rreg(wdata, offset, size);
377 spin_unlock_irqrestore(&wdata->state.lock, flags);
378
379 ret = wiimote_cmd_wait(wdata);
380
381 spin_lock_irqsave(&wdata->state.lock, flags);
382 wdata->state.cmd_read_buf = NULL;
383 spin_unlock_irqrestore(&wdata->state.lock, flags);
384
385 if (!ret) {
386 if (wdata->state.cmd_read_size == 0)
387 ret = -EIO;
388 else
389 ret = wdata->state.cmd_read_size;
390 }
391
392 return ret;
393}
394
334static int wiimote_battery_get_property(struct power_supply *psy, 395static int wiimote_battery_get_property(struct power_supply *psy,
335 enum power_supply_property psp, 396 enum power_supply_property psp,
336 union power_supply_propval *val) 397 union power_supply_propval *val)
@@ -742,7 +803,23 @@ static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
742 803
743static void handler_data(struct wiimote_data *wdata, const __u8 *payload) 804static void handler_data(struct wiimote_data *wdata, const __u8 *payload)
744{ 805{
806 __u16 offset = payload[3] << 8 | payload[4];
807 __u8 size = (payload[2] >> 4) + 1;
808 __u8 err = payload[2] & 0x0f;
809
745 handler_keys(wdata, payload); 810 handler_keys(wdata, payload);
811
812 if (wiimote_cmd_pending(wdata, WIIPROTO_REQ_RMEM, offset)) {
813 if (err)
814 size = 0;
815 else if (size > wdata->state.cmd_read_size)
816 size = wdata->state.cmd_read_size;
817
818 wdata->state.cmd_read_size = size;
819 if (wdata->state.cmd_read_buf)
820 memcpy(wdata->state.cmd_read_buf, &payload[5], size);
821 wiimote_cmd_complete(wdata);
822 }
746} 823}
747 824
748static void handler_return(struct wiimote_data *wdata, const __u8 *payload) 825static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index d78f79c08901..865740d3a3fe 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -62,6 +62,8 @@ struct wiimote_state {
62 /* results of synchronous requests */ 62 /* results of synchronous requests */
63 __u8 cmd_battery; 63 __u8 cmd_battery;
64 __u8 cmd_err; 64 __u8 cmd_err;
65 __u8 *cmd_read_buf;
66 __u8 cmd_read_size;
65}; 67};
66 68
67struct wiimote_data { 69struct wiimote_data {
@@ -113,6 +115,8 @@ enum wiiproto_reqs {
113extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); 115extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
114extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, 116extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
115 const __u8 *wmem, __u8 size); 117 const __u8 *wmem, __u8 size);
118extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,
119 __u8 *rmem, __u8 size);
116 120
117/* requires the state.lock spinlock to be held */ 121/* requires the state.lock spinlock to be held */
118static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd, 122static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd,