diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-05-05 17:12:53 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-06-03 05:07:01 -0400 |
commit | dcf392313817efb4f318ebbf21f607dbdaf5ea56 (patch) | |
tree | edf299dd868642038d52714ddcd553b532f2511d /drivers | |
parent | 20cef813b4791ba55b2f3c4258414b6ded21e8ff (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.c | 80 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote-modules.c | 98 | ||||
-rw-r--r-- | drivers/hid/hid-wiimote.h | 2 |
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 | ||
25 | static 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 | ||
32 | static int wiimote_hid_send(struct hid_device *hdev, __u8 *buffer, | 26 | static 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 | ||
235 | static void wiiproto_req_status(struct wiimote_data *wdata) | 229 | void 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 | ||
426 | static 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 | |||
468 | static int wiimote_init_ir(struct wiimote_data *wdata, __u16 mode) | 420 | static 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 | ||
1455 | err_battery: | ||
1456 | kfree(wdata->battery.name); | ||
1457 | err_battery_name: | ||
1458 | input_unregister_device(wdata->ir); | ||
1459 | wdata->ir = NULL; | ||
1460 | err_ir: | 1388 | err_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 | |||
182 | static enum power_supply_property wiimod_battery_props[] = { | ||
183 | POWER_SUPPLY_PROP_CAPACITY, | ||
184 | POWER_SUPPLY_PROP_SCOPE, | ||
185 | }; | ||
186 | |||
187 | static 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 | |||
223 | static 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 | |||
247 | err_free: | ||
248 | kfree(wdata->battery.name); | ||
249 | wdata->battery.name = NULL; | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static 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 | |||
264 | static 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 | ||
176 | const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { | 273 | const 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 { | |||
128 | enum wiimod_module { | 128 | enum 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 | ||
185 | extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); | 186 | extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); |
186 | extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble); | 187 | extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble); |
188 | extern void wiiproto_req_status(struct wiimote_data *wdata); | ||
187 | extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, | 189 | extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, |
188 | const __u8 *wmem, __u8 size); | 190 | const __u8 *wmem, __u8 size); |
189 | extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, | 191 | extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, |