Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 114433
b: refs/heads/master
c: 14a21cd
h: refs/heads/master
i:
  114431: 7ac63b8
v: v3
  • Loading branch information
Jiri Slaby authored and Jiri Kosina committed Oct 14, 2008
1 parent 3a81b7d commit e5267a1
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f2213208f8da51bcb665309e3468f000489c04f
refs/heads/master: 14a21cd459f97e3b3cc4fcde48fc5bcdb81d097e
7 changes: 7 additions & 0 deletions trunk/drivers/hid/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/hid/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
162 changes: 162 additions & 0 deletions trunk/drivers/hid/hid-a4tech.c
Original file line number Diff line number Diff line change
@@ -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);
2 changes: 2 additions & 0 deletions trunk/drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) },
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/hid/hid-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 0 additions & 25 deletions trunk/drivers/hid/hid-input-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 0 additions & 9 deletions trunk/drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -515,15 +515,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
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))
Expand Down
4 changes: 0 additions & 4 deletions trunk/drivers/hid/usbhid/hid-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
5 changes: 0 additions & 5 deletions trunk/include/linux/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e5267a1

Please sign in to comment.