aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-05-05 17:12:52 -0400
committerJiri Kosina <jkosina@suse.cz>2013-06-03 05:07:01 -0400
commit20cef813b4791ba55b2f3c4258414b6ded21e8ff (patch)
tree029520dd3091490dd6babad91886b0be72f7ae54 /drivers
parent27f06942142e7a17757b5de1dc4f128c179b7c13 (diff)
HID: wiimote: convert KEYS and RUMBLE to modules
This introduces the first sub-device modules by converting the KEYS and RUMBLE sub-devices into wiimote modules. Both must be converted at once because they depend on the built-in shared input device. This mostly moves code from wiimote-core to wiimote-modules and doesn't change any semantics or ABI. 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.c134
-rw-r--r--drivers/hid/hid-wiimote-modules.c134
-rw-r--r--drivers/hid/hid-wiimote.h18
3 files changed, 172 insertions, 114 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 275428b31509..6ada22606707 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -22,35 +22,6 @@
22#include "hid-ids.h" 22#include "hid-ids.h"
23#include "hid-wiimote.h" 23#include "hid-wiimote.h"
24 24
25enum wiiproto_keys {
26 WIIPROTO_KEY_LEFT,
27 WIIPROTO_KEY_RIGHT,
28 WIIPROTO_KEY_UP,
29 WIIPROTO_KEY_DOWN,
30 WIIPROTO_KEY_PLUS,
31 WIIPROTO_KEY_MINUS,
32 WIIPROTO_KEY_ONE,
33 WIIPROTO_KEY_TWO,
34 WIIPROTO_KEY_A,
35 WIIPROTO_KEY_B,
36 WIIPROTO_KEY_HOME,
37 WIIPROTO_KEY_COUNT
38};
39
40static __u16 wiiproto_keymap[] = {
41 KEY_LEFT, /* WIIPROTO_KEY_LEFT */
42 KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */
43 KEY_UP, /* WIIPROTO_KEY_UP */
44 KEY_DOWN, /* WIIPROTO_KEY_DOWN */
45 KEY_NEXT, /* WIIPROTO_KEY_PLUS */
46 KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */
47 BTN_1, /* WIIPROTO_KEY_ONE */
48 BTN_2, /* WIIPROTO_KEY_TWO */
49 BTN_A, /* WIIPROTO_KEY_A */
50 BTN_B, /* WIIPROTO_KEY_B */
51 BTN_MODE, /* WIIPROTO_KEY_HOME */
52};
53
54static enum power_supply_property wiimote_battery_props[] = { 25static enum power_supply_property wiimote_battery_props[] = {
55 POWER_SUPPLY_PROP_CAPACITY, 26 POWER_SUPPLY_PROP_CAPACITY,
56 POWER_SUPPLY_PROP_SCOPE, 27 POWER_SUPPLY_PROP_SCOPE,
@@ -166,7 +137,7 @@ static inline void wiiproto_keep_rumble(struct wiimote_data *wdata, __u8 *cmd1)
166 *cmd1 |= 0x01; 137 *cmd1 |= 0x01;
167} 138}
168 139
169static void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble) 140void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble)
170{ 141{
171 __u8 cmd[2]; 142 __u8 cmd[2];
172 143
@@ -654,31 +625,6 @@ static void wiimote_leds_set(struct led_classdev *led_dev,
654 } 625 }
655} 626}
656 627
657static int wiimote_ff_play(struct input_dev *dev, void *data,
658 struct ff_effect *eff)
659{
660 struct wiimote_data *wdata = input_get_drvdata(dev);
661 __u8 value;
662 unsigned long flags;
663
664 /*
665 * The wiimote supports only a single rumble motor so if any magnitude
666 * is set to non-zero then we start the rumble motor. If both are set to
667 * zero, we stop the rumble motor.
668 */
669
670 if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
671 value = 1;
672 else
673 value = 0;
674
675 spin_lock_irqsave(&wdata->state.lock, flags);
676 wiiproto_req_rumble(wdata, value);
677 spin_unlock_irqrestore(&wdata->state.lock, flags);
678
679 return 0;
680}
681
682static int wiimote_accel_open(struct input_dev *dev) 628static int wiimote_accel_open(struct input_dev *dev)
683{ 629{
684 struct wiimote_data *wdata = input_get_drvdata(dev); 630 struct wiimote_data *wdata = input_get_drvdata(dev);
@@ -725,12 +671,18 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = {
725 WIIMOD_NULL, 671 WIIMOD_NULL,
726 }, 672 },
727 [WIIMOTE_DEV_GENERIC] = (const __u8[]){ 673 [WIIMOTE_DEV_GENERIC] = (const __u8[]){
674 WIIMOD_KEYS,
675 WIIMOD_RUMBLE,
728 WIIMOD_NULL, 676 WIIMOD_NULL,
729 }, 677 },
730 [WIIMOTE_DEV_GEN10] = (const __u8[]){ 678 [WIIMOTE_DEV_GEN10] = (const __u8[]){
679 WIIMOD_KEYS,
680 WIIMOD_RUMBLE,
731 WIIMOD_NULL, 681 WIIMOD_NULL,
732 }, 682 },
733 [WIIMOTE_DEV_GEN20] = (const __u8[]){ 683 [WIIMOTE_DEV_GEN20] = (const __u8[]){
684 WIIMOD_KEYS,
685 WIIMOD_RUMBLE,
734 WIIMOD_NULL, 686 WIIMOD_NULL,
735 }, 687 },
736}; 688};
@@ -933,29 +885,17 @@ static void wiimote_init_worker(struct work_struct *work)
933 885
934static void handler_keys(struct wiimote_data *wdata, const __u8 *payload) 886static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
935{ 887{
936 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT], 888 const __u8 *iter, *mods;
937 !!(payload[0] & 0x01)); 889 const struct wiimod_ops *ops;
938 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT], 890
939 !!(payload[0] & 0x02)); 891 mods = wiimote_devtype_mods[wdata->state.devtype];
940 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN], 892 for (iter = mods; *iter != WIIMOD_NULL; ++iter) {
941 !!(payload[0] & 0x04)); 893 ops = wiimod_table[*iter];
942 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP], 894 if (ops->in_keys) {
943 !!(payload[0] & 0x08)); 895 ops->in_keys(wdata, payload);
944 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS], 896 break;
945 !!(payload[0] & 0x10)); 897 }
946 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO], 898 }
947 !!(payload[1] & 0x01));
948 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE],
949 !!(payload[1] & 0x02));
950 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B],
951 !!(payload[1] & 0x04));
952 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A],
953 !!(payload[1] & 0x08));
954 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS],
955 !!(payload[1] & 0x10));
956 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME],
957 !!(payload[1] & 0x80));
958 input_sync(wdata->input);
959} 899}
960 900
961static void handler_accel(struct wiimote_data *wdata, const __u8 *payload) 901static void handler_accel(struct wiimote_data *wdata, const __u8 *payload)
@@ -1319,38 +1259,17 @@ err:
1319static struct wiimote_data *wiimote_create(struct hid_device *hdev) 1259static struct wiimote_data *wiimote_create(struct hid_device *hdev)
1320{ 1260{
1321 struct wiimote_data *wdata; 1261 struct wiimote_data *wdata;
1322 int i;
1323 1262
1324 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); 1263 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
1325 if (!wdata) 1264 if (!wdata)
1326 return NULL; 1265 return NULL;
1327 1266
1328 wdata->input = input_allocate_device();
1329 if (!wdata->input)
1330 goto err;
1331
1332 wdata->hdev = hdev; 1267 wdata->hdev = hdev;
1333 hid_set_drvdata(hdev, wdata); 1268 hid_set_drvdata(hdev, wdata);
1334 1269
1335 input_set_drvdata(wdata->input, wdata);
1336 wdata->input->dev.parent = &wdata->hdev->dev;
1337 wdata->input->id.bustype = wdata->hdev->bus;
1338 wdata->input->id.vendor = wdata->hdev->vendor;
1339 wdata->input->id.product = wdata->hdev->product;
1340 wdata->input->id.version = wdata->hdev->version;
1341 wdata->input->name = WIIMOTE_NAME;
1342
1343 set_bit(EV_KEY, wdata->input->evbit);
1344 for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
1345 set_bit(wiiproto_keymap[i], wdata->input->keybit);
1346
1347 set_bit(FF_RUMBLE, wdata->input->ffbit);
1348 if (input_ff_create_memless(wdata->input, NULL, wiimote_ff_play))
1349 goto err_input;
1350
1351 wdata->accel = input_allocate_device(); 1270 wdata->accel = input_allocate_device();
1352 if (!wdata->accel) 1271 if (!wdata->accel)
1353 goto err_input; 1272 goto err;
1354 1273
1355 input_set_drvdata(wdata->accel, wdata); 1274 input_set_drvdata(wdata->accel, wdata);
1356 wdata->accel->open = wiimote_accel_open; 1275 wdata->accel->open = wiimote_accel_open;
@@ -1417,8 +1336,6 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev)
1417 1336
1418err_ir: 1337err_ir:
1419 input_free_device(wdata->accel); 1338 input_free_device(wdata->accel);
1420err_input:
1421 input_free_device(wdata->input);
1422err: 1339err:
1423 kfree(wdata); 1340 kfree(wdata);
1424 return NULL; 1341 return NULL;
@@ -1430,13 +1347,12 @@ static void wiimote_destroy(struct wiimote_data *wdata)
1430 wiiext_deinit(wdata); 1347 wiiext_deinit(wdata);
1431 wiimote_leds_destroy(wdata); 1348 wiimote_leds_destroy(wdata);
1432 1349
1350 cancel_work_sync(&wdata->init_worker);
1433 wiimote_modules_unload(wdata); 1351 wiimote_modules_unload(wdata);
1434 power_supply_unregister(&wdata->battery); 1352 power_supply_unregister(&wdata->battery);
1435 kfree(wdata->battery.name); 1353 kfree(wdata->battery.name);
1436 input_unregister_device(wdata->accel); 1354 input_unregister_device(wdata->accel);
1437 input_unregister_device(wdata->ir); 1355 input_unregister_device(wdata->ir);
1438 input_unregister_device(wdata->input);
1439 cancel_work_sync(&wdata->init_worker);
1440 cancel_work_sync(&wdata->queue.worker); 1356 cancel_work_sync(&wdata->queue.worker);
1441 hid_hw_close(wdata->hdev); 1357 hid_hw_close(wdata->hdev);
1442 hid_hw_stop(wdata->hdev); 1358 hid_hw_stop(wdata->hdev);
@@ -1488,12 +1404,6 @@ static int wiimote_hid_probe(struct hid_device *hdev,
1488 goto err_ir; 1404 goto err_ir;
1489 } 1405 }
1490 1406
1491 ret = input_register_device(wdata->input);
1492 if (ret) {
1493 hid_err(hdev, "Cannot register input device\n");
1494 goto err_input;
1495 }
1496
1497 wdata->battery.properties = wiimote_battery_props; 1407 wdata->battery.properties = wiimote_battery_props;
1498 wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props); 1408 wdata->battery.num_properties = ARRAY_SIZE(wiimote_battery_props);
1499 wdata->battery.get_property = wiimote_battery_get_property; 1409 wdata->battery.get_property = wiimote_battery_get_property;
@@ -1545,9 +1455,6 @@ err_free:
1545err_battery: 1455err_battery:
1546 kfree(wdata->battery.name); 1456 kfree(wdata->battery.name);
1547err_battery_name: 1457err_battery_name:
1548 input_unregister_device(wdata->input);
1549 wdata->input = NULL;
1550err_input:
1551 input_unregister_device(wdata->ir); 1458 input_unregister_device(wdata->ir);
1552 wdata->ir = NULL; 1459 wdata->ir = NULL;
1553err_ir: 1460err_ir:
@@ -1560,7 +1467,6 @@ err_stop:
1560err: 1467err:
1561 input_free_device(wdata->ir); 1468 input_free_device(wdata->ir);
1562 input_free_device(wdata->accel); 1469 input_free_device(wdata->accel);
1563 input_free_device(wdata->input);
1564 kfree(wdata); 1470 kfree(wdata);
1565 return ret; 1471 return ret;
1566} 1472}
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 5dcdd234f29c..616f24024f77 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -39,7 +39,141 @@
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include "hid-wiimote.h" 40#include "hid-wiimote.h"
41 41
42/*
43 * Keys
44 * The initial Wii Remote provided a bunch of buttons that are reported as
45 * part of the core protocol. Many later devices dropped these and report
46 * invalid data in the core button reports. Load this only on devices which
47 * correctly send button reports.
48 * It uses the shared input device.
49 */
50
51static const __u16 wiimod_keys_map[] = {
52 KEY_LEFT, /* WIIPROTO_KEY_LEFT */
53 KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */
54 KEY_UP, /* WIIPROTO_KEY_UP */
55 KEY_DOWN, /* WIIPROTO_KEY_DOWN */
56 KEY_NEXT, /* WIIPROTO_KEY_PLUS */
57 KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */
58 BTN_1, /* WIIPROTO_KEY_ONE */
59 BTN_2, /* WIIPROTO_KEY_TWO */
60 BTN_A, /* WIIPROTO_KEY_A */
61 BTN_B, /* WIIPROTO_KEY_B */
62 BTN_MODE, /* WIIPROTO_KEY_HOME */
63};
64
65static void wiimod_keys_in_keys(struct wiimote_data *wdata, const __u8 *keys)
66{
67 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_LEFT],
68 !!(keys[0] & 0x01));
69 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_RIGHT],
70 !!(keys[0] & 0x02));
71 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_DOWN],
72 !!(keys[0] & 0x04));
73 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_UP],
74 !!(keys[0] & 0x08));
75 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_PLUS],
76 !!(keys[0] & 0x10));
77 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_TWO],
78 !!(keys[1] & 0x01));
79 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_ONE],
80 !!(keys[1] & 0x02));
81 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_B],
82 !!(keys[1] & 0x04));
83 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_A],
84 !!(keys[1] & 0x08));
85 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_MINUS],
86 !!(keys[1] & 0x10));
87 input_report_key(wdata->input, wiimod_keys_map[WIIPROTO_KEY_HOME],
88 !!(keys[1] & 0x80));
89 input_sync(wdata->input);
90}
91
92static int wiimod_keys_probe(const struct wiimod_ops *ops,
93 struct wiimote_data *wdata)
94{
95 unsigned int i;
96
97 set_bit(EV_KEY, wdata->input->evbit);
98 for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
99 set_bit(wiimod_keys_map[i], wdata->input->keybit);
100
101 return 0;
102}
103
104static const struct wiimod_ops wiimod_keys = {
105 .flags = WIIMOD_FLAG_INPUT,
106 .arg = 0,
107 .probe = wiimod_keys_probe,
108 .remove = NULL,
109 .in_keys = wiimod_keys_in_keys,
110};
111
112/*
113 * Rumble
114 * Nearly all devices provide a rumble feature. A small motor for
115 * force-feedback effects. We provide an FF_RUMBLE memless ff device on the
116 * shared input device if this module is loaded.
117 * The rumble motor is controlled via a flag on almost every output report so
118 * the wiimote core handles the rumble flag. But if a device doesn't provide
119 * the rumble motor, this flag shouldn't be set.
120 */
121
122static int wiimod_rumble_play(struct input_dev *dev, void *data,
123 struct ff_effect *eff)
124{
125 struct wiimote_data *wdata = input_get_drvdata(dev);
126 __u8 value;
127 unsigned long flags;
128
129 /*
130 * The wiimote supports only a single rumble motor so if any magnitude
131 * is set to non-zero then we start the rumble motor. If both are set to
132 * zero, we stop the rumble motor.
133 */
134
135 if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude)
136 value = 1;
137 else
138 value = 0;
139
140 spin_lock_irqsave(&wdata->state.lock, flags);
141 wiiproto_req_rumble(wdata, value);
142 spin_unlock_irqrestore(&wdata->state.lock, flags);
143
144 return 0;
145}
146
147static int wiimod_rumble_probe(const struct wiimod_ops *ops,
148 struct wiimote_data *wdata)
149{
150 set_bit(FF_RUMBLE, wdata->input->ffbit);
151 if (input_ff_create_memless(wdata->input, NULL, wiimod_rumble_play))
152 return -ENOMEM;
153
154 return 0;
155}
156
157static void wiimod_rumble_remove(const struct wiimod_ops *ops,
158 struct wiimote_data *wdata)
159{
160 unsigned long flags;
161
162 spin_lock_irqsave(&wdata->state.lock, flags);
163 wiiproto_req_rumble(wdata, 0);
164 spin_unlock_irqrestore(&wdata->state.lock, flags);
165}
166
167static const struct wiimod_ops wiimod_rumble = {
168 .flags = WIIMOD_FLAG_INPUT,
169 .arg = 0,
170 .probe = wiimod_rumble_probe,
171 .remove = wiimod_rumble_remove,
172};
173
42/* module table */ 174/* module table */
43 175
44const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { 176const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = {
177 [WIIMOD_KEYS] = &wiimod_keys,
178 [WIIMOD_RUMBLE] = &wiimod_rumble,
45}; 179};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index 3c94e3c657c6..93c48fbef7a5 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -45,6 +45,21 @@
45/* return flag for led \num */ 45/* return flag for led \num */
46#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1)) 46#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
47 47
48enum wiiproto_keys {
49 WIIPROTO_KEY_LEFT,
50 WIIPROTO_KEY_RIGHT,
51 WIIPROTO_KEY_UP,
52 WIIPROTO_KEY_DOWN,
53 WIIPROTO_KEY_PLUS,
54 WIIPROTO_KEY_MINUS,
55 WIIPROTO_KEY_ONE,
56 WIIPROTO_KEY_TWO,
57 WIIPROTO_KEY_A,
58 WIIPROTO_KEY_B,
59 WIIPROTO_KEY_HOME,
60 WIIPROTO_KEY_COUNT
61};
62
48enum wiimote_devtype { 63enum wiimote_devtype {
49 WIIMOTE_DEV_PENDING, 64 WIIMOTE_DEV_PENDING,
50 WIIMOTE_DEV_UNKNOWN, 65 WIIMOTE_DEV_UNKNOWN,
@@ -111,6 +126,8 @@ struct wiimote_data {
111/* wiimote modules */ 126/* wiimote modules */
112 127
113enum wiimod_module { 128enum wiimod_module {
129 WIIMOD_KEYS,
130 WIIMOD_RUMBLE,
114 WIIMOD_NUM, 131 WIIMOD_NUM,
115 WIIMOD_NULL = WIIMOD_NUM, 132 WIIMOD_NULL = WIIMOD_NUM,
116}; 133};
@@ -166,6 +183,7 @@ enum wiiproto_reqs {
166 dev)) 183 dev))
167 184
168extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm); 185extern void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm);
186extern void wiiproto_req_rumble(struct wiimote_data *wdata, __u8 rumble);
169extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, 187extern int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset,
170 const __u8 *wmem, __u8 size); 188 const __u8 *wmem, __u8 size);
171extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, 189extern ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset,