From cb7cf3da0daa9830e00640da8f7d2380f4b4de42 Mon Sep 17 00:00:00 2001 From: Stefan Achatz Date: Sun, 29 Aug 2010 12:30:18 +0200 Subject: HID: roccat: add driver for Roccat Pyra mouse This patch add support for Pyra mobile gaming mouse from Roccat. It provides access to profiles, settings, actual settings etc. through sysfs attributes. This driver is conceptual similar to the existing Kone driver. Userland tools can soon be found at http://sourceforge.net/projects/roccat Signed-off-by: Stefan Achatz Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6369ba7f96f8..b07440a172b5 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -376,6 +376,13 @@ config HID_ROCCAT_KONE ---help--- Support for Roccat Kone mouse. +config HID_ROCCAT_PYRA + tristate "Roccat Pyra mouse support" + depends on USB_HID + select HID_ROCCAT + ---help--- + Support for Roccat Pyra mouse. + config HID_SAMSUNG tristate "Samsung" depends on USB_HID -- cgit 1.4.1 From 32c88cbc3080f43c429f6456aa9cd845e37f3778 Mon Sep 17 00:00:00 2001 From: Simon Wood Date: Wed, 22 Sep 2010 13:19:42 +0200 Subject: HID: Add support for Logitech Speed Force Wireless gaming wheel The following patch adds support for the Logitech Speed Force Wireless gaming wheel. Originally designed for the WII console. Details on the protocol: http://wiibrew.org/wiki/Logitech_USB_steering_wheel This patch relies on previous patch: "Don't Send Feature Reports on Interrupt Endpoint" Logitech as produce a very similar wheel for the PS2/PS3, it is expected that this patch could also support the PS2/PS3 wheel if the USB ID's are added and (if required) the HID descriptor is modified. Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 8 +++ drivers/hid/Makefile | 3 ++ drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-lg.c | 38 ++++++++++++++ drivers/hid/hid-lg.h | 6 +++ drivers/hid/hid-lg4ff.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 193 insertions(+) create mode 100644 drivers/hid/hid-lg4ff.c (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6369ba7f96f8..6664c573cf33 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -235,6 +235,14 @@ config LOGIG940_FF Say Y here if you want to enable force feedback support for Logitech Flight System G940 devices. +config LOGIWII_FF + bool "Logitech Speed Force Wireless force feedback support" + depends on HID_LOGITECH + select INPUT_FF_MEMLESS + help + Say Y here if you want to enable force feedback support for Logitech + Speed Force Wireless (Wii) devices. + config HID_MAGICMOUSE tristate "Apple MagicMouse multi-touch support" depends on BT_HIDP diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 46f037f3df80..d46a455eefc1 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -21,6 +21,9 @@ endif ifdef CONFIG_LOGIG940_FF hid-logitech-objs += hid-lg3ff.o endif +ifdef CONFIG_LOGIWII_FF + hid-logitech-objs += hid-lg4ff.o +endif obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3f7292486024..19d45473f24f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1335,6 +1335,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 765a4f53eb5c..6b111e1e2df1 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -350,6 +350,7 @@ #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 +#define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a #define USB_DEVICE_ID_S510_RECEIVER 0xc50c #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index f6433d8050a9..8989f151e0d7 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "hid-ids.h" #include "hid-lg.h" @@ -35,6 +38,7 @@ #define LG_FF2 0x400 #define LG_RDESC_REL_ABS 0x800 #define LG_FF3 0x1000 +#define LG_FF4 0x2000 /* * Certain Logitech keyboards send in report #3 keys which are far @@ -60,6 +64,17 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, "report descriptor\n"); rdesc[33] = rdesc[50] = 0x02; } + + if ((quirks & LG_FF4) && rsize >= 101 && + rdesc[41] == 0x95 && rdesc[42] == 0x0B && + rdesc[47] == 0x05 && rdesc[48] == 0x09) { + dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless " + "button descriptor\n"); + rdesc[41] = 0x05; + rdesc[42] = 0x09; + rdesc[47] = 0x95; + rdesc[48] = 0x0B; + } } #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ @@ -285,12 +300,33 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err_free; } + if (quirks & LG_FF4) { + unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); + + if (ret >= 0) { + /* insert a little delay of 10 jiffies ~ 40ms */ + wait_queue_head_t wait; + init_waitqueue_head (&wait); + wait_event_interruptible_timeout(wait, 0, 10); + + /* Select random Address */ + buf[1] = 0xB2; + get_random_bytes(&buf[2], 2); + + ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); + } + } + if (quirks & LG_FF) lgff_init(hdev); if (quirks & LG_FF2) lg2ff_init(hdev); if (quirks & LG_FF3) lg3ff_init(hdev); + if (quirks & LG_FF4) + lg4ff_init(hdev); return 0; err_free: @@ -339,6 +375,8 @@ static const struct hid_device_id lg_devices[] = { .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), .driver_data = 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 ), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h index ce2ac8672624..b0100ba2ae0b 100644 --- a/drivers/hid/hid-lg.h +++ b/drivers/hid/hid-lg.h @@ -19,4 +19,10 @@ int lg3ff_init(struct hid_device *hdev); static inline int lg3ff_init(struct hid_device *hdev) { return -1; } #endif +#ifdef CONFIG_LOGIWII_FF +int lg4ff_init(struct hid_device *hdev); +#else +static inline int lg4ff_init(struct hid_device *hdev) { return -1; } +#endif + #endif diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c new file mode 100644 index 000000000000..7eef5a2ce948 --- /dev/null +++ b/drivers/hid/hid-lg4ff.c @@ -0,0 +1,136 @@ +/* + * Force feedback support for Logitech Speed Force Wireless + * + * http://wiibrew.org/wiki/Logitech_USB_steering_wheel + * + * Copyright (c) 2010 Simon Wood + */ + +/* + * 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 +#include +#include + +#include "usbhid/usbhid.h" +#include "hid-lg.h" + +struct lg4ff_device { + struct hid_report *report; +}; + +static const signed short ff4_wheel_ac[] = { + FF_CONSTANT, + FF_AUTOCENTER, + -1 +}; + +static int hid_lg4ff_play(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct hid_device *hid = input_get_drvdata(dev); + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct hid_report *report = list_entry(report_list->next, struct hid_report, list); + int x; + +#define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff + + switch (effect->type) { + case FF_CONSTANT: + x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ + CLAMP(x); + report->field[0]->value[0] = 0x11; /* Slot 1 */ + report->field[0]->value[1] = 0x10; + report->field[0]->value[2] = x; + report->field[0]->value[3] = 0x00; + report->field[0]->value[4] = 0x00; + report->field[0]->value[5] = 0x08; + report->field[0]->value[6] = 0x00; + dbg_hid("Autocenter, x=0x%02X\n", x); + + usbhid_submit_report(hid, report, USB_DIR_OUT); + break; + } + return 0; +} + +static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude) +{ + struct hid_device *hid = input_get_drvdata(dev); + struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct hid_report *report = list_entry(report_list->next, struct hid_report, list); + __s32 *value = report->field[0]->value; + + *value++ = 0xfe; + *value++ = 0x0d; + *value++ = 0x07; + *value++ = 0x07; + *value++ = (magnitude >> 8) & 0xff; + *value++ = 0x00; + *value = 0x00; + + usbhid_submit_report(hid, report, USB_DIR_OUT); +} + + +int lg4ff_init(struct hid_device *hid) +{ + 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; + struct hid_report *report; + struct hid_field *field; + const signed short *ff_bits = ff4_wheel_ac; + int error; + int i; + + /* Find the report to use */ + if (list_empty(report_list)) { + err_hid("No output report found"); + return -1; + } + + /* Check that the report looks ok */ + report = list_entry(report_list->next, struct hid_report, list); + if (!report) { + err_hid("NULL output report"); + return -1; + } + + field = report->field[0]; + if (!field) { + err_hid("NULL field"); + return -1; + } + + for (i = 0; ff_bits[i] >= 0; i++) + set_bit(ff_bits[i], dev->ffbit); + + error = input_ff_create_memless(dev, NULL, hid_lg4ff_play); + + if (error) + return error; + + if (test_bit(FF_AUTOCENTER, dev->ffbit)) + dev->ff->set_autocenter = hid_lg4ff_set_autocenter; + + dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by " + "Simon Wood \n"); + return 0; +} + -- cgit 1.4.1 From 2c6118e43040034d80894daeba41960bf0035b31 Mon Sep 17 00:00:00 2001 From: Hendrik Iben Date: Mon, 4 Oct 2010 15:39:49 +0200 Subject: HID: force feedback support for Logitech RumblePad gamepad This patch adds force feedback support for Logitech WingMan RumblePad gamepads by extending the Logitech Rumblepad 2 force feedback code. Signed-off-by: Hendrik Iben Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 4 ++-- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-lg.c | 3 +++ drivers/hid/hid-lg2ff.c | 4 ++-- 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/hid/Kconfig') diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6664c573cf33..3892ff5fa11b 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -220,12 +220,12 @@ config LOGITECH_FF force feedback. config LOGIRUMBLEPAD2_FF - bool "Logitech Rumblepad 2 force feedback support" + bool "Logitech RumblePad/Rumblepad 2 force feedback support" depends on HID_LOGITECH select INPUT_FF_MEMLESS help Say Y here if you want to enable force feedback support for Logitech - Rumblepad 2 devices. + RumblePad and Rumblepad 2 devices. config LOGIG940_FF bool "Logitech Flight System G940 force feedback support" diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 19d45473f24f..0120557022bf 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1326,6 +1326,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6b111e1e2df1..79f0304aee8a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -339,6 +339,7 @@ #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f +#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 8989f151e0d7..9e92c27002ca 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -7,6 +7,7 @@ * Copyright (c) 2006-2007 Jiri Kosina * Copyright (c) 2007 Paul Walmsley * Copyright (c) 2008 Jiri Slaby + * Copyright (c) 2010 Hendrik Iben */ /* @@ -361,6 +362,8 @@ static const struct hid_device_id lg_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), .driver_data = LG_NOGET | LG_FF }, + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD), + .driver_data = LG_FF2 }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), .driver_data = LG_FF }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index d888f1e6794f..4258253c36b3 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -1,5 +1,5 @@ /* - * Force feedback support for Logitech Rumblepad 2 + * Force feedback support for Logitech RumblePad and Rumblepad 2 * * Copyright (c) 2008 Anssi Hannula */ @@ -110,7 +110,7 @@ int lg2ff_init(struct hid_device *hid) usbhid_submit_report(hid, report, USB_DIR_OUT); - dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by " + dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by " "Anssi Hannula \n"); return 0; -- cgit 1.4.1