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