1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Device Modules for Nintendo Wii / Wii U HID Driver |
4 | * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com> |
5 | */ |
6 | |
7 | /* |
8 | */ |
9 | |
10 | /* |
11 | * Wiimote Modules |
12 | * Nintendo devices provide different peripherals and many new devices lack |
13 | * initial features like the IR camera. Therefore, each peripheral device is |
14 | * implemented as an independent module and we probe on each device only the |
15 | * modules for the hardware that really is available. |
16 | * |
17 | * Module registration is sequential. Unregistration is done in reverse order. |
18 | * After device detection, the needed modules are loaded. Users can trigger |
19 | * re-detection which causes all modules to be unloaded and then reload the |
20 | * modules for the new detected device. |
21 | * |
22 | * wdata->input is a shared input device. It is always initialized prior to |
23 | * module registration. If at least one registered module is marked as |
24 | * WIIMOD_FLAG_INPUT, then the input device will get registered after all |
25 | * modules were registered. |
26 | * Please note that it is unregistered _before_ the "remove" callbacks are |
27 | * called. This guarantees that no input interaction is done, anymore. However, |
28 | * the wiimote core keeps a reference to the input device so it is freed only |
29 | * after all modules were removed. It is safe to send events to unregistered |
30 | * input devices. |
31 | */ |
32 | |
33 | #include <linux/device.h> |
34 | #include <linux/hid.h> |
35 | #include <linux/input.h> |
36 | #include <linux/spinlock.h> |
37 | #include "hid-wiimote.h" |
38 | |
39 | /* |
40 | * Keys |
41 | * The initial Wii Remote provided a bunch of buttons that are reported as |
42 | * part of the core protocol. Many later devices dropped these and report |
43 | * invalid data in the core button reports. Load this only on devices which |
44 | * correctly send button reports. |
45 | * It uses the shared input device. |
46 | */ |
47 | |
48 | static const __u16 wiimod_keys_map[] = { |
49 | KEY_LEFT, /* WIIPROTO_KEY_LEFT */ |
50 | KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */ |
51 | KEY_UP, /* WIIPROTO_KEY_UP */ |
52 | KEY_DOWN, /* WIIPROTO_KEY_DOWN */ |
53 | KEY_NEXT, /* WIIPROTO_KEY_PLUS */ |
54 | KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */ |
55 | BTN_1, /* WIIPROTO_KEY_ONE */ |
56 | BTN_2, /* WIIPROTO_KEY_TWO */ |
57 | BTN_A, /* WIIPROTO_KEY_A */ |
58 | BTN_B, /* WIIPROTO_KEY_B */ |
59 | BTN_MODE, /* WIIPROTO_KEY_HOME */ |
60 | }; |
61 | |
62 | static void wiimod_keys_in_keys(struct wiimote_data *wdata, const __u8 *keys) |
63 | { |
64 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_LEFT], |
65 | value: !!(keys[0] & 0x01)); |
66 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_RIGHT], |
67 | value: !!(keys[0] & 0x02)); |
68 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_DOWN], |
69 | value: !!(keys[0] & 0x04)); |
70 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_UP], |
71 | value: !!(keys[0] & 0x08)); |
72 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_PLUS], |
73 | value: !!(keys[0] & 0x10)); |
74 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_TWO], |
75 | value: !!(keys[1] & 0x01)); |
76 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_ONE], |
77 | value: !!(keys[1] & 0x02)); |
78 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_B], |
79 | value: !!(keys[1] & 0x04)); |
80 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_A], |
81 | value: !!(keys[1] & 0x08)); |
82 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_MINUS], |
83 | value: !!(keys[1] & 0x10)); |
84 | input_report_key(dev: wdata->input, code: wiimod_keys_map[WIIPROTO_KEY_HOME], |
85 | value: !!(keys[1] & 0x80)); |
86 | input_sync(dev: wdata->input); |
87 | } |
88 | |
89 | static int wiimod_keys_probe(const struct wiimod_ops *ops, |
90 | struct wiimote_data *wdata) |
91 | { |
92 | unsigned int i; |
93 | |
94 | set_bit(EV_KEY, addr: wdata->input->evbit); |
95 | for (i = 0; i < WIIPROTO_KEY_COUNT; ++i) |
96 | set_bit(nr: wiimod_keys_map[i], addr: wdata->input->keybit); |
97 | |
98 | return 0; |
99 | } |
100 | |
101 | static const struct wiimod_ops wiimod_keys = { |
102 | .flags = WIIMOD_FLAG_INPUT, |
103 | .arg = 0, |
104 | .probe = wiimod_keys_probe, |
105 | .remove = NULL, |
106 | .in_keys = wiimod_keys_in_keys, |
107 | }; |
108 | |
109 | /* |
110 | * Rumble |
111 | * Nearly all devices provide a rumble feature. A small motor for |
112 | * force-feedback effects. We provide an FF_RUMBLE memless ff device on the |
113 | * shared input device if this module is loaded. |
114 | * The rumble motor is controlled via a flag on almost every output report so |
115 | * the wiimote core handles the rumble flag. But if a device doesn't provide |
116 | * the rumble motor, this flag shouldn't be set. |
117 | */ |
118 | |
119 | /* used by wiimod_rumble and wiipro_rumble */ |
120 | static void wiimod_rumble_worker(struct work_struct *work) |
121 | { |
122 | struct wiimote_data *wdata = container_of(work, struct wiimote_data, |
123 | rumble_worker); |
124 | |
125 | spin_lock_irq(lock: &wdata->state.lock); |
126 | wiiproto_req_rumble(wdata, rumble: wdata->state.cache_rumble); |
127 | spin_unlock_irq(lock: &wdata->state.lock); |
128 | } |
129 | |
130 | static int wiimod_rumble_play(struct input_dev *dev, void *data, |
131 | struct ff_effect *eff) |
132 | { |
133 | struct wiimote_data *wdata = input_get_drvdata(dev); |
134 | __u8 value; |
135 | |
136 | /* |
137 | * The wiimote supports only a single rumble motor so if any magnitude |
138 | * is set to non-zero then we start the rumble motor. If both are set to |
139 | * zero, we stop the rumble motor. |
140 | */ |
141 | |
142 | if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) |
143 | value = 1; |
144 | else |
145 | value = 0; |
146 | |
147 | /* Locking state.lock here might deadlock with input_event() calls. |
148 | * schedule_work acts as barrier. Merging multiple changes is fine. */ |
149 | wdata->state.cache_rumble = value; |
150 | schedule_work(work: &wdata->rumble_worker); |
151 | |
152 | return 0; |
153 | } |
154 | |
155 | static int wiimod_rumble_probe(const struct wiimod_ops *ops, |
156 | struct wiimote_data *wdata) |
157 | { |
158 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); |
159 | |
160 | set_bit(FF_RUMBLE, addr: wdata->input->ffbit); |
161 | if (input_ff_create_memless(dev: wdata->input, NULL, play_effect: wiimod_rumble_play)) |
162 | return -ENOMEM; |
163 | |
164 | return 0; |
165 | } |
166 | |
167 | static void wiimod_rumble_remove(const struct wiimod_ops *ops, |
168 | struct wiimote_data *wdata) |
169 | { |
170 | unsigned long flags; |
171 | |
172 | cancel_work_sync(work: &wdata->rumble_worker); |
173 | |
174 | spin_lock_irqsave(&wdata->state.lock, flags); |
175 | wiiproto_req_rumble(wdata, rumble: 0); |
176 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
177 | } |
178 | |
179 | static const struct wiimod_ops wiimod_rumble = { |
180 | .flags = WIIMOD_FLAG_INPUT, |
181 | .arg = 0, |
182 | .probe = wiimod_rumble_probe, |
183 | .remove = wiimod_rumble_remove, |
184 | }; |
185 | |
186 | /* |
187 | * Battery |
188 | * 1 byte of battery capacity information is sent along every protocol status |
189 | * report. The wiimote core caches it but we try to update it on every |
190 | * user-space request. |
191 | * This is supported by nearly every device so it's almost always enabled. |
192 | */ |
193 | |
194 | static enum power_supply_property wiimod_battery_props[] = { |
195 | POWER_SUPPLY_PROP_CAPACITY, |
196 | POWER_SUPPLY_PROP_SCOPE, |
197 | }; |
198 | |
199 | static int wiimod_battery_get_property(struct power_supply *psy, |
200 | enum power_supply_property psp, |
201 | union power_supply_propval *val) |
202 | { |
203 | struct wiimote_data *wdata = power_supply_get_drvdata(psy); |
204 | int ret = 0, state; |
205 | unsigned long flags; |
206 | |
207 | if (psp == POWER_SUPPLY_PROP_SCOPE) { |
208 | val->intval = POWER_SUPPLY_SCOPE_DEVICE; |
209 | return 0; |
210 | } else if (psp != POWER_SUPPLY_PROP_CAPACITY) { |
211 | return -EINVAL; |
212 | } |
213 | |
214 | ret = wiimote_cmd_acquire(wdata); |
215 | if (ret) |
216 | return ret; |
217 | |
218 | spin_lock_irqsave(&wdata->state.lock, flags); |
219 | wiimote_cmd_set(wdata, cmd: WIIPROTO_REQ_SREQ, opt: 0); |
220 | wiiproto_req_status(wdata); |
221 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
222 | |
223 | wiimote_cmd_wait(wdata); |
224 | wiimote_cmd_release(wdata); |
225 | |
226 | spin_lock_irqsave(&wdata->state.lock, flags); |
227 | state = wdata->state.cmd_battery; |
228 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
229 | |
230 | val->intval = state * 100 / 255; |
231 | return ret; |
232 | } |
233 | |
234 | static int wiimod_battery_probe(const struct wiimod_ops *ops, |
235 | struct wiimote_data *wdata) |
236 | { |
237 | struct power_supply_config psy_cfg = { .drv_data = wdata, }; |
238 | int ret; |
239 | |
240 | wdata->battery_desc.properties = wiimod_battery_props; |
241 | wdata->battery_desc.num_properties = ARRAY_SIZE(wiimod_battery_props); |
242 | wdata->battery_desc.get_property = wiimod_battery_get_property; |
243 | wdata->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; |
244 | wdata->battery_desc.use_for_apm = 0; |
245 | wdata->battery_desc.name = kasprintf(GFP_KERNEL, fmt: "wiimote_battery_%s" , |
246 | wdata->hdev->uniq); |
247 | if (!wdata->battery_desc.name) |
248 | return -ENOMEM; |
249 | |
250 | wdata->battery = power_supply_register(parent: &wdata->hdev->dev, |
251 | desc: &wdata->battery_desc, |
252 | cfg: &psy_cfg); |
253 | if (IS_ERR(ptr: wdata->battery)) { |
254 | hid_err(wdata->hdev, "cannot register battery device\n" ); |
255 | ret = PTR_ERR(ptr: wdata->battery); |
256 | goto err_free; |
257 | } |
258 | |
259 | power_supply_powers(psy: wdata->battery, dev: &wdata->hdev->dev); |
260 | return 0; |
261 | |
262 | err_free: |
263 | kfree(objp: wdata->battery_desc.name); |
264 | wdata->battery_desc.name = NULL; |
265 | return ret; |
266 | } |
267 | |
268 | static void wiimod_battery_remove(const struct wiimod_ops *ops, |
269 | struct wiimote_data *wdata) |
270 | { |
271 | if (!wdata->battery_desc.name) |
272 | return; |
273 | |
274 | power_supply_unregister(psy: wdata->battery); |
275 | kfree(objp: wdata->battery_desc.name); |
276 | wdata->battery_desc.name = NULL; |
277 | } |
278 | |
279 | static const struct wiimod_ops wiimod_battery = { |
280 | .flags = 0, |
281 | .arg = 0, |
282 | .probe = wiimod_battery_probe, |
283 | .remove = wiimod_battery_remove, |
284 | }; |
285 | |
286 | /* |
287 | * LED |
288 | * 0 to 4 player LEDs are supported by devices. The "arg" field of the |
289 | * wiimod_ops structure specifies which LED this module controls. This allows |
290 | * to register a limited number of LEDs. |
291 | * State is managed by wiimote core. |
292 | */ |
293 | |
294 | static enum led_brightness wiimod_led_get(struct led_classdev *led_dev) |
295 | { |
296 | struct device *dev = led_dev->dev->parent; |
297 | struct wiimote_data *wdata = dev_to_wii(dev); |
298 | int i; |
299 | unsigned long flags; |
300 | bool value = false; |
301 | |
302 | for (i = 0; i < 4; ++i) { |
303 | if (wdata->leds[i] == led_dev) { |
304 | spin_lock_irqsave(&wdata->state.lock, flags); |
305 | value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1); |
306 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
307 | break; |
308 | } |
309 | } |
310 | |
311 | return value ? LED_FULL : LED_OFF; |
312 | } |
313 | |
314 | static void wiimod_led_set(struct led_classdev *led_dev, |
315 | enum led_brightness value) |
316 | { |
317 | struct device *dev = led_dev->dev->parent; |
318 | struct wiimote_data *wdata = dev_to_wii(dev); |
319 | int i; |
320 | unsigned long flags; |
321 | __u8 state, flag; |
322 | |
323 | for (i = 0; i < 4; ++i) { |
324 | if (wdata->leds[i] == led_dev) { |
325 | flag = WIIPROTO_FLAG_LED(i + 1); |
326 | spin_lock_irqsave(&wdata->state.lock, flags); |
327 | state = wdata->state.flags; |
328 | if (value == LED_OFF) |
329 | wiiproto_req_leds(wdata, leds: state & ~flag); |
330 | else |
331 | wiiproto_req_leds(wdata, leds: state | flag); |
332 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
333 | break; |
334 | } |
335 | } |
336 | } |
337 | |
338 | static int wiimod_led_probe(const struct wiimod_ops *ops, |
339 | struct wiimote_data *wdata) |
340 | { |
341 | struct device *dev = &wdata->hdev->dev; |
342 | size_t namesz = strlen(dev_name(dev)) + 9; |
343 | struct led_classdev *led; |
344 | unsigned long flags; |
345 | char *name; |
346 | int ret; |
347 | |
348 | led = kzalloc(size: sizeof(struct led_classdev) + namesz, GFP_KERNEL); |
349 | if (!led) |
350 | return -ENOMEM; |
351 | |
352 | name = (void*)&led[1]; |
353 | snprintf(buf: name, size: namesz, fmt: "%s:blue:p%lu" , dev_name(dev), ops->arg); |
354 | led->name = name; |
355 | led->brightness = 0; |
356 | led->max_brightness = 1; |
357 | led->brightness_get = wiimod_led_get; |
358 | led->brightness_set = wiimod_led_set; |
359 | |
360 | wdata->leds[ops->arg] = led; |
361 | ret = led_classdev_register(parent: dev, led_cdev: led); |
362 | if (ret) |
363 | goto err_free; |
364 | |
365 | /* enable LED1 to stop initial LED-blinking */ |
366 | if (ops->arg == 0) { |
367 | spin_lock_irqsave(&wdata->state.lock, flags); |
368 | wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1); |
369 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
370 | } |
371 | |
372 | return 0; |
373 | |
374 | err_free: |
375 | wdata->leds[ops->arg] = NULL; |
376 | kfree(objp: led); |
377 | return ret; |
378 | } |
379 | |
380 | static void wiimod_led_remove(const struct wiimod_ops *ops, |
381 | struct wiimote_data *wdata) |
382 | { |
383 | if (!wdata->leds[ops->arg]) |
384 | return; |
385 | |
386 | led_classdev_unregister(led_cdev: wdata->leds[ops->arg]); |
387 | kfree(objp: wdata->leds[ops->arg]); |
388 | wdata->leds[ops->arg] = NULL; |
389 | } |
390 | |
391 | static const struct wiimod_ops wiimod_leds[4] = { |
392 | { |
393 | .flags = 0, |
394 | .arg = 0, |
395 | .probe = wiimod_led_probe, |
396 | .remove = wiimod_led_remove, |
397 | }, |
398 | { |
399 | .flags = 0, |
400 | .arg = 1, |
401 | .probe = wiimod_led_probe, |
402 | .remove = wiimod_led_remove, |
403 | }, |
404 | { |
405 | .flags = 0, |
406 | .arg = 2, |
407 | .probe = wiimod_led_probe, |
408 | .remove = wiimod_led_remove, |
409 | }, |
410 | { |
411 | .flags = 0, |
412 | .arg = 3, |
413 | .probe = wiimod_led_probe, |
414 | .remove = wiimod_led_remove, |
415 | }, |
416 | }; |
417 | |
418 | /* |
419 | * Accelerometer |
420 | * 3 axis accelerometer data is part of nearly all DRMs. If not supported by a |
421 | * device, it's mostly cleared to 0. This module parses this data and provides |
422 | * it via a separate input device. |
423 | */ |
424 | |
425 | static void wiimod_accel_in_accel(struct wiimote_data *wdata, |
426 | const __u8 *accel) |
427 | { |
428 | __u16 x, y, z; |
429 | |
430 | if (!(wdata->state.flags & WIIPROTO_FLAG_ACCEL)) |
431 | return; |
432 | |
433 | /* |
434 | * payload is: BB BB XX YY ZZ |
435 | * Accelerometer data is encoded into 3 10bit values. XX, YY and ZZ |
436 | * contain the upper 8 bits of each value. The lower 2 bits are |
437 | * contained in the buttons data BB BB. |
438 | * Bits 6 and 7 of the first buttons byte BB is the lower 2 bits of the |
439 | * X accel value. Bit 5 of the second buttons byte is the 2nd bit of Y |
440 | * accel value and bit 6 is the second bit of the Z value. |
441 | * The first bit of Y and Z values is not available and always set to 0. |
442 | * 0x200 is returned on no movement. |
443 | */ |
444 | |
445 | x = accel[2] << 2; |
446 | y = accel[3] << 2; |
447 | z = accel[4] << 2; |
448 | |
449 | x |= (accel[0] >> 5) & 0x3; |
450 | y |= (accel[1] >> 4) & 0x2; |
451 | z |= (accel[1] >> 5) & 0x2; |
452 | |
453 | input_report_abs(dev: wdata->accel, ABS_RX, value: x - 0x200); |
454 | input_report_abs(dev: wdata->accel, ABS_RY, value: y - 0x200); |
455 | input_report_abs(dev: wdata->accel, ABS_RZ, value: z - 0x200); |
456 | input_sync(dev: wdata->accel); |
457 | } |
458 | |
459 | static int wiimod_accel_open(struct input_dev *dev) |
460 | { |
461 | struct wiimote_data *wdata = input_get_drvdata(dev); |
462 | unsigned long flags; |
463 | |
464 | spin_lock_irqsave(&wdata->state.lock, flags); |
465 | wiiproto_req_accel(wdata, accel: true); |
466 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
467 | |
468 | return 0; |
469 | } |
470 | |
471 | static void wiimod_accel_close(struct input_dev *dev) |
472 | { |
473 | struct wiimote_data *wdata = input_get_drvdata(dev); |
474 | unsigned long flags; |
475 | |
476 | spin_lock_irqsave(&wdata->state.lock, flags); |
477 | wiiproto_req_accel(wdata, accel: false); |
478 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
479 | } |
480 | |
481 | static int wiimod_accel_probe(const struct wiimod_ops *ops, |
482 | struct wiimote_data *wdata) |
483 | { |
484 | int ret; |
485 | |
486 | wdata->accel = input_allocate_device(); |
487 | if (!wdata->accel) |
488 | return -ENOMEM; |
489 | |
490 | input_set_drvdata(dev: wdata->accel, data: wdata); |
491 | wdata->accel->open = wiimod_accel_open; |
492 | wdata->accel->close = wiimod_accel_close; |
493 | wdata->accel->dev.parent = &wdata->hdev->dev; |
494 | wdata->accel->id.bustype = wdata->hdev->bus; |
495 | wdata->accel->id.vendor = wdata->hdev->vendor; |
496 | wdata->accel->id.product = wdata->hdev->product; |
497 | wdata->accel->id.version = wdata->hdev->version; |
498 | wdata->accel->name = WIIMOTE_NAME " Accelerometer" ; |
499 | |
500 | set_bit(EV_ABS, addr: wdata->accel->evbit); |
501 | set_bit(ABS_RX, addr: wdata->accel->absbit); |
502 | set_bit(ABS_RY, addr: wdata->accel->absbit); |
503 | set_bit(ABS_RZ, addr: wdata->accel->absbit); |
504 | input_set_abs_params(dev: wdata->accel, ABS_RX, min: -500, max: 500, fuzz: 2, flat: 4); |
505 | input_set_abs_params(dev: wdata->accel, ABS_RY, min: -500, max: 500, fuzz: 2, flat: 4); |
506 | input_set_abs_params(dev: wdata->accel, ABS_RZ, min: -500, max: 500, fuzz: 2, flat: 4); |
507 | |
508 | ret = input_register_device(wdata->accel); |
509 | if (ret) { |
510 | hid_err(wdata->hdev, "cannot register input device\n" ); |
511 | goto err_free; |
512 | } |
513 | |
514 | return 0; |
515 | |
516 | err_free: |
517 | input_free_device(dev: wdata->accel); |
518 | wdata->accel = NULL; |
519 | return ret; |
520 | } |
521 | |
522 | static void wiimod_accel_remove(const struct wiimod_ops *ops, |
523 | struct wiimote_data *wdata) |
524 | { |
525 | if (!wdata->accel) |
526 | return; |
527 | |
528 | input_unregister_device(wdata->accel); |
529 | wdata->accel = NULL; |
530 | } |
531 | |
532 | static const struct wiimod_ops wiimod_accel = { |
533 | .flags = 0, |
534 | .arg = 0, |
535 | .probe = wiimod_accel_probe, |
536 | .remove = wiimod_accel_remove, |
537 | .in_accel = wiimod_accel_in_accel, |
538 | }; |
539 | |
540 | /* |
541 | * IR Cam |
542 | * Up to 4 IR sources can be tracked by a normal Wii Remote. The IR cam needs |
543 | * to be initialized with a fairly complex procedure and consumes a lot of |
544 | * power. Therefore, as long as no application uses the IR input device, it is |
545 | * kept offline. |
546 | * Nearly no other device than the normal Wii Remotes supports the IR cam so |
547 | * you can disable this module for these devices. |
548 | */ |
549 | |
550 | static void wiimod_ir_in_ir(struct wiimote_data *wdata, const __u8 *ir, |
551 | bool packed, unsigned int id) |
552 | { |
553 | __u16 x, y; |
554 | __u8 xid, yid; |
555 | bool sync = false; |
556 | |
557 | if (!(wdata->state.flags & WIIPROTO_FLAGS_IR)) |
558 | return; |
559 | |
560 | switch (id) { |
561 | case 0: |
562 | xid = ABS_HAT0X; |
563 | yid = ABS_HAT0Y; |
564 | break; |
565 | case 1: |
566 | xid = ABS_HAT1X; |
567 | yid = ABS_HAT1Y; |
568 | break; |
569 | case 2: |
570 | xid = ABS_HAT2X; |
571 | yid = ABS_HAT2Y; |
572 | break; |
573 | case 3: |
574 | xid = ABS_HAT3X; |
575 | yid = ABS_HAT3Y; |
576 | sync = true; |
577 | break; |
578 | default: |
579 | return; |
580 | } |
581 | |
582 | /* |
583 | * Basic IR data is encoded into 3 bytes. The first two bytes are the |
584 | * lower 8 bit of the X/Y data, the 3rd byte contains the upper 2 bits |
585 | * of both. |
586 | * If data is packed, then the 3rd byte is put first and slightly |
587 | * reordered. This allows to interleave packed and non-packed data to |
588 | * have two IR sets in 5 bytes instead of 6. |
589 | * The resulting 10bit X/Y values are passed to the ABS_HAT? input dev. |
590 | */ |
591 | |
592 | if (packed) { |
593 | x = ir[1] | ((ir[0] & 0x03) << 8); |
594 | y = ir[2] | ((ir[0] & 0x0c) << 6); |
595 | } else { |
596 | x = ir[0] | ((ir[2] & 0x30) << 4); |
597 | y = ir[1] | ((ir[2] & 0xc0) << 2); |
598 | } |
599 | |
600 | input_report_abs(dev: wdata->ir, code: xid, value: x); |
601 | input_report_abs(dev: wdata->ir, code: yid, value: y); |
602 | |
603 | if (sync) |
604 | input_sync(dev: wdata->ir); |
605 | } |
606 | |
607 | static int wiimod_ir_change(struct wiimote_data *wdata, __u16 mode) |
608 | { |
609 | int ret; |
610 | unsigned long flags; |
611 | __u8 format = 0; |
612 | static const __u8 data_enable[] = { 0x01 }; |
613 | static const __u8 data_sens1[] = { 0x02, 0x00, 0x00, 0x71, 0x01, |
614 | 0x00, 0xaa, 0x00, 0x64 }; |
615 | static const __u8 data_sens2[] = { 0x63, 0x03 }; |
616 | static const __u8 data_fin[] = { 0x08 }; |
617 | |
618 | spin_lock_irqsave(&wdata->state.lock, flags); |
619 | |
620 | if (mode == (wdata->state.flags & WIIPROTO_FLAGS_IR)) { |
621 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
622 | return 0; |
623 | } |
624 | |
625 | if (mode == 0) { |
626 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; |
627 | wiiproto_req_ir1(wdata, flags: 0); |
628 | wiiproto_req_ir2(wdata, flags: 0); |
629 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
630 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
631 | return 0; |
632 | } |
633 | |
634 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
635 | |
636 | ret = wiimote_cmd_acquire(wdata); |
637 | if (ret) |
638 | return ret; |
639 | |
640 | /* send PIXEL CLOCK ENABLE cmd first */ |
641 | spin_lock_irqsave(&wdata->state.lock, flags); |
642 | wiimote_cmd_set(wdata, cmd: WIIPROTO_REQ_IR1, opt: 0); |
643 | wiiproto_req_ir1(wdata, flags: 0x06); |
644 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
645 | |
646 | ret = wiimote_cmd_wait(wdata); |
647 | if (ret) |
648 | goto unlock; |
649 | if (wdata->state.cmd_err) { |
650 | ret = -EIO; |
651 | goto unlock; |
652 | } |
653 | |
654 | /* enable IR LOGIC */ |
655 | spin_lock_irqsave(&wdata->state.lock, flags); |
656 | wiimote_cmd_set(wdata, cmd: WIIPROTO_REQ_IR2, opt: 0); |
657 | wiiproto_req_ir2(wdata, flags: 0x06); |
658 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
659 | |
660 | ret = wiimote_cmd_wait(wdata); |
661 | if (ret) |
662 | goto unlock; |
663 | if (wdata->state.cmd_err) { |
664 | ret = -EIO; |
665 | goto unlock; |
666 | } |
667 | |
668 | /* enable IR cam but do not make it send data, yet */ |
669 | ret = wiimote_cmd_write(wdata, offset: 0xb00030, wmem: data_enable, |
670 | size: sizeof(data_enable)); |
671 | if (ret) |
672 | goto unlock; |
673 | |
674 | /* write first sensitivity block */ |
675 | ret = wiimote_cmd_write(wdata, offset: 0xb00000, wmem: data_sens1, |
676 | size: sizeof(data_sens1)); |
677 | if (ret) |
678 | goto unlock; |
679 | |
680 | /* write second sensitivity block */ |
681 | ret = wiimote_cmd_write(wdata, offset: 0xb0001a, wmem: data_sens2, |
682 | size: sizeof(data_sens2)); |
683 | if (ret) |
684 | goto unlock; |
685 | |
686 | /* put IR cam into desired state */ |
687 | switch (mode) { |
688 | case WIIPROTO_FLAG_IR_FULL: |
689 | format = 5; |
690 | break; |
691 | case WIIPROTO_FLAG_IR_EXT: |
692 | format = 3; |
693 | break; |
694 | case WIIPROTO_FLAG_IR_BASIC: |
695 | format = 1; |
696 | break; |
697 | } |
698 | ret = wiimote_cmd_write(wdata, offset: 0xb00033, wmem: &format, size: sizeof(format)); |
699 | if (ret) |
700 | goto unlock; |
701 | |
702 | /* make IR cam send data */ |
703 | ret = wiimote_cmd_write(wdata, offset: 0xb00030, wmem: data_fin, size: sizeof(data_fin)); |
704 | if (ret) |
705 | goto unlock; |
706 | |
707 | /* request new DRM mode compatible to IR mode */ |
708 | spin_lock_irqsave(&wdata->state.lock, flags); |
709 | wdata->state.flags &= ~WIIPROTO_FLAGS_IR; |
710 | wdata->state.flags |= mode & WIIPROTO_FLAGS_IR; |
711 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
712 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
713 | |
714 | unlock: |
715 | wiimote_cmd_release(wdata); |
716 | return ret; |
717 | } |
718 | |
719 | static int wiimod_ir_open(struct input_dev *dev) |
720 | { |
721 | struct wiimote_data *wdata = input_get_drvdata(dev); |
722 | |
723 | return wiimod_ir_change(wdata, WIIPROTO_FLAG_IR_BASIC); |
724 | } |
725 | |
726 | static void wiimod_ir_close(struct input_dev *dev) |
727 | { |
728 | struct wiimote_data *wdata = input_get_drvdata(dev); |
729 | |
730 | wiimod_ir_change(wdata, mode: 0); |
731 | } |
732 | |
733 | static int wiimod_ir_probe(const struct wiimod_ops *ops, |
734 | struct wiimote_data *wdata) |
735 | { |
736 | int ret; |
737 | |
738 | wdata->ir = input_allocate_device(); |
739 | if (!wdata->ir) |
740 | return -ENOMEM; |
741 | |
742 | input_set_drvdata(dev: wdata->ir, data: wdata); |
743 | wdata->ir->open = wiimod_ir_open; |
744 | wdata->ir->close = wiimod_ir_close; |
745 | wdata->ir->dev.parent = &wdata->hdev->dev; |
746 | wdata->ir->id.bustype = wdata->hdev->bus; |
747 | wdata->ir->id.vendor = wdata->hdev->vendor; |
748 | wdata->ir->id.product = wdata->hdev->product; |
749 | wdata->ir->id.version = wdata->hdev->version; |
750 | wdata->ir->name = WIIMOTE_NAME " IR" ; |
751 | |
752 | set_bit(EV_ABS, addr: wdata->ir->evbit); |
753 | set_bit(ABS_HAT0X, addr: wdata->ir->absbit); |
754 | set_bit(ABS_HAT0Y, addr: wdata->ir->absbit); |
755 | set_bit(ABS_HAT1X, addr: wdata->ir->absbit); |
756 | set_bit(ABS_HAT1Y, addr: wdata->ir->absbit); |
757 | set_bit(ABS_HAT2X, addr: wdata->ir->absbit); |
758 | set_bit(ABS_HAT2Y, addr: wdata->ir->absbit); |
759 | set_bit(ABS_HAT3X, addr: wdata->ir->absbit); |
760 | set_bit(ABS_HAT3Y, addr: wdata->ir->absbit); |
761 | input_set_abs_params(dev: wdata->ir, ABS_HAT0X, min: 0, max: 1023, fuzz: 2, flat: 4); |
762 | input_set_abs_params(dev: wdata->ir, ABS_HAT0Y, min: 0, max: 767, fuzz: 2, flat: 4); |
763 | input_set_abs_params(dev: wdata->ir, ABS_HAT1X, min: 0, max: 1023, fuzz: 2, flat: 4); |
764 | input_set_abs_params(dev: wdata->ir, ABS_HAT1Y, min: 0, max: 767, fuzz: 2, flat: 4); |
765 | input_set_abs_params(dev: wdata->ir, ABS_HAT2X, min: 0, max: 1023, fuzz: 2, flat: 4); |
766 | input_set_abs_params(dev: wdata->ir, ABS_HAT2Y, min: 0, max: 767, fuzz: 2, flat: 4); |
767 | input_set_abs_params(dev: wdata->ir, ABS_HAT3X, min: 0, max: 1023, fuzz: 2, flat: 4); |
768 | input_set_abs_params(dev: wdata->ir, ABS_HAT3Y, min: 0, max: 767, fuzz: 2, flat: 4); |
769 | |
770 | ret = input_register_device(wdata->ir); |
771 | if (ret) { |
772 | hid_err(wdata->hdev, "cannot register input device\n" ); |
773 | goto err_free; |
774 | } |
775 | |
776 | return 0; |
777 | |
778 | err_free: |
779 | input_free_device(dev: wdata->ir); |
780 | wdata->ir = NULL; |
781 | return ret; |
782 | } |
783 | |
784 | static void wiimod_ir_remove(const struct wiimod_ops *ops, |
785 | struct wiimote_data *wdata) |
786 | { |
787 | if (!wdata->ir) |
788 | return; |
789 | |
790 | input_unregister_device(wdata->ir); |
791 | wdata->ir = NULL; |
792 | } |
793 | |
794 | static const struct wiimod_ops wiimod_ir = { |
795 | .flags = 0, |
796 | .arg = 0, |
797 | .probe = wiimod_ir_probe, |
798 | .remove = wiimod_ir_remove, |
799 | .in_ir = wiimod_ir_in_ir, |
800 | }; |
801 | |
802 | /* |
803 | * Nunchuk Extension |
804 | * The Nintendo Wii Nunchuk was the first official extension published by |
805 | * Nintendo. It provides two additional keys and a separate accelerometer. It |
806 | * can be hotplugged to standard Wii Remotes. |
807 | */ |
808 | |
809 | enum wiimod_nunchuk_keys { |
810 | WIIMOD_NUNCHUK_KEY_C, |
811 | WIIMOD_NUNCHUK_KEY_Z, |
812 | WIIMOD_NUNCHUK_KEY_NUM, |
813 | }; |
814 | |
815 | static const __u16 wiimod_nunchuk_map[] = { |
816 | BTN_C, /* WIIMOD_NUNCHUK_KEY_C */ |
817 | BTN_Z, /* WIIMOD_NUNCHUK_KEY_Z */ |
818 | }; |
819 | |
820 | static void wiimod_nunchuk_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
821 | { |
822 | __s16 x, y, z, bx, by; |
823 | |
824 | /* Byte | 8 7 | 6 5 | 4 3 | 2 | 1 | |
825 | * -----+----------+---------+---------+----+-----+ |
826 | * 1 | Button X <7:0> | |
827 | * 2 | Button Y <7:0> | |
828 | * -----+----------+---------+---------+----+-----+ |
829 | * 3 | Speed X <9:2> | |
830 | * 4 | Speed Y <9:2> | |
831 | * 5 | Speed Z <9:2> | |
832 | * -----+----------+---------+---------+----+-----+ |
833 | * 6 | Z <1:0> | Y <1:0> | X <1:0> | BC | BZ | |
834 | * -----+----------+---------+---------+----+-----+ |
835 | * Button X/Y is the analog stick. Speed X, Y and Z are the |
836 | * accelerometer data in the same format as the wiimote's accelerometer. |
837 | * The 6th byte contains the LSBs of the accelerometer data. |
838 | * BC and BZ are the C and Z buttons: 0 means pressed |
839 | * |
840 | * If reported interleaved with motionp, then the layout changes. The |
841 | * 5th and 6th byte changes to: |
842 | * -----+-----------------------------------+-----+ |
843 | * 5 | Speed Z <9:3> | EXT | |
844 | * -----+--------+-----+-----+----+----+----+-----+ |
845 | * 6 |Z <2:1> |Y <1>|X <1>| BC | BZ | 0 | 0 | |
846 | * -----+--------+-----+-----+----+----+----+-----+ |
847 | * All three accelerometer values lose their LSB. The other data is |
848 | * still available but slightly moved. |
849 | * |
850 | * Center data for button values is 128. Center value for accelerometer |
851 | * values it 512 / 0x200 |
852 | */ |
853 | |
854 | bx = ext[0]; |
855 | by = ext[1]; |
856 | bx -= 128; |
857 | by -= 128; |
858 | |
859 | x = ext[2] << 2; |
860 | y = ext[3] << 2; |
861 | z = ext[4] << 2; |
862 | |
863 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
864 | x |= (ext[5] >> 3) & 0x02; |
865 | y |= (ext[5] >> 4) & 0x02; |
866 | z &= ~0x4; |
867 | z |= (ext[5] >> 5) & 0x06; |
868 | } else { |
869 | x |= (ext[5] >> 2) & 0x03; |
870 | y |= (ext[5] >> 4) & 0x03; |
871 | z |= (ext[5] >> 6) & 0x03; |
872 | } |
873 | |
874 | x -= 0x200; |
875 | y -= 0x200; |
876 | z -= 0x200; |
877 | |
878 | input_report_abs(dev: wdata->extension.input, ABS_HAT0X, value: bx); |
879 | input_report_abs(dev: wdata->extension.input, ABS_HAT0Y, value: by); |
880 | |
881 | input_report_abs(dev: wdata->extension.input, ABS_RX, value: x); |
882 | input_report_abs(dev: wdata->extension.input, ABS_RY, value: y); |
883 | input_report_abs(dev: wdata->extension.input, ABS_RZ, value: z); |
884 | |
885 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
886 | input_report_key(dev: wdata->extension.input, |
887 | code: wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], |
888 | value: !(ext[5] & 0x04)); |
889 | input_report_key(dev: wdata->extension.input, |
890 | code: wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], |
891 | value: !(ext[5] & 0x08)); |
892 | } else { |
893 | input_report_key(dev: wdata->extension.input, |
894 | code: wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_Z], |
895 | value: !(ext[5] & 0x01)); |
896 | input_report_key(dev: wdata->extension.input, |
897 | code: wiimod_nunchuk_map[WIIMOD_NUNCHUK_KEY_C], |
898 | value: !(ext[5] & 0x02)); |
899 | } |
900 | |
901 | input_sync(dev: wdata->extension.input); |
902 | } |
903 | |
904 | static int wiimod_nunchuk_open(struct input_dev *dev) |
905 | { |
906 | struct wiimote_data *wdata = input_get_drvdata(dev); |
907 | unsigned long flags; |
908 | |
909 | spin_lock_irqsave(&wdata->state.lock, flags); |
910 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
911 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
912 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
913 | |
914 | return 0; |
915 | } |
916 | |
917 | static void wiimod_nunchuk_close(struct input_dev *dev) |
918 | { |
919 | struct wiimote_data *wdata = input_get_drvdata(dev); |
920 | unsigned long flags; |
921 | |
922 | spin_lock_irqsave(&wdata->state.lock, flags); |
923 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
924 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
925 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
926 | } |
927 | |
928 | static int wiimod_nunchuk_probe(const struct wiimod_ops *ops, |
929 | struct wiimote_data *wdata) |
930 | { |
931 | int ret, i; |
932 | |
933 | wdata->extension.input = input_allocate_device(); |
934 | if (!wdata->extension.input) |
935 | return -ENOMEM; |
936 | |
937 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
938 | wdata->extension.input->open = wiimod_nunchuk_open; |
939 | wdata->extension.input->close = wiimod_nunchuk_close; |
940 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
941 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
942 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
943 | wdata->extension.input->id.product = wdata->hdev->product; |
944 | wdata->extension.input->id.version = wdata->hdev->version; |
945 | wdata->extension.input->name = WIIMOTE_NAME " Nunchuk" ; |
946 | |
947 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
948 | for (i = 0; i < WIIMOD_NUNCHUK_KEY_NUM; ++i) |
949 | set_bit(nr: wiimod_nunchuk_map[i], |
950 | addr: wdata->extension.input->keybit); |
951 | |
952 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
953 | set_bit(ABS_HAT0X, addr: wdata->extension.input->absbit); |
954 | set_bit(ABS_HAT0Y, addr: wdata->extension.input->absbit); |
955 | input_set_abs_params(dev: wdata->extension.input, |
956 | ABS_HAT0X, min: -120, max: 120, fuzz: 2, flat: 4); |
957 | input_set_abs_params(dev: wdata->extension.input, |
958 | ABS_HAT0Y, min: -120, max: 120, fuzz: 2, flat: 4); |
959 | set_bit(ABS_RX, addr: wdata->extension.input->absbit); |
960 | set_bit(ABS_RY, addr: wdata->extension.input->absbit); |
961 | set_bit(ABS_RZ, addr: wdata->extension.input->absbit); |
962 | input_set_abs_params(dev: wdata->extension.input, |
963 | ABS_RX, min: -500, max: 500, fuzz: 2, flat: 4); |
964 | input_set_abs_params(dev: wdata->extension.input, |
965 | ABS_RY, min: -500, max: 500, fuzz: 2, flat: 4); |
966 | input_set_abs_params(dev: wdata->extension.input, |
967 | ABS_RZ, min: -500, max: 500, fuzz: 2, flat: 4); |
968 | |
969 | ret = input_register_device(wdata->extension.input); |
970 | if (ret) |
971 | goto err_free; |
972 | |
973 | return 0; |
974 | |
975 | err_free: |
976 | input_free_device(dev: wdata->extension.input); |
977 | wdata->extension.input = NULL; |
978 | return ret; |
979 | } |
980 | |
981 | static void wiimod_nunchuk_remove(const struct wiimod_ops *ops, |
982 | struct wiimote_data *wdata) |
983 | { |
984 | if (!wdata->extension.input) |
985 | return; |
986 | |
987 | input_unregister_device(wdata->extension.input); |
988 | wdata->extension.input = NULL; |
989 | } |
990 | |
991 | static const struct wiimod_ops wiimod_nunchuk = { |
992 | .flags = 0, |
993 | .arg = 0, |
994 | .probe = wiimod_nunchuk_probe, |
995 | .remove = wiimod_nunchuk_remove, |
996 | .in_ext = wiimod_nunchuk_in_ext, |
997 | }; |
998 | |
999 | /* |
1000 | * Classic Controller |
1001 | * Another official extension from Nintendo. It provides a classic |
1002 | * gamecube-like controller that can be hotplugged on the Wii Remote. |
1003 | * It has several hardware buttons and switches that are all reported via |
1004 | * a normal extension device. |
1005 | */ |
1006 | |
1007 | enum wiimod_classic_keys { |
1008 | WIIMOD_CLASSIC_KEY_A, |
1009 | WIIMOD_CLASSIC_KEY_B, |
1010 | WIIMOD_CLASSIC_KEY_X, |
1011 | WIIMOD_CLASSIC_KEY_Y, |
1012 | WIIMOD_CLASSIC_KEY_ZL, |
1013 | WIIMOD_CLASSIC_KEY_ZR, |
1014 | WIIMOD_CLASSIC_KEY_PLUS, |
1015 | WIIMOD_CLASSIC_KEY_MINUS, |
1016 | WIIMOD_CLASSIC_KEY_HOME, |
1017 | WIIMOD_CLASSIC_KEY_LEFT, |
1018 | WIIMOD_CLASSIC_KEY_RIGHT, |
1019 | WIIMOD_CLASSIC_KEY_UP, |
1020 | WIIMOD_CLASSIC_KEY_DOWN, |
1021 | WIIMOD_CLASSIC_KEY_LT, |
1022 | WIIMOD_CLASSIC_KEY_RT, |
1023 | WIIMOD_CLASSIC_KEY_NUM, |
1024 | }; |
1025 | |
1026 | static const __u16 wiimod_classic_map[] = { |
1027 | BTN_A, /* WIIMOD_CLASSIC_KEY_A */ |
1028 | BTN_B, /* WIIMOD_CLASSIC_KEY_B */ |
1029 | BTN_X, /* WIIMOD_CLASSIC_KEY_X */ |
1030 | BTN_Y, /* WIIMOD_CLASSIC_KEY_Y */ |
1031 | BTN_TL2, /* WIIMOD_CLASSIC_KEY_ZL */ |
1032 | BTN_TR2, /* WIIMOD_CLASSIC_KEY_ZR */ |
1033 | KEY_NEXT, /* WIIMOD_CLASSIC_KEY_PLUS */ |
1034 | KEY_PREVIOUS, /* WIIMOD_CLASSIC_KEY_MINUS */ |
1035 | BTN_MODE, /* WIIMOD_CLASSIC_KEY_HOME */ |
1036 | KEY_LEFT, /* WIIMOD_CLASSIC_KEY_LEFT */ |
1037 | KEY_RIGHT, /* WIIMOD_CLASSIC_KEY_RIGHT */ |
1038 | KEY_UP, /* WIIMOD_CLASSIC_KEY_UP */ |
1039 | KEY_DOWN, /* WIIMOD_CLASSIC_KEY_DOWN */ |
1040 | BTN_TL, /* WIIMOD_CLASSIC_KEY_LT */ |
1041 | BTN_TR, /* WIIMOD_CLASSIC_KEY_RT */ |
1042 | }; |
1043 | |
1044 | static void wiimod_classic_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
1045 | { |
1046 | __s8 rx, ry, lx, ly, lt, rt; |
1047 | |
1048 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
1049 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1050 | * 1 | RX <5:4> | LX <5:0> | |
1051 | * 2 | RX <3:2> | LY <5:0> | |
1052 | * -----+-----+-----+-----+-----------------------------+ |
1053 | * 3 |RX<1>| LT <5:4> | RY <5:1> | |
1054 | * -----+-----+-----------+-----------------------------+ |
1055 | * 4 | LT <3:1> | RT <5:1> | |
1056 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1057 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | |
1058 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1059 | * 6 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | |
1060 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1061 | * All buttons are 0 if pressed |
1062 | * RX and RY are right analog stick |
1063 | * LX and LY are left analog stick |
1064 | * LT is left trigger, RT is right trigger |
1065 | * BLT is 0 if left trigger is fully pressed |
1066 | * BRT is 0 if right trigger is fully pressed |
1067 | * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons |
1068 | * BZL is left Z button and BZR is right Z button |
1069 | * B-, BH, B+ are +, HOME and - buttons |
1070 | * BB, BY, BA, BX are A, B, X, Y buttons |
1071 | * LSB of RX, RY, LT, and RT are not transmitted and always 0. |
1072 | * |
1073 | * With motionp enabled it changes slightly to this: |
1074 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
1075 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1076 | * 1 | RX <5:4> | LX <5:1> | BDU | |
1077 | * 2 | RX <3:2> | LY <5:1> | BDL | |
1078 | * -----+-----+-----+-----+-----------------------+-----+ |
1079 | * 3 |RX<1>| LT <5:4> | RY <5:1> | |
1080 | * -----+-----+-----------+-----------------------------+ |
1081 | * 4 | LT <3:1> | RT <5:1> | |
1082 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1083 | * 5 | BDR | BDD | BLT | B- | BH | B+ | BRT | EXT | |
1084 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1085 | * 6 | BZL | BB | BY | BA | BX | BZR | 0 | 0 | |
1086 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1087 | * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest |
1088 | * is the same as before. |
1089 | */ |
1090 | |
1091 | static const s8 digital_to_analog[3] = {0x20, 0, -0x20}; |
1092 | |
1093 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
1094 | if (wiimote_dpad_as_analog) { |
1095 | lx = digital_to_analog[1 - !(ext[4] & 0x80) |
1096 | + !(ext[1] & 0x01)]; |
1097 | ly = digital_to_analog[1 - !(ext[4] & 0x40) |
1098 | + !(ext[0] & 0x01)]; |
1099 | } else { |
1100 | lx = (ext[0] & 0x3e) - 0x20; |
1101 | ly = (ext[1] & 0x3e) - 0x20; |
1102 | } |
1103 | } else { |
1104 | if (wiimote_dpad_as_analog) { |
1105 | lx = digital_to_analog[1 - !(ext[4] & 0x80) |
1106 | + !(ext[5] & 0x02)]; |
1107 | ly = digital_to_analog[1 - !(ext[4] & 0x40) |
1108 | + !(ext[5] & 0x01)]; |
1109 | } else { |
1110 | lx = (ext[0] & 0x3f) - 0x20; |
1111 | ly = (ext[1] & 0x3f) - 0x20; |
1112 | } |
1113 | } |
1114 | |
1115 | rx = (ext[0] >> 3) & 0x18; |
1116 | rx |= (ext[1] >> 5) & 0x06; |
1117 | rx |= (ext[2] >> 7) & 0x01; |
1118 | ry = ext[2] & 0x1f; |
1119 | |
1120 | rt = ext[3] & 0x1f; |
1121 | lt = (ext[2] >> 2) & 0x18; |
1122 | lt |= (ext[3] >> 5) & 0x07; |
1123 | |
1124 | rx <<= 1; |
1125 | ry <<= 1; |
1126 | rt <<= 1; |
1127 | lt <<= 1; |
1128 | |
1129 | input_report_abs(dev: wdata->extension.input, ABS_HAT1X, value: lx); |
1130 | input_report_abs(dev: wdata->extension.input, ABS_HAT1Y, value: ly); |
1131 | input_report_abs(dev: wdata->extension.input, ABS_HAT2X, value: rx - 0x20); |
1132 | input_report_abs(dev: wdata->extension.input, ABS_HAT2Y, value: ry - 0x20); |
1133 | input_report_abs(dev: wdata->extension.input, ABS_HAT3X, value: rt); |
1134 | input_report_abs(dev: wdata->extension.input, ABS_HAT3Y, value: lt); |
1135 | |
1136 | input_report_key(dev: wdata->extension.input, |
1137 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_LT], |
1138 | value: !(ext[4] & 0x20)); |
1139 | input_report_key(dev: wdata->extension.input, |
1140 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_MINUS], |
1141 | value: !(ext[4] & 0x10)); |
1142 | input_report_key(dev: wdata->extension.input, |
1143 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_HOME], |
1144 | value: !(ext[4] & 0x08)); |
1145 | input_report_key(dev: wdata->extension.input, |
1146 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_PLUS], |
1147 | value: !(ext[4] & 0x04)); |
1148 | input_report_key(dev: wdata->extension.input, |
1149 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_RT], |
1150 | value: !(ext[4] & 0x02)); |
1151 | input_report_key(dev: wdata->extension.input, |
1152 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZL], |
1153 | value: !(ext[5] & 0x80)); |
1154 | input_report_key(dev: wdata->extension.input, |
1155 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_B], |
1156 | value: !(ext[5] & 0x40)); |
1157 | input_report_key(dev: wdata->extension.input, |
1158 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_Y], |
1159 | value: !(ext[5] & 0x20)); |
1160 | input_report_key(dev: wdata->extension.input, |
1161 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_A], |
1162 | value: !(ext[5] & 0x10)); |
1163 | input_report_key(dev: wdata->extension.input, |
1164 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_X], |
1165 | value: !(ext[5] & 0x08)); |
1166 | input_report_key(dev: wdata->extension.input, |
1167 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_ZR], |
1168 | value: !(ext[5] & 0x04)); |
1169 | |
1170 | if (!wiimote_dpad_as_analog) { |
1171 | input_report_key(dev: wdata->extension.input, |
1172 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_RIGHT], |
1173 | value: !(ext[4] & 0x80)); |
1174 | input_report_key(dev: wdata->extension.input, |
1175 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_DOWN], |
1176 | value: !(ext[4] & 0x40)); |
1177 | |
1178 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
1179 | input_report_key(dev: wdata->extension.input, |
1180 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT], |
1181 | value: !(ext[1] & 0x01)); |
1182 | input_report_key(dev: wdata->extension.input, |
1183 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP], |
1184 | value: !(ext[0] & 0x01)); |
1185 | } else { |
1186 | input_report_key(dev: wdata->extension.input, |
1187 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_LEFT], |
1188 | value: !(ext[5] & 0x02)); |
1189 | input_report_key(dev: wdata->extension.input, |
1190 | code: wiimod_classic_map[WIIMOD_CLASSIC_KEY_UP], |
1191 | value: !(ext[5] & 0x01)); |
1192 | } |
1193 | } |
1194 | |
1195 | input_sync(dev: wdata->extension.input); |
1196 | } |
1197 | |
1198 | static int wiimod_classic_open(struct input_dev *dev) |
1199 | { |
1200 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1201 | unsigned long flags; |
1202 | |
1203 | spin_lock_irqsave(&wdata->state.lock, flags); |
1204 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
1205 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1206 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1207 | |
1208 | return 0; |
1209 | } |
1210 | |
1211 | static void wiimod_classic_close(struct input_dev *dev) |
1212 | { |
1213 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1214 | unsigned long flags; |
1215 | |
1216 | spin_lock_irqsave(&wdata->state.lock, flags); |
1217 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
1218 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1219 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1220 | } |
1221 | |
1222 | static int wiimod_classic_probe(const struct wiimod_ops *ops, |
1223 | struct wiimote_data *wdata) |
1224 | { |
1225 | int ret, i; |
1226 | |
1227 | wdata->extension.input = input_allocate_device(); |
1228 | if (!wdata->extension.input) |
1229 | return -ENOMEM; |
1230 | |
1231 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
1232 | wdata->extension.input->open = wiimod_classic_open; |
1233 | wdata->extension.input->close = wiimod_classic_close; |
1234 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
1235 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
1236 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
1237 | wdata->extension.input->id.product = wdata->hdev->product; |
1238 | wdata->extension.input->id.version = wdata->hdev->version; |
1239 | wdata->extension.input->name = WIIMOTE_NAME " Classic Controller" ; |
1240 | |
1241 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
1242 | for (i = 0; i < WIIMOD_CLASSIC_KEY_NUM; ++i) |
1243 | set_bit(nr: wiimod_classic_map[i], |
1244 | addr: wdata->extension.input->keybit); |
1245 | |
1246 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
1247 | set_bit(ABS_HAT1X, addr: wdata->extension.input->absbit); |
1248 | set_bit(ABS_HAT1Y, addr: wdata->extension.input->absbit); |
1249 | set_bit(ABS_HAT2X, addr: wdata->extension.input->absbit); |
1250 | set_bit(ABS_HAT2Y, addr: wdata->extension.input->absbit); |
1251 | set_bit(ABS_HAT3X, addr: wdata->extension.input->absbit); |
1252 | set_bit(ABS_HAT3Y, addr: wdata->extension.input->absbit); |
1253 | input_set_abs_params(dev: wdata->extension.input, |
1254 | ABS_HAT1X, min: -30, max: 30, fuzz: 1, flat: 1); |
1255 | input_set_abs_params(dev: wdata->extension.input, |
1256 | ABS_HAT1Y, min: -30, max: 30, fuzz: 1, flat: 1); |
1257 | input_set_abs_params(dev: wdata->extension.input, |
1258 | ABS_HAT2X, min: -30, max: 30, fuzz: 1, flat: 1); |
1259 | input_set_abs_params(dev: wdata->extension.input, |
1260 | ABS_HAT2Y, min: -30, max: 30, fuzz: 1, flat: 1); |
1261 | input_set_abs_params(dev: wdata->extension.input, |
1262 | ABS_HAT3X, min: -30, max: 30, fuzz: 1, flat: 1); |
1263 | input_set_abs_params(dev: wdata->extension.input, |
1264 | ABS_HAT3Y, min: -30, max: 30, fuzz: 1, flat: 1); |
1265 | |
1266 | ret = input_register_device(wdata->extension.input); |
1267 | if (ret) |
1268 | goto err_free; |
1269 | |
1270 | return 0; |
1271 | |
1272 | err_free: |
1273 | input_free_device(dev: wdata->extension.input); |
1274 | wdata->extension.input = NULL; |
1275 | return ret; |
1276 | } |
1277 | |
1278 | static void wiimod_classic_remove(const struct wiimod_ops *ops, |
1279 | struct wiimote_data *wdata) |
1280 | { |
1281 | if (!wdata->extension.input) |
1282 | return; |
1283 | |
1284 | input_unregister_device(wdata->extension.input); |
1285 | wdata->extension.input = NULL; |
1286 | } |
1287 | |
1288 | static const struct wiimod_ops wiimod_classic = { |
1289 | .flags = 0, |
1290 | .arg = 0, |
1291 | .probe = wiimod_classic_probe, |
1292 | .remove = wiimod_classic_remove, |
1293 | .in_ext = wiimod_classic_in_ext, |
1294 | }; |
1295 | |
1296 | /* |
1297 | * Balance Board Extension |
1298 | * The Nintendo Wii Balance Board provides four hardware weight sensor plus a |
1299 | * single push button. No other peripherals are available. However, the |
1300 | * balance-board data is sent via a standard Wii Remote extension. All other |
1301 | * data for non-present hardware is zeroed out. |
1302 | * Some 3rd party devices react allergic if we try to access normal Wii Remote |
1303 | * hardware, so this extension module should be the only module that is loaded |
1304 | * on balance boards. |
1305 | * The balance board needs 8 bytes extension data instead of basic 6 bytes so |
1306 | * it needs the WIIMOD_FLAG_EXT8 flag. |
1307 | */ |
1308 | |
1309 | static void wiimod_bboard_in_keys(struct wiimote_data *wdata, const __u8 *keys) |
1310 | { |
1311 | input_report_key(dev: wdata->extension.input, BTN_A, |
1312 | value: !!(keys[1] & 0x08)); |
1313 | input_sync(dev: wdata->extension.input); |
1314 | } |
1315 | |
1316 | static void wiimod_bboard_in_ext(struct wiimote_data *wdata, |
1317 | const __u8 *ext) |
1318 | { |
1319 | __s32 val[4], tmp, div; |
1320 | unsigned int i; |
1321 | struct wiimote_state *s = &wdata->state; |
1322 | |
1323 | /* |
1324 | * Balance board data layout: |
1325 | * |
1326 | * Byte | 8 7 6 5 4 3 2 1 | |
1327 | * -----+--------------------------+ |
1328 | * 1 | Top Right <15:8> | |
1329 | * 2 | Top Right <7:0> | |
1330 | * -----+--------------------------+ |
1331 | * 3 | Bottom Right <15:8> | |
1332 | * 4 | Bottom Right <7:0> | |
1333 | * -----+--------------------------+ |
1334 | * 5 | Top Left <15:8> | |
1335 | * 6 | Top Left <7:0> | |
1336 | * -----+--------------------------+ |
1337 | * 7 | Bottom Left <15:8> | |
1338 | * 8 | Bottom Left <7:0> | |
1339 | * -----+--------------------------+ |
1340 | * |
1341 | * These values represent the weight-measurements of the Wii-balance |
1342 | * board with 16bit precision. |
1343 | * |
1344 | * The balance-board is never reported interleaved with motionp. |
1345 | */ |
1346 | |
1347 | val[0] = ext[0]; |
1348 | val[0] <<= 8; |
1349 | val[0] |= ext[1]; |
1350 | |
1351 | val[1] = ext[2]; |
1352 | val[1] <<= 8; |
1353 | val[1] |= ext[3]; |
1354 | |
1355 | val[2] = ext[4]; |
1356 | val[2] <<= 8; |
1357 | val[2] |= ext[5]; |
1358 | |
1359 | val[3] = ext[6]; |
1360 | val[3] <<= 8; |
1361 | val[3] |= ext[7]; |
1362 | |
1363 | /* apply calibration data */ |
1364 | for (i = 0; i < 4; i++) { |
1365 | if (val[i] <= s->calib_bboard[i][0]) { |
1366 | tmp = 0; |
1367 | } else if (val[i] < s->calib_bboard[i][1]) { |
1368 | tmp = val[i] - s->calib_bboard[i][0]; |
1369 | tmp *= 1700; |
1370 | div = s->calib_bboard[i][1] - s->calib_bboard[i][0]; |
1371 | tmp /= div ? div : 1; |
1372 | } else { |
1373 | tmp = val[i] - s->calib_bboard[i][1]; |
1374 | tmp *= 1700; |
1375 | div = s->calib_bboard[i][2] - s->calib_bboard[i][1]; |
1376 | tmp /= div ? div : 1; |
1377 | tmp += 1700; |
1378 | } |
1379 | val[i] = tmp; |
1380 | } |
1381 | |
1382 | input_report_abs(dev: wdata->extension.input, ABS_HAT0X, value: val[0]); |
1383 | input_report_abs(dev: wdata->extension.input, ABS_HAT0Y, value: val[1]); |
1384 | input_report_abs(dev: wdata->extension.input, ABS_HAT1X, value: val[2]); |
1385 | input_report_abs(dev: wdata->extension.input, ABS_HAT1Y, value: val[3]); |
1386 | input_sync(dev: wdata->extension.input); |
1387 | } |
1388 | |
1389 | static int wiimod_bboard_open(struct input_dev *dev) |
1390 | { |
1391 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1392 | unsigned long flags; |
1393 | |
1394 | spin_lock_irqsave(&wdata->state.lock, flags); |
1395 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
1396 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1397 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1398 | |
1399 | return 0; |
1400 | } |
1401 | |
1402 | static void wiimod_bboard_close(struct input_dev *dev) |
1403 | { |
1404 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1405 | unsigned long flags; |
1406 | |
1407 | spin_lock_irqsave(&wdata->state.lock, flags); |
1408 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
1409 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1410 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1411 | } |
1412 | |
1413 | static ssize_t wiimod_bboard_calib_show(struct device *dev, |
1414 | struct device_attribute *attr, |
1415 | char *out) |
1416 | { |
1417 | struct wiimote_data *wdata = dev_to_wii(dev); |
1418 | int i, j, ret; |
1419 | __u16 val; |
1420 | __u8 buf[24], offs; |
1421 | |
1422 | ret = wiimote_cmd_acquire(wdata); |
1423 | if (ret) |
1424 | return ret; |
1425 | |
1426 | ret = wiimote_cmd_read(wdata, offset: 0xa40024, rmem: buf, size: 12); |
1427 | if (ret != 12) { |
1428 | wiimote_cmd_release(wdata); |
1429 | return ret < 0 ? ret : -EIO; |
1430 | } |
1431 | ret = wiimote_cmd_read(wdata, offset: 0xa40024 + 12, rmem: buf + 12, size: 12); |
1432 | if (ret != 12) { |
1433 | wiimote_cmd_release(wdata); |
1434 | return ret < 0 ? ret : -EIO; |
1435 | } |
1436 | |
1437 | wiimote_cmd_release(wdata); |
1438 | |
1439 | spin_lock_irq(lock: &wdata->state.lock); |
1440 | offs = 0; |
1441 | for (i = 0; i < 3; ++i) { |
1442 | for (j = 0; j < 4; ++j) { |
1443 | wdata->state.calib_bboard[j][i] = buf[offs]; |
1444 | wdata->state.calib_bboard[j][i] <<= 8; |
1445 | wdata->state.calib_bboard[j][i] |= buf[offs + 1]; |
1446 | offs += 2; |
1447 | } |
1448 | } |
1449 | spin_unlock_irq(lock: &wdata->state.lock); |
1450 | |
1451 | ret = 0; |
1452 | for (i = 0; i < 3; ++i) { |
1453 | for (j = 0; j < 4; ++j) { |
1454 | val = wdata->state.calib_bboard[j][i]; |
1455 | if (i == 2 && j == 3) |
1456 | ret += sprintf(buf: &out[ret], fmt: "%04x\n" , val); |
1457 | else |
1458 | ret += sprintf(buf: &out[ret], fmt: "%04x:" , val); |
1459 | } |
1460 | } |
1461 | |
1462 | return ret; |
1463 | } |
1464 | |
1465 | static DEVICE_ATTR(bboard_calib, S_IRUGO, wiimod_bboard_calib_show, NULL); |
1466 | |
1467 | static int wiimod_bboard_probe(const struct wiimod_ops *ops, |
1468 | struct wiimote_data *wdata) |
1469 | { |
1470 | int ret, i, j; |
1471 | __u8 buf[24], offs; |
1472 | |
1473 | wiimote_cmd_acquire_noint(wdata); |
1474 | |
1475 | ret = wiimote_cmd_read(wdata, offset: 0xa40024, rmem: buf, size: 12); |
1476 | if (ret != 12) { |
1477 | wiimote_cmd_release(wdata); |
1478 | return ret < 0 ? ret : -EIO; |
1479 | } |
1480 | ret = wiimote_cmd_read(wdata, offset: 0xa40024 + 12, rmem: buf + 12, size: 12); |
1481 | if (ret != 12) { |
1482 | wiimote_cmd_release(wdata); |
1483 | return ret < 0 ? ret : -EIO; |
1484 | } |
1485 | |
1486 | wiimote_cmd_release(wdata); |
1487 | |
1488 | offs = 0; |
1489 | for (i = 0; i < 3; ++i) { |
1490 | for (j = 0; j < 4; ++j) { |
1491 | wdata->state.calib_bboard[j][i] = buf[offs]; |
1492 | wdata->state.calib_bboard[j][i] <<= 8; |
1493 | wdata->state.calib_bboard[j][i] |= buf[offs + 1]; |
1494 | offs += 2; |
1495 | } |
1496 | } |
1497 | |
1498 | wdata->extension.input = input_allocate_device(); |
1499 | if (!wdata->extension.input) |
1500 | return -ENOMEM; |
1501 | |
1502 | ret = device_create_file(device: &wdata->hdev->dev, |
1503 | entry: &dev_attr_bboard_calib); |
1504 | if (ret) { |
1505 | hid_err(wdata->hdev, "cannot create sysfs attribute\n" ); |
1506 | goto err_free; |
1507 | } |
1508 | |
1509 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
1510 | wdata->extension.input->open = wiimod_bboard_open; |
1511 | wdata->extension.input->close = wiimod_bboard_close; |
1512 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
1513 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
1514 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
1515 | wdata->extension.input->id.product = wdata->hdev->product; |
1516 | wdata->extension.input->id.version = wdata->hdev->version; |
1517 | wdata->extension.input->name = WIIMOTE_NAME " Balance Board" ; |
1518 | |
1519 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
1520 | set_bit(BTN_A, addr: wdata->extension.input->keybit); |
1521 | |
1522 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
1523 | set_bit(ABS_HAT0X, addr: wdata->extension.input->absbit); |
1524 | set_bit(ABS_HAT0Y, addr: wdata->extension.input->absbit); |
1525 | set_bit(ABS_HAT1X, addr: wdata->extension.input->absbit); |
1526 | set_bit(ABS_HAT1Y, addr: wdata->extension.input->absbit); |
1527 | input_set_abs_params(dev: wdata->extension.input, |
1528 | ABS_HAT0X, min: 0, max: 65535, fuzz: 2, flat: 4); |
1529 | input_set_abs_params(dev: wdata->extension.input, |
1530 | ABS_HAT0Y, min: 0, max: 65535, fuzz: 2, flat: 4); |
1531 | input_set_abs_params(dev: wdata->extension.input, |
1532 | ABS_HAT1X, min: 0, max: 65535, fuzz: 2, flat: 4); |
1533 | input_set_abs_params(dev: wdata->extension.input, |
1534 | ABS_HAT1Y, min: 0, max: 65535, fuzz: 2, flat: 4); |
1535 | |
1536 | ret = input_register_device(wdata->extension.input); |
1537 | if (ret) |
1538 | goto err_file; |
1539 | |
1540 | return 0; |
1541 | |
1542 | err_file: |
1543 | device_remove_file(dev: &wdata->hdev->dev, |
1544 | attr: &dev_attr_bboard_calib); |
1545 | err_free: |
1546 | input_free_device(dev: wdata->extension.input); |
1547 | wdata->extension.input = NULL; |
1548 | return ret; |
1549 | } |
1550 | |
1551 | static void wiimod_bboard_remove(const struct wiimod_ops *ops, |
1552 | struct wiimote_data *wdata) |
1553 | { |
1554 | if (!wdata->extension.input) |
1555 | return; |
1556 | |
1557 | input_unregister_device(wdata->extension.input); |
1558 | wdata->extension.input = NULL; |
1559 | device_remove_file(dev: &wdata->hdev->dev, |
1560 | attr: &dev_attr_bboard_calib); |
1561 | } |
1562 | |
1563 | static const struct wiimod_ops wiimod_bboard = { |
1564 | .flags = WIIMOD_FLAG_EXT8, |
1565 | .arg = 0, |
1566 | .probe = wiimod_bboard_probe, |
1567 | .remove = wiimod_bboard_remove, |
1568 | .in_keys = wiimod_bboard_in_keys, |
1569 | .in_ext = wiimod_bboard_in_ext, |
1570 | }; |
1571 | |
1572 | /* |
1573 | * Pro Controller |
1574 | * Released with the Wii U was the Nintendo Wii U Pro Controller. It does not |
1575 | * work together with the classic Wii, but only with the new Wii U. However, it |
1576 | * uses the same protocol and provides a builtin "classic controller pro" |
1577 | * extension, few standard buttons, a rumble motor, 4 LEDs and a battery. |
1578 | * We provide all these via a standard extension device as the device doesn't |
1579 | * feature an extension port. |
1580 | */ |
1581 | |
1582 | enum wiimod_pro_keys { |
1583 | WIIMOD_PRO_KEY_A, |
1584 | WIIMOD_PRO_KEY_B, |
1585 | WIIMOD_PRO_KEY_X, |
1586 | WIIMOD_PRO_KEY_Y, |
1587 | WIIMOD_PRO_KEY_PLUS, |
1588 | WIIMOD_PRO_KEY_MINUS, |
1589 | WIIMOD_PRO_KEY_HOME, |
1590 | WIIMOD_PRO_KEY_LEFT, |
1591 | WIIMOD_PRO_KEY_RIGHT, |
1592 | WIIMOD_PRO_KEY_UP, |
1593 | WIIMOD_PRO_KEY_DOWN, |
1594 | WIIMOD_PRO_KEY_TL, |
1595 | WIIMOD_PRO_KEY_TR, |
1596 | WIIMOD_PRO_KEY_ZL, |
1597 | WIIMOD_PRO_KEY_ZR, |
1598 | WIIMOD_PRO_KEY_THUMBL, |
1599 | WIIMOD_PRO_KEY_THUMBR, |
1600 | WIIMOD_PRO_KEY_NUM, |
1601 | }; |
1602 | |
1603 | static const __u16 wiimod_pro_map[] = { |
1604 | BTN_EAST, /* WIIMOD_PRO_KEY_A */ |
1605 | BTN_SOUTH, /* WIIMOD_PRO_KEY_B */ |
1606 | BTN_NORTH, /* WIIMOD_PRO_KEY_X */ |
1607 | BTN_WEST, /* WIIMOD_PRO_KEY_Y */ |
1608 | BTN_START, /* WIIMOD_PRO_KEY_PLUS */ |
1609 | BTN_SELECT, /* WIIMOD_PRO_KEY_MINUS */ |
1610 | BTN_MODE, /* WIIMOD_PRO_KEY_HOME */ |
1611 | BTN_DPAD_LEFT, /* WIIMOD_PRO_KEY_LEFT */ |
1612 | BTN_DPAD_RIGHT, /* WIIMOD_PRO_KEY_RIGHT */ |
1613 | BTN_DPAD_UP, /* WIIMOD_PRO_KEY_UP */ |
1614 | BTN_DPAD_DOWN, /* WIIMOD_PRO_KEY_DOWN */ |
1615 | BTN_TL, /* WIIMOD_PRO_KEY_TL */ |
1616 | BTN_TR, /* WIIMOD_PRO_KEY_TR */ |
1617 | BTN_TL2, /* WIIMOD_PRO_KEY_ZL */ |
1618 | BTN_TR2, /* WIIMOD_PRO_KEY_ZR */ |
1619 | BTN_THUMBL, /* WIIMOD_PRO_KEY_THUMBL */ |
1620 | BTN_THUMBR, /* WIIMOD_PRO_KEY_THUMBR */ |
1621 | }; |
1622 | |
1623 | static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
1624 | { |
1625 | __s16 rx, ry, lx, ly; |
1626 | |
1627 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
1628 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1629 | * 1 | LX <7:0> | |
1630 | * -----+-----------------------+-----------------------+ |
1631 | * 2 | 0 0 0 0 | LX <11:8> | |
1632 | * -----+-----------------------+-----------------------+ |
1633 | * 3 | RX <7:0> | |
1634 | * -----+-----------------------+-----------------------+ |
1635 | * 4 | 0 0 0 0 | RX <11:8> | |
1636 | * -----+-----------------------+-----------------------+ |
1637 | * 5 | LY <7:0> | |
1638 | * -----+-----------------------+-----------------------+ |
1639 | * 6 | 0 0 0 0 | LY <11:8> | |
1640 | * -----+-----------------------+-----------------------+ |
1641 | * 7 | RY <7:0> | |
1642 | * -----+-----------------------+-----------------------+ |
1643 | * 8 | 0 0 0 0 | RY <11:8> | |
1644 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1645 | * 9 | BDR | BDD | BLT | B- | BH | B+ | BRT | 1 | |
1646 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1647 | * 10 | BZL | BB | BY | BA | BX | BZR | BDL | BDU | |
1648 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
1649 | * 11 | 1 | BATTERY | USB |CHARG|LTHUM|RTHUM| |
1650 | * -----+-----+-----------------+-----------+-----+-----+ |
1651 | * All buttons are low-active (0 if pressed) |
1652 | * RX and RY are right analog stick |
1653 | * LX and LY are left analog stick |
1654 | * BLT is left trigger, BRT is right trigger. |
1655 | * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons |
1656 | * BZL is left Z button and BZR is right Z button |
1657 | * B-, BH, B+ are +, HOME and - buttons |
1658 | * BB, BY, BA, BX are A, B, X, Y buttons |
1659 | * |
1660 | * Bits marked as 0/1 are unknown and never changed during tests. |
1661 | * |
1662 | * Not entirely verified: |
1663 | * CHARG: 1 if uncharging, 0 if charging |
1664 | * USB: 1 if not connected, 0 if connected |
1665 | * BATTERY: battery capacity from 000 (empty) to 100 (full) |
1666 | */ |
1667 | |
1668 | lx = (ext[0] & 0xff) | ((ext[1] & 0x0f) << 8); |
1669 | rx = (ext[2] & 0xff) | ((ext[3] & 0x0f) << 8); |
1670 | ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8); |
1671 | ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8); |
1672 | |
1673 | /* zero-point offsets */ |
1674 | lx -= 0x800; |
1675 | ly = 0x800 - ly; |
1676 | rx -= 0x800; |
1677 | ry = 0x800 - ry; |
1678 | |
1679 | /* Trivial automatic calibration. We don't know any calibration data |
1680 | * in the EEPROM so we must use the first report to calibrate the |
1681 | * null-position of the analog sticks. Users can retrigger calibration |
1682 | * via sysfs, or set it explicitly. If data is off more than abs(500), |
1683 | * we skip calibration as the sticks are likely to be moved already. */ |
1684 | if (!(wdata->state.flags & WIIPROTO_FLAG_PRO_CALIB_DONE)) { |
1685 | wdata->state.flags |= WIIPROTO_FLAG_PRO_CALIB_DONE; |
1686 | if (abs(lx) < 500) |
1687 | wdata->state.calib_pro_sticks[0] = -lx; |
1688 | if (abs(ly) < 500) |
1689 | wdata->state.calib_pro_sticks[1] = -ly; |
1690 | if (abs(rx) < 500) |
1691 | wdata->state.calib_pro_sticks[2] = -rx; |
1692 | if (abs(ry) < 500) |
1693 | wdata->state.calib_pro_sticks[3] = -ry; |
1694 | } |
1695 | |
1696 | /* apply calibration data */ |
1697 | lx += wdata->state.calib_pro_sticks[0]; |
1698 | ly += wdata->state.calib_pro_sticks[1]; |
1699 | rx += wdata->state.calib_pro_sticks[2]; |
1700 | ry += wdata->state.calib_pro_sticks[3]; |
1701 | |
1702 | input_report_abs(dev: wdata->extension.input, ABS_X, value: lx); |
1703 | input_report_abs(dev: wdata->extension.input, ABS_Y, value: ly); |
1704 | input_report_abs(dev: wdata->extension.input, ABS_RX, value: rx); |
1705 | input_report_abs(dev: wdata->extension.input, ABS_RY, value: ry); |
1706 | |
1707 | input_report_key(dev: wdata->extension.input, |
1708 | code: wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT], |
1709 | value: !(ext[8] & 0x80)); |
1710 | input_report_key(dev: wdata->extension.input, |
1711 | code: wiimod_pro_map[WIIMOD_PRO_KEY_DOWN], |
1712 | value: !(ext[8] & 0x40)); |
1713 | input_report_key(dev: wdata->extension.input, |
1714 | code: wiimod_pro_map[WIIMOD_PRO_KEY_TL], |
1715 | value: !(ext[8] & 0x20)); |
1716 | input_report_key(dev: wdata->extension.input, |
1717 | code: wiimod_pro_map[WIIMOD_PRO_KEY_MINUS], |
1718 | value: !(ext[8] & 0x10)); |
1719 | input_report_key(dev: wdata->extension.input, |
1720 | code: wiimod_pro_map[WIIMOD_PRO_KEY_HOME], |
1721 | value: !(ext[8] & 0x08)); |
1722 | input_report_key(dev: wdata->extension.input, |
1723 | code: wiimod_pro_map[WIIMOD_PRO_KEY_PLUS], |
1724 | value: !(ext[8] & 0x04)); |
1725 | input_report_key(dev: wdata->extension.input, |
1726 | code: wiimod_pro_map[WIIMOD_PRO_KEY_TR], |
1727 | value: !(ext[8] & 0x02)); |
1728 | |
1729 | input_report_key(dev: wdata->extension.input, |
1730 | code: wiimod_pro_map[WIIMOD_PRO_KEY_ZL], |
1731 | value: !(ext[9] & 0x80)); |
1732 | input_report_key(dev: wdata->extension.input, |
1733 | code: wiimod_pro_map[WIIMOD_PRO_KEY_B], |
1734 | value: !(ext[9] & 0x40)); |
1735 | input_report_key(dev: wdata->extension.input, |
1736 | code: wiimod_pro_map[WIIMOD_PRO_KEY_Y], |
1737 | value: !(ext[9] & 0x20)); |
1738 | input_report_key(dev: wdata->extension.input, |
1739 | code: wiimod_pro_map[WIIMOD_PRO_KEY_A], |
1740 | value: !(ext[9] & 0x10)); |
1741 | input_report_key(dev: wdata->extension.input, |
1742 | code: wiimod_pro_map[WIIMOD_PRO_KEY_X], |
1743 | value: !(ext[9] & 0x08)); |
1744 | input_report_key(dev: wdata->extension.input, |
1745 | code: wiimod_pro_map[WIIMOD_PRO_KEY_ZR], |
1746 | value: !(ext[9] & 0x04)); |
1747 | input_report_key(dev: wdata->extension.input, |
1748 | code: wiimod_pro_map[WIIMOD_PRO_KEY_LEFT], |
1749 | value: !(ext[9] & 0x02)); |
1750 | input_report_key(dev: wdata->extension.input, |
1751 | code: wiimod_pro_map[WIIMOD_PRO_KEY_UP], |
1752 | value: !(ext[9] & 0x01)); |
1753 | |
1754 | input_report_key(dev: wdata->extension.input, |
1755 | code: wiimod_pro_map[WIIMOD_PRO_KEY_THUMBL], |
1756 | value: !(ext[10] & 0x02)); |
1757 | input_report_key(dev: wdata->extension.input, |
1758 | code: wiimod_pro_map[WIIMOD_PRO_KEY_THUMBR], |
1759 | value: !(ext[10] & 0x01)); |
1760 | |
1761 | input_sync(dev: wdata->extension.input); |
1762 | } |
1763 | |
1764 | static int wiimod_pro_open(struct input_dev *dev) |
1765 | { |
1766 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1767 | unsigned long flags; |
1768 | |
1769 | spin_lock_irqsave(&wdata->state.lock, flags); |
1770 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
1771 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1772 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1773 | |
1774 | return 0; |
1775 | } |
1776 | |
1777 | static void wiimod_pro_close(struct input_dev *dev) |
1778 | { |
1779 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1780 | unsigned long flags; |
1781 | |
1782 | spin_lock_irqsave(&wdata->state.lock, flags); |
1783 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
1784 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
1785 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1786 | } |
1787 | |
1788 | static int wiimod_pro_play(struct input_dev *dev, void *data, |
1789 | struct ff_effect *eff) |
1790 | { |
1791 | struct wiimote_data *wdata = input_get_drvdata(dev); |
1792 | __u8 value; |
1793 | |
1794 | /* |
1795 | * The wiimote supports only a single rumble motor so if any magnitude |
1796 | * is set to non-zero then we start the rumble motor. If both are set to |
1797 | * zero, we stop the rumble motor. |
1798 | */ |
1799 | |
1800 | if (eff->u.rumble.strong_magnitude || eff->u.rumble.weak_magnitude) |
1801 | value = 1; |
1802 | else |
1803 | value = 0; |
1804 | |
1805 | /* Locking state.lock here might deadlock with input_event() calls. |
1806 | * schedule_work acts as barrier. Merging multiple changes is fine. */ |
1807 | wdata->state.cache_rumble = value; |
1808 | schedule_work(work: &wdata->rumble_worker); |
1809 | |
1810 | return 0; |
1811 | } |
1812 | |
1813 | static ssize_t wiimod_pro_calib_show(struct device *dev, |
1814 | struct device_attribute *attr, |
1815 | char *out) |
1816 | { |
1817 | struct wiimote_data *wdata = dev_to_wii(dev); |
1818 | int r; |
1819 | |
1820 | r = 0; |
1821 | r += sprintf(buf: &out[r], fmt: "%+06hd:" , wdata->state.calib_pro_sticks[0]); |
1822 | r += sprintf(buf: &out[r], fmt: "%+06hd " , wdata->state.calib_pro_sticks[1]); |
1823 | r += sprintf(buf: &out[r], fmt: "%+06hd:" , wdata->state.calib_pro_sticks[2]); |
1824 | r += sprintf(buf: &out[r], fmt: "%+06hd\n" , wdata->state.calib_pro_sticks[3]); |
1825 | |
1826 | return r; |
1827 | } |
1828 | |
1829 | static ssize_t wiimod_pro_calib_store(struct device *dev, |
1830 | struct device_attribute *attr, |
1831 | const char *buf, size_t count) |
1832 | { |
1833 | struct wiimote_data *wdata = dev_to_wii(dev); |
1834 | int r; |
1835 | s16 x1, y1, x2, y2; |
1836 | |
1837 | if (!strncmp(buf, "scan\n" , 5)) { |
1838 | spin_lock_irq(lock: &wdata->state.lock); |
1839 | wdata->state.flags &= ~WIIPROTO_FLAG_PRO_CALIB_DONE; |
1840 | spin_unlock_irq(lock: &wdata->state.lock); |
1841 | } else { |
1842 | r = sscanf(buf, "%hd:%hd %hd:%hd" , &x1, &y1, &x2, &y2); |
1843 | if (r != 4) |
1844 | return -EINVAL; |
1845 | |
1846 | spin_lock_irq(lock: &wdata->state.lock); |
1847 | wdata->state.flags |= WIIPROTO_FLAG_PRO_CALIB_DONE; |
1848 | spin_unlock_irq(lock: &wdata->state.lock); |
1849 | |
1850 | wdata->state.calib_pro_sticks[0] = x1; |
1851 | wdata->state.calib_pro_sticks[1] = y1; |
1852 | wdata->state.calib_pro_sticks[2] = x2; |
1853 | wdata->state.calib_pro_sticks[3] = y2; |
1854 | } |
1855 | |
1856 | return strnlen(p: buf, PAGE_SIZE); |
1857 | } |
1858 | |
1859 | static DEVICE_ATTR(pro_calib, S_IRUGO|S_IWUSR|S_IWGRP, wiimod_pro_calib_show, |
1860 | wiimod_pro_calib_store); |
1861 | |
1862 | static int wiimod_pro_probe(const struct wiimod_ops *ops, |
1863 | struct wiimote_data *wdata) |
1864 | { |
1865 | int ret, i; |
1866 | unsigned long flags; |
1867 | |
1868 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); |
1869 | wdata->state.calib_pro_sticks[0] = 0; |
1870 | wdata->state.calib_pro_sticks[1] = 0; |
1871 | wdata->state.calib_pro_sticks[2] = 0; |
1872 | wdata->state.calib_pro_sticks[3] = 0; |
1873 | |
1874 | spin_lock_irqsave(&wdata->state.lock, flags); |
1875 | wdata->state.flags &= ~WIIPROTO_FLAG_PRO_CALIB_DONE; |
1876 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1877 | |
1878 | wdata->extension.input = input_allocate_device(); |
1879 | if (!wdata->extension.input) |
1880 | return -ENOMEM; |
1881 | |
1882 | set_bit(FF_RUMBLE, addr: wdata->extension.input->ffbit); |
1883 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
1884 | |
1885 | if (input_ff_create_memless(dev: wdata->extension.input, NULL, |
1886 | play_effect: wiimod_pro_play)) { |
1887 | ret = -ENOMEM; |
1888 | goto err_free; |
1889 | } |
1890 | |
1891 | ret = device_create_file(device: &wdata->hdev->dev, |
1892 | entry: &dev_attr_pro_calib); |
1893 | if (ret) { |
1894 | hid_err(wdata->hdev, "cannot create sysfs attribute\n" ); |
1895 | goto err_free; |
1896 | } |
1897 | |
1898 | wdata->extension.input->open = wiimod_pro_open; |
1899 | wdata->extension.input->close = wiimod_pro_close; |
1900 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
1901 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
1902 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
1903 | wdata->extension.input->id.product = wdata->hdev->product; |
1904 | wdata->extension.input->id.version = wdata->hdev->version; |
1905 | wdata->extension.input->name = WIIMOTE_NAME " Pro Controller" ; |
1906 | |
1907 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
1908 | for (i = 0; i < WIIMOD_PRO_KEY_NUM; ++i) |
1909 | set_bit(nr: wiimod_pro_map[i], |
1910 | addr: wdata->extension.input->keybit); |
1911 | |
1912 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
1913 | set_bit(ABS_X, addr: wdata->extension.input->absbit); |
1914 | set_bit(ABS_Y, addr: wdata->extension.input->absbit); |
1915 | set_bit(ABS_RX, addr: wdata->extension.input->absbit); |
1916 | set_bit(ABS_RY, addr: wdata->extension.input->absbit); |
1917 | input_set_abs_params(dev: wdata->extension.input, |
1918 | ABS_X, min: -0x400, max: 0x400, fuzz: 4, flat: 100); |
1919 | input_set_abs_params(dev: wdata->extension.input, |
1920 | ABS_Y, min: -0x400, max: 0x400, fuzz: 4, flat: 100); |
1921 | input_set_abs_params(dev: wdata->extension.input, |
1922 | ABS_RX, min: -0x400, max: 0x400, fuzz: 4, flat: 100); |
1923 | input_set_abs_params(dev: wdata->extension.input, |
1924 | ABS_RY, min: -0x400, max: 0x400, fuzz: 4, flat: 100); |
1925 | |
1926 | ret = input_register_device(wdata->extension.input); |
1927 | if (ret) |
1928 | goto err_file; |
1929 | |
1930 | return 0; |
1931 | |
1932 | err_file: |
1933 | device_remove_file(dev: &wdata->hdev->dev, |
1934 | attr: &dev_attr_pro_calib); |
1935 | err_free: |
1936 | input_free_device(dev: wdata->extension.input); |
1937 | wdata->extension.input = NULL; |
1938 | return ret; |
1939 | } |
1940 | |
1941 | static void wiimod_pro_remove(const struct wiimod_ops *ops, |
1942 | struct wiimote_data *wdata) |
1943 | { |
1944 | unsigned long flags; |
1945 | |
1946 | if (!wdata->extension.input) |
1947 | return; |
1948 | |
1949 | input_unregister_device(wdata->extension.input); |
1950 | wdata->extension.input = NULL; |
1951 | cancel_work_sync(work: &wdata->rumble_worker); |
1952 | device_remove_file(dev: &wdata->hdev->dev, |
1953 | attr: &dev_attr_pro_calib); |
1954 | |
1955 | spin_lock_irqsave(&wdata->state.lock, flags); |
1956 | wiiproto_req_rumble(wdata, rumble: 0); |
1957 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
1958 | } |
1959 | |
1960 | static const struct wiimod_ops wiimod_pro = { |
1961 | .flags = WIIMOD_FLAG_EXT16, |
1962 | .arg = 0, |
1963 | .probe = wiimod_pro_probe, |
1964 | .remove = wiimod_pro_remove, |
1965 | .in_ext = wiimod_pro_in_ext, |
1966 | }; |
1967 | |
1968 | /* |
1969 | * Drums |
1970 | * Guitar-Hero, Rock-Band and other games came bundled with drums which can |
1971 | * be plugged as extension to a Wiimote. Drum-reports are still not entirely |
1972 | * figured out, but the most important information is known. |
1973 | * We create a separate device for drums and report all information via this |
1974 | * input device. |
1975 | */ |
1976 | |
1977 | static inline void wiimod_drums_report_pressure(struct wiimote_data *wdata, |
1978 | __u8 none, __u8 which, |
1979 | __u8 pressure, __u8 onoff, |
1980 | __u8 *store, __u16 code, |
1981 | __u8 which_code) |
1982 | { |
1983 | static const __u8 default_pressure = 3; |
1984 | |
1985 | if (!none && which == which_code) { |
1986 | *store = pressure; |
1987 | input_report_abs(dev: wdata->extension.input, code, value: *store); |
1988 | } else if (onoff != !!*store) { |
1989 | *store = onoff ? default_pressure : 0; |
1990 | input_report_abs(dev: wdata->extension.input, code, value: *store); |
1991 | } |
1992 | } |
1993 | |
1994 | static void wiimod_drums_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
1995 | { |
1996 | __u8 pressure, which, none, hhp, sx, sy; |
1997 | __u8 o, r, y, g, b, bass, bm, bp; |
1998 | |
1999 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
2000 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2001 | * 1 | 0 | 0 | SX <5:0> | |
2002 | * 2 | 0 | 0 | SY <5:0> | |
2003 | * -----+-----+-----+-----------------------------+-----+ |
2004 | * 3 | HPP | NON | WHICH <5:1> | ? | |
2005 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2006 | * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? | |
2007 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2008 | * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 | ? | |
2009 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2010 | * 6 | O | R | Y | G | B | BSS | 1 | 1 | |
2011 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2012 | * All buttons are 0 if pressed |
2013 | * |
2014 | * With Motion+ enabled, the following bits will get invalid: |
2015 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
2016 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2017 | * 1 | 0 | 0 | SX <5:1> |XXXXX| |
2018 | * 2 | 0 | 0 | SY <5:1> |XXXXX| |
2019 | * -----+-----+-----+-----------------------------+-----+ |
2020 | * 3 | HPP | NON | WHICH <5:1> | ? | |
2021 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2022 | * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? | |
2023 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2024 | * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 |XXXXX| |
2025 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2026 | * 6 | O | R | Y | G | B | BSS |XXXXX|XXXXX| |
2027 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2028 | */ |
2029 | |
2030 | pressure = 7 - (ext[3] >> 5); |
2031 | which = (ext[2] >> 1) & 0x1f; |
2032 | none = !!(ext[2] & 0x40); |
2033 | hhp = !(ext[2] & 0x80); |
2034 | sx = ext[0] & 0x3f; |
2035 | sy = ext[1] & 0x3f; |
2036 | o = !(ext[5] & 0x80); |
2037 | r = !(ext[5] & 0x40); |
2038 | y = !(ext[5] & 0x20); |
2039 | g = !(ext[5] & 0x10); |
2040 | b = !(ext[5] & 0x08); |
2041 | bass = !(ext[5] & 0x04); |
2042 | bm = !(ext[4] & 0x10); |
2043 | bp = !(ext[4] & 0x04); |
2044 | |
2045 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
2046 | sx &= 0x3e; |
2047 | sy &= 0x3e; |
2048 | } |
2049 | |
2050 | wiimod_drums_report_pressure(wdata, none, which, pressure, |
2051 | onoff: o, store: &wdata->state.pressure_drums[0], |
2052 | ABS_HAT2Y, which_code: 0x0e); |
2053 | wiimod_drums_report_pressure(wdata, none, which, pressure, |
2054 | onoff: r, store: &wdata->state.pressure_drums[1], |
2055 | ABS_HAT0X, which_code: 0x19); |
2056 | wiimod_drums_report_pressure(wdata, none, which, pressure, |
2057 | onoff: y, store: &wdata->state.pressure_drums[2], |
2058 | ABS_HAT2X, which_code: 0x11); |
2059 | wiimod_drums_report_pressure(wdata, none, which, pressure, |
2060 | onoff: g, store: &wdata->state.pressure_drums[3], |
2061 | ABS_HAT1X, which_code: 0x12); |
2062 | wiimod_drums_report_pressure(wdata, none, which, pressure, |
2063 | onoff: b, store: &wdata->state.pressure_drums[4], |
2064 | ABS_HAT0Y, which_code: 0x0f); |
2065 | |
2066 | /* Bass shares pressure with hi-hat (set via hhp) */ |
2067 | wiimod_drums_report_pressure(wdata, none, which: hhp ? 0xff : which, pressure, |
2068 | onoff: bass, store: &wdata->state.pressure_drums[5], |
2069 | ABS_HAT3X, which_code: 0x1b); |
2070 | /* Hi-hat has no on/off values, just pressure. Force to off/0. */ |
2071 | wiimod_drums_report_pressure(wdata, none, which: hhp ? which : 0xff, pressure, |
2072 | onoff: 0, store: &wdata->state.pressure_drums[6], |
2073 | ABS_HAT3Y, which_code: 0x0e); |
2074 | |
2075 | input_report_abs(dev: wdata->extension.input, ABS_X, value: sx - 0x20); |
2076 | input_report_abs(dev: wdata->extension.input, ABS_Y, value: sy - 0x20); |
2077 | |
2078 | input_report_key(dev: wdata->extension.input, BTN_START, value: bp); |
2079 | input_report_key(dev: wdata->extension.input, BTN_SELECT, value: bm); |
2080 | |
2081 | input_sync(dev: wdata->extension.input); |
2082 | } |
2083 | |
2084 | static int wiimod_drums_open(struct input_dev *dev) |
2085 | { |
2086 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2087 | unsigned long flags; |
2088 | |
2089 | spin_lock_irqsave(&wdata->state.lock, flags); |
2090 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
2091 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2092 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2093 | |
2094 | return 0; |
2095 | } |
2096 | |
2097 | static void wiimod_drums_close(struct input_dev *dev) |
2098 | { |
2099 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2100 | unsigned long flags; |
2101 | |
2102 | spin_lock_irqsave(&wdata->state.lock, flags); |
2103 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
2104 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2105 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2106 | } |
2107 | |
2108 | static int wiimod_drums_probe(const struct wiimod_ops *ops, |
2109 | struct wiimote_data *wdata) |
2110 | { |
2111 | int ret; |
2112 | |
2113 | wdata->extension.input = input_allocate_device(); |
2114 | if (!wdata->extension.input) |
2115 | return -ENOMEM; |
2116 | |
2117 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
2118 | wdata->extension.input->open = wiimod_drums_open; |
2119 | wdata->extension.input->close = wiimod_drums_close; |
2120 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
2121 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
2122 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
2123 | wdata->extension.input->id.product = wdata->hdev->product; |
2124 | wdata->extension.input->id.version = wdata->hdev->version; |
2125 | wdata->extension.input->name = WIIMOTE_NAME " Drums" ; |
2126 | |
2127 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
2128 | set_bit(BTN_START, addr: wdata->extension.input->keybit); |
2129 | set_bit(BTN_SELECT, addr: wdata->extension.input->keybit); |
2130 | |
2131 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
2132 | set_bit(ABS_X, addr: wdata->extension.input->absbit); |
2133 | set_bit(ABS_Y, addr: wdata->extension.input->absbit); |
2134 | set_bit(ABS_HAT0X, addr: wdata->extension.input->absbit); |
2135 | set_bit(ABS_HAT0Y, addr: wdata->extension.input->absbit); |
2136 | set_bit(ABS_HAT1X, addr: wdata->extension.input->absbit); |
2137 | set_bit(ABS_HAT2X, addr: wdata->extension.input->absbit); |
2138 | set_bit(ABS_HAT2Y, addr: wdata->extension.input->absbit); |
2139 | set_bit(ABS_HAT3X, addr: wdata->extension.input->absbit); |
2140 | set_bit(ABS_HAT3Y, addr: wdata->extension.input->absbit); |
2141 | input_set_abs_params(dev: wdata->extension.input, |
2142 | ABS_X, min: -32, max: 31, fuzz: 1, flat: 1); |
2143 | input_set_abs_params(dev: wdata->extension.input, |
2144 | ABS_Y, min: -32, max: 31, fuzz: 1, flat: 1); |
2145 | input_set_abs_params(dev: wdata->extension.input, |
2146 | ABS_HAT0X, min: 0, max: 7, fuzz: 0, flat: 0); |
2147 | input_set_abs_params(dev: wdata->extension.input, |
2148 | ABS_HAT0Y, min: 0, max: 7, fuzz: 0, flat: 0); |
2149 | input_set_abs_params(dev: wdata->extension.input, |
2150 | ABS_HAT1X, min: 0, max: 7, fuzz: 0, flat: 0); |
2151 | input_set_abs_params(dev: wdata->extension.input, |
2152 | ABS_HAT2X, min: 0, max: 7, fuzz: 0, flat: 0); |
2153 | input_set_abs_params(dev: wdata->extension.input, |
2154 | ABS_HAT2Y, min: 0, max: 7, fuzz: 0, flat: 0); |
2155 | input_set_abs_params(dev: wdata->extension.input, |
2156 | ABS_HAT3X, min: 0, max: 7, fuzz: 0, flat: 0); |
2157 | input_set_abs_params(dev: wdata->extension.input, |
2158 | ABS_HAT3Y, min: 0, max: 7, fuzz: 0, flat: 0); |
2159 | |
2160 | ret = input_register_device(wdata->extension.input); |
2161 | if (ret) |
2162 | goto err_free; |
2163 | |
2164 | return 0; |
2165 | |
2166 | err_free: |
2167 | input_free_device(dev: wdata->extension.input); |
2168 | wdata->extension.input = NULL; |
2169 | return ret; |
2170 | } |
2171 | |
2172 | static void wiimod_drums_remove(const struct wiimod_ops *ops, |
2173 | struct wiimote_data *wdata) |
2174 | { |
2175 | if (!wdata->extension.input) |
2176 | return; |
2177 | |
2178 | input_unregister_device(wdata->extension.input); |
2179 | wdata->extension.input = NULL; |
2180 | } |
2181 | |
2182 | static const struct wiimod_ops wiimod_drums = { |
2183 | .flags = 0, |
2184 | .arg = 0, |
2185 | .probe = wiimod_drums_probe, |
2186 | .remove = wiimod_drums_remove, |
2187 | .in_ext = wiimod_drums_in_ext, |
2188 | }; |
2189 | |
2190 | /* |
2191 | * Guitar |
2192 | * Guitar-Hero, Rock-Band and other games came bundled with guitars which can |
2193 | * be plugged as extension to a Wiimote. |
2194 | * We create a separate device for guitars and report all information via this |
2195 | * input device. |
2196 | */ |
2197 | |
2198 | enum wiimod_guitar_keys { |
2199 | WIIMOD_GUITAR_KEY_G, |
2200 | WIIMOD_GUITAR_KEY_R, |
2201 | WIIMOD_GUITAR_KEY_Y, |
2202 | WIIMOD_GUITAR_KEY_B, |
2203 | WIIMOD_GUITAR_KEY_O, |
2204 | WIIMOD_GUITAR_KEY_UP, |
2205 | WIIMOD_GUITAR_KEY_DOWN, |
2206 | WIIMOD_GUITAR_KEY_PLUS, |
2207 | WIIMOD_GUITAR_KEY_MINUS, |
2208 | WIIMOD_GUITAR_KEY_NUM, |
2209 | }; |
2210 | |
2211 | static const __u16 wiimod_guitar_map[] = { |
2212 | BTN_1, /* WIIMOD_GUITAR_KEY_G */ |
2213 | BTN_2, /* WIIMOD_GUITAR_KEY_R */ |
2214 | BTN_3, /* WIIMOD_GUITAR_KEY_Y */ |
2215 | BTN_4, /* WIIMOD_GUITAR_KEY_B */ |
2216 | BTN_5, /* WIIMOD_GUITAR_KEY_O */ |
2217 | BTN_DPAD_UP, /* WIIMOD_GUITAR_KEY_UP */ |
2218 | BTN_DPAD_DOWN, /* WIIMOD_GUITAR_KEY_DOWN */ |
2219 | BTN_START, /* WIIMOD_GUITAR_KEY_PLUS */ |
2220 | BTN_SELECT, /* WIIMOD_GUITAR_KEY_MINUS */ |
2221 | }; |
2222 | |
2223 | static void wiimod_guitar_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
2224 | { |
2225 | __u8 sx, sy, tb, wb, bd, bm, bp, bo, br, bb, bg, by, bu; |
2226 | |
2227 | /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
2228 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2229 | * 1 | 0 | 0 | SX <5:0> | |
2230 | * 2 | 0 | 0 | SY <5:0> | |
2231 | * -----+-----+-----+-----+-----------------------------+ |
2232 | * 3 | 0 | 0 | 0 | TB <4:0> | |
2233 | * -----+-----+-----+-----+-----------------------------+ |
2234 | * 4 | 0 | 0 | 0 | WB <4:0> | |
2235 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2236 | * 5 | 1 | BD | 1 | B- | 1 | B+ | 1 | 1 | |
2237 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2238 | * 6 | BO | BR | BB | BG | BY | 1 | 1 | BU | |
2239 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2240 | * All buttons are 0 if pressed |
2241 | * |
2242 | * With Motion+ enabled, it will look like this: |
2243 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
2244 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2245 | * 1 | 0 | 0 | SX <5:1> | BU | |
2246 | * 2 | 0 | 0 | SY <5:1> | 1 | |
2247 | * -----+-----+-----+-----+-----------------------+-----+ |
2248 | * 3 | 0 | 0 | 0 | TB <4:0> | |
2249 | * -----+-----+-----+-----+-----------------------------+ |
2250 | * 4 | 0 | 0 | 0 | WB <4:0> | |
2251 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2252 | * 5 | 1 | BD | 1 | B- | 1 | B+ | 1 |XXXXX| |
2253 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2254 | * 6 | BO | BR | BB | BG | BY | 1 |XXXXX|XXXXX| |
2255 | * -----+-----+-----+-----+-----+-----+-----+-----+-----+ |
2256 | */ |
2257 | |
2258 | sx = ext[0] & 0x3f; |
2259 | sy = ext[1] & 0x3f; |
2260 | tb = ext[2] & 0x1f; |
2261 | wb = ext[3] & 0x1f; |
2262 | bd = !(ext[4] & 0x40); |
2263 | bm = !(ext[4] & 0x10); |
2264 | bp = !(ext[4] & 0x04); |
2265 | bo = !(ext[5] & 0x80); |
2266 | br = !(ext[5] & 0x40); |
2267 | bb = !(ext[5] & 0x20); |
2268 | bg = !(ext[5] & 0x10); |
2269 | by = !(ext[5] & 0x08); |
2270 | bu = !(ext[5] & 0x01); |
2271 | |
2272 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
2273 | bu = !(ext[0] & 0x01); |
2274 | sx &= 0x3e; |
2275 | sy &= 0x3e; |
2276 | } |
2277 | |
2278 | input_report_abs(dev: wdata->extension.input, ABS_X, value: sx - 0x20); |
2279 | input_report_abs(dev: wdata->extension.input, ABS_Y, value: sy - 0x20); |
2280 | input_report_abs(dev: wdata->extension.input, ABS_HAT0X, value: tb); |
2281 | input_report_abs(dev: wdata->extension.input, ABS_HAT1X, value: wb - 0x10); |
2282 | |
2283 | input_report_key(dev: wdata->extension.input, |
2284 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_G], |
2285 | value: bg); |
2286 | input_report_key(dev: wdata->extension.input, |
2287 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_R], |
2288 | value: br); |
2289 | input_report_key(dev: wdata->extension.input, |
2290 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_Y], |
2291 | value: by); |
2292 | input_report_key(dev: wdata->extension.input, |
2293 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_B], |
2294 | value: bb); |
2295 | input_report_key(dev: wdata->extension.input, |
2296 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_O], |
2297 | value: bo); |
2298 | input_report_key(dev: wdata->extension.input, |
2299 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_UP], |
2300 | value: bu); |
2301 | input_report_key(dev: wdata->extension.input, |
2302 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_DOWN], |
2303 | value: bd); |
2304 | input_report_key(dev: wdata->extension.input, |
2305 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_PLUS], |
2306 | value: bp); |
2307 | input_report_key(dev: wdata->extension.input, |
2308 | code: wiimod_guitar_map[WIIMOD_GUITAR_KEY_MINUS], |
2309 | value: bm); |
2310 | |
2311 | input_sync(dev: wdata->extension.input); |
2312 | } |
2313 | |
2314 | static int wiimod_guitar_open(struct input_dev *dev) |
2315 | { |
2316 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2317 | unsigned long flags; |
2318 | |
2319 | spin_lock_irqsave(&wdata->state.lock, flags); |
2320 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
2321 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2322 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2323 | |
2324 | return 0; |
2325 | } |
2326 | |
2327 | static void wiimod_guitar_close(struct input_dev *dev) |
2328 | { |
2329 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2330 | unsigned long flags; |
2331 | |
2332 | spin_lock_irqsave(&wdata->state.lock, flags); |
2333 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
2334 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2335 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2336 | } |
2337 | |
2338 | static int wiimod_guitar_probe(const struct wiimod_ops *ops, |
2339 | struct wiimote_data *wdata) |
2340 | { |
2341 | int ret, i; |
2342 | |
2343 | wdata->extension.input = input_allocate_device(); |
2344 | if (!wdata->extension.input) |
2345 | return -ENOMEM; |
2346 | |
2347 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
2348 | wdata->extension.input->open = wiimod_guitar_open; |
2349 | wdata->extension.input->close = wiimod_guitar_close; |
2350 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
2351 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
2352 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
2353 | wdata->extension.input->id.product = wdata->hdev->product; |
2354 | wdata->extension.input->id.version = wdata->hdev->version; |
2355 | wdata->extension.input->name = WIIMOTE_NAME " Guitar" ; |
2356 | |
2357 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
2358 | for (i = 0; i < WIIMOD_GUITAR_KEY_NUM; ++i) |
2359 | set_bit(nr: wiimod_guitar_map[i], |
2360 | addr: wdata->extension.input->keybit); |
2361 | |
2362 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
2363 | set_bit(ABS_X, addr: wdata->extension.input->absbit); |
2364 | set_bit(ABS_Y, addr: wdata->extension.input->absbit); |
2365 | set_bit(ABS_HAT0X, addr: wdata->extension.input->absbit); |
2366 | set_bit(ABS_HAT1X, addr: wdata->extension.input->absbit); |
2367 | input_set_abs_params(dev: wdata->extension.input, |
2368 | ABS_X, min: -32, max: 31, fuzz: 1, flat: 1); |
2369 | input_set_abs_params(dev: wdata->extension.input, |
2370 | ABS_Y, min: -32, max: 31, fuzz: 1, flat: 1); |
2371 | input_set_abs_params(dev: wdata->extension.input, |
2372 | ABS_HAT0X, min: 0, max: 0x1f, fuzz: 1, flat: 1); |
2373 | input_set_abs_params(dev: wdata->extension.input, |
2374 | ABS_HAT1X, min: 0, max: 0x0f, fuzz: 1, flat: 1); |
2375 | |
2376 | ret = input_register_device(wdata->extension.input); |
2377 | if (ret) |
2378 | goto err_free; |
2379 | |
2380 | return 0; |
2381 | |
2382 | err_free: |
2383 | input_free_device(dev: wdata->extension.input); |
2384 | wdata->extension.input = NULL; |
2385 | return ret; |
2386 | } |
2387 | |
2388 | static void wiimod_guitar_remove(const struct wiimod_ops *ops, |
2389 | struct wiimote_data *wdata) |
2390 | { |
2391 | if (!wdata->extension.input) |
2392 | return; |
2393 | |
2394 | input_unregister_device(wdata->extension.input); |
2395 | wdata->extension.input = NULL; |
2396 | } |
2397 | |
2398 | static const struct wiimod_ops wiimod_guitar = { |
2399 | .flags = 0, |
2400 | .arg = 0, |
2401 | .probe = wiimod_guitar_probe, |
2402 | .remove = wiimod_guitar_remove, |
2403 | .in_ext = wiimod_guitar_in_ext, |
2404 | }; |
2405 | |
2406 | /* |
2407 | * Turntable |
2408 | * DJ Hero came with a Turntable Controller that was plugged in |
2409 | * as an extension. |
2410 | * We create a separate device for turntables and report all information via this |
2411 | * input device. |
2412 | */ |
2413 | |
2414 | enum wiimod_turntable_keys { |
2415 | WIIMOD_TURNTABLE_KEY_G_RIGHT, |
2416 | WIIMOD_TURNTABLE_KEY_R_RIGHT, |
2417 | WIIMOD_TURNTABLE_KEY_B_RIGHT, |
2418 | WIIMOD_TURNTABLE_KEY_G_LEFT, |
2419 | WIIMOD_TURNTABLE_KEY_R_LEFT, |
2420 | WIIMOD_TURNTABLE_KEY_B_LEFT, |
2421 | WIIMOD_TURNTABLE_KEY_EUPHORIA, |
2422 | WIIMOD_TURNTABLE_KEY_PLUS, |
2423 | WIIMOD_TURNTABLE_KEY_MINUS, |
2424 | WIIMOD_TURNTABLE_KEY_NUM |
2425 | }; |
2426 | |
2427 | static const __u16 wiimod_turntable_map[] = { |
2428 | BTN_1, /* WIIMOD_TURNTABLE_KEY_G_RIGHT */ |
2429 | BTN_2, /* WIIMOD_TURNTABLE_KEY_R_RIGHT */ |
2430 | BTN_3, /* WIIMOD_TURNTABLE_KEY_B_RIGHT */ |
2431 | BTN_4, /* WIIMOD_TURNTABLE_KEY_G_LEFT */ |
2432 | BTN_5, /* WIIMOD_TURNTABLE_KEY_R_LEFT */ |
2433 | BTN_6, /* WIIMOD_TURNTABLE_KEY_B_LEFT */ |
2434 | BTN_7, /* WIIMOD_TURNTABLE_KEY_EUPHORIA */ |
2435 | BTN_START, /* WIIMOD_TURNTABLE_KEY_PLUS */ |
2436 | BTN_SELECT, /* WIIMOD_TURNTABLE_KEY_MINUS */ |
2437 | }; |
2438 | |
2439 | static void wiimod_turntable_in_ext(struct wiimote_data *wdata, const __u8 *ext) |
2440 | { |
2441 | __u8 be, cs, sx, sy, ed, rtt, rbg, rbr, rbb, ltt, lbg, lbr, lbb, bp, bm; |
2442 | /* |
2443 | * Byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
2444 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2445 | * 0 | RTT<4:3> | SX <5:0> | |
2446 | * 1 | RTT<2:1> | SY <5:0> | |
2447 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2448 | * 2 |RTT<0>| ED<4:3> | CS<3:0> | RTT<5> | |
2449 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2450 | * 3 | ED<2:0> | LTT<4:0> | |
2451 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2452 | * 4 | 0 | 0 | LBR | B- | 0 | B+ | RBR | LTT<5> | |
2453 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2454 | * 5 | LBB | 0 | RBG | BE | LBG | RBB | 0 | 0 | |
2455 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2456 | * All pressed buttons are 0 |
2457 | * |
2458 | * With Motion+ enabled, it will look like this: |
2459 | * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
2460 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2461 | * 1 | RTT<4:3> | SX <5:1> | 0 | |
2462 | * 2 | RTT<2:1> | SY <5:1> | 0 | |
2463 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2464 | * 3 |RTT<0>| ED<4:3> | CS<3:0> | RTT<5> | |
2465 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2466 | * 4 | ED<2:0> | LTT<4:0> | |
2467 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2468 | * 5 | 0 | 0 | LBR | B- | 0 | B+ | RBR | XXXX | |
2469 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2470 | * 6 | LBB | 0 | RBG | BE | LBG | RBB | XXXX | XXXX | |
2471 | *------+------+-----+-----+-----+-----+------+------+--------+ |
2472 | */ |
2473 | |
2474 | be = !(ext[5] & 0x10); |
2475 | cs = ((ext[2] & 0x1e)); |
2476 | sx = ext[0] & 0x3f; |
2477 | sy = ext[1] & 0x3f; |
2478 | ed = (ext[3] & 0xe0) >> 5; |
2479 | rtt = ((ext[2] & 0x01) << 5 | (ext[0] & 0xc0) >> 3 | (ext[1] & 0xc0) >> 5 | ( ext[2] & 0x80 ) >> 7); |
2480 | ltt = ((ext[4] & 0x01) << 5 | (ext[3] & 0x1f)); |
2481 | rbg = !(ext[5] & 0x20); |
2482 | rbr = !(ext[4] & 0x02); |
2483 | rbb = !(ext[5] & 0x04); |
2484 | lbg = !(ext[5] & 0x08); |
2485 | lbb = !(ext[5] & 0x80); |
2486 | lbr = !(ext[4] & 0x20); |
2487 | bm = !(ext[4] & 0x10); |
2488 | bp = !(ext[4] & 0x04); |
2489 | |
2490 | if (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE) { |
2491 | ltt = (ext[4] & 0x01) << 5; |
2492 | sx &= 0x3e; |
2493 | sy &= 0x3e; |
2494 | } |
2495 | |
2496 | input_report_abs(dev: wdata->extension.input, ABS_X, value: sx); |
2497 | input_report_abs(dev: wdata->extension.input, ABS_Y, value: sy); |
2498 | input_report_abs(dev: wdata->extension.input, ABS_HAT0X, value: rtt); |
2499 | input_report_abs(dev: wdata->extension.input, ABS_HAT1X, value: ltt); |
2500 | input_report_abs(dev: wdata->extension.input, ABS_HAT2X, value: cs); |
2501 | input_report_abs(dev: wdata->extension.input, ABS_HAT3X, value: ed); |
2502 | input_report_key(dev: wdata->extension.input, |
2503 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_G_RIGHT], |
2504 | value: rbg); |
2505 | input_report_key(dev: wdata->extension.input, |
2506 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_R_RIGHT], |
2507 | value: rbr); |
2508 | input_report_key(dev: wdata->extension.input, |
2509 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_B_RIGHT], |
2510 | value: rbb); |
2511 | input_report_key(dev: wdata->extension.input, |
2512 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_G_LEFT], |
2513 | value: lbg); |
2514 | input_report_key(dev: wdata->extension.input, |
2515 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_R_LEFT], |
2516 | value: lbr); |
2517 | input_report_key(dev: wdata->extension.input, |
2518 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_B_LEFT], |
2519 | value: lbb); |
2520 | input_report_key(dev: wdata->extension.input, |
2521 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_EUPHORIA], |
2522 | value: be); |
2523 | input_report_key(dev: wdata->extension.input, |
2524 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_PLUS], |
2525 | value: bp); |
2526 | input_report_key(dev: wdata->extension.input, |
2527 | code: wiimod_turntable_map[WIIMOD_TURNTABLE_KEY_MINUS], |
2528 | value: bm); |
2529 | |
2530 | input_sync(dev: wdata->extension.input); |
2531 | } |
2532 | |
2533 | static int wiimod_turntable_open(struct input_dev *dev) |
2534 | { |
2535 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2536 | unsigned long flags; |
2537 | |
2538 | spin_lock_irqsave(&wdata->state.lock, flags); |
2539 | wdata->state.flags |= WIIPROTO_FLAG_EXT_USED; |
2540 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2541 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2542 | |
2543 | return 0; |
2544 | } |
2545 | |
2546 | static void wiimod_turntable_close(struct input_dev *dev) |
2547 | { |
2548 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2549 | unsigned long flags; |
2550 | |
2551 | spin_lock_irqsave(&wdata->state.lock, flags); |
2552 | wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; |
2553 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2554 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2555 | } |
2556 | |
2557 | static int wiimod_turntable_probe(const struct wiimod_ops *ops, |
2558 | struct wiimote_data *wdata) |
2559 | { |
2560 | int ret, i; |
2561 | |
2562 | wdata->extension.input = input_allocate_device(); |
2563 | if (!wdata->extension.input) |
2564 | return -ENOMEM; |
2565 | |
2566 | input_set_drvdata(dev: wdata->extension.input, data: wdata); |
2567 | wdata->extension.input->open = wiimod_turntable_open; |
2568 | wdata->extension.input->close = wiimod_turntable_close; |
2569 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
2570 | wdata->extension.input->id.bustype = wdata->hdev->bus; |
2571 | wdata->extension.input->id.vendor = wdata->hdev->vendor; |
2572 | wdata->extension.input->id.product = wdata->hdev->product; |
2573 | wdata->extension.input->id.version = wdata->hdev->version; |
2574 | wdata->extension.input->name = WIIMOTE_NAME " Turntable" ; |
2575 | |
2576 | set_bit(EV_KEY, addr: wdata->extension.input->evbit); |
2577 | for (i = 0; i < WIIMOD_TURNTABLE_KEY_NUM; ++i) |
2578 | set_bit(nr: wiimod_turntable_map[i], |
2579 | addr: wdata->extension.input->keybit); |
2580 | |
2581 | set_bit(EV_ABS, addr: wdata->extension.input->evbit); |
2582 | set_bit(ABS_X, addr: wdata->extension.input->absbit); |
2583 | set_bit(ABS_Y, addr: wdata->extension.input->absbit); |
2584 | set_bit(ABS_HAT0X, addr: wdata->extension.input->absbit); |
2585 | set_bit(ABS_HAT1X, addr: wdata->extension.input->absbit); |
2586 | set_bit(ABS_HAT2X, addr: wdata->extension.input->absbit); |
2587 | set_bit(ABS_HAT3X, addr: wdata->extension.input->absbit); |
2588 | input_set_abs_params(dev: wdata->extension.input, |
2589 | ABS_X, min: 0, max: 63, fuzz: 1, flat: 0); |
2590 | input_set_abs_params(dev: wdata->extension.input, |
2591 | ABS_Y, min: 63, max: 0, fuzz: 1, flat: 0); |
2592 | input_set_abs_params(dev: wdata->extension.input, |
2593 | ABS_HAT0X, min: -8, max: 8, fuzz: 0, flat: 0); |
2594 | input_set_abs_params(dev: wdata->extension.input, |
2595 | ABS_HAT1X, min: -8, max: 8, fuzz: 0, flat: 0); |
2596 | input_set_abs_params(dev: wdata->extension.input, |
2597 | ABS_HAT2X, min: 0, max: 31, fuzz: 1, flat: 1); |
2598 | input_set_abs_params(dev: wdata->extension.input, |
2599 | ABS_HAT3X, min: 0, max: 7, fuzz: 0, flat: 0); |
2600 | ret = input_register_device(wdata->extension.input); |
2601 | if (ret) |
2602 | goto err_free; |
2603 | |
2604 | return 0; |
2605 | |
2606 | err_free: |
2607 | input_free_device(dev: wdata->extension.input); |
2608 | wdata->extension.input = NULL; |
2609 | return ret; |
2610 | } |
2611 | |
2612 | static void wiimod_turntable_remove(const struct wiimod_ops *ops, |
2613 | struct wiimote_data *wdata) |
2614 | { |
2615 | if (!wdata->extension.input) |
2616 | return; |
2617 | |
2618 | input_unregister_device(wdata->extension.input); |
2619 | wdata->extension.input = NULL; |
2620 | } |
2621 | |
2622 | static const struct wiimod_ops wiimod_turntable = { |
2623 | .flags = 0, |
2624 | .arg = 0, |
2625 | .probe = wiimod_turntable_probe, |
2626 | .remove = wiimod_turntable_remove, |
2627 | .in_ext = wiimod_turntable_in_ext, |
2628 | }; |
2629 | |
2630 | /* |
2631 | * Builtin Motion Plus |
2632 | * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which |
2633 | * disables polling for Motion-Plus. This should be set only for devices which |
2634 | * don't allow MP hotplugging. |
2635 | */ |
2636 | |
2637 | static int wiimod_builtin_mp_probe(const struct wiimod_ops *ops, |
2638 | struct wiimote_data *wdata) |
2639 | { |
2640 | unsigned long flags; |
2641 | |
2642 | spin_lock_irqsave(&wdata->state.lock, flags); |
2643 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; |
2644 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2645 | |
2646 | return 0; |
2647 | } |
2648 | |
2649 | static void wiimod_builtin_mp_remove(const struct wiimod_ops *ops, |
2650 | struct wiimote_data *wdata) |
2651 | { |
2652 | unsigned long flags; |
2653 | |
2654 | spin_lock_irqsave(&wdata->state.lock, flags); |
2655 | wdata->state.flags |= WIIPROTO_FLAG_BUILTIN_MP; |
2656 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2657 | } |
2658 | |
2659 | static const struct wiimod_ops wiimod_builtin_mp = { |
2660 | .flags = 0, |
2661 | .arg = 0, |
2662 | .probe = wiimod_builtin_mp_probe, |
2663 | .remove = wiimod_builtin_mp_remove, |
2664 | }; |
2665 | |
2666 | /* |
2667 | * No Motion Plus |
2668 | * This module simply sets the WIIPROTO_FLAG_NO_MP protocol flag which |
2669 | * disables motion-plus. This is needed for devices that advertise this but we |
2670 | * don't know how to use it (or whether it is actually present). |
2671 | */ |
2672 | |
2673 | static int wiimod_no_mp_probe(const struct wiimod_ops *ops, |
2674 | struct wiimote_data *wdata) |
2675 | { |
2676 | unsigned long flags; |
2677 | |
2678 | spin_lock_irqsave(&wdata->state.lock, flags); |
2679 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; |
2680 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2681 | |
2682 | return 0; |
2683 | } |
2684 | |
2685 | static void wiimod_no_mp_remove(const struct wiimod_ops *ops, |
2686 | struct wiimote_data *wdata) |
2687 | { |
2688 | unsigned long flags; |
2689 | |
2690 | spin_lock_irqsave(&wdata->state.lock, flags); |
2691 | wdata->state.flags |= WIIPROTO_FLAG_NO_MP; |
2692 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2693 | } |
2694 | |
2695 | static const struct wiimod_ops wiimod_no_mp = { |
2696 | .flags = 0, |
2697 | .arg = 0, |
2698 | .probe = wiimod_no_mp_probe, |
2699 | .remove = wiimod_no_mp_remove, |
2700 | }; |
2701 | |
2702 | /* |
2703 | * Motion Plus |
2704 | * The Motion Plus extension provides rotation sensors (gyro) as a small |
2705 | * extension device for Wii Remotes. Many devices have them built-in so |
2706 | * you cannot see them from the outside. |
2707 | * Motion Plus extensions are special because they are on a separate extension |
2708 | * port and allow other extensions to be used simultaneously. This is all |
2709 | * handled by the Wiimote Core so we don't have to deal with it. |
2710 | */ |
2711 | |
2712 | static void wiimod_mp_in_mp(struct wiimote_data *wdata, const __u8 *ext) |
2713 | { |
2714 | __s32 x, y, z; |
2715 | |
2716 | /* | 8 7 6 5 4 3 | 2 | 1 | |
2717 | * -----+------------------------------+-----+-----+ |
2718 | * 1 | Yaw Speed <7:0> | |
2719 | * 2 | Roll Speed <7:0> | |
2720 | * 3 | Pitch Speed <7:0> | |
2721 | * -----+------------------------------+-----+-----+ |
2722 | * 4 | Yaw Speed <13:8> | Yaw |Pitch| |
2723 | * -----+------------------------------+-----+-----+ |
2724 | * 5 | Roll Speed <13:8> |Roll | Ext | |
2725 | * -----+------------------------------+-----+-----+ |
2726 | * 6 | Pitch Speed <13:8> | 1 | 0 | |
2727 | * -----+------------------------------+-----+-----+ |
2728 | * The single bits Yaw, Roll, Pitch in the lower right corner specify |
2729 | * whether the wiimote is rotating fast (0) or slow (1). Speed for slow |
2730 | * roation is 8192/440 units / deg/s and for fast rotation 8192/2000 |
2731 | * units / deg/s. To get a linear scale for fast rotation we multiply |
2732 | * by 2000/440 = ~4.5454 and scale both fast and slow by 9 to match the |
2733 | * previous scale reported by this driver. |
2734 | * This leaves a linear scale with 8192*9/440 (~167.564) units / deg/s. |
2735 | * If the wiimote is not rotating the sensor reports 2^13 = 8192. |
2736 | * Ext specifies whether an extension is connected to the motionp. |
2737 | * which is parsed by wiimote-core. |
2738 | */ |
2739 | |
2740 | x = ext[0]; |
2741 | y = ext[1]; |
2742 | z = ext[2]; |
2743 | |
2744 | x |= (((__u16)ext[3]) << 6) & 0xff00; |
2745 | y |= (((__u16)ext[4]) << 6) & 0xff00; |
2746 | z |= (((__u16)ext[5]) << 6) & 0xff00; |
2747 | |
2748 | x -= 8192; |
2749 | y -= 8192; |
2750 | z -= 8192; |
2751 | |
2752 | if (!(ext[3] & 0x02)) |
2753 | x = (x * 2000 * 9) / 440; |
2754 | else |
2755 | x *= 9; |
2756 | if (!(ext[4] & 0x02)) |
2757 | y = (y * 2000 * 9) / 440; |
2758 | else |
2759 | y *= 9; |
2760 | if (!(ext[3] & 0x01)) |
2761 | z = (z * 2000 * 9) / 440; |
2762 | else |
2763 | z *= 9; |
2764 | |
2765 | input_report_abs(dev: wdata->mp, ABS_RX, value: x); |
2766 | input_report_abs(dev: wdata->mp, ABS_RY, value: y); |
2767 | input_report_abs(dev: wdata->mp, ABS_RZ, value: z); |
2768 | input_sync(dev: wdata->mp); |
2769 | } |
2770 | |
2771 | static int wiimod_mp_open(struct input_dev *dev) |
2772 | { |
2773 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2774 | unsigned long flags; |
2775 | |
2776 | spin_lock_irqsave(&wdata->state.lock, flags); |
2777 | wdata->state.flags |= WIIPROTO_FLAG_MP_USED; |
2778 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2779 | __wiimote_schedule(wdata); |
2780 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2781 | |
2782 | return 0; |
2783 | } |
2784 | |
2785 | static void wiimod_mp_close(struct input_dev *dev) |
2786 | { |
2787 | struct wiimote_data *wdata = input_get_drvdata(dev); |
2788 | unsigned long flags; |
2789 | |
2790 | spin_lock_irqsave(&wdata->state.lock, flags); |
2791 | wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED; |
2792 | wiiproto_req_drm(wdata, drm: WIIPROTO_REQ_NULL); |
2793 | __wiimote_schedule(wdata); |
2794 | spin_unlock_irqrestore(lock: &wdata->state.lock, flags); |
2795 | } |
2796 | |
2797 | static int wiimod_mp_probe(const struct wiimod_ops *ops, |
2798 | struct wiimote_data *wdata) |
2799 | { |
2800 | int ret; |
2801 | |
2802 | wdata->mp = input_allocate_device(); |
2803 | if (!wdata->mp) |
2804 | return -ENOMEM; |
2805 | |
2806 | input_set_drvdata(dev: wdata->mp, data: wdata); |
2807 | wdata->mp->open = wiimod_mp_open; |
2808 | wdata->mp->close = wiimod_mp_close; |
2809 | wdata->mp->dev.parent = &wdata->hdev->dev; |
2810 | wdata->mp->id.bustype = wdata->hdev->bus; |
2811 | wdata->mp->id.vendor = wdata->hdev->vendor; |
2812 | wdata->mp->id.product = wdata->hdev->product; |
2813 | wdata->mp->id.version = wdata->hdev->version; |
2814 | wdata->mp->name = WIIMOTE_NAME " Motion Plus" ; |
2815 | |
2816 | set_bit(EV_ABS, addr: wdata->mp->evbit); |
2817 | set_bit(ABS_RX, addr: wdata->mp->absbit); |
2818 | set_bit(ABS_RY, addr: wdata->mp->absbit); |
2819 | set_bit(ABS_RZ, addr: wdata->mp->absbit); |
2820 | input_set_abs_params(dev: wdata->mp, |
2821 | ABS_RX, min: -16000, max: 16000, fuzz: 4, flat: 8); |
2822 | input_set_abs_params(dev: wdata->mp, |
2823 | ABS_RY, min: -16000, max: 16000, fuzz: 4, flat: 8); |
2824 | input_set_abs_params(dev: wdata->mp, |
2825 | ABS_RZ, min: -16000, max: 16000, fuzz: 4, flat: 8); |
2826 | |
2827 | ret = input_register_device(wdata->mp); |
2828 | if (ret) |
2829 | goto err_free; |
2830 | |
2831 | return 0; |
2832 | |
2833 | err_free: |
2834 | input_free_device(dev: wdata->mp); |
2835 | wdata->mp = NULL; |
2836 | return ret; |
2837 | } |
2838 | |
2839 | static void wiimod_mp_remove(const struct wiimod_ops *ops, |
2840 | struct wiimote_data *wdata) |
2841 | { |
2842 | if (!wdata->mp) |
2843 | return; |
2844 | |
2845 | input_unregister_device(wdata->mp); |
2846 | wdata->mp = NULL; |
2847 | } |
2848 | |
2849 | const struct wiimod_ops wiimod_mp = { |
2850 | .flags = 0, |
2851 | .arg = 0, |
2852 | .probe = wiimod_mp_probe, |
2853 | .remove = wiimod_mp_remove, |
2854 | .in_mp = wiimod_mp_in_mp, |
2855 | }; |
2856 | |
2857 | /* module table */ |
2858 | |
2859 | static const struct wiimod_ops wiimod_dummy; |
2860 | |
2861 | const struct wiimod_ops *wiimod_table[WIIMOD_NUM] = { |
2862 | [WIIMOD_KEYS] = &wiimod_keys, |
2863 | [WIIMOD_RUMBLE] = &wiimod_rumble, |
2864 | [WIIMOD_BATTERY] = &wiimod_battery, |
2865 | [WIIMOD_LED1] = &wiimod_leds[0], |
2866 | [WIIMOD_LED2] = &wiimod_leds[1], |
2867 | [WIIMOD_LED3] = &wiimod_leds[2], |
2868 | [WIIMOD_LED4] = &wiimod_leds[3], |
2869 | [WIIMOD_ACCEL] = &wiimod_accel, |
2870 | [WIIMOD_IR] = &wiimod_ir, |
2871 | [WIIMOD_BUILTIN_MP] = &wiimod_builtin_mp, |
2872 | [WIIMOD_NO_MP] = &wiimod_no_mp, |
2873 | }; |
2874 | |
2875 | const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = { |
2876 | [WIIMOTE_EXT_NONE] = &wiimod_dummy, |
2877 | [WIIMOTE_EXT_UNKNOWN] = &wiimod_dummy, |
2878 | [WIIMOTE_EXT_NUNCHUK] = &wiimod_nunchuk, |
2879 | [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic, |
2880 | [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard, |
2881 | [WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro, |
2882 | [WIIMOTE_EXT_DRUMS] = &wiimod_drums, |
2883 | [WIIMOTE_EXT_GUITAR] = &wiimod_guitar, |
2884 | [WIIMOTE_EXT_TURNTABLE] = &wiimod_turntable, |
2885 | }; |
2886 | |