aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-08-26 13:14:47 -0400
committerJiri Kosina <jkosina@suse.cz>2013-09-04 04:44:17 -0400
commit73f8645db1913ab2475ec3c1cee8d5f748963aa7 (patch)
tree5415151a1b7fc473459490d0d5dc2695089e981e /drivers/hid
parent61e00655e9cb82e034eb72b95a51072e718d14a7 (diff)
HID: wiimote: add support for Guitar-Hero drums
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. Initial-work-by: Nicolas Adenis-Lamarre <nicolas.adenis.lamarre@gmail.com> Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/hid-wiimote-core.c7
-rw-r--r--drivers/hid/hid-wiimote-modules.c218
-rw-r--r--drivers/hid/hid-wiimote.h2
3 files changed, 227 insertions, 0 deletions
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c
index 660209824e56..946cdeff4798 100644
--- a/drivers/hid/hid-wiimote-core.c
+++ b/drivers/hid/hid-wiimote-core.c
@@ -456,6 +456,9 @@ static __u8 wiimote_cmd_read_ext(struct wiimote_data *wdata, __u8 *rmem)
456 return WIIMOTE_EXT_BALANCE_BOARD; 456 return WIIMOTE_EXT_BALANCE_BOARD;
457 if (rmem[4] == 0x01 && rmem[5] == 0x20) 457 if (rmem[4] == 0x01 && rmem[5] == 0x20)
458 return WIIMOTE_EXT_PRO_CONTROLLER; 458 return WIIMOTE_EXT_PRO_CONTROLLER;
459 if (rmem[0] == 0x01 && rmem[1] == 0x00 &&
460 rmem[4] == 0x01 && rmem[5] == 0x03)
461 return WIIMOTE_EXT_GUITAR_HERO_DRUMS;
459 462
460 return WIIMOTE_EXT_UNKNOWN; 463 return WIIMOTE_EXT_UNKNOWN;
461} 464}
@@ -489,6 +492,7 @@ static bool wiimote_cmd_map_mp(struct wiimote_data *wdata, __u8 exttype)
489 /* map MP with correct pass-through mode */ 492 /* map MP with correct pass-through mode */
490 switch (exttype) { 493 switch (exttype) {
491 case WIIMOTE_EXT_CLASSIC_CONTROLLER: 494 case WIIMOTE_EXT_CLASSIC_CONTROLLER:
495 case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
492 wmem = 0x07; 496 wmem = 0x07;
493 break; 497 break;
494 case WIIMOTE_EXT_NUNCHUK: 498 case WIIMOTE_EXT_NUNCHUK:
@@ -1079,6 +1083,7 @@ static const char *wiimote_exttype_names[WIIMOTE_EXT_NUM] = {
1079 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller", 1083 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = "Nintendo Wii Classic Controller",
1080 [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board", 1084 [WIIMOTE_EXT_BALANCE_BOARD] = "Nintendo Wii Balance Board",
1081 [WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller", 1085 [WIIMOTE_EXT_PRO_CONTROLLER] = "Nintendo Wii U Pro Controller",
1086 [WIIMOTE_EXT_GUITAR_HERO_DRUMS] = "Nintendo Wii Guitar Hero Drums",
1082}; 1087};
1083 1088
1084/* 1089/*
@@ -1665,6 +1670,8 @@ static ssize_t wiimote_ext_show(struct device *dev,
1665 return sprintf(buf, "balanceboard\n"); 1670 return sprintf(buf, "balanceboard\n");
1666 case WIIMOTE_EXT_PRO_CONTROLLER: 1671 case WIIMOTE_EXT_PRO_CONTROLLER:
1667 return sprintf(buf, "procontroller\n"); 1672 return sprintf(buf, "procontroller\n");
1673 case WIIMOTE_EXT_GUITAR_HERO_DRUMS:
1674 return sprintf(buf, "drums\n");
1668 case WIIMOTE_EXT_UNKNOWN: 1675 case WIIMOTE_EXT_UNKNOWN:
1669 /* fallthrough */ 1676 /* fallthrough */
1670 default: 1677 default:
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c
index 2e7d644dba18..08a44a7fc5fd 100644
--- a/drivers/hid/hid-wiimote-modules.c
+++ b/drivers/hid/hid-wiimote-modules.c
@@ -1834,6 +1834,223 @@ static const struct wiimod_ops wiimod_pro = {
1834}; 1834};
1835 1835
1836/* 1836/*
1837 * Drums
1838 * Guitar-Hero, Rock-Band and other games came bundled with drums which can
1839 * be plugged as extension to a Wiimote. Drum-reports are still not entirely
1840 * figured out, but the most important information is known.
1841 * We create a separate device for drums and report all information via this
1842 * input device.
1843 */
1844
1845static inline void wiimod_drums_report_pressure(struct wiimote_data *wdata,
1846 __u8 none, __u8 which,
1847 __u8 pressure, __u8 onoff,
1848 __u8 *store, __u16 code,
1849 __u8 which_code)
1850{
1851 static const __u8 default_pressure = 3;
1852
1853 if (!none && which == which_code) {
1854 *store = pressure;
1855 input_report_abs(wdata->extension.input, code, *store);
1856 } else if (onoff != !!*store) {
1857 *store = onoff ? default_pressure : 0;
1858 input_report_abs(wdata->extension.input, code, *store);
1859 }
1860}
1861
1862static void wiimod_drums_in_ext(struct wiimote_data *wdata, const __u8 *ext)
1863{
1864 __u8 pressure, which, none, hhp, sx, sy;
1865 __u8 o, r, y, g, b, bass, bm, bp;
1866
1867 /* Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
1868 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1869 * 1 | 0 | 0 | SX <5:0> |
1870 * 2 | 0 | 0 | SY <5:0> |
1871 * -----+-----+-----+-----------------------------+-----+
1872 * 3 | HPP | NON | WHICH <5:1> | ? |
1873 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1874 * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? |
1875 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1876 * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 | ? |
1877 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1878 * 6 | O | R | Y | G | B | BSS | 1 | 1 |
1879 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1880 * All buttons are 0 if pressed
1881 *
1882 * With Motion+ enabled, the following bits will get invalid:
1883 * Byte | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
1884 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1885 * 1 | 0 | 0 | SX <5:1> |XXXXX|
1886 * 2 | 0 | 0 | SY <5:1> |XXXXX|
1887 * -----+-----+-----+-----------------------------+-----+
1888 * 3 | HPP | NON | WHICH <5:1> | ? |
1889 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1890 * 4 | SOFT <7:5> | 0 | 1 | 1 | 0 | ? |
1891 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1892 * 5 | ? | 1 | 1 | B- | 1 | B+ | 1 |XXXXX|
1893 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1894 * 6 | O | R | Y | G | B | BSS |XXXXX|XXXXX|
1895 * -----+-----+-----+-----+-----+-----+-----+-----+-----+
1896 */
1897
1898 pressure = 7 - (ext[3] >> 5);
1899 which = (ext[2] >> 1) & 0x1f;
1900 none = !!(ext[2] & 0x40);
1901 hhp = !(ext[2] & 0x80);
1902 sx = ext[0] & 0x3f;
1903 sy = ext[1] & 0x3f;
1904 o = !(ext[5] & 0x80);
1905 r = !(ext[5] & 0x40);
1906 y = !(ext[5] & 0x20);
1907 g = !(ext[5] & 0x10);
1908 b = !(ext[5] & 0x08);
1909 bass = !(ext[5] & 0x04);
1910 bm = !(ext[4] & 0x10);
1911 bp = !(ext[4] & 0x04);
1912
1913 wiimod_drums_report_pressure(wdata, none, which, pressure,
1914 o, &wdata->state.pressure_drums[0],
1915 ABS_CYMBAL_RIGHT, 0x0e);
1916 wiimod_drums_report_pressure(wdata, none, which, pressure,
1917 r, &wdata->state.pressure_drums[1],
1918 ABS_TOM_LEFT, 0x19);
1919 wiimod_drums_report_pressure(wdata, none, which, pressure,
1920 y, &wdata->state.pressure_drums[2],
1921 ABS_CYMBAL_LEFT, 0x11);
1922 wiimod_drums_report_pressure(wdata, none, which, pressure,
1923 g, &wdata->state.pressure_drums[3],
1924 ABS_TOM_FAR_RIGHT, 0x12);
1925 wiimod_drums_report_pressure(wdata, none, which, pressure,
1926 b, &wdata->state.pressure_drums[4],
1927 ABS_TOM_RIGHT, 0x0f);
1928
1929 /* Bass shares pressure with hi-hat (set via hhp) */
1930 wiimod_drums_report_pressure(wdata, none, hhp ? 0xff : which, pressure,
1931 bass, &wdata->state.pressure_drums[5],
1932 ABS_BASS, 0x1b);
1933 /* Hi-hat has no on/off values, just pressure. Force to off/0. */
1934 wiimod_drums_report_pressure(wdata, none, hhp ? which : 0xff, pressure,
1935 0, &wdata->state.pressure_drums[6],
1936 ABS_HI_HAT, 0x0e);
1937
1938 input_report_abs(wdata->extension.input, ABS_X, sx - 0x20);
1939 input_report_abs(wdata->extension.input, ABS_Y, sy - 0x20);
1940
1941 input_report_key(wdata->extension.input, BTN_START, bp);
1942 input_report_key(wdata->extension.input, BTN_SELECT, bm);
1943
1944 input_sync(wdata->extension.input);
1945}
1946
1947static int wiimod_drums_open(struct input_dev *dev)
1948{
1949 struct wiimote_data *wdata = input_get_drvdata(dev);
1950 unsigned long flags;
1951
1952 spin_lock_irqsave(&wdata->state.lock, flags);
1953 wdata->state.flags |= WIIPROTO_FLAG_EXT_USED;
1954 wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
1955 spin_unlock_irqrestore(&wdata->state.lock, flags);
1956
1957 return 0;
1958}
1959
1960static void wiimod_drums_close(struct input_dev *dev)
1961{
1962 struct wiimote_data *wdata = input_get_drvdata(dev);
1963 unsigned long flags;
1964
1965 spin_lock_irqsave(&wdata->state.lock, flags);
1966 wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED;
1967 wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
1968 spin_unlock_irqrestore(&wdata->state.lock, flags);
1969}
1970
1971static int wiimod_drums_probe(const struct wiimod_ops *ops,
1972 struct wiimote_data *wdata)
1973{
1974 int ret;
1975
1976 wdata->extension.input = input_allocate_device();
1977 if (!wdata->extension.input)
1978 return -ENOMEM;
1979
1980 input_set_drvdata(wdata->extension.input, wdata);
1981 wdata->extension.input->open = wiimod_drums_open;
1982 wdata->extension.input->close = wiimod_drums_close;
1983 wdata->extension.input->dev.parent = &wdata->hdev->dev;
1984 wdata->extension.input->id.bustype = wdata->hdev->bus;
1985 wdata->extension.input->id.vendor = wdata->hdev->vendor;
1986 wdata->extension.input->id.product = wdata->hdev->product;
1987 wdata->extension.input->id.version = wdata->hdev->version;
1988 wdata->extension.input->name = WIIMOTE_NAME " Drums";
1989
1990 set_bit(EV_KEY, wdata->extension.input->evbit);
1991 set_bit(BTN_START, wdata->extension.input->keybit);
1992 set_bit(BTN_SELECT, wdata->extension.input->keybit);
1993
1994 set_bit(EV_ABS, wdata->extension.input->evbit);
1995 set_bit(ABS_X, wdata->extension.input->absbit);
1996 set_bit(ABS_Y, wdata->extension.input->absbit);
1997 set_bit(ABS_TOM_LEFT, wdata->extension.input->absbit);
1998 set_bit(ABS_TOM_RIGHT, wdata->extension.input->absbit);
1999 set_bit(ABS_TOM_FAR_RIGHT, wdata->extension.input->absbit);
2000 set_bit(ABS_CYMBAL_LEFT, wdata->extension.input->absbit);
2001 set_bit(ABS_CYMBAL_RIGHT, wdata->extension.input->absbit);
2002 set_bit(ABS_BASS, wdata->extension.input->absbit);
2003 set_bit(ABS_HI_HAT, wdata->extension.input->absbit);
2004 input_set_abs_params(wdata->extension.input,
2005 ABS_X, -32, 31, 1, 1);
2006 input_set_abs_params(wdata->extension.input,
2007 ABS_Y, -32, 31, 1, 1);
2008 input_set_abs_params(wdata->extension.input,
2009 ABS_TOM_LEFT, 0, 7, 0, 0);
2010 input_set_abs_params(wdata->extension.input,
2011 ABS_TOM_RIGHT, 0, 7, 0, 0);
2012 input_set_abs_params(wdata->extension.input,
2013 ABS_TOM_FAR_RIGHT, 0, 7, 0, 0);
2014 input_set_abs_params(wdata->extension.input,
2015 ABS_CYMBAL_LEFT, 0, 7, 0, 0);
2016 input_set_abs_params(wdata->extension.input,
2017 ABS_CYMBAL_RIGHT, 0, 7, 0, 0);
2018 input_set_abs_params(wdata->extension.input,
2019 ABS_BASS, 0, 7, 0, 0);
2020 input_set_abs_params(wdata->extension.input,
2021 ABS_HI_HAT, 0, 7, 0, 0);
2022
2023 ret = input_register_device(wdata->extension.input);
2024 if (ret)
2025 goto err_free;
2026
2027 return 0;
2028
2029err_free:
2030 input_free_device(wdata->extension.input);
2031 wdata->extension.input = NULL;
2032 return ret;
2033}
2034
2035static void wiimod_drums_remove(const struct wiimod_ops *ops,
2036 struct wiimote_data *wdata)
2037{
2038 if (!wdata->extension.input)
2039 return;
2040
2041 input_unregister_device(wdata->extension.input);
2042 wdata->extension.input = NULL;
2043}
2044
2045static const struct wiimod_ops wiimod_drums = {
2046 .flags = 0,
2047 .arg = 0,
2048 .probe = wiimod_drums_probe,
2049 .remove = wiimod_drums_remove,
2050 .in_ext = wiimod_drums_in_ext,
2051};
2052
2053/*
1837 * Builtin Motion Plus 2054 * Builtin Motion Plus
1838 * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which 2055 * This module simply sets the WIIPROTO_FLAG_BUILTIN_MP protocol flag which
1839 * disables polling for Motion-Plus. This should be set only for devices which 2056 * disables polling for Motion-Plus. This should be set only for devices which
@@ -2083,4 +2300,5 @@ const struct wiimod_ops *wiimod_ext_table[WIIMOTE_EXT_NUM] = {
2083 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic, 2300 [WIIMOTE_EXT_CLASSIC_CONTROLLER] = &wiimod_classic,
2084 [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard, 2301 [WIIMOTE_EXT_BALANCE_BOARD] = &wiimod_bboard,
2085 [WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro, 2302 [WIIMOTE_EXT_PRO_CONTROLLER] = &wiimod_pro,
2303 [WIIMOTE_EXT_GUITAR_HERO_DRUMS] = &wiimod_drums,
2086}; 2304};
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h
index f1474f372c0b..6e18b55951fb 100644
--- a/drivers/hid/hid-wiimote.h
+++ b/drivers/hid/hid-wiimote.h
@@ -88,6 +88,7 @@ enum wiimote_exttype {
88 WIIMOTE_EXT_CLASSIC_CONTROLLER, 88 WIIMOTE_EXT_CLASSIC_CONTROLLER,
89 WIIMOTE_EXT_BALANCE_BOARD, 89 WIIMOTE_EXT_BALANCE_BOARD,
90 WIIMOTE_EXT_PRO_CONTROLLER, 90 WIIMOTE_EXT_PRO_CONTROLLER,
91 WIIMOTE_EXT_GUITAR_HERO_DRUMS,
91 WIIMOTE_EXT_NUM, 92 WIIMOTE_EXT_NUM,
92}; 93};
93 94
@@ -135,6 +136,7 @@ struct wiimote_state {
135 136
136 /* calibration data */ 137 /* calibration data */
137 __u16 calib_bboard[4][3]; 138 __u16 calib_bboard[4][3];
139 __u8 pressure_drums[7];
138}; 140};
139 141
140struct wiimote_data { 142struct wiimote_data {