Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
hid
hid-a4tech.c
Go to the documentation of this file.
1
/*
2
* HID driver for some a4tech "special" devices
3
*
4
* Copyright (c) 1999 Andreas Gal
5
* Copyright (c) 2000-2005 Vojtech Pavlik <
[email protected]
>
6
* Copyright (c) 2005 Michael Haboustak <
[email protected]
> for Concept2, Inc
7
* Copyright (c) 2006-2007 Jiri Kosina
8
* Copyright (c) 2008 Jiri Slaby
9
*/
10
11
/*
12
* This program is free software; you can redistribute it and/or modify it
13
* under the terms of the GNU General Public License as published by the Free
14
* Software Foundation; either version 2 of the License, or (at your option)
15
* any later version.
16
*/
17
18
#include <linux/device.h>
19
#include <linux/input.h>
20
#include <linux/hid.h>
21
#include <linux/module.h>
22
#include <linux/slab.h>
23
24
#include "
hid-ids.h
"
25
26
#define A4_2WHEEL_MOUSE_HACK_7 0x01
27
#define A4_2WHEEL_MOUSE_HACK_B8 0x02
28
29
struct
a4tech_sc
{
30
unsigned
long
quirks
;
31
unsigned
int
hw_wheel
;
32
__s32
delayed_value
;
33
};
34
35
static
int
a4_input_mapped(
struct
hid_device
*hdev,
struct
hid_input
*hi,
36
struct
hid_field
*
field
,
struct
hid_usage
*
usage
,
37
unsigned
long
**
bit
,
int
*
max
)
38
{
39
struct
a4tech_sc
*
a4
= hid_get_drvdata(hdev);
40
41
if
(usage->
type
==
EV_REL
&& usage->
code
==
REL_WHEEL
)
42
set_bit
(
REL_HWHEEL
, *bit);
43
44
if
((a4->
quirks
&
A4_2WHEEL_MOUSE_HACK_7
) && usage->
hid
== 0x00090007)
45
return
-1;
46
47
return
0;
48
}
49
50
static
int
a4_event(
struct
hid_device
*hdev,
struct
hid_field
*
field
,
51
struct
hid_usage
*
usage
,
__s32
value
)
52
{
53
struct
a4tech_sc
*
a4
= hid_get_drvdata(hdev);
54
struct
input_dev *
input
;
55
56
if
(!(hdev->
claimed
&
HID_CLAIMED_INPUT
) || !field->
hidinput
||
57
!usage->
type
)
58
return
0;
59
60
input = field->
hidinput
->input;
61
62
if
(a4->
quirks
&
A4_2WHEEL_MOUSE_HACK_B8
) {
63
if
(usage->
type
==
EV_REL
&& usage->
code
==
REL_WHEEL
) {
64
a4->
delayed_value
=
value
;
65
return
1;
66
}
67
68
if
(usage->
hid
== 0x000100b8) {
69
input_event
(input,
EV_REL
, value ?
REL_HWHEEL
:
70
REL_WHEEL
, a4->
delayed_value
);
71
return
1;
72
}
73
}
74
75
if
((a4->
quirks
&
A4_2WHEEL_MOUSE_HACK_7
) && usage->
hid
== 0x00090007) {
76
a4->
hw_wheel
= !!
value
;
77
return
1;
78
}
79
80
if
(usage->
code
==
REL_WHEEL
&& a4->
hw_wheel
) {
81
input_event
(input, usage->
type
,
REL_HWHEEL
, value);
82
return
1;
83
}
84
85
return
0;
86
}
87
88
static
int
a4_probe(
struct
hid_device
*hdev,
const
struct
hid_device_id
*
id
)
89
{
90
struct
a4tech_sc
*
a4
;
91
int
ret
;
92
93
a4 = kzalloc(
sizeof
(*a4),
GFP_KERNEL
);
94
if
(a4 ==
NULL
) {
95
hid_err
(hdev,
"can't alloc device descriptor\n"
);
96
ret = -
ENOMEM
;
97
goto
err_free;
98
}
99
100
a4->
quirks
=
id
->driver_data;
101
102
hid_set_drvdata(hdev, a4);
103
104
ret = hid_parse(hdev);
105
if
(ret) {
106
hid_err
(hdev,
"parse failed\n"
);
107
goto
err_free;
108
}
109
110
ret = hid_hw_start(hdev,
HID_CONNECT_DEFAULT
);
111
if
(ret) {
112
hid_err
(hdev,
"hw start failed\n"
);
113
goto
err_free;
114
}
115
116
return
0;
117
err_free:
118
kfree
(a4);
119
return
ret
;
120
}
121
122
static
void
a4_remove(
struct
hid_device
*hdev)
123
{
124
struct
a4tech_sc
*a4 = hid_get_drvdata(hdev);
125
126
hid_hw_stop(hdev);
127
kfree
(a4);
128
}
129
130
static
const
struct
hid_device_id
a4_devices[] = {
131
{
HID_USB_DEVICE
(
USB_VENDOR_ID_A4TECH
,
USB_DEVICE_ID_A4TECH_WCP32PU
),
132
.driver_data =
A4_2WHEEL_MOUSE_HACK_7
},
133
{
HID_USB_DEVICE
(
USB_VENDOR_ID_A4TECH
,
USB_DEVICE_ID_A4TECH_X5_005D
),
134
.driver_data =
A4_2WHEEL_MOUSE_HACK_B8
},
135
{
HID_USB_DEVICE
(
USB_VENDOR_ID_A4TECH
,
USB_DEVICE_ID_A4TECH_RP_649
),
136
.driver_data =
A4_2WHEEL_MOUSE_HACK_B8
},
137
{ }
138
};
139
MODULE_DEVICE_TABLE
(hid, a4_devices);
140
141
static
struct
hid_driver
a4_driver = {
142
.name =
"a4tech"
,
143
.id_table = a4_devices,
144
.input_mapped = a4_input_mapped,
145
.event = a4_event,
146
.probe = a4_probe,
147
.remove = a4_remove,
148
};
149
150
static
int
__init
a4_init(
void
)
151
{
152
return
hid_register_driver
(&a4_driver);
153
}
154
155
static
void
__exit
a4_exit(
void
)
156
{
157
hid_unregister_driver
(&a4_driver);
158
}
159
160
module_init
(a4_init);
161
module_exit
(a4_exit);
162
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:33:57 for Linux Kernel by
1.8.2