diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-05-05 17:12:54 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-06-03 05:07:01 -0400 |
commit | 6c5ae01805e2cc1810328b538ccb2376b5f8bd9f (patch) | |
tree | 0870bb177a597bb36787d48b4112c587ab2614f9 /drivers/hid/hid-wiimote-core.c | |
parent | dcf392313817efb4f318ebbf21f607dbdaf5ea56 (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>
Diffstat (limited to 'drivers/hid/hid-wiimote-core.c')
-rw-r--r-- | drivers/hid/hid-wiimote-core.c | 125 |
1 files changed, 13 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 | ||
154 | static void wiiproto_req_leds(struct wiimote_data *wdata, int leds) | 153 | void 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 | ||
532 | static 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 | |||
554 | static 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 | |||
580 | static int wiimote_accel_open(struct input_dev *dev) | 531 | static 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 | ||
1162 | static 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 | |||
1177 | static 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 | |||
1209 | err: | ||
1210 | wiimote_leds_destroy(wdata); | ||
1211 | return ret; | ||
1212 | } | ||
1213 | |||
1214 | static struct wiimote_data *wiimote_create(struct hid_device *hdev) | 1125 | static 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 | ||