diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 15:02:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 15:02:58 -0700 |
commit | 22a3b9771117d566def0150ea787fcc95f16e724 (patch) | |
tree | 20e24aa4df50cde8d28211531e893a7be61d1dfe /drivers | |
parent | acb41c0f928fdb84a1c3753ac92c534a2a0f08d2 (diff) | |
parent | a91f423e598912ab301592c7759cfd89e10682a1 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (31 commits)
HID: fix support for Microsoft comfort mouse 4500
HID: hid-multitouch: add one new multitouch device's VID/PID
HID: prodikeys: remove a redundant forward declaration of struct pcmidi_snd
HID: prodikeys: make needlessly global symbols static
HID: emsff: properly handle emsff_init failure
HID: ACRUX - add missing hid_hw_stop() in ax_probe() error path
HID: fix horizontal wheel for ms comfort mouse 4500
HID: uclogic: Add support for UC-Logic WP1062
HID: wiimote: Add sysfs support to wiimote driver
HID: wiimote: Cache wiimote led state
HID: wiimote: Add wiimote led request
HID: wiimote: Add wiimote input button parser
HID: wiimote: Add wiimote event handler
HID: wiimote: Add output queue for wiimote driver
HID: wiimote: Add wiimote send function
HID: wiimote: Synchronize wiimote input and hid event handling
HID: wiimote: Register input device in wiimote hid driver
HID: wiimote: Add wiimote device structure
HID: wiimote: Register wiimote hid driver stub
HID: wiimote: Add Nintendo Wii Remote driver stub
...
Diffstat (limited to 'drivers')
28 files changed, 1377 insertions, 135 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 36ca465c00c..306b15f39c9 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -172,6 +172,20 @@ config HID_EZKEY ---help--- Support for Ezkey BTC 8193 keyboard. +config HID_HOLTEK + tristate "Holtek On Line Grip based game controller support" + depends on USB_HID + ---help--- + Say Y here if you have a Holtek On Line Grip based game controller. + +config HOLTEK_FF + bool "Holtek On Line Grip force feedback support" + depends on HID_HOLTEK + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you have a Holtek On Line Grip based game controller + and want to have force feedback support for it. + config HID_KEYTOUCH tristate "Keytouch HID devices" depends on USB_HID @@ -322,6 +336,7 @@ config HID_MULTITOUCH - Stantum multitouch panels - Touch International Panels - Unitec Panels + - XAT optical touch panels If unsure, say N. @@ -435,6 +450,7 @@ config HID_QUANTA config HID_ROCCAT tristate "Roccat special event support" depends on USB_HID + select HID_ROCCAT_COMMON ---help--- Support for Roccat special events. Say Y here if you have a Roccat mouse or keyboard and want OSD or @@ -442,44 +458,40 @@ config HID_ROCCAT config HID_ROCCAT_COMMON tristate + depends on HID_ROCCAT config HID_ROCCAT_ARVO tristate "Roccat Arvo keyboard support" depends on USB_HID - select HID_ROCCAT - select HID_ROCCAT_COMMON + depends on HID_ROCCAT ---help--- Support for Roccat Arvo keyboard. config HID_ROCCAT_KONE tristate "Roccat Kone Mouse support" depends on USB_HID - select HID_ROCCAT - select HID_ROCCAT_COMMON + depends on HID_ROCCAT ---help--- Support for Roccat Kone mouse. config HID_ROCCAT_KONEPLUS tristate "Roccat Kone[+] mouse support" depends on USB_HID - select HID_ROCCAT - select HID_ROCCAT_COMMON + depends on HID_ROCCAT ---help--- Support for Roccat Kone[+] mouse. config HID_ROCCAT_KOVAPLUS tristate "Roccat Kova[+] mouse support" depends on USB_HID - select HID_ROCCAT - select HID_ROCCAT_COMMON + depends on HID_ROCCAT ---help--- Support for Roccat Kova[+] mouse. config HID_ROCCAT_PYRA tristate "Roccat Pyra mouse support" depends on USB_HID - select HID_ROCCAT - select HID_ROCCAT_COMMON + depends on HID_ROCCAT ---help--- Support for Roccat Pyra mouse. @@ -495,6 +507,12 @@ config HID_SONY ---help--- Support for Sony PS3 controller. +config HID_SPEEDLINK + tristate "Speedlink VAD Cezanne mouse support" + depends on USB_HID + ---help--- + Support for Speedlink Vicious and Divine Cezanne mouse. + config HID_SUNPLUS tristate "Sunplus wireless desktop" depends on USB_HID @@ -568,6 +586,12 @@ config HID_WACOM_POWER_SUPPLY Say Y here if you want to enable power supply status monitoring for Wacom Bluetooth devices. +config HID_WIIMOTE + tristate "Nintendo Wii Remote support" + depends on BT_HIDP + ---help--- + Support for the Nintendo Wii Remote bluetooth device. + config HID_ZEROPLUS tristate "Zeroplus based game controller support" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index f8cc4ea7335..0a0a38e9fd2 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o obj-$(CONFIG_HID_ELECOM) += hid-elecom.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o obj-$(CONFIG_HID_GYRATION) += hid-gyration.o +obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o obj-$(CONFIG_HID_KYE) += hid-kye.o @@ -63,6 +64,7 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SONY) += hid-sony.o +obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o @@ -73,6 +75,7 @@ obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o obj-$(CONFIG_HID_WACOM) += hid-wacom.o obj-$(CONFIG_HID_WALTOP) += hid-waltop.o +obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o obj-$(CONFIG_USB_HID) += usbhid/ obj-$(CONFIG_USB_MOUSE) += usbhid/ diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index b4554288de0..121514149e0 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -154,6 +154,7 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) error = hid_hw_open(hdev); if (error) { dev_err(&hdev->dev, "hw open failed\n"); + hid_hw_stop(hdev); return error; } diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6f3289a5788..1a5cf0c9cfc 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1388,6 +1388,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, @@ -1426,10 +1427,12 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, @@ -1491,6 +1494,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, + { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) }, { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, @@ -1499,11 +1503,14 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) }, { } }; @@ -1771,7 +1778,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, - { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) }, { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, @@ -1912,6 +1918,11 @@ static bool hid_ignore(struct hid_device *hdev) hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST) return true; break; + case USB_VENDOR_ID_JESS: + if (hdev->product == USB_DEVICE_ID_JESS_YUREX && + hdev->type == HID_TYPE_USBNONE) + return true; + break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 81877c67cae..a5dc13fe367 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -126,7 +126,12 @@ static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err; } - emsff_init(hdev); + ret = emsff_init(hdev); + if (ret) { + dev_err(&hdev->dev, "force feedback init failed\n"); + hid_hw_stop(hdev); + goto err; + } return 0; err: diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c new file mode 100644 index 00000000000..91e3a032112 --- /dev/null +++ b/drivers/hid/hid-holtekff.c @@ -0,0 +1,240 @@ +/* + * Force feedback support for Holtek On Line Grip based gamepads + * + * These include at least a Brazilian "Clone Joypad Super Power Fire" + * which uses vendor ID 0x1241 and identifies as "HOLTEK On Line Grip". + * + * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi> + */ + +/* + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/hid.h> +#include <linux/input.h> +#include <linux/slab.h> +#include <linux/usb.h> + +#include "hid-ids.h" + +#ifdef CONFIG_HOLTEK_FF +#include "usbhid/usbhid.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>"); +MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices"); + +/* + * These commands and parameters are currently known: + * + * byte 0: command id: + * 01 set effect parameters + * 02 play specified effect + * 03 stop specified effect + * 04 stop all effects + * 06 stop all effects + * (the difference between 04 and 06 isn't known; win driver + * sends 06,04 on application init, and 06 otherwise) + * + * Commands 01 and 02 need to be sent as pairs, i.e. you need to send 01 + * before each 02. + * + * The rest of the bytes are parameters. Command 01 takes all of them, and + * commands 02,03 take only the effect id. + * + * byte 1: + * bits 0-3: effect id: + * 1: very strong rumble + * 2: periodic rumble, short intervals + * 3: very strong rumble + * 4: periodic rumble, long intervals + * 5: weak periodic rumble, long intervals + * 6: weak periodic rumble, short intervals + * 7: periodic rumble, short intervals + * 8: strong periodic rumble, short intervals + * 9: very strong rumble + * a: causes an error + * b: very strong periodic rumble, very short intervals + * c-f: nothing + * bit 6: right (weak) motor enabled + * bit 7: left (strong) motor enabled + * + * bytes 2-3: time in milliseconds, big-endian + * bytes 5-6: unknown (win driver seems to use at least 10e0 with effect 1 + * and 0014 with effect 6) + * byte 7: + * bits 0-3: effect magnitude + */ + +#define HOLTEKFF_MSG_LENGTH 7 + +static const u8 start_effect_1[] = { 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const u8 stop_all4[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +static const u8 stop_all6[] = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +struct holtekff_device { + struct hid_field *field; +}; + +static void holtekff_send(struct holtekff_device *holtekff, + struct hid_device *hid, + const u8 data[HOLTEKFF_MSG_LENGTH]) +{ + int i; + + for (i = 0; i < HOLTEKFF_MSG_LENGTH; i++) { + holtekff->field->value[i] = data[i]; + } + + dbg_hid("sending %02x %02x %02x %02x %02x %02x %02x\n", data[0], + data[1], data[2], data[3], data[4], data[5], data[6]); + + usbhid_submit_report(hid, holtekff->field->report, USB_DIR_OUT); +} + +static int holtekff_play(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct hid_device *hid = input_get_drvdata(dev); + struct holtekff_device *holtekff = data; + int left, right; + /* effect type 1, length 65535 msec */ + u8 buf[HOLTEKFF_MSG_LENGTH] = + { 0x01, 0x01, 0xff, 0xff, 0x10, 0xe0, 0x00 }; + + left = effect->u.rumble.strong_magnitude; + right = effect->u.rumble.weak_magnitude; + dbg_hid("called with 0x%04x 0x%04x\n", left, right); + + if (!left && !right) { + holtekff_send(holtekff, hid, stop_all6); + return 0; + } + + if (left) + buf[1] |= 0x80; + if (right) + buf[1] |= 0x40; + + /* The device takes a single magnitude, so we just sum them up. */ + buf[6] = min(0xf, (left >> 12) + (right >> 12)); + + holtekff_send(holtekff, hid, buf); + holtekff_send(holtekff, hid, start_effect_1); + + return 0; +} + +static int holtekff_init(struct hid_device *hid) +{ + struct holtekff_device *holtekff; + struct hid_report *report; + struct hid_input *hidinput = list_entry(hid->inputs.next, + struct hid_input, list); + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + + if (list_empty(report_list)) { + hid_err(hid, "no output report found\n"); + return -ENODEV; + } + + report = list_entry(report_list->next, struct hid_report, list); + + if (report->maxfield < 1 || report->field[0]->report_count != 7) { + hid_err(hid, "unexpected output report layout\n"); + return -ENODEV; + } + + holtekff = kzalloc(sizeof(*holtekff), GFP_KERNEL); + if (!holtekff) + return -ENOMEM; + + set_bit(FF_RUMBLE, dev->ffbit); + + holtekff->field = report->field[0]; + + /* initialize the same way as win driver does */ + holtekff_send(holtekff, hid, stop_all4); + holtekff_send(holtekff, hid, stop_all6); + + error = input_ff_create_memless(dev, holtekff, holtekff_play); + if (error) { + kfree(holtekff); + return error; + } + + hid_info(hid, "Force feedback for Holtek On Line Grip based devices by Anssi Hannula <anssi.hannula@iki.fi>\n"); + + return 0; +} +#else +static inline int holtekff_init(struct hid_device *hid) +{ + return 0; +} +#endif + +static int holtek_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + if (ret) { + hid_err(hdev, "hw start failed\n"); + goto err; + } + + holtekff_init(hdev); + + return 0; +err: + return ret; +} + +static const struct hid_device_id holtek_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, + { } +}; +MODULE_DEVICE_TABLE(hid, holtek_devices); + +static struct hid_driver holtek_driver = { + .name = "holtek", + .id_table = holtek_devices, + .probe = holtek_probe, +}; + +static int __init holtek_init(void) +{ + return hid_register_driver(&holtek_driver); +} + +static void __exit holtek_exit(void) +{ + hid_unregister_driver(&holtek_driver); +} + +module_init(holtek_init); +module_exit(holtek_exit); + diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index a756ee6c7df..db63ccf21cc 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -350,6 +350,9 @@ #define USB_VENDOR_ID_ILITEK 0x222a #define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 +#define USB_VENDOR_ID_HOLTEK 0x1241 +#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 + #define USB_VENDOR_ID_IMATION 0x0718 #define USB_DEVICE_ID_DISC_STAKKA 0xd000 @@ -472,6 +475,8 @@ #define USB_DEVICE_ID_MS_LK6K 0x00f9 #define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 +#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 +#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c #define USB_VENDOR_ID_MOJO 0x8282 #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 @@ -495,6 +500,9 @@ #define USB_VENDOR_ID_NEXTWINDOW 0x1926 #define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 +#define USB_VENDOR_ID_NINTENDO 0x057e +#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 + #define USB_VENDOR_ID_NTRIG 0x1b96 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 @@ -630,6 +638,7 @@ #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 +#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064 #define USB_VENDOR_ID_UNITEC 0x227d #define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 @@ -663,6 +672,12 @@ #define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 +#define USB_VENDOR_ID_X_TENSIONS 0x1ae7 +#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001 + +#define USB_VENDOR_ID_XAT 0x2505 +#define USB_DEVICE_ID_XAT_CSR 0x0220 + #define USB_VENDOR_ID_YEALINK 0x6993 #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 21f205f0925..a7f916e8fc3 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -41,6 +41,66 @@ #define LG_FF3 0x1000 #define LG_FF4 0x2000 +/* Size of the original descriptor of the Driving Force Pro wheel */ +#define DFP_RDESC_ORIG_SIZE 97 + +/* Fixed report descriptor for Logitech Driving Force Pro wheel controller + * + * The original descriptor hides the separate throttle and brake axes in + * a custom vendor usage page, providing only a combined value as + * GenericDesktop.Y. + * This descriptor removes the combined Y axis and instead reports + * separate throttle (Y) and brake (RZ). + */ +static __u8 dfp_rdesc_fixed[] = { +0x05, 0x01, /* Usage Page (Desktop), */ +0x09, 0x04, /* Usage (Joystik), */ +0xA1, 0x01, /* Collection (Application), */ +0xA1, 0x02, /* Collection (Logical), */ +0x95, 0x01, /* Report Count (1), */ +0x75, 0x0E, /* Report Size (14), */ +0x14, /* Logical Minimum (0), */ +0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */ +0x34, /* Physical Minimum (0), */ +0x46, 0xFF, 0x3F, /* Physical Maximum (16383), */ +0x09, 0x30, /* Usage (X), */ +0x81, 0x02, /* Input (Variable), */ +0x95, 0x0E, /* Report Count (14), */ +0x75, 0x01, /* Report Size (1), */ +0x25, 0x01, /* Logical Maximum (1), */ +0x45, 0x01, /* Physical Maximum (1), */ +0x05, 0x09, /* Usage Page (Button), */ +0x19, 0x01, /* Usage Minimum (01h), */ +0x29, 0x0E, /* Usage Maximum (0Eh), */ +0x81, 0x02, /* Input (Variable), */ +0x05, 0x01, /* Usage Page (Desktop), */ +0x95, 0x01, /* Report Count (1), */ +0x75, 0x04, /* Report Size (4), */ +0x25, 0x07, /* Logical Maximum (7), */ +0x46, 0x3B, 0x01, /* Physical Maximum (315), */ +0x65, 0x14, /* Unit (Degrees), */ +0x09, 0x39, /* Usage (Hat Switch), */ +0x81, 0x42, /* Input (Variable, Nullstate), */ +0x65, 0x00, /* Unit, */ +0x26, 0xFF, 0x00, /* Logical Maximum (255), */ +0x46, 0xFF, 0x00, /* Physical Maximum (255), */ +0x75, 0x08, /* Report Size (8), */ +0x81, 0x01, /* Input (Constant), */ +0x09, 0x31, /* Usage (Y), */ +0x81, 0x02, /* Input (Variable), */ +0x09, 0x35, /* Usage (Rz), */ +0x81, 0x02, /* Input (Variable), */ +0x81, 0x01, /* Input (Constant), */ +0xC0, /* End Collection, */ +0xA1, 0x02, /* Collection (Logical), */ +0x09, 0x02, /* Usage (02h), */ +0x95, 0x07, /* Report Count (7), */ +0x91, 0x02, /* Output (Variable), */ +0xC0, /* End Collection, */ +0xC0 /* End Collection */ +}; + + /* * Certain Logitech keyboards send in report #3 keys which are far * above the logical maximum described in descriptor. This extends @@ -74,6 +134,18 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[47] = 0x95; rdesc[48] = 0x0B; } + + switch (hdev->product) { + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: + if (*rsize == DFP_RDESC_ORIG_SIZE) { + hid_info(hdev, + "fixing up Logitech Driving Force Pro report descriptor\n"); + rdesc = dfp_rdesc_fixed; + *rsize = sizeof(dfp_rdesc_fixed); + } + break; + } + return rdesc; } @@ -380,7 +452,7 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), - .driver_data = LG_FF }, + .driver_data = LG_NOGET | LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), .driver_data = LG_FF4 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 0f6fc54dc19..e5c699b6c6f 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -23,11 +23,12 @@ #include "hid-ids.h" -#define MS_HIDINPUT 0x01 -#define MS_ERGONOMY 0x02 -#define MS_PRESENTER 0x04 -#define MS_RDESC 0x08 -#define MS_NOGET 0x10 +#define MS_HIDINPUT 0x01 +#define MS_ERGONOMY 0x02 +#define MS_PRESENTER 0x04 +#define MS_RDESC 0x08 +#define MS_NOGET 0x10 +#define MS_DUPLICATE_USAGES 0x20 /* * Microsoft Wireless Desktop Receiver (Model 1028) has @@ -109,6 +110,18 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi, return 0; } +static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi, + struct hid_field *field, struct hid_usage *usage, + unsigned long **bit, int *max) +{ + unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); + + if (quirks & MS_DUPLICATE_USAGES) + clear_bit(usage->code, *bit); + + return 0; +} + static int ms_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -179,8 +192,12 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_ERGONOMY | MS_RDESC }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), .driver_data = MS_PRESENTER }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K), + .driver_data = MS_ERGONOMY }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), .driver_data = MS_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), + .driver_data = MS_DUPLICATE_USAGES }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), .driver_data = MS_PRESENTER }, @@ -193,6 +210,7 @@ static struct hid_driver ms_driver = { .id_table = ms_devices, .report_fixup = ms_report_fixup, .input_mapping = ms_input_mapping, + .input_mapped = ms_input_mapped, .event = ms_event, .probe = ms_probe, }; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 62cac4dc3b6..58d0e7aaf08 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -727,6 +727,10 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_DEFAULT, HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, + /* XAT */ + { .driver_data = MT_CLS_DEFAULT, + HID_USB_DEVICE(USB_VENDOR_ID_XAT, + USB_DEVICE_ID_XAT_CSR) }, { } }; diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index ab19f2905d2..158b389d0fb 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -44,8 +44,6 @@ struct pk_device { struct pcmidi_snd *pm; /* pcmidi device context */ }; -struct pcmidi_snd; - struct pcmidi_sustain { unsigned long in_use; struct pcmidi_snd *pm; @@ -242,7 +240,7 @@ drop_note: return; } -void pcmidi_sustained_note_release(unsigned long data) +static void pcmidi_sustained_note_release(unsigned long data) { struct pcmidi_sustain *pms = (struct pcmidi_sustain *)data; @@ -250,7 +248,7 @@ void pcmidi_sustained_note_release(unsigned long data) pms->in_use = 0; } -void init_sustain_timers(struct pcmidi_snd *pm) +static void init_sustain_timers(struct pcmidi_snd *pm) { struct pcmidi_sustain *pms; unsigned i; @@ -264,7 +262,7 @@ void init_sustain_timers(struct pcmidi_snd *pm) } } -void stop_sustain_timers(struct pcmidi_snd *pm) +static void stop_sustain_timers(struct pcmidi_snd *pm) { struct pcmidi_sustain *pms; unsigned i; @@ -499,7 +497,7 @@ static int pcmidi_handle_report4(struct pcmidi_snd *pm, u8 *data) return 1; } -int pcmidi_handle_report( +static int pcmidi_handle_report( struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size) { int ret = 0; @@ -518,7 +516,8 @@ int pcmidi_handle_report( return ret; } -void pcmidi_setup_extra_keys(struct pcmidi_snd *pm, struct input_dev *input) +static void pcmidi_setup_extra_keys( + struct pcmidi_snd *pm, struct input_dev *input) { /* reassigned functionality for N/A keys MY PICTURES => KEY_WORDPROCESSOR @@ -602,7 +601,7 @@ static struct snd_rawmi |