Loading drivers/hid/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,13 @@ config HID_COMPAT If unsure, say Y. config HID_A4TECH tristate "A4 tech" default m depends on USB_HID ---help--- Support for A4 tech X5 and WOP-35 / Trust 450L mice. config HID_APPLE tristate "Apple" default m Loading drivers/hid/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ ifdef CONFIG_HID_COMPAT obj-m += hid-dummy.o endif obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o Loading drivers/hid/hid-a4tech.c 0 → 100644 +162 −0 Original line number Diff line number Diff line /* * HID driver for some a4tech "special" devices * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc * Copyright (c) 2006-2007 Jiri Kosina * Copyright (c) 2007 Paul Walmsley * Copyright (c) 2008 Jiri Slaby */ /* * 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/input.h> #include <linux/hid.h> #include <linux/module.h> #include "hid-ids.h" #define A4_2WHEEL_MOUSE_HACK_7 0x01 #define A4_2WHEEL_MOUSE_HACK_B8 0x02 struct a4tech_sc { unsigned long quirks; unsigned int hw_wheel; __s32 delayed_value; }; static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); if (usage->type == EV_REL && usage->code == REL_WHEEL) set_bit(REL_HWHEEL, *bit); if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) return -1; return 0; } static int a4_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); struct input_dev *input; if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || !usage->type) return 0; input = field->hidinput->input; if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { if (usage->type == EV_REL && usage->code == REL_WHEEL) { a4->delayed_value = value; return 1; } if (usage->hid == 0x000100b8) { input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, a4->delayed_value); return 1; } } if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { a4->hw_wheel = !!value; return 1; } if (usage->code == REL_WHEEL && a4->hw_wheel) { input_event(input, usage->type, REL_HWHEEL, value); return 1; } return 0; } static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct a4tech_sc *a4; int ret; a4 = kzalloc(sizeof(*a4), GFP_KERNEL); if (a4 == NULL) { dev_err(&hdev->dev, "can't alloc device descriptor\n"); ret = -ENOMEM; goto err_free; } a4->quirks = id->driver_data; hid_set_drvdata(hdev, a4); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } return 0; err_free: kfree(a4); return ret; } static void a4_remove(struct hid_device *hdev) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); hid_hw_stop(hdev); kfree(a4); } static const struct hid_device_id a4_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, { } }; MODULE_DEVICE_TABLE(hid, a4_devices); static struct hid_driver a4_driver = { .name = "a4tech", .id_table = a4_devices, .input_mapped = a4_input_mapped, .event = a4_event, .probe = a4_probe, .remove = a4_remove, }; static int a4_init(void) { return hid_register_driver(&a4_driver); } static void a4_exit(void) { hid_unregister_driver(&a4_driver); } module_init(a4_init); module_exit(a4_exit); MODULE_LICENSE("GPL"); HID_COMPAT_LOAD_DRIVER(a4tech); drivers/hid/hid-core.c +2 −0 Original line number Diff line number Diff line Loading @@ -1132,6 +1132,8 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev, } static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, Loading drivers/hid/hid-dummy.c +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ static int __init hid_dummy_init(void) { #ifdef CONFIG_HID_A4TECH_MODULE HID_COMPAT_CALL_DRIVER(a4tech); #endif #ifdef CONFIG_HID_APPLE_MODULE HID_COMPAT_CALL_DRIVER(apple); #endif Loading Loading
drivers/hid/Kconfig +7 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,13 @@ config HID_COMPAT If unsure, say Y. config HID_A4TECH tristate "A4 tech" default m depends on USB_HID ---help--- Support for A4 tech X5 and WOP-35 / Trust 450L mice. config HID_APPLE tristate "Apple" default m Loading
drivers/hid/Makefile +1 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ ifdef CONFIG_HID_COMPAT obj-m += hid-dummy.o endif obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o Loading
drivers/hid/hid-a4tech.c 0 → 100644 +162 −0 Original line number Diff line number Diff line /* * HID driver for some a4tech "special" devices * * Copyright (c) 1999 Andreas Gal * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc * Copyright (c) 2006-2007 Jiri Kosina * Copyright (c) 2007 Paul Walmsley * Copyright (c) 2008 Jiri Slaby */ /* * 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/input.h> #include <linux/hid.h> #include <linux/module.h> #include "hid-ids.h" #define A4_2WHEEL_MOUSE_HACK_7 0x01 #define A4_2WHEEL_MOUSE_HACK_B8 0x02 struct a4tech_sc { unsigned long quirks; unsigned int hw_wheel; __s32 delayed_value; }; static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); if (usage->type == EV_REL && usage->code == REL_WHEEL) set_bit(REL_HWHEEL, *bit); if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) return -1; return 0; } static int a4_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); struct input_dev *input; if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || !usage->type) return 0; input = field->hidinput->input; if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { if (usage->type == EV_REL && usage->code == REL_WHEEL) { a4->delayed_value = value; return 1; } if (usage->hid == 0x000100b8) { input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, a4->delayed_value); return 1; } } if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { a4->hw_wheel = !!value; return 1; } if (usage->code == REL_WHEEL && a4->hw_wheel) { input_event(input, usage->type, REL_HWHEEL, value); return 1; } return 0; } static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) { struct a4tech_sc *a4; int ret; a4 = kzalloc(sizeof(*a4), GFP_KERNEL); if (a4 == NULL) { dev_err(&hdev->dev, "can't alloc device descriptor\n"); ret = -ENOMEM; goto err_free; } a4->quirks = id->driver_data; hid_set_drvdata(hdev, a4); ret = hid_parse(hdev); if (ret) { dev_err(&hdev->dev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev); if (ret) { dev_err(&hdev->dev, "hw start failed\n"); goto err_free; } return 0; err_free: kfree(a4); return ret; } static void a4_remove(struct hid_device *hdev) { struct a4tech_sc *a4 = hid_get_drvdata(hdev); hid_hw_stop(hdev); kfree(a4); } static const struct hid_device_id a4_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, { } }; MODULE_DEVICE_TABLE(hid, a4_devices); static struct hid_driver a4_driver = { .name = "a4tech", .id_table = a4_devices, .input_mapped = a4_input_mapped, .event = a4_event, .probe = a4_probe, .remove = a4_remove, }; static int a4_init(void) { return hid_register_driver(&a4_driver); } static void a4_exit(void) { hid_unregister_driver(&a4_driver); } module_init(a4_init); module_exit(a4_exit); MODULE_LICENSE("GPL"); HID_COMPAT_LOAD_DRIVER(a4tech);
drivers/hid/hid-core.c +2 −0 Original line number Diff line number Diff line Loading @@ -1132,6 +1132,8 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev, } static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, Loading
drivers/hid/hid-dummy.c +3 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,9 @@ static int __init hid_dummy_init(void) { #ifdef CONFIG_HID_A4TECH_MODULE HID_COMPAT_CALL_DRIVER(a4tech); #endif #ifdef CONFIG_HID_APPLE_MODULE HID_COMPAT_CALL_DRIVER(apple); #endif Loading