This source file includes following definitions.
- get_key
- key_up
- key_down
- battery_flat
- key_up_tick
- appleir_raw_event
- appleir_input_configured
- appleir_input_mapping
- appleir_probe
- appleir_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <linux/device.h>
19 #include <linux/hid.h>
20 #include <linux/module.h>
21 #include "hid-ids.h"
22
23 MODULE_AUTHOR("James McKenzie");
24 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
25 MODULE_DESCRIPTION("HID Apple IR remote controls");
26 MODULE_LICENSE("GPL");
27
28 #define KEY_MASK 0x0F
29 #define TWO_PACKETS_MASK 0x40
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 static const unsigned short appleir_key_table[] = {
88 KEY_RESERVED,
89 KEY_MENU,
90 KEY_PLAYPAUSE,
91 KEY_FORWARD,
92 KEY_BACK,
93 KEY_VOLUMEUP,
94 KEY_VOLUMEDOWN,
95 KEY_RESERVED,
96 KEY_RESERVED,
97 KEY_RESERVED,
98 KEY_RESERVED,
99 KEY_RESERVED,
100 KEY_RESERVED,
101 KEY_RESERVED,
102 KEY_ENTER,
103 KEY_PLAYPAUSE,
104 KEY_RESERVED,
105 };
106
107 struct appleir {
108 struct input_dev *input_dev;
109 struct hid_device *hid;
110 unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
111 struct timer_list key_up_timer;
112 spinlock_t lock;
113 int current_key;
114 int prev_key_idx;
115 };
116
117 static int get_key(int data)
118 {
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 int key = (data >> 1) & KEY_MASK;
143
144 if ((data & TWO_PACKETS_MASK))
145
146 key = -key;
147
148 return key;
149 }
150
151 static void key_up(struct hid_device *hid, struct appleir *appleir, int key)
152 {
153 input_report_key(appleir->input_dev, key, 0);
154 input_sync(appleir->input_dev);
155 }
156
157 static void key_down(struct hid_device *hid, struct appleir *appleir, int key)
158 {
159 input_report_key(appleir->input_dev, key, 1);
160 input_sync(appleir->input_dev);
161 }
162
163 static void battery_flat(struct appleir *appleir)
164 {
165 dev_err(&appleir->input_dev->dev, "possible flat battery?\n");
166 }
167
168 static void key_up_tick(struct timer_list *t)
169 {
170 struct appleir *appleir = from_timer(appleir, t, key_up_timer);
171 struct hid_device *hid = appleir->hid;
172 unsigned long flags;
173
174 spin_lock_irqsave(&appleir->lock, flags);
175 if (appleir->current_key) {
176 key_up(hid, appleir, appleir->current_key);
177 appleir->current_key = 0;
178 }
179 spin_unlock_irqrestore(&appleir->lock, flags);
180 }
181
182 static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
183 u8 *data, int len)
184 {
185 struct appleir *appleir = hid_get_drvdata(hid);
186 static const u8 keydown[] = { 0x25, 0x87, 0xee };
187 static const u8 keyrepeat[] = { 0x26, };
188 static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
189 unsigned long flags;
190
191 if (len != 5)
192 goto out;
193
194 if (!memcmp(data, keydown, sizeof(keydown))) {
195 int index;
196
197 spin_lock_irqsave(&appleir->lock, flags);
198
199
200
201
202 if (appleir->current_key)
203 key_up(hid, appleir, appleir->current_key);
204
205
206 if (appleir->prev_key_idx > 0)
207 index = appleir->prev_key_idx;
208 else
209 index = get_key(data[4]);
210
211 if (index >= 0) {
212 appleir->current_key = appleir->keymap[index];
213
214 key_down(hid, appleir, appleir->current_key);
215
216
217
218
219
220 mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
221 appleir->prev_key_idx = 0;
222 } else
223
224 appleir->prev_key_idx = -index;
225 spin_unlock_irqrestore(&appleir->lock, flags);
226 goto out;
227 }
228
229 appleir->prev_key_idx = 0;
230
231 if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
232 key_down(hid, appleir, appleir->current_key);
233
234
235
236
237 mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
238 goto out;
239 }
240
241 if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
242 battery_flat(appleir);
243
244 }
245
246 out:
247
248 return 0;
249 }
250
251 static int appleir_input_configured(struct hid_device *hid,
252 struct hid_input *hidinput)
253 {
254 struct input_dev *input_dev = hidinput->input;
255 struct appleir *appleir = hid_get_drvdata(hid);
256 int i;
257
258 appleir->input_dev = input_dev;
259
260 input_dev->keycode = appleir->keymap;
261 input_dev->keycodesize = sizeof(unsigned short);
262 input_dev->keycodemax = ARRAY_SIZE(appleir->keymap);
263
264 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
265
266 memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap));
267 for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
268 set_bit(appleir->keymap[i], input_dev->keybit);
269 clear_bit(KEY_RESERVED, input_dev->keybit);
270
271 return 0;
272 }
273
274 static int appleir_input_mapping(struct hid_device *hid,
275 struct hid_input *hi, struct hid_field *field,
276 struct hid_usage *usage, unsigned long **bit, int *max)
277 {
278 return -1;
279 }
280
281 static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id)
282 {
283 int ret;
284 struct appleir *appleir;
285
286 appleir = kzalloc(sizeof(struct appleir), GFP_KERNEL);
287 if (!appleir) {
288 ret = -ENOMEM;
289 goto allocfail;
290 }
291
292 appleir->hid = hid;
293
294
295 hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
296
297 spin_lock_init(&appleir->lock);
298 timer_setup(&appleir->key_up_timer, key_up_tick, 0);
299
300 hid_set_drvdata(hid, appleir);
301
302 ret = hid_parse(hid);
303 if (ret) {
304 hid_err(hid, "parse failed\n");
305 goto fail;
306 }
307
308 ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE);
309 if (ret) {
310 hid_err(hid, "hw start failed\n");
311 goto fail;
312 }
313
314 return 0;
315 fail:
316 kfree(appleir);
317 allocfail:
318 return ret;
319 }
320
321 static void appleir_remove(struct hid_device *hid)
322 {
323 struct appleir *appleir = hid_get_drvdata(hid);
324 hid_hw_stop(hid);
325 del_timer_sync(&appleir->key_up_timer);
326 kfree(appleir);
327 }
328
329 static const struct hid_device_id appleir_devices[] = {
330 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
331 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
332 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
333 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
334 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
335 { }
336 };
337 MODULE_DEVICE_TABLE(hid, appleir_devices);
338
339 static struct hid_driver appleir_driver = {
340 .name = "appleir",
341 .id_table = appleir_devices,
342 .raw_event = appleir_raw_event,
343 .input_configured = appleir_input_configured,
344 .probe = appleir_probe,
345 .remove = appleir_remove,
346 .input_mapping = appleir_input_mapping,
347 };
348 module_hid_driver(appleir_driver);