aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-05-05 17:12:54 -0400
committerJiri Kosina <jkosina@suse.cz>2013-06-03 05:07:01 -0400
commit6c5ae01805e2cc1810328b538ccb2376b5f8bd9f (patch)
tree0870bb177a597bb36787d48b4112c587ab2614f9
parentdcf392313817efb4f318ebbf21f607dbdaf5ea56 (diff)
HID: wiimote: convert LEDS to modules
Each of the 4 LEDs may be supported individually by devices. Therefore, we need one module for each device. To avoid code-duplication, we simply pass the LED ID as "arg" argument to the module loading code. This just moves the code over to wiimote-module. The semantics stay the same as before. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-wiimote-core.c125
-rw-r--r--drivers/hid/hid-wiimote-modules.c140
-rw-r--r--drivers/hid/hid-wiimote.h5
3 files changed, 158 insertions, 112 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index bb1b3e3f4550..4f58c7827395 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -14,7 +14,6 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/hid.h> 15#include <linux/hid.h>
16#include <linux/input.h> 16#include <linux/input.h>
17#include <linux/leds.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
20#include <linux/spinlock.h> 19#include <linux/spinlock.h>
@@ -151,7 +150,7 @@ void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
151 wiimote_queue(wdata, cmd, sizeof(cmd)); 150 wiimote_queue(wdata, cmd, sizeof(cmd));
152} 151}
153 152
154static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) 153void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
155{ 154{
156 __u8 cmd[2]; 155 __u8 cmd[2];
157 156
@@ -529,54 +528,6 @@ unlock:
529 return ret; 528 return ret;
530} 529}
531 530
532static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
533{
534 struct wiimote_data *wdata;
535 struct device *dev = led_dev->dev->parent;
536 int i;
537 unsigned long flags;
538 bool value = false;
539
540 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
541
542 for (i = 0; i < 4; ++i) {
543 if (wdata->leds[i] == led_dev) {
544 spin_lock_irqsave(&wdata->state.lock, flags);
545 value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
546 spin_unlock_irqrestore(&wdata->state.lock, flags);
547 break;
548 }
549 }
550
551 return value ? LED_FULL : LED_OFF;
552}
553
554static void wiimote_leds_set(struct led_classdev *led_dev,
555 enum led_brightness value)
556{
557 struct wiimote_data *wdata;
558 struct device *dev = led_dev->dev->parent;
559 int i;
560 unsigned long flags;
561 __u8 state, flag;
562
563 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
564
565 for (i = 0; i < 4; ++i) {
566 if (wdata->leds[i] == led_dev) {
567 flag = WIIPROTO_FLAG_LED(i + 1);
568 spin_lock_irqsave(&wdata->state.lock, flags);
569 state = wdata->state.flags;
570 if (value == LED_OFF)
571 wiiproto_req_leds(wdata, state & ~flag);
572 else
573 wiiproto_req_leds(wdata, state | flag);
574 spin_unlock_irqrestore(&wdata->state.lock, flags);
575 break;
576 }
577 }
578}
579
580static int wiimote_accel_open(struct input_dev *dev) 531static int wiimote_accel_open(struct input_dev *dev)
581{ 532{
582 struct wiimote_data *wdata = input_get_drvdata(dev); 533 struct wiimote_data *wdata = input_get_drvdata(dev);
@@ -626,18 +577,30 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
626 WIIMOD_KEYS, 577 WIIMOD_KEYS,
627 WIIMOD_RUMBLE, 578 WIIMOD_RUMBLE,
628 WIIMOD_BATTERY, 579 WIIMOD_BATTERY,
580 WIIMOD_LED1,
581 WIIMOD_LED2,
582 WIIMOD_LED3,
583 WIIMOD_LED4,
629 WIIMOD_NULL, 584 WIIMOD_NULL,
630 }, 585 },
631 [WIIMOTE_DEV_GEN10] = (const __u8[]){ 586 [WIIMOTE_DEV_GEN10] = (const __u8[]){
632 WIIMOD_KEYS, 587 WIIMOD_KEYS,
633 WIIMOD_RUMBLE, 588 WIIMOD_RUMBLE,
634 WIIMOD_BATTERY, 589 WIIMOD_BATTERY,
590 WIIMOD_LED1,
591 WIIMOD_LED2,
592 WIIMOD_LED3,
593 WIIMOD_LED4,
635 WIIMOD_NULL, 594 WIIMOD_NULL,
636 }, 595 },
637 [WIIMOTE_DEV_GEN20] = (const __u8[]){ 596 [WIIMOTE_DEV_GEN20] = (const __u8[]){
638 WIIMOD_KEYS, 597 WIIMOD_KEYS,
639 WIIMOD_RUMBLE, 598 WIIMOD_RUMBLE,
640 WIIMOD_BATTERY, 599 WIIMOD_BATTERY,
600 WIIMOD_LED1,
601 WIIMOD_LED2,
602 WIIMOD_LED3,
603 WIIMOD_LED4,
641 WIIMOD_NULL, 604 WIIMOD_NULL,
642 }, 605 },
643}; 606};
@@ -1159,58 +1122,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
1159 return 0; 1122 return 0;
1160} 1123}
1161 1124
1162static void wiimote_leds_destroy(struct wiimote_data *wdata)
1163{
1164 int i;
1165 struct led_classdev *led;
1166
1167 for (i = 0; i < 4; ++i) {
1168 if (wdata->leds[i]) {
1169 led = wdata->leds[i];
1170 wdata->leds[i] = NULL;
1171 led_classdev_unregister(led);
1172 kfree(led);
1173 }
1174 }
1175}
1176
1177static int wiimote_leds_create(struct wiimote_data *wdata)
1178{
1179 int i, ret;
1180 struct device *dev = &wdata->hdev->dev;
1181 size_t namesz = strlen(dev_name(dev)) + 9;
1182 struct led_classdev *led;
1183 char *name;
1184
1185 for (i = 0; i < 4; ++i) {
1186 led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
1187 if (!led) {
1188 ret = -ENOMEM;
1189 goto err;
1190 }
1191 name = (void*)&led[1];
1192 snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
1193 led->name = name;
1194 led->brightness = 0;
1195 led->max_brightness = 1;
1196 led->brightness_get = wiimote_leds_get;
1197 led->brightness_set = wiimote_leds_set;
1198
1199 ret = led_classdev_register(dev, led);
1200 if (ret) {
1201 kfree(led);
1202 goto err;
1203 }
1204 wdata->leds[i] = led;
1205 }
1206
1207 return 0;
1208
1209err:
1210 wiimote_leds_destroy(wdata);
1211 return ret;
1212}
1213
1214static struct wiimote_data *wiimote_create(struct hid_device *hdev) 1125static struct wiimote_data *wiimote_create(struct hid_device *hdev)
1215{ 1126{
1216 struct wiimote_data *wdata; 1127 struct wiimote_data *wdata;
@@ -1300,7 +1211,6 @@ static void wiimote_destroy(struct wiimote_data *wdata)
1300{ 1211{
1301 wiidebug_deinit(wdata); 1212 wiidebug_deinit(wdata);
1302 wiiext_deinit(wdata); 1213 wiiext_deinit(wdata);
1303 wiimote_leds_destroy(wdata);
1304 1214
1305 cancel_work_sync(&wdata->init_worker); 1215 cancel_work_sync(&wdata->init_worker);
1306 wiimote_modules_unload(wdata); 1216 wiimote_modules_unload(wdata);
@@ -1357,10 +1267,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
1357 goto err_ir; 1267 goto err_ir;
1358 } 1268 }
1359 1269
1360 ret = wiimote_leds_create(wdata);
1361 if (ret)
1362 goto err_free;
1363
1364 ret = wiiext_init(wdata); 1270 ret = wiiext_init(wdata);
1365 if (ret) 1271 if (ret)
1366 goto err_free; 1272 goto err_free;
@@ -1371,11 +1277,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
1371 1277
1372 hid_info(hdev, "New device registered\n"); 1278 hid_info(hdev, "New device registered\n");
1373 1279
1374 /* by default set led1 after device initialization */
1375 spin_lock_irq(&wdata->state.lock);
1376 wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
1377 spin_unlock_irq(&wdata->state.lock);
1378
1379 /* schedule device detection */ 1280 /* schedule device detection */
1380 schedule_work(&wdata->init_worker); 1281 schedule_work(&wdata->init_worker);
1381 1282
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 4cbbbe651ba5..f96de153971c 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -268,10 +268,150 @@ static const struct wiimod_ops wiimod_battery = {
268 .remove = wiimod_battery_remove, 268 .remove = wiimod_battery_remove,
269}; 269};
270 270
271/*
272 * LED
273 * 0 to 4 player LEDs are supported by devices. The "arg" field of the
274 * wiimod_ops structure specifies which LED this module controls. This allows
275 * to register a limited number of LEDs.
276 * State is managed by wiimote core.
277 */
278
279static enum led_brightness wiimod_led_get(struct led_classdev *led_dev)
280{
281 struct wiimote_data *wdata;
282 struct device *dev = led_dev->dev->parent;
283 int i;
284 unsigned long flags;
285 bool value = false;
286
287 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
288
289 for (i = 0; i < 4; ++i) {
290 if (wdata->leds[i] == led_dev) {
291 spin_lock_irqsave(&wdata->state.lock, flags);
292 value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
293 spin_unlock_irqrestore(&wdata->state.lock, flags);
294 break;
295 }
296 }
297
298 return value ? LED_FULL : LED_OFF;
299}
300
301static void wiimod_led_set(struct led_classdev *led_dev,
302 enum led_brightness value)
303{
304 struct wiimote_data *wdata;
305 struct device *dev = led_dev->dev->parent;
306 int i;
307 unsigned long flags;
308 __u8 state, flag;
309
310 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
311
312 for (i = 0; i < 4; ++i) {
313 if (wdata->leds[i] == led_dev) {
314 flag = WIIPROTO_FLAG_LED(i + 1);
315 spin_lock_irqsave(&wdata->state.lock, flags);
316 state = wdata->state.flags;
317 if (value == LED_OFF)
318 wiiproto_req_leds(wdata, state & ~flag);
319 else
320 wiiproto_req_leds(wdata, state | flag);
321 spin_unlock_irqrestore(&wdata->state.lock, flags);
322 break;
323 }
324 }
325}
326
327static int wiimod_led_probe(const struct wiimod_ops *ops,
328 struct wiimote_data *wdata)
329{
330 struct device *dev = &wdata->hdev->dev;
331 size_t namesz = strlen(dev_name(dev)) + 9;
332 struct led_classdev *led;
333 unsigned long flags;
334 char *name;
335 int ret;
336
337 led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
338 if (!led)
339 return -ENOMEM;
340
341 name = (void*)&led[1];
342 snprintf(name, namesz, "%s:blue:p%lu", dev_name(dev), ops->arg);
343 led->name = name;
344 led->brightness = 0;
345 led->max_brightness = 1;
346 led->brightness_get = wiimod_led_get;
347 led->brightness_set = wiimod_led_set;
348
349 wdata->leds[ops->arg] = led;
350 ret = led_classdev_register(dev, led);
351 if (ret)
352 goto err_free;
353
354 /* enable LED1 to stop initial LED-blinking */
355 if (ops->arg == 0) {
356 spin_lock_irqsave(&wdata->state.lock, flags);
357 wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
358 spin_unlock_irqrestore(&wdata->state.lock, flags);
359 }
360
361 return 0;
362
363err_free:
364 wdata->leds[ops->arg] = NULL;
365 kfree(led);
366 return ret;
367}
368
369static void wiimod_led_remove(const struct wiimod_ops *ops,
370 struct wiimote_data *wdata)
371{
372 if (!wdata->leds[ops->arg])
373 return;
374
375 led_classdev_unregister(wdata->leds[ops->arg]);
376 kfree(wdata->leds[ops->arg]);
377 wdata->leds[ops->arg] = NULL;
378}
379
380static const struct wiimod_ops wiimod_leds[4] = {
381 {
382 .flags = 0,
383 .arg = 0,
384 .probe = wiimod_led_probe,
385 .remove = wiimod_led_remove,
386 },
387 {
388 .flags = 0,
389 .arg = 1,
390 .probe = wiimod_led_probe,
391 .remove = wiimod_led_remove,
392 },
393 {
394 .flags = 0,
395 .arg = 2,
396 .probe = wiimod_led_probe,
397 .remove = wiimod_led_remove,
398 },
399 {
400 .flags = 0,
401 .arg = 3,
402 .probe = wiimod_led_probe,
403 .remove = wiimod_led_remove,
404 },
405};
406
271/* module table */ 407/* module table */
272 408
273const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { 409const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
274 [WIIMOD_KEYS] = &wiimod_keys, 410 [WIIMOD_KEYS] = &wiimod_keys,
275 [WIIMOD_RUMBLE] = &wiimod_rumble, 411 [WIIMOD_RUMBLE] = &wiimod_rumble,
276 [WIIMOD_BATTERY] = &wiimod_battery, 412 [WIIMOD_BATTERY] = &wiimod_battery,
413 [WIIMOD_LED1] = &wiimod_leds[0],
414 [WIIMOD_LED2] = &wiimod_leds[1],
415 [WIIMOD_LED3] = &wiimod_leds[2],
416 [WIIMOD_LED4] = &wiimod_leds[3],
277}; 417};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 4151514fcd2e..66150a693324 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -129,6 +129,10 @@ enum wiimod_module {
129 WIIMOD_KEYS, 129 WIIMOD_KEYS,
130 WIIMOD_RUMBLE, 130 WIIMOD_RUMBLE,
131 WIIMOD_BATTERY, 131 WIIMOD_BATTERY,
132 WIIMOD_LED1,
133 WIIMOD_LED2,
134 WIIMOD_LED3,
135 WIIMOD_LED4,
132 WIIMOD_NUM, 136 WIIMOD_NUM,
133 WIIMOD_NULL = WIIMOD_NUM, 137 WIIMOD_NULL = WIIMOD_NUM,
134}; 138};
@@ -185,6 +189,7 @@ enum wiiproto_reqs {
185 189
186extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); 190extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
187extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble); 191extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble);
192extern void wiiproto_req_leds(struct wiimote_data *wdata, int leds);
188extern void wiiproto_req_status(struct wiimote_data *wdata); 193extern void wiiproto_req_status(struct wiimote_data *wdata);
189extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, 194extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
190 const __u8 *wmem, __u8 size); 195 const __u8 *wmem, __u8 size);