Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ad67fbc authored by David Herrmann's avatar David Herrmann Committed by Jiri Kosina
Browse files

HID: wiimote: Add Nintendo Balance-Board support



The Nintendo Balance-Board is a controller which behaves exactly like the
Wii Remote but reports all its data through a special extension device.
Hence, we can simply add the Balance-Board as extension device and we get
full support for it.

Tested-by: default avatarFlorian Echtler <floe@butterbrot.org>
Signed-off-by: default avatarDavid Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 5b6e7f1c
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ enum wiiext_type {
	WIIEXT_NONE,		/* placeholder */
	WIIEXT_CLASSIC,		/* Nintendo classic controller */
	WIIEXT_NUNCHUCK,	/* Nintendo nunchuck controller */
	WIIEXT_BALANCE_BOARD,	/* Nintendo balance board controller */
};

enum wiiext_keys {
@@ -151,6 +152,8 @@ static __u8 ext_read(struct wiimote_ext *ext)
			type = WIIEXT_NUNCHUCK;
		else if (rmem[0] == 0x01 && rmem[1] == 0x01)
			type = WIIEXT_CLASSIC;
		else if (rmem[0] == 0x04 && rmem[1] == 0x02)
			type = WIIEXT_BALANCE_BOARD;
	}

	wiimote_cmd_release(ext->wdata);
@@ -509,6 +512,55 @@ static void handler_classic(struct wiimote_ext *ext, const __u8 *payload)
	input_sync(ext->input);
}

static void handler_balance_board(struct wiimote_ext *ext, const __u8 *payload)
{
	__s32 val[4];

	/*   Byte |  8  7  6  5  4  3  2  1  |
	 *   -----+--------------------------+
	 *    1   |    Top Right <15:8>      |
	 *    2   |    Top Right  <7:0>      |
	 *   -----+--------------------------+
	 *    3   | Bottom Right <15:8>      |
	 *    4   | Bottom Right  <7:0>      |
	 *   -----+--------------------------+
	 *    5   |     Top Left <15:8>      |
	 *    6   |     Top Left  <7:0>      |
	 *   -----+--------------------------+
	 *    7   |  Bottom Left <15:8>      |
	 *    8   |  Bottom Left  <7:0>      |
	 *   -----+--------------------------+
	 *
	 * These values represent the weight-measurements of the Wii-balance
	 * board with 16bit precision.
	 *
	 * The balance-board is never reported interleaved with motionp.
	 */

	val[0] = payload[0];
	val[0] <<= 8;
	val[0] |= payload[1];

	val[1] = payload[2];
	val[1] <<= 8;
	val[1] |= payload[3];

	val[2] = payload[4];
	val[2] <<= 8;
	val[2] |= payload[5];

	val[3] = payload[6];
	val[3] <<= 8;
	val[3] |= payload[7];

	input_report_abs(ext->input, ABS_HAT0X, val[0]);
	input_report_abs(ext->input, ABS_HAT0Y, val[1]);
	input_report_abs(ext->input, ABS_HAT1X, val[2]);
	input_report_abs(ext->input, ABS_HAT1Y, val[3]);

	input_sync(ext->input);
}

/* call this with state.lock spinlock held */
void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
{
@@ -523,6 +575,8 @@ void wiiext_handle(struct wiimote_data *wdata, const __u8 *payload)
		handler_nunchuck(ext, payload);
	} else if (ext->ext_type == WIIEXT_CLASSIC) {
		handler_classic(ext, payload);
	} else if (ext->ext_type == WIIEXT_BALANCE_BOARD) {
		handler_balance_board(ext, payload);
	}
}

@@ -551,6 +605,11 @@ static ssize_t wiiext_show(struct device *dev, struct device_attribute *attr,
			return sprintf(buf, "motionp+classic\n");
		else
			return sprintf(buf, "classic\n");
	} else if (type == WIIEXT_BALANCE_BOARD) {
		if (motionp)
			return sprintf(buf, "motionp+balanceboard\n");
		else
			return sprintf(buf, "balanceboard\n");
	} else {
		if (motionp)
			return sprintf(buf, "motionp\n");