aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-wiimote.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2011-09-06 07:50:39 -0400
committerJiri Kosina <jkosina@suse.cz>2011-09-07 07:25:18 -0400
commit6591d758d54291fcc5fd560653edef73d50bd978 (patch)
tree1b5df45a7d4b175e2a5706c08aee1efed2e78db3 /drivers/hid/hid-wiimote.c
parente3979a9189d744ffecae1bcd36ae0a8b6d22f65f (diff)
HID: wiimote: Read wiimote battery charge level
This registers a power_supply device for every remote to retrieve the current battery charge level. Since this information is not sent by the wiimote continously, we need to explicitely request it. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-wiimote.c')
-rw-r--r--drivers/hid/hid-wiimote.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
index 48198cb0fed2..c83cafaa46a3 100644
--- a/drivers/hid/hid-wiimote.c
+++ b/drivers/hid/hid-wiimote.c
@@ -17,6 +17,7 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/power_supply.h>
20#include <linux/spinlock.h> 21#include <linux/spinlock.h>
21#include "hid-ids.h" 22#include "hid-ids.h"
22 23
@@ -51,6 +52,7 @@ struct wiimote_data {
51 struct led_classdev *leds[4]; 52 struct led_classdev *leds[4];
52 struct input_dev *accel; 53 struct input_dev *accel;
53 struct input_dev *ir; 54 struct input_dev *ir;
55 struct power_supply battery;
54 56
55 spinlock_t qlock; 57 spinlock_t qlock;
56 __u8 head; 58 __u8 head;
@@ -133,6 +135,10 @@ static __u16 wiiproto_keymap[] = {
133 BTN_MODE, /* WIIPROTO_KEY_HOME */ 135 BTN_MODE, /* WIIPROTO_KEY_HOME */
134}; 136};
135 137
138static enum power_supply_property wiimote_battery_props[] = {
139 POWER_SUPPLY_PROP_CAPACITY
140};
141
136/* requires the state.lock spinlock to be held */ 142/* requires the state.lock spinlock to be held */
137static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd, 143static inline bool wiimote_cmd_pending(struct wiimote_data *wdata, int cmd,
138 __u32 opt) 144 __u32 opt)
@@ -453,6 +459,43 @@ static int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
453 return ret; 459 return ret;
454} 460}
455 461
462static int wiimote_battery_get_property(struct power_supply *psy,
463 enum power_supply_property psp,
464 union power_supply_propval *val)
465{
466 struct wiimote_data *wdata = container_of(psy,
467 struct wiimote_data, battery);
468 int ret = 0, state;
469 unsigned long flags;
470
471 ret = wiimote_cmd_acquire(wdata);
472 if (ret)
473 return ret;
474
475 spin_lock_irqsave(&wdata->state.lock, flags);
476 wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
477 wiiproto_req_status(wdata);
478 spin_unlock_irqrestore(&wdata->state.lock, flags);
479
480 ret = wiimote_cmd_wait(wdata);
481 state = wdata->state.cmd_battery;
482 wiimote_cmd_release(wdata);
483
484 if (ret)
485 return ret;
486
487 switch (psp) {
488 case POWER_SUPPLY_PROP_CAPACITY:
489 val->intval = state * 100 / 255;
490 break;
491 default:
492 ret = -EINVAL;
493 break;
494 }
495
496 return ret;
497}
498
456static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode) 499static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode)
457{ 500{
458 int ret; 501 int ret;
@@ -1155,6 +1198,7 @@ static void wiimote_destroy(struct wiimote_data *wdata)
1155{ 1198{
1156 wiimote_leds_destroy(wdata); 1199 wiimote_leds_destroy(wdata);
1157 1200
1201 power_supply_unregister(&wdata->battery);
1158 input_unregister_device(wdata->accel); 1202 input_unregister_device(wdata->accel);
1159 input_unregister_device(wdata->ir); 1203 input_unregister_device(wdata->ir);
1160 input_unregister_device(wdata->input); 1204 input_unregister_device(wdata->input);
@@ -1206,6 +1250,19 @@ static int wiimote_hid_probe(struct hid_device *hdev,
1206 goto err_input; 1250 goto err_input;
1207 } 1251 }
1208 1252
1253 wdata->battery.properties = wiimote_battery_props;
1254 wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props);
1255 wdata->battery.get_property = wiimote_battery_get_property;
1256 wdata->battery.name = "wiimote_battery";
1257 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1258 wdata->battery.use_for_apm = 0;
1259
1260 ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
1261 if (ret) {
1262 hid_err(hdev, "Cannot register battery device\n");
1263 goto err_battery;
1264 }
1265
1209 ret = wiimote_leds_create(wdata); 1266 ret = wiimote_leds_create(wdata);
1210 if (ret) 1267 if (ret)
1211 goto err_free; 1268 goto err_free;
@@ -1223,6 +1280,9 @@ err_free:
1223 wiimote_destroy(wdata); 1280 wiimote_destroy(wdata);
1224 return ret; 1281 return ret;
1225 1282
1283err_battery:
1284 input_unregister_device(wdata->input);
1285 wdata->input = NULL;
1226err_input: 1286err_input:
1227 input_unregister_device(wdata->ir); 1287 input_unregister_device(wdata->ir);
1228 wdata->ir = NULL; 1288 wdata->ir = NULL;