Skip to contentSkip to conversation

Input/HID: Guitar/Drums support

PATCH Applied David Herrmann 3 participants 8 messages Aug 26, 2013 – Sep 4, 2013

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Input/HID: Guitar/Drums support

Hi

This series adds wiimote extension support for guitars and drums. The patches are fairly simple and work the same as the other 5 wiimote extensions. But as we currently don't have IDs to report drums or guitar events to user-space, I had to add them.

Patch #1 adds basic IDs to <linux/input.h>. I tried to find as many devices as I could and looked what IDs would be required. Turned out, the device I was implementing already supported almost all (except 2 instead of 4 cymbals and 3 instead of 4 toms).

Patch #2 and #3 add the wiimote extensions.

This has been mostly worked out and tested by Nicolas (thanks!) and we started this work almost 3 month ago. Due to holidays it took a bit longer to get pressure reports working. But now everything should be fine.

The xwiimote user-space tools already support this and provide testing utilities if someone is interested: http://github.com/dvdhrm/xwiimote

Jiri, Dmitry, can we try merging this for 3.13? I know it's late, but it did see a lot of testing from Nicolas.

Regards
David

Btw., if someone has similar PS3 or WorldTour devices, I'd be glad to add support for them!

David Herrmann (2):
Input: introduce BTN/ABS bits for drums and guitars
HID: wiimote: add support for Guitar-Hero drums

Nicolas Adenis-Lamarre (1):
HID: wiimote: add support for Guitar-Hero guitars

 drivers/hid/hid-wiimote-core.c    |  14 ++
 drivers/hid/hid-wiimote-modules.c | 392 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-wiimote.h         |   3 +
 include/linux/mod_devicetable.h   |   2 +-
 include/uapi/linux/input.h        |  25 ++-
 5 files changed, 433 insertions(+), 3 deletions(-)
Signature · 1 line
1.8.4
#1 lore raw

PATCH 1/3 Input: introduce BTN/ABS bits for drums and guitars

There are a bunch of guitar and drums devices out there that all report similar data. To avoid reporting this as BTN_MISC or ABS_MISC, we allocate some proper namespace for them. Note that most of these devices are toys and we cannot report any sophisticated physics via this API.

I did some google-images research and tried to provide definitions that work with all common devices. That's why I went with 4 toms, 4 cymbals, one bass, one hi-hat. I haven't seen other drums and I doubt that we need any additions to that. Anyway, the naming-scheme is intentionally done in an extensible way.

For guitars, we support 5 frets (normally aligned vertically, compared to the real horizontal layouts), a single strum-bar with up/down directions, an optional fret-board and a whammy-bar.

Most of the devices provide pressure values so I went with ABS_* bits. If we ever support devices which only provide digital input, we have to decide whether to emulate pressure data or add additional BTN_* bits.

If someone is not familiar with these devices, here are two pictures which provide almost all introduced interfaces (or try the given keywords with a google-image search):
Guitar: ("guitar hero world tour guitar")

    http://images1.wikia.nocookie.net/__cb20120911023442/applezone/es/images/f/f9/Wii_Guitar.jpg
  Drums: ("guitar hero drums")
    http://oyster.ignimgs.com/franchises/images/03/55/35526_band-hero-drum-set-hands-on-20090929040735768.jpg
---
 include/linux/mod_devicetable.h |  2 +-
 include/uapi/linux/input.h      | 25 +++++++++++++++++++++++--
 2 files changed, 24 insertions(+), 3 deletions(-)
include/linux/mod_devicetable.h +1 -1
index 45e9214..329aa30 100644
@@ -277,7 +277,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING	0x71
 #define INPUT_DEVICE_ID_KEY_MAX		0x2ff
 #define INPUT_DEVICE_ID_REL_MAX		0x0f
-#define INPUT_DEVICE_ID_ABS_MAX		0x3f
+#define INPUT_DEVICE_ID_ABS_MAX		0x4f
 #define INPUT_DEVICE_ID_MSC_MAX		0x07
 #define INPUT_DEVICE_ID_LED_MAX		0x0f
 #define INPUT_DEVICE_ID_SND_MAX		0x07
include/uapi/linux/input.h +23 -2
index d584047..76457ee 100644
@@ -716,6 +716,14 @@ struct input_keymap_entry {
 #define BTN_DPAD_LEFT		0x222
 #define BTN_DPAD_RIGHT		0x223
 
+#define BTN_FRET_FAR_UP		0x224
+#define BTN_FRET_UP		0x225
+#define BTN_FRET_MID		0x226
+#define BTN_FRET_LOW		0x227
+#define BTN_FRET_FAR_LOW	0x228
+#define BTN_STRUM_BAR_UP	0x229
+#define BTN_STRUM_BAR_DOWN	0x22a
+
 #define BTN_TRIGGER_HAPPY		0x2c0
 #define BTN_TRIGGER_HAPPY1		0x2c0
 #define BTN_TRIGGER_HAPPY2		0x2c1
@@ -829,8 +837,21 @@ struct input_keymap_entry {
 #define ABS_MT_TOOL_X		0x3c	/* Center X tool position */
 #define ABS_MT_TOOL_Y		0x3d	/* Center Y tool position */
 
-
-#define ABS_MAX			0x3f
+/* Drums and guitars (mostly toys) */
+#define ABS_TOM_FAR_LEFT	0x40
+#define ABS_TOM_LEFT		0x41
+#define ABS_TOM_RIGHT		0x42
+#define ABS_TOM_FAR_RIGHT	0x43
+#define ABS_CYMBAL_FAR_LEFT	0x44
+#define ABS_CYMBAL_LEFT		0x45
+#define ABS_CYMBAL_RIGHT	0x46
+#define ABS_CYMBAL_FAR_RIGHT	0x47
+#define ABS_BASS		0x48
+#define ABS_HI_HAT		0x49
+#define ABS_FRET_BOARD		0x4a	/* Guitar fret board, vertical pos */
+#define ABS_WHAMMY_BAR		0x4b	/* Guitar whammy bar (or vibrato) */
+
+#define ABS_MAX			0x4f
 #define ABS_CNT			(ABS_MAX+1)
 
 /*
Signature · 1 line
1.8.4
#2 lore raw

Re: [PATCH 1/3] Input: introduce BTN/ABS bits for drums and guitars

Quoted 23 lines · David Herrmann

There are a bunch of guitar and drums devices out there that all report similar data. To avoid reporting this as BTN_MISC or ABS_MISC, we allocate some proper namespace for them. Note that most of these devices are toys and we cannot report any sophisticated physics via this API.

I did some google-images research and tried to provide definitions that work with all common devices. That's why I went with 4 toms, 4 cymbals, one bass, one hi-hat. I haven't seen other drums and I doubt that we need any additions to that. Anyway, the naming-scheme is intentionally done in an extensible way.

For guitars, we support 5 frets (normally aligned vertically, compared to the real horizontal layouts), a single strum-bar with up/down directions, an optional fret-board and a whammy-bar.

Most of the devices provide pressure values so I went with ABS_* bits. If we ever support devices which only provide digital input, we have to decide whether to emulate pressure data or add additional BTN_* bits.

If someone is not familiar with these devices, here are two pictures which provide almost all introduced interfaces (or try the given keywords with a google-image search):
Guitar: ("guitar hero world tour guitar")

Quoted 5 lines
    http://images1.wikia.nocookie.net/__cb20120911023442/applezone/es/images/f/f9/Wii_Guitar.jpg
  Drums: ("guitar hero drums")
    http://oyster.ignimgs.com/franchises/images/03/55/35526_band-hero-drum-set-hands-on-20090929040735768.jpg

Hi,

I have reviewed and like the implementation of 2/3 and 3/3, but I of course would like to have Ack from Dmitry for this, so that I could take it through my tree together with the rest of the patchset.

Dmitry, pretty please?

Thanks.

Quoted 64 lines
---
 include/linux/mod_devicetable.h |  2 +-
 include/uapi/linux/input.h      | 25 +++++++++++++++++++++++--
 2 files changed, 24 insertions(+), 3 deletions(-)
include/linux/mod_devicetable.h +1 -1
index 45e9214..329aa30 100644
@@ -277,7 +277,7 @@ struct pcmcia_device_id {
 #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING	0x71
 #define INPUT_DEVICE_ID_KEY_MAX		0x2ff
 #define INPUT_DEVICE_ID_REL_MAX		0x0f
-#define INPUT_DEVICE_ID_ABS_MAX		0x3f
+#define INPUT_DEVICE_ID_ABS_MAX		0x4f
 #define INPUT_DEVICE_ID_MSC_MAX		0x07
 #define INPUT_DEVICE_ID_LED_MAX		0x0f
 #define INPUT_DEVICE_ID_SND_MAX		0x07
include/uapi/linux/input.h +23 -2
index d584047..76457ee 100644
@@ -716,6 +716,14 @@ struct input_keymap_entry {
 #define BTN_DPAD_LEFT		0x222
 #define BTN_DPAD_RIGHT		0x223
 
+#define BTN_FRET_FAR_UP		0x224
+#define BTN_FRET_UP		0x225
+#define BTN_FRET_MID		0x226
+#define BTN_FRET_LOW		0x227
+#define BTN_FRET_FAR_LOW	0x228
+#define BTN_STRUM_BAR_UP	0x229
+#define BTN_STRUM_BAR_DOWN	0x22a
+
 #define BTN_TRIGGER_HAPPY		0x2c0
 #define BTN_TRIGGER_HAPPY1		0x2c0
 #define BTN_TRIGGER_HAPPY2		0x2c1
@@ -829,8 +837,21 @@ struct input_keymap_entry {
 #define ABS_MT_TOOL_X		0x3c	/* Center X tool position */
 #define ABS_MT_TOOL_Y		0x3d	/* Center Y tool position */
 
-
-#define ABS_MAX			0x3f
+/* Drums and guitars (mostly toys) */
+#define ABS_TOM_FAR_LEFT	0x40
+#define ABS_TOM_LEFT		0x41
+#define ABS_TOM_RIGHT		0x42
+#define ABS_TOM_FAR_RIGHT	0x43
+#define ABS_CYMBAL_FAR_LEFT	0x44
+#define ABS_CYMBAL_LEFT		0x45
+#define ABS_CYMBAL_RIGHT	0x46
+#define ABS_CYMBAL_FAR_RIGHT	0x47
+#define ABS_BASS		0x48
+#define ABS_HI_HAT		0x49
+#define ABS_FRET_BOARD		0x4a	/* Guitar fret board, vertical pos */
+#define ABS_WHAMMY_BAR		0x4b	/* Guitar whammy bar (or vibrato) */
+
+#define ABS_MAX			0x4f
 #define ABS_CNT			(ABS_MAX+1)
 
 /*
Signature · 1 line
1.8.4
Signature · 2 lines
Jiri Kosina
SUSE Labs
maintainer Acked-by
#3 lore raw

Re: [PATCH 1/3] Input: introduce BTN/ABS bits for drums and guitars

Quoted 31 lines · Jiri Kosina
Quoted 23 lines · David Herrmann

There are a bunch of guitar and drums devices out there that all report similar data. To avoid reporting this as BTN_MISC or ABS_MISC, we allocate some proper namespace for them. Note that most of these devices are toys and we cannot report any sophisticated physics via this API.

I did some google-images research and tried to provide definitions that work with all common devices. That's why I went with 4 toms, 4 cymbals, one bass, one hi-hat. I haven't seen other drums and I doubt that we need any additions to that. Anyway, the naming-scheme is intentionally done in an extensible way.

For guitars, we support 5 frets (normally aligned vertically, compared to the real horizontal layouts), a single strum-bar with up/down directions, an optional fret-board and a whammy-bar.

Most of the devices provide pressure values so I went with ABS_* bits. If we ever support devices which only provide digital input, we have to decide whether to emulate pressure data or add additional BTN_* bits.

If someone is not familiar with these devices, here are two pictures which provide almost all introduced interfaces (or try the given keywords with a google-image search):
Guitar: ("guitar hero world tour guitar")

Quoted 5 lines
    http://images1.wikia.nocookie.net/__cb20120911023442/applezone/es/images/f/f9/Wii_Guitar.jpg
  Drums: ("guitar hero drums")
    http://oyster.ignimgs.com/franchises/images/03/55/35526_band-hero-drum-set-hands-on-20090929040735768.jpg
Quoted 7 lines

Hi,

I have reviewed and like the implementation of 2/3 and 3/3, but I of course would like to have Ack from Dmitry for this, so that I could take it through my tree together with the rest of the patchset.

Dmitry, pretty please?

We might want to see how much memory is taken now by ABS structures and think if we could reduce it somehow...

Thanks.

Dmitry

#4 lore raw

Re: [PATCH 1/3] Input: introduce BTN/ABS bits for drums and guitars

Hi

Quoted 38 lines · Dmitry Torokhov
Quoted 37 lines · Jiri Kosina
Quoted 23 lines · David Herrmann

There are a bunch of guitar and drums devices out there that all report similar data. To avoid reporting this as BTN_MISC or ABS_MISC, we allocate some proper namespace for them. Note that most of these devices are toys and we cannot report any sophisticated physics via this API.

I did some google-images research and tried to provide definitions that work with all common devices. That's why I went with 4 toms, 4 cymbals, one bass, one hi-hat. I haven't seen other drums and I doubt that we need any additions to that. Anyway, the naming-scheme is intentionally done in an extensible way.

For guitars, we support 5 frets (normally aligned vertically, compared to the real horizontal layouts), a single strum-bar with up/down directions, an optional fret-board and a whammy-bar.

Most of the devices provide pressure values so I went with ABS_* bits. If we ever support devices which only provide digital input, we have to decide whether to emulate pressure data or add additional BTN_* bits.

If someone is not familiar with these devices, here are two pictures which provide almost all introduced interfaces (or try the given keywords with a google-image search):
Guitar: ("guitar hero world tour guitar")

Quoted 5 lines
    http://images1.wikia.nocookie.net/__cb20120911023442/applezone/es/images/f/f9/Wii_Guitar.jpg
  Drums: ("guitar hero drums")
    http://oyster.ignimgs.com/franchises/images/03/55/35526_band-hero-drum-set-hands-on-20090929040735768.jpg

Hi,

I have reviewed and like the implementation of 2/3 and 3/3, but I of course would like to have Ack from Dmitry for this, so that I could take it through my tree together with the rest of the patchset.

Quoted 6 lines
Quoted 1 line

Dmitry, pretty please?

We might want to see how much memory is taken now by ABS structures and think if we could reduce it somehow...

Thanks Dmitry! And I thought about the "absinfo"-size, too. Some rough numbers:

sizeof(struct input_absinfo) = 24 bytes
ABS_CNT * sizeof(struct input_absinfo) = 0x50 * 24 bytes = 1920 bytes

sizeof(struct input_dev) = 1824 bytes
name, phys, uniq + misc ~= 100 bytes
dev->vals ~= 10 * sizeof(struct input_value) = 10 * 8 bytes = 80 bytes

So we get 1824 + 100 + 80 = 2008 bytes for an average trivial input device. The abs-values add 1920 bytes to that. So I don't think it's that bad.

Anyway, some trivial ideas off the top of my head:

1)
Changing "absinfo" to double-indirection:

    struct input_absinfo *absinfo[ABS_CNT];
    struct input_absinfo *real_absinfo;

We allocate "real_absinfo" as array for as many ABS entries as we need and set the pointers in "absinfo" accordingly (setting everything else to NULL).
This, however, still adds ABS_CNT * 8 = 0x50 * 8 = 640 bytes only for the pointer array. So not really much better. And we get the additional TLB lookup for the double-indirection. I don't know whether it matters for the quite expensive input-handling, though.

2)
Using idr. But considering that most input-devices only have very few (<10?) ABS bits set, it probably doesn't scale.

3)
An rbtree for all absinfo objects. Only adds 24 bytes per absinfo and lookup is only needed once in input_handle_abs_event(). It takes the least space of all (except for linear search) and it's still reasonably fast for all setups.
All in all, if we assume <10 input devices on a machine, we would save around 20kb with 3). I am not sure what impact it has on performance. But looking at the deep call-chains in input-interrupts, I doubt it would be noticeable. But that's only a rough guess..

4)
We let drivers manage absinfo objects and pass it together with input_event() (for ABS only). Would probably be the nicest solution but require huge codebase changes.

But maybe someone else has some way better ideas.. It's getting late here.

Cheers
David

#5 lore raw

PATCH 2/3 HID: wiimote: add support for Guitar-Hero drums

In reply to David Herrmann

Guitar-Hero comes with a drums extension. Use the newly introduced input drums-bits to report this back to user-space. This is a usual extension like any other device. Nothing special to take care of.

We report this to user-space as "Nintendo Wii Remote Drums". There are other drums (like "RockBand" drums) which we currently do not support and maybe will at some point. However, it is quite likely that we can report these via the same interface. This allows user-space to work with them without knowing the exact branding.
I couldn't find anyone who owns a "RockBand" device, though.

---
 drivers/hid/hid-wiimote-core.c    |   7 ++
 drivers/hid/hid-wiimote-modules.c | 218 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-wiimote.h         |   2 +
 3 files changed, 227 insertions(+)
drivers/hid/hid-wiimote-core.c +7 -0
index 6602098..946cdef 100644
@@ -456,6 +456,9 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
 		return WIIMOTE_EXT_BALANCE_BOARD;
 	if (rmem[4] == 0x01 && rmem[5] == 0x20)
 		return WIIMOTE_EXT_PRO_CONTROLLER;
+	if (rmem[0] == 0x01 && rmem[1] == 0x00 &&
+	    rmem[4] == 0x01 && rmem[5] == 0x03)
+		return WIIMOTE_EXT_GUITAR_HERO_DRUMS;
 
 	return WIIMOTE_EXT_UNKNOWN;
 }
@@ -489,6 +492,7 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
 	/* map MP with correct pass-through mode */
 	switch (exttype) {
 	case WIIMOTE_EXT_CLASSIC_CONTROLLER:
+	case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
 		wmem = 0x07;
 		break;
 	case WIIMOTE_EXT_NUNCHUK:
@@ -1079,6 +1083,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
 	[WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller",
 	[WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
 	[WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
+	[WIIMOTE_EXT_GUITAR_HERO_DRUMS] = "Nintendo Wii Guitar Hero Drums",
 };
 
 /*
@@ -1665,6 +1670,8 @@ static ssize_t wiimote_ext_show(struct device *dev,
 		return sprintf(buf, "balanceboard\n");
 	case WIIMOTE_EXT_PRO_CONTROLLER:
 		return sprintf(buf, "procontroller\n");
+	case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
+		return sprintf(buf, "drums\n");
 	case WIIMOTE_EXT_UNKNOWN:
 		/* fallthrough */
 	default:
drivers/hid/hid-wiimote-modules.c +218 -0

228 lines not on this page · raw message

drivers/hid/hid-wiimote.h +2 -0
index f1474f3..6e18b55 100644
@@ -88,6 +88,7 @@ enum wiimote_exttype {
 	WIIMOTE_EXT_CLASSIC_CONTROLLER,
 	WIIMOTE_EXT_BALANCE_BOARD,
 	WIIMOTE_EXT_PRO_CONTROLLER,
+	WIIMOTE_EXT_GUITAR_HERO_DRUMS,
 	WIIMOTE_EXT_NUM,
 };
 
@@ -135,6 +136,7 @@ struct wiimote_state {
 
 	/* calibration data */
 	__u16 calib_bboard[4][3];
+	__u8 pressure_drums[7];
 };
 
 struct wiimote_data {
Signature · 1 line
1.8.4
#6 lore raw

PATCH 3/3 HID: wiimote: add support for Guitar-Hero guitars

In reply to David Herrmann

From: Nicolas Adenis-Lamarre <[email protected]>

Apart from drums, Guitar-Hero also ships with guitars. Use the recently introduced input ABS/BTN-bits to report this to user-space.

Devices are reported as "Nintendo Wii Remote Guitar". If I ever get my hands on "RockBand" guitars, I will try to report them via the same interface so user-space does not have to bother which device it deals with.

(add commit-msg and adjust to new BTN_* IDs)

---
 drivers/hid/hid-wiimote-core.c    |   7 ++
 drivers/hid/hid-wiimote-modules.c | 174 ++++++++++++++++++++++++++++++++++++++
 drivers/hid/hid-wiimote.h         |   1 +
 3 files changed, 182 insertions(+)
drivers/hid/hid-wiimote-core.c +7 -0
index 946cdef..d3055d1 100644
@@ -459,6 +459,9 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
 	if (rmem[0] == 0x01 && rmem[1] == 0x00 &&
 	    rmem[4] == 0x01 && rmem[5] == 0x03)
 		return WIIMOTE_EXT_GUITAR_HERO_DRUMS;
+	if (rmem[0] == 0x00 && rmem[1] == 0x00 &&
+	    rmem[4] == 0x01 && rmem[5] == 0x03)
+		return WIIMOTE_EXT_GUITAR_HERO_GUITAR;
 
 	return WIIMOTE_EXT_UNKNOWN;
 }
@@ -493,6 +496,7 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
 	switch (exttype) {
 	case WIIMOTE_EXT_CLASSIC_CONTROLLER:
 	case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
+	case WIIMOTE_EXT_GUITAR_HERO_GUITAR:
 		wmem = 0x07;
 		break;
 	case WIIMOTE_EXT_NUNCHUK:
@@ -1084,6 +1088,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
 	[WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
 	[WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
 	[WIIMOTE_EXT_GUITAR_HERO_DRUMS] = "Nintendo Wii Guitar Hero Drums",
+	[WIIMOTE_EXT_GUITAR_HERO_GUITAR] = "Nintendo Wii Guitar Hero Guitar",
 };
 
 /*
@@ -1672,6 +1677,8 @@ static ssize_t wiimote_ext_show(struct device *dev,
 		return sprintf(buf, "procontroller\n");
 	case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
 		return sprintf(buf, "drums\n");
+	case WIIMOTE_EXT_GUITAR_HERO_GUITAR:
+		return sprintf(buf, "guitar\n");
 	case WIIMOTE_EXT_UNKNOWN:
 		/* fallthrough */
 	default:
drivers/hid/hid-wiimote-modules.c +174 -0

184 lines not on this page · raw message

drivers/hid/hid-wiimote.h +1 -0
index 6e18b55..379cdfb 100644
@@ -89,6 +89,7 @@ enum wiimote_exttype {
 	WIIMOTE_EXT_BALANCE_BOARD,
 	WIIMOTE_EXT_PRO_CONTROLLER,
 	WIIMOTE_EXT_GUITAR_HERO_DRUMS,
+	WIIMOTE_EXT_GUITAR_HERO_GUITAR,
 	WIIMOTE_EXT_NUM,
 };
 
Signature · 1 line
1.8.4
Applied
#7 lore raw
In reply to David Herrmann
Quoted 1 line · David Herrmann

This series adds wiimote extension support for guitars and drums.

Applied, thanks!

Signature · 2 lines
Jiri Kosina
SUSE Labs