aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-05-05 17:12:53 -0400
committerJiri Kosina <jkosina@suse.cz>2013-06-03 05:07:01 -0400
commitdcf392313817efb4f318ebbf21f607dbdaf5ea56 (patch)
treeedf299dd868642038d52714ddcd553b532f2511d /drivers
parent20cef813b4791ba55b2f3c4258414b6ded21e8ff (diff)
HID: wiimote: convert BATTERY to module
This introduces a new sub-device module for the BATTERY handlers. It moves the whole power_supply battery handling over to wiimote-modules. This doesn't change any semantics or ABI but only converts the battery handling into a sub-device module. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/hid-wiimote-core.c80
-rw-r--r--drivers/hid/hid-wiimote-modules.c98
-rw-r--r--drivers/hid/hid-wiimote.h2
3 files changed, 104 insertions, 76 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 6ada22606707..bb1b3e3f4550 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -17,16 +17,10 @@
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>
21#include <linux/spinlock.h> 20#include <linux/spinlock.h>
22#include "hid-ids.h" 21#include "hid-ids.h"
23#include "hid-wiimote.h" 22#include "hid-wiimote.h"
24 23
25static enum power_supply_property wiimote_battery_props[] = {
26 POWER_SUPPLY_PROP_CAPACITY,
27 POWER_SUPPLY_PROP_SCOPE,
28};
29
30/* output queue handling */ 24/* output queue handling */
31 25
32static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, 26static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
@@ -232,7 +226,7 @@ void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
232 wiimote_queue(wdata, cmd, sizeof(cmd)); 226 wiimote_queue(wdata, cmd, sizeof(cmd));
233} 227}
234 228
235static void wiiproto_req_status(struct wiimote_data *wdata) 229void wiiproto_req_status(struct wiimote_data *wdata)
236{ 230{
237 __u8 cmd[2]; 231 __u8 cmd[2];
238 232
@@ -423,48 +417,6 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata)
423 return WIIMOTE_EXT_UNKNOWN; 417 return WIIMOTE_EXT_UNKNOWN;
424} 418}
425 419
426static int wiimote_battery_get_property(struct power_supply *psy,
427 enum power_supply_property psp,
428 union power_supply_propval *val)
429{
430 struct wiimote_data *wdata = container_of(psy,
431 struct wiimote_data, battery);
432 int ret = 0, state;
433 unsigned long flags;
434
435 if (psp == POWER_SUPPLY_PROP_SCOPE) {
436 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
437 return 0;
438 }
439
440 ret = wiimote_cmd_acquire(wdata);
441 if (ret)
442 return ret;
443
444 spin_lock_irqsave(&wdata->state.lock, flags);
445 wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
446 wiiproto_req_status(wdata);
447 spin_unlock_irqrestore(&wdata->state.lock, flags);
448
449 wiimote_cmd_wait(wdata);
450 wiimote_cmd_release(wdata);
451
452 spin_lock_irqsave(&wdata->state.lock, flags);
453 state = wdata->state.cmd_battery;
454 spin_unlock_irqrestore(&wdata->state.lock, flags);
455
456 switch (psp) {
457 case POWER_SUPPLY_PROP_CAPACITY:
458 val->intval = state * 100 / 255;
459 break;
460 default:
461 ret = -EINVAL;
462 break;
463 }
464
465 return ret;
466}
467
468static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode) 420static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode)
469{ 421{
470 int ret; 422 int ret;
@@ -673,16 +625,19 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
673 [WIIMOTE_DEV_GENERIC] = (const __u8[]){ 625 [WIIMOTE_DEV_GENERIC] = (const __u8[]){
674 WIIMOD_KEYS, 626 WIIMOD_KEYS,
675 WIIMOD_RUMBLE, 627 WIIMOD_RUMBLE,
628 WIIMOD_BATTERY,
676 WIIMOD_NULL, 629 WIIMOD_NULL,
677 }, 630 },
678 [WIIMOTE_DEV_GEN10] = (const __u8[]){ 631 [WIIMOTE_DEV_GEN10] = (const __u8[]){
679 WIIMOD_KEYS, 632 WIIMOD_KEYS,
680 WIIMOD_RUMBLE, 633 WIIMOD_RUMBLE,
634 WIIMOD_BATTERY,
681 WIIMOD_NULL, 635 WIIMOD_NULL,
682 }, 636 },
683 [WIIMOTE_DEV_GEN20] = (const __u8[]){ 637 [WIIMOTE_DEV_GEN20] = (const __u8[]){
684 WIIMOD_KEYS, 638 WIIMOD_KEYS,
685 WIIMOD_RUMBLE, 639 WIIMOD_RUMBLE,
640 WIIMOD_BATTERY,
686 WIIMOD_NULL, 641 WIIMOD_NULL,
687 }, 642 },
688}; 643};
@@ -1349,8 +1304,6 @@ static void wiimote_destroy(struct wiimote_data *wdata)
1349 1304
1350 cancel_work_sync(&wdata->init_worker); 1305 cancel_work_sync(&wdata->init_worker);
1351 wiimote_modules_unload(wdata); 1306 wiimote_modules_unload(wdata);
1352 power_supply_unregister(&wdata->battery);
1353 kfree(wdata->battery.name);
1354 input_unregister_device(wdata->accel); 1307 input_unregister_device(wdata->accel);
1355 input_unregister_device(wdata->ir); 1308 input_unregister_device(wdata->ir);
1356 cancel_work_sync(&wdata->queue.worker); 1309 cancel_work_sync(&wdata->queue.worker);
@@ -1404,26 +1357,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
1404 goto err_ir; 1357 goto err_ir;
1405 } 1358 }
1406 1359
1407 wdata->battery.properties = wiimote_battery_props;
1408 wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props);
1409 wdata->battery.get_property = wiimote_battery_get_property;
1410 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
1411 wdata->battery.use_for_apm = 0;
1412 wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s",
1413 wdata->hdev->uniq);
1414 if (!wdata->battery.name) {
1415 ret = -ENOMEM;
1416 goto err_battery_name;
1417 }
1418
1419 ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
1420 if (ret) {
1421 hid_err(hdev, "Cannot register battery device\n");
1422 goto err_battery;
1423 }
1424
1425 power_supply_powers(&wdata->battery, &hdev->dev);
1426
1427 ret = wiimote_leds_create(wdata); 1360 ret = wiimote_leds_create(wdata);
1428 if (ret) 1361 if (ret)
1429 goto err_free; 1362 goto err_free;
@@ -1452,11 +1385,6 @@ err_free:
1452 wiimote_destroy(wdata); 1385 wiimote_destroy(wdata);
1453 return ret; 1386 return ret;
1454 1387
1455err_battery:
1456 kfree(wdata->battery.name);
1457err_battery_name:
1458 input_unregister_device(wdata->ir);
1459 wdata->ir = NULL;
1460err_ir: 1388err_ir:
1461 input_unregister_device(wdata->accel); 1389 input_unregister_device(wdata->accel);
1462 wdata->accel = NULL; 1390 wdata->accel = NULL;
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 616f24024f77..4cbbbe651ba5 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -171,9 +171,107 @@ static const struct wiimod_ops wiimod_rumble = {
171 .remove = wiimod_rumble_remove, 171 .remove = wiimod_rumble_remove,
172}; 172};
173 173
174/*
175 * Battery
176 * 1 byte of battery capacity information is sent along every protocol status
177 * report. The wiimote core caches it but we try to update it on every
178 * user-space request.
179 * This is supported by nearly every device so it's almost always enabled.
180 */
181
182static enum power_supply_property wiimod_battery_props[] = {
183 POWER_SUPPLY_PROP_CAPACITY,
184 POWER_SUPPLY_PROP_SCOPE,
185};
186
187static int wiimod_battery_get_property(struct power_supply *psy,
188 enum power_supply_property psp,
189 union power_supply_propval *val)
190{
191 struct wiimote_data *wdata = container_of(psy, struct wiimote_data,
192 battery);
193 int ret = 0, state;
194 unsigned long flags;
195
196 if (psp == POWER_SUPPLY_PROP_SCOPE) {
197 val->intval = POWER_SUPPLY_SCOPE_DEVICE;
198 return 0;
199 } else if (psp != POWER_SUPPLY_PROP_CAPACITY) {
200 return -EINVAL;
201 }
202
203 ret = wiimote_cmd_acquire(wdata);
204 if (ret)
205 return ret;
206
207 spin_lock_irqsave(&wdata->state.lock, flags);
208 wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0);
209 wiiproto_req_status(wdata);
210 spin_unlock_irqrestore(&wdata->state.lock, flags);
211
212 wiimote_cmd_wait(wdata);
213 wiimote_cmd_release(wdata);
214
215 spin_lock_irqsave(&wdata->state.lock, flags);
216 state = wdata->state.cmd_battery;
217 spin_unlock_irqrestore(&wdata->state.lock, flags);
218
219 val->intval = state * 100 / 255;
220 return ret;
221}
222
223static int wiimod_battery_probe(const struct wiimod_ops *ops,
224 struct wiimote_data *wdata)
225{
226 int ret;
227
228 wdata->battery.properties = wiimod_battery_props;
229 wdata->battery.num_properties = ARRAY_SIZE(wiimod_battery_props);
230 wdata->battery.get_property = wiimod_battery_get_property;
231 wdata->battery.type = POWER_SUPPLY_TYPE_BATTERY;
232 wdata->battery.use_for_apm = 0;
233 wdata->battery.name = kasprintf(GFP_KERNEL, "wiimote_battery_%s",
234 wdata->hdev->uniq);
235 if (!wdata->battery.name)
236 return -ENOMEM;
237
238 ret = power_supply_register(&wdata->hdev->dev, &wdata->battery);
239 if (ret) {
240 hid_err(wdata->hdev, "cannot register battery device\n");
241 goto err_free;
242 }
243
244 power_supply_powers(&wdata->battery, &wdata->hdev->dev);
245 return 0;
246
247err_free:
248 kfree(wdata->battery.name);
249 wdata->battery.name = NULL;
250 return ret;
251}
252
253static void wiimod_battery_remove(const struct wiimod_ops *ops,
254 struct wiimote_data *wdata)
255{
256 if (!wdata->battery.name)
257 return;
258
259 power_supply_unregister(&wdata->battery);
260 kfree(wdata->battery.name);
261 wdata->battery.name = NULL;
262}
263
264static const struct wiimod_ops wiimod_battery = {
265 .flags = 0,
266 .arg = 0,
267 .probe = wiimod_battery_probe,
268 .remove = wiimod_battery_remove,
269};
270
174/* module table */ 271/* module table */
175 272
176const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { 273const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
177 [WIIMOD_KEYS] = &wiimod_keys, 274 [WIIMOD_KEYS] = &wiimod_keys,
178 [WIIMOD_RUMBLE] = &wiimod_rumble, 275 [WIIMOD_RUMBLE] = &wiimod_rumble,
276 [WIIMOD_BATTERY] = &wiimod_battery,
179}; 277};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 93c48fbef7a5..4151514fcd2e 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -128,6 +128,7 @@ struct wiimote_data {
128enum wiimod_module { 128enum wiimod_module {
129 WIIMOD_KEYS, 129 WIIMOD_KEYS,
130 WIIMOD_RUMBLE, 130 WIIMOD_RUMBLE,
131 WIIMOD_BATTERY,
131 WIIMOD_NUM, 132 WIIMOD_NUM,
132 WIIMOD_NULL = WIIMOD_NUM, 133 WIIMOD_NULL = WIIMOD_NUM,
133}; 134};
@@ -184,6 +185,7 @@ enum wiiproto_reqs {
184 185
185extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); 186extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
186extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble); 187extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble);
188extern void wiiproto_req_status(struct wiimote_data *wdata);
187extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, 189extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
188 const __u8 *wmem, __u8 size); 190 const __u8 *wmem, __u8 size);
189extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, 191extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,