1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/device.h>
16#include <linux/hid.h>
17#include <linux/module.h>
18
19#include "hid-ids.h"
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126#define ICADE_MAX_USAGE 29
127
128struct icade_key {
129 u16 to;
130 u8 press:1;
131};
132
133static const struct icade_key icade_usage_table[30] = {
134 [26] = { KEY_UP, 1 },
135 [8] = { KEY_UP, 0 },
136 [7] = { KEY_RIGHT, 1 },
137 [6] = { KEY_RIGHT, 0 },
138 [27] = { KEY_DOWN, 1 },
139 [29] = { KEY_DOWN, 0 },
140 [4] = { KEY_LEFT, 1 },
141 [20] = { KEY_LEFT, 0 },
142 [28] = { BTN_A, 1 },
143 [23] = { BTN_A, 0 },
144 [11] = { BTN_B, 1 },
145 [21] = { BTN_B, 0 },
146 [24] = { BTN_C, 1 },
147 [9] = { BTN_C, 0 },
148 [13] = { BTN_X, 1 },
149 [17] = { BTN_X, 0 },
150 [12] = { BTN_Y, 1 },
151 [16] = { BTN_Y, 0 },
152 [14] = { BTN_Z, 1 },
153 [19] = { BTN_Z, 0 },
154 [18] = { BTN_THUMBL, 1 },
155 [10] = { BTN_THUMBL, 0 },
156 [15] = { BTN_THUMBR, 1 },
157 [25] = { BTN_THUMBR, 0 },
158};
159
160static const struct icade_key *icade_find_translation(u16 from)
161{
162 if (from > ICADE_MAX_USAGE)
163 return NULL;
164 return &icade_usage_table[from];
165}
166
167static int icade_event(struct hid_device *hdev, struct hid_field *field,
168 struct hid_usage *usage, __s32 value)
169{
170 const struct icade_key *trans;
171
172 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
173 !usage->type)
174 return 0;
175
176
177 if (!value)
178 return 1;
179
180 trans = icade_find_translation(usage->hid & HID_USAGE);
181
182 if (!trans)
183 return 1;
184
185 input_event(field->hidinput->input, usage->type,
186 trans->to, trans->press);
187
188 return 1;
189}
190
191static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi,
192 struct hid_field *field, struct hid_usage *usage,
193 unsigned long **bit, int *max)
194{
195 const struct icade_key *trans;
196
197 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
198 trans = icade_find_translation(usage->hid & HID_USAGE);
199
200 if (!trans)
201 return -1;
202
203 hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to);
204 set_bit(trans->to, hi->input->keybit);
205
206 return 1;
207 }
208
209
210 return -1;
211
212}
213
214static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi,
215 struct hid_field *field, struct hid_usage *usage,
216 unsigned long **bit, int *max)
217{
218 if (usage->type == EV_KEY)
219 set_bit(usage->type, hi->input->evbit);
220
221 return -1;
222}
223
224static const struct hid_device_id icade_devices[] = {
225 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ION, USB_DEVICE_ID_ICADE) },
226
227 { }
228};
229MODULE_DEVICE_TABLE(hid, icade_devices);
230
231static struct hid_driver icade_driver = {
232 .name = "icade",
233 .id_table = icade_devices,
234 .event = icade_event,
235 .input_mapped = icade_input_mapped,
236 .input_mapping = icade_input_mapping,
237};
238module_hid_driver(icade_driver);
239
240MODULE_LICENSE("GPL");
241MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
242MODULE_DESCRIPTION("ION iCade input driver");
243