/*
 * 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 */
};

/* disable 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);
}
