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