/*
 * HID driver for Nintendo Wiimote extension devices
 * Copyright (c) 2011 David Herrmann
 */

/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 */

#include <linux/atomic.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include "hid-wiimote.h"

struct wiimote_ext {
	struct wiimote_data *wdata;
	struct work_struct worker;
	struct input_dev *input;
	struct input_dev *mp_input;

	atomic_t opened;
	atomic_t mp_opened;
	bool plugged;
	bool mp_plugged;
	bool motionp;
	__u8 ext_type;
};

enum wiiext_type {
	WIIEXT_NONE,		/* placeholder */
	WIIEXT_CLASSIC,		/* Nintendo classic controller */
	WIIEXT_NUNCHUCK,	/* Nintendo nunchuck controller */
};

enum wiiext_keys {
	WIIEXT_KEY_C,
	WIIEXT_KEY_Z,
	WIIEXT_KEY_A,
	WIIEXT_KEY_B,
	WIIEXT_KEY_X,
	WIIEXT_KEY_Y,
	WIIEXT_KEY_ZL,
	WIIEXT_KEY_ZR,
	WIIEXT_KEY_PLUS,
	WIIEXT_KEY_MINUS,
	WIIEXT_KEY_HOME,
	WIIEXT_KEY_LEFT,
	WIIEXT_KEY_RIGHT,
	WIIEXT_KEY_UP,
	WIIEXT_KEY_DOWN,
	WIIEXT_KEY_LT,
	WIIEXT_KEY_RT,
	WIIEXT_KEY_COUNT
};

static __u16 wiiext_keymap[] = {
	BTN_C,		/* WIIEXT_KEY_C */
	BTN_Z,		/* WIIEXT_KEY_Z */
	BTN_A,		/* WIIEXT_KEY_A */
	BTN_B,		/* WIIEXT_KEY_B */
	BTN_X,		/* WIIEXT_KEY_X */
	BTN_Y,		/* WIIEXT_KEY_Y */
	BTN_TL2,	/* WIIEXT_KEY_ZL */
	BTN_TR2,	/* WIIEXT_KEY_ZR */
	KEY_NEXT,	/* WIIEXT_KEY_PLUS */
	KEY_PREVIOUS,	/* WIIEXT_KEY_MINUS */
	BTN_MODE,	/* WIIEXT_KEY_HOME */
	KEY_LEFT,	/* WIIEXT_KEY_LEFT */
	KEY_RIGHT,	/* WIIEXT_KEY_RIGHT */
	KEY_UP,		/* WIIEXT_KEY_UP */
	KEY_DOWN,	/* WIIEXT_KEY_DOWN */
	BTN_TL,		/* WIIEXT_KEY_LT */
	BTN_TR,		/* WIIEXT_KEY_RT */
};

/* diable all extensions */
static void ext_disable(struct wiimote_ext *ext)
{
	unsigned long flags;
	__u8 wmem = 0x55;

	if (!wiimote_cmd_acquire(ext->wdata)) {
		wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
		wiimote_cmd_release(ext->wdata);
	}

	spin_lock_irqsave(&ext->wdata->state.lock, flags);
	ext->motionp = false;
	ext->ext_type = WIIEXT_NONE;
	wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
	spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
}

static bool motionp_read(struct wiimote_ext *ext)
{
	__u8 rmem[2], wmem;
	ssize_t ret;
	bool avail = false;

	if (!atomic_read(&ext->mp_opened))
		return false;

	if (wiimote_cmd_acquire(ext->wdata))
		return false;

	/* initialize motion plus */
	wmem = 0x55;
	ret = wiimote_cmd_write(ext->wdata, 0xa600f0, &wmem, sizeof(wmem));
	if (ret)
		goto error;

	/* read motion plus ID */
	ret = wiimote_cmd_read(ext->wdata, 0xa600fe, rmem, 2);
	if (ret == 2 || rmem[1] == 0x5)
		avail = true;

error:
	wiimote_cmd_release(ext->wdata);
	return avail;
}

static __u8 ext_read(struct wiimote_ext *ext)
{
	ssize_t ret;
	__u8 rmem[2], wmem;
	__u8 type = WIIEXT_NONE;

	if (!ext->plugged || !atomic_read(&ext->opened))
		return WIIEXT_NONE;

	if (wiimote_cmd_acquire(ext->wdata))
		return WIIEXT_NONE;

	/* initialize extension */
	wmem = 0x55;
	ret = wiimote_cmd_write(ext->wdata, 0xa400f0, &wmem, sizeof(wmem));
	if (!ret) {
		/* disable encryption */
		wmem = 0x0;
		wiimote_cmd_write(ext->wdata, 0xa400fb, &wmem, sizeof(wmem));
	}

	/* read extension ID */
	ret = wiimote_cmd_read(ext->wdata, 0xa400fe, rmem, 2);
	if (ret == 2) {
		if (rmem[0] == 0 && rmem[1] == 0)
			type = WIIEXT_NUNCHUCK;
		else if (rmem[0] == 0x01 && rmem[1] == 0x01)
			type = WIIEXT_CLASSIC;
	}

	wiimote_cmd_release(ext->wdata);

	return type;
}

static void ext_enable(struct wiimote_ext *ext, bool motionp, __u8 ext_type)
{
	unsigned long flags;
	__u8 wmem;
	int ret;

	if (motionp) {
		if (wiimote_cmd_acquire(ext->wdata))
			return;

		if (ext_type == WIIEXT_CLASSIC)
			wmem = 0x07;
		else if (ext_type == WIIEXT_NUNCHUCK)
			wmem = 0x05;
		else
			wmem = 0x04;

		ret = wiimote_cmd_write(ext->wdata, 0xa600fe, &wmem, sizeof(wmem));
		wiimote_cmd_release(ext->wdata);
		if (ret)
			return;
	}

	spin_lock_irqsave(&ext->wdata->state.lock, flags);
	ext->motionp = motionp;
	ext->ext_type = ext_type;
	wiiproto_req_drm(ext->wdata, WIIPROTO_REQ_NULL);
	spin_unlock_irqrestore(&ext->wdata->state.lock, flags);
}

static void wiiext_worker(struct work_struct *work)
{
	struct wiimote_ext *ext = container_of(work, struct wiimote_ext,
									worker);
	bool motionp;
	__u8 ext_type;

	ext_disable(ext);
	motionp = motionp_read(ext);
	ext_type = ext_read(ext);
	ext_enable(ext, motionp, ext_type);
}

/* schedule work only once, otherwise mark for reschedule */
static void wiiext_schedule(struct wiimote_ext *ext)
{
	queue_work(system_nrt_wq, &ext->worker);
}

/*
 * Reacts on extension port events
 * Whenever the driver gets an event from the wiimote that an extension has been
 * plugged or unplugged, this funtion shall be called. It checks what extensions
 * are connected and initializes and activates them.
 * This can be called in atomic context. The initialization is done in a
 * separate worker thread. The state.lock spinlock must be held by the caller.
 */
void wiiext_event(struct wiimote_data *wdata, bool plugged)
{
	if (!wdata->ext)
		return;

	if (wdata->ext->plugged == plugged)
		return;

	wdata->ext->plugged = plugged;

	if (!plugged)
		wdata->ext->mp_plugged = false;

	/*
	 * We need to call wiiext_schedule(wdata->ext) here, however, the
	 * extension initialization logic is not fully understood and so
	 * automatic initialization is not supported, yet.
	 */
}

/*
 * Returns true if the current DRM mode should contain extension data and false
 * if there is no interest in extension data.
 * All supported extensions send 6 byte extension data so any DRM that contains
 * extension bytes is fine.
 * The caller must hold the state.lock spinlock.
 */
bool wiiext_active(struct wiimote_data *wdata)
{
	if (!wdata->ext)
		return false;

	return wdata->ext->motionp || wdata->ext->ext_type;
}

static void handler_motionp(struct wiimote_ext *ext, const __u8 *payload)
{
	__s32 x, y, z;
	bool plugged;

	/*        |   8    7    6    5    4    3 |  2  |  1  |
	 *   -----+------------------------------+-----+-----+
	 *    1   |               Yaw Speed <7:0>            |
	 *    2   |              Roll Speed <7:0>            |
	 *    3   |             Pitch Speed <7:0>            |
	 *   -----+------------------------------+-----+-----+
	 *    4   |       Yaw Speed <13:8>       | Yaw |Pitch|
	 *   -----+------------------------------+-----+-----+
	 *    5   |      Roll Speed <13:8>       |Roll | Ext |
	 *   -----+------------------------------+-----+-----+
	 *    6   |     Pitch Speed <13:8>       |  1  |  0  |
	 *   -----+------------------------------+-----+-----+
	 * The single bits Yaw, Roll, Pitch in the lower right corner specify
	 * whether the wiimote is rotating fast (0) or slow (1). Speed for slow
	 * roation is 440 deg/s and for fast rotation 2000 deg/s. To get a
	 * linear scale we multiply by 2000/440 = ~4.5454 which is 18 for fast
	 * and 9 for slow.
	 * If the wiimote is not rotating the sensor reports 2^13 = 8192.
	 * Ext specifies whether an extension is connected to the motionp.
	 */

	x = payload[0];
	y = payload[1];
	z = payload[2];

	x |= (((__u16)payload[3]) << 6) & 0xff00;
	y |= (((__u16)payload[4]) << 6) & 0xff00;
	z |= (((__u16)payload[5]) << 6) & 0xff00;

	x -= 8192;
	y -= 8192;
	z -= 8192;

	if (!(payload[3] & 0x02))
		x *= 18;
	else
		x *= 9;
	if (!(payload[4] & 0x02))
		y *= 18;
	else
		y *= 9;
	if (!(payload[3] & 0x01))
		z *= 18;
	else
		z *= 9;

	input_report_abs(ext->mp_input, ABS_RX, x);
	input_report_abs(ext->mp_input, ABS_RY, y);
	input_report_abs(ext->mp_input, ABS_RZ, z);
	input_sync(ext->mp_input);

	plugged = payload[5] & 0x01;
	if (plugged != ext->mp_plugged)
		ext->mp_plugged = plugged;
}

static void handler_nunchuck(struct wiimote_ext *ext, const __u8 *payload)
{
	__s16 x, y, z, bx, by;

	/*   Byte |   8    7 |  6    5 |  4    3 |  2 |  1  |
	 *   -----+----------+---------+---------+----+-----+
	 *    1   |              Button X <7:0>             |
	 *    2   |              Button Y <7:0>             |
	 *   -----+----------+---------+---------+----+-----+
	 *    3   |               Speed X <9:2>             |
	 *    4   |               Speed Y <9:2>             |
	 *    5   |               Speed Z <9:2>             |
	 *   -----+----------+---------+---------+----+-----+
	 *    6   | Z <1:0>  | Y <1:0> | X <1:0> | BC | BZ  |
	 *   -----+----------+---------+---------+----+-----+
	 * Button X/Y is the analog stick. Speed X, Y and Z are the
	 * accelerometer data in the same format as the wiimote's accelerometer.
	 * The 6th byte contains the LSBs of the accelerometer data.
	 * BC and BZ are the C and Z buttons: 0 means pressed
	 *
	 * If reported interleaved with motionp, then the layout changes. The
	 * 5th and 6th byte changes to:
	 *   -----+-----------------------------------+-----+
	 *    5   |            Speed Z <9:3>          | EXT |
	 *   -----+--------+-----+-----+----+----+----+-----+
	 *    6   |Z <2:1> |Y <1>|X <1>| BC | BZ | 0  |  0  |
	 *   -----+--------+-----+-----+----+----+----+-----+
	 * All three accelerometer values lose their LSB. The other data is
	 * still available but slightly moved.
	 *
	 * Center data for button values is 128. Center value for accelerometer
	 * values it 512 / 0x200
	 */

	bx = payload[0];
	by = payload[1];
	bx -= 128;
	by -= 128;

	x = payload[2] << 2;
	y = payload[3] << 2;
	z = payload[4] << 2;

	if (ext->motionp) {
		x |= (payload[5] >> 3) & 0x02;
		y |= (payload[5] >> 4) & 0x02;
		z &= ~0x4;
		z |= (payload[5] >> 5) & 0x06;
	} else {
		x |= (payload[5] >> 2) & 0x03;
		y |= (payload[5] >> 4) & 0x03;
		z |= (payload[5] >> 6) & 0x03;
	}

	x -= 0x200;
	y -= 0x200;
	z -= 0x200;

	input_report_abs(ext->input, ABS_HAT0X, bx);
	input_report_abs(ext->input, ABS_HAT0Y, by);

	input_report_abs(ext->input, ABS_RX, x);
	input_report_abs(ext->input, ABS_RY, y);
	input_report_abs(ext->input, ABS_RZ, z);

	if (ext->motionp) {
		input_report_key(ext->input,
			wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x04));
		input_report_key(ext->input,
			wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x08));
	} else {
		input_report_key(ext->input,
			wiiext_keymap[WIIEXT_KEY_Z], !(payload[5] & 0x01));
		input_report_key(ext->input,
			wiiext_keymap[WIIEXT_KEY_C], !(payload[5] & 0x02));
	}

	input_sync(ext->input);
}

static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
{
	__s8 rx, ry, lx, ly, lt, rt;

	/*   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    1   | RX <5:4>  |              LX <5:0>             |
	 *    2   | RX <3:2>  |              LY <5:0>             |
	 *   -----+-----+-----+-----+-----------------------------+
	 *    3   |RX<1>| LT <5:4>  |         RY <5:1>            |
	 *   -----+-----+-----------+-----------------------------+
	 *    4   |     LT <3:1>    |         RT <5:1>            |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR | BDL | BDU |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 * All buttons are 0 if pressed
	 * RX and RY are right analog stick
	 * LX and LY are left analog stick
	 * LT is left trigger, RT is right trigger
	 * BLT is 0 if left trigger is fully pressed
	 * BRT is 0 if right trigger is fully pressed
	 * BDR, BDD, BDL, BDU form the D-Pad with right, down, left, up buttons
	 * BZL is left Z button and BZR is right Z button
	 * B-, BH, B+ are +, HOME and - buttons
	 * BB, BY, BA, BX are A, B, X, Y buttons
	 * LSB of RX, RY, LT, and RT are not transmitted and always 0.
	 *
	 * With motionp enabled it changes slightly to this:
	 *   Byte |  8  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    1   | RX <4:3>  |          LX <5:1>           | BDU |
	 *    2   | RX <2:1>  |          LY <5:1>           | BDL |
	 *   -----+-----+-----+-----+-----------------------+-----+
	 *    3   |RX<0>| LT <4:3>  |         RY <4:0>            |
	 *   -----+-----+-----------+-----------------------------+
	 *    4   |     LT <2:0>    |         RT <4:0>            |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    5   | BDR | BDD | BLT | B-  | BH  | B+  | BRT | EXT |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 *    6   | BZL | BB  | BY  | BA  | BX  | BZR |  0  |  0  |
	 *   -----+-----+-----+-----+-----+-----+-----+-----+-----+
	 * Only the LSBs of LX and LY are lost. BDU and BDL are moved, the rest
	 * is the same as before.
	 */

	if (ext->motionp) {
		lx = payload[0] & 0x3e;
		ly = payload[0] & 0x3e;
	} else {
		lx = payload[0] & 0x3f;
		ly = payload[0] & 0x3f;
	}

	rx = (payload[0] >> 3) & 0x14;
	rx |= (payload[1] >> 5) & 0x06;
	rx |= (payload[2] >> 7) & 0x01;
	ry = payload[2] & 0x1f;

	rt = payload[3] & 0x1f;
	lt = (payload[2] >> 2) & 0x18;
	lt |= (payload[3] >> 5) & 0x07;

	rx <<= 1;
	ry <<= 1;
	rt <<= 1;
	lt <<= 1;

	input_report_abs(ext->input, ABS_HAT1X, lx - 0x20);
	input_report_abs(ext->input, ABS_HAT1Y, ly - 0x20);
	input_report_abs(ext->input, ABS_HAT2X, rx - 0x20);
	input_report_abs(ext->input, ABS_HAT2Y, ry - 0x20);
	input_report_abs(ext->input, ABS_HAT3X, rt - 0x20);
	input_report_abs(ext->input, ABS_HAT3Y, lt - 0x20);

	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RIGHT],
							!!(payload[4] & 0x80));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_DOWN],
							!!(payload[4] & 0x40));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LT],
							!!(payload[4] & 0x20));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_MINUS],
							!!(payload[4] & 0x10));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_HOME],
							!!(payload[4] & 0x08));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_PLUS],
							!!(payload[4] & 0x04));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_RT],
							!!(payload[4] & 0x02));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZL],
							!!(payload[5] & 0x80));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_B],
							!!(payload[5] & 0x40));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_Y],
							!!(payload[5] & 0x20));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_A],
							!!(payload[5] & 0x10));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_X],
							!!(payload[5] & 0x08));
	input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_ZR],
							!!(payload[5] & 0x04));

	if (ext->motionp) {
		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
							!!(payload[0] & 0x01));
		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
							!!(payload[1] & 0x01));
	} else {
		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_UP],
							!!(payload[5] & 0x01));
		input_report_key(ext->input, wiiext_keymap[WIIEXT_KEY_LEFT],
							!!(payload[5] & 0x02));
	}

	input_sync(ext->input);
}

/* call this with state.lock spinlock held */
void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
{
	struct wiimote_ext *ext = wdata->ext;

	if (!ext)
		return;

	if (ext->motionp && (payload[5] & 0x02)) {
		handler_motionp(ext, payload);
	} else if (ext->ext_type == WIIEXT_NUNCHUCK) {
		handler_nunchuck(ext, payload);
	} else if (ext->ext_type == WIIEXT_CLASSIC) {
		handler_classic(ext, payload);
	}
}

static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
								char *buf)
{
	struct wiimote_data *wdata = dev_to_wii(dev);
	__u8 type = WIIEXT_NONE;
	bool motionp = false;
	unsigned long flags;

	spin_lock_irqsave(&wdata->state.lock, flags);
	if (wdata->ext) {
		motionp = wdata->ext->motionp;
		type = wdata->ext->ext_type;
	}
	spin_unlock_irqrestore(&wdata->state.lock, flags);

	if (type == WIIEXT_NUNCHUCK) {
		if (motionp)
			return sprintf(buf, "motionp+nunchuck\n");
		else
			return sprintf(buf, "nunchuck\n");
	} else if (type == WIIEXT_CLASSIC) {
		if (motionp)
			return sprintf(buf, "motionp+classic\n");
		else
			return sprintf(buf, "classic\n");
	} else {
		if (motionp)
			return sprintf(buf, "motionp\n");
		else
			return sprintf(buf, "none\n");
	}
}

static DEVICE_ATTR(extension, S_IRUGO, wiiext_show, NULL);

static int wiiext_input_open(struct input_dev *dev)
{
	struct wiimote_ext *ext = input_get_drvdata(dev);
	int ret;

	ret = hid_hw_open(ext->wdata->hdev);
	if (ret)
		return ret;

	atomic_inc(&ext->opened);
	wiiext_schedule(ext);

	return 0;
}

static void wiiext_input_close(struct input_dev *dev)
{
	struct wiimote_ext *ext = input_get_drvdata(dev);

	atomic_dec(&ext->opened);
	wiiext_schedule(ext);
	hid_hw_close(ext->wdata->hdev);
}

static int wiiext_mp_open(struct input_dev *dev)
{
	struct wiimote_ext *ext = input_get_drvdata(dev);
	int ret;

	ret = hid_hw_open(ext->wdata->hdev);
	if (ret)
		return ret;

	atomic_inc(&ext->mp_opened);
	wiiext_schedule(ext);

	return 0;
}

static void wiiext_mp_close(struct input_dev *dev)
{
	struct wiimote_ext *ext = input_get_drvdata(dev);

	atomic_dec(&ext->mp_opened);
	wiiext_schedule(ext);
	hid_hw_close(ext->wdata->hdev);
}

/* Initializes the extension driver of a wiimote */
int wiiext_init(struct wiimote_data *wdata)
{
	struct wiimote_ext *ext;
	unsigned long flags;
	int ret, i;

	ext = kzalloc(sizeof(*ext), GFP_KERNEL);
	if (!ext)
		return -ENOMEM;

	ext->wdata = wdata;
	INIT_WORK(&ext->worker, wiiext_worker);

	ext->input = input_allocate_device();
	if (!ext->input) {
		ret = -ENOMEM;
		goto err_input;
	}

	input_set_drvdata(ext->input, ext);
	ext->input->open = wiiext_input_open;
	ext->input->close = wiiext_input_close;
	ext->input->dev.parent = &wdata->hdev->dev;
	ext->input->id.bustype = wdata->hdev->bus;
	ext->input->id.vendor = wdata->hdev->vendor;
	ext->input->id.product = wdata->hdev->product;
	ext->input->id.version = wdata->hdev->version;
	ext->input->name = WIIMOTE_NAME " Extension";

	set_bit(EV_KEY, ext->input->evbit);
	for (i = 0; i < WIIEXT_KEY_COUNT; ++i)
		set_bit(wiiext_keymap[i], ext->input->keybit);

	set_bit(EV_ABS, ext->input->evbit);
	set_bit(ABS_HAT0X, ext->input->absbit);
	set_bit(ABS_HAT0Y, ext->input->absbit);
	set_bit(ABS_HAT1X, ext->input->absbit);
	set_bit(ABS_HAT1Y, ext->input->absbit);
	set_bit(ABS_HAT2X, ext->input->absbit);
	set_bit(ABS_HAT2Y, ext->input->absbit);
	set_bit(ABS_HAT3X, ext->input->absbit);
	set_bit(ABS_HAT3Y, ext->input->absbit);
	input_set_abs_params(ext->input, ABS_HAT0X, -120, 120, 2, 4);
	input_set_abs_params(ext->input, ABS_HAT0Y, -120, 120, 2, 4);
	input_set_abs_params(ext->input, ABS_HAT1X, -30, 30, 1, 1);
	input_set_abs_params(ext->input, ABS_HAT1Y, -30, 30, 1, 1);
	input_set_abs_params(ext->input, ABS_HAT2X, -30, 30, 1, 1);
	input_set_abs_params(ext->input, ABS_HAT2Y, -30, 30, 1, 1);
	input_set_abs_params(ext->input, ABS_HAT3X, -30, 30, 1, 1);
	input_set_abs_params(ext->input, ABS_HAT3Y, -30, 30, 1, 1);
	set_bit(ABS_RX, ext->input->absbit);
	set_bit(ABS_RY, ext->input->absbit);
	set_bit(ABS_RZ, ext->input->absbit);
	input_set_abs_params(ext->input, ABS_RX, -500, 500, 2, 4);
	input_set_abs_params(ext->input, ABS_RY, -500, 500, 2, 4);
	input_set_abs_params(ext->input, ABS_RZ, -500, 500, 2, 4);

	ret = input_register_device(ext->input);
	if (ret) {
		input_free_device(ext->input);
		goto err_input;
	}

	ext->mp_input = input_allocate_device();
	if (!ext->mp_input) {
		ret = -ENOMEM;
		goto err_mp;
	}

	input_set_drvdata(ext->mp_input, ext);
	ext->mp_input->open = wiiext_mp_open;
	ext->mp_input->close = wiiext_mp_close;
	ext->mp_input->dev.parent = &wdata->hdev->dev;
	ext->mp_input->id.bustype = wdata->hdev->bus;
	ext->mp_input->id.vendor = wdata->hdev->vendor;
	ext->mp_input->id.product = wdata->hdev->product;
	ext->mp_input->id.version = wdata->hdev->version;
	ext->mp_input->name = WIIMOTE_NAME " Motion+";

	set_bit(EV_ABS, ext->mp_input->evbit);
	set_bit(ABS_RX, ext->mp_input->absbit);
	set_bit(ABS_RY, ext->mp_input->absbit);
	set_bit(ABS_RZ, ext->mp_input->absbit);
	input_set_abs_params(ext->mp_input, ABS_RX, -160000, 160000, 4, 8);
	input_set_abs_params(ext->mp_input, ABS_RY, -160000, 160000, 4, 8);
	input_set_abs_params(ext->mp_input, ABS_RZ, -160000, 160000, 4, 8);

	ret = input_register_device(ext->mp_input);
	if (ret) {
		input_free_device(ext->mp_input);
		goto err_mp;
	}

	ret = device_create_file(&wdata->hdev->dev, &dev_attr_extension);
	if (ret)
		goto err_dev;

	spin_lock_irqsave(&wdata->state.lock, flags);
	wdata->ext = ext;
	spin_unlock_irqrestore(&wdata->state.lock, flags);

	return 0;

err_dev:
	input_unregister_device(ext->mp_input);
err_mp:
	input_unregister_device(ext->input);
err_input:
	kfree(ext);
	return ret;
}

/* Deinitializes the extension driver of a wiimote */
void wiiext_deinit(struct wiimote_data *wdata)
{
	struct wiimote_ext *ext = wdata->ext;
	unsigned long flags;

	if (!ext)
		return;

	/*
	 * We first unset wdata->ext to avoid further input from the wiimote
	 * core. The worker thread does not access this pointer so it is not
	 * affected by this.
	 * We kill the worker after this so it does not get respawned during
	 * deinitialization.
	 */

	spin_lock_irqsave(&wdata->state.lock, flags);
	wdata->ext = NULL;
	spin_unlock_irqrestore(&wdata->state.lock, flags);

	device_remove_file(&wdata->hdev->dev, &dev_attr_extension);
	input_unregister_device(ext->mp_input);
	input_unregister_device(ext->input);

	cancel_work_sync(&ext->worker);
	kfree(ext);
}
