The driver currently only supports the PS1000 controller. It fixes the report descriptor by removing a non-existing axis and clearing the constant bit on the d-pad and button input reports. Signed-off-by: Andreas Hübner <andreas@xxxxxx> --- drivers/hid/Kconfig | 9 ++++++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-saitek.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 0 deletions(-) create mode 100644 drivers/hid/hid-saitek.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index a421abd..3619985 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -530,6 +530,15 @@ config HID_ROCCAT_PYRA ---help--- Support for Roccat Pyra mouse. +config HID_SAITEK + tristate "Saitek non-fully HID-compliant devices" + depends on USB_HID + ---help--- + Support for Saitek devices that are not fully compliant with the + HID standard. + + Currently only supports the PS1000 controller. + config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 8aefdc9..c14029c 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o obj-$(CONFIG_HID_ROCCAT_KONEPLUS) += hid-roccat-koneplus.o obj-$(CONFIG_HID_ROCCAT_KOVAPLUS) += hid-roccat-kovaplus.o obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o +obj-$(CONFIG_HID_SAITEK) += hid-saitek.o obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o obj-$(CONFIG_HID_SONY) += hid-sony.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7..5260421 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1516,6 +1516,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cd..dc3dee5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -613,6 +613,7 @@ #define USB_VENDOR_ID_SAITEK 0x06a3 #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 +#define USB_DEVICE_ID_SAITEK_PS1000 0xff17 #define USB_VENDOR_ID_SAMSUNG 0x0419 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 diff --git a/drivers/hid/hid-saitek.c b/drivers/hid/hid-saitek.c new file mode 100644 index 0000000..45aea77 --- /dev/null +++ b/drivers/hid/hid-saitek.c @@ -0,0 +1,70 @@ +/* + * HID driver for Saitek devices, currently only the PS1000 (USB gamepad). + * Fixes the HID report descriptor by removing a non-existent axis and + * clearing the constant bit on the input reports for buttons and d-pad. + * (This module is based on "hid-ortek".) + * + * Copyright (c) 2012 Andreas Hübner + */ + +/* + * 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. + */ + +#include <linux/device.h> +#include <linux/hid.h> +#include <linux/module.h> +#include <linux/kernel.h> + +#include "hid-ids.h" + +static __u8 *saitek_report_fixup(struct hid_device *hdev, __u8 *rdesc, + unsigned int *rsize) +{ + if (*rsize == 137 && rdesc[20] == 0x09 && rdesc[21] == 0x33 + && rdesc[94] == 0x81 && rdesc[95] == 0x03 + && rdesc[110] == 0x81 && rdesc[111] == 0x03) { + + hid_info(hdev, "Fixing up Saitek PS1000 report descriptor\n"); + + /* convert spurious axis to a "noop" Logical Minimum (0) */ + rdesc[20] = 0x15; + rdesc[21] = 0x00; + + /* clear constant bit on buttons and d-pad */ + rdesc[95] = 0x02; + rdesc[111] = 0x02; + + } + return rdesc; +} + +static const struct hid_device_id saitek_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000)}, + { } +}; + +MODULE_DEVICE_TABLE(hid, saitek_devices); + +static struct hid_driver saitek_driver = { + .name = "saitek", + .id_table = saitek_devices, + .report_fixup = saitek_report_fixup +}; + +static int __init saitek_init(void) +{ + return hid_register_driver(&saitek_driver); +} + +static void __exit saitek_exit(void) +{ + hid_unregister_driver(&saitek_driver); +} + +module_init(saitek_init); +module_exit(saitek_exit); +MODULE_LICENSE("GPL"); -- 1.7.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html