HID: move a4tech quirks
Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
0f2213208f
commit
14a21cd459
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* 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);
|
|
@ -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) },
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -236,31 +236,6 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
|
|||
|
||||
input = field->hidinput->input;
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) &&
|
||||
(usage->hid == 0x00090007)) {
|
||||
if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
||||
else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
||||
(usage->type == EV_REL) &&
|
||||
(usage->code == REL_WHEEL)) {
|
||||
hid->delayed_value = value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) &&
|
||||
(usage->hid == 0x000100b8)) {
|
||||
input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
|
||||
input_event(input, usage->type, REL_HWHEEL, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* handle the temporary quirky mapping to HWHEEL */
|
||||
if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT &&
|
||||
usage->type == EV_REL && usage->code == REL_HWHEEL) {
|
||||
|
|
|
@ -515,15 +515,6 @@ mapped:
|
|||
hidinput, field, usage, &bit, &max) < 0)
|
||||
goto ignore;
|
||||
|
||||
if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 |
|
||||
HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) &&
|
||||
(usage->code == REL_WHEEL))
|
||||
set_bit(REL_HWHEEL, bit);
|
||||
|
||||
if ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) &&
|
||||
(usage->hid == 0x00090007))
|
||||
goto ignore;
|
||||
|
||||
set_bit(usage->type, input->evbit);
|
||||
|
||||
while (usage->code <= max && test_and_set_bit(usage->code, bit))
|
||||
|
|
|
@ -28,10 +28,6 @@ static const struct hid_blacklist {
|
|||
__u16 idProduct;
|
||||
__u32 quirks;
|
||||
} hid_blacklist[] = {
|
||||
|
||||
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
|
||||
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 },
|
||||
|
||||
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
|
|
|
@ -261,14 +261,11 @@ struct hid_item {
|
|||
#define HID_QUIRK_HIDDEV 0x00000010
|
||||
#define HID_QUIRK_BADPAD 0x00000020
|
||||
#define HID_QUIRK_MULTI_INPUT 0x00000040
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
|
||||
#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
|
||||
#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000
|
||||
#define HID_QUIRK_RESET_LEDS 0x00100000
|
||||
#define HID_QUIRK_HIDINPUT 0x00200000
|
||||
#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000
|
||||
#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000
|
||||
#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000
|
||||
#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
|
||||
|
||||
|
@ -453,8 +450,6 @@ struct hid_device { /* device report descriptor */
|
|||
|
||||
void *driver_data;
|
||||
|
||||
__s32 delayed_value; /* For A4 Tech mice hwheel quirk */
|
||||
|
||||
/* hiddev event handler */
|
||||
void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field,
|
||||
struct hid_usage *, __s32);
|
||||
|
|
Loading…
Reference in New Issue