1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * HID driver for the apple ir device
4 *
5 * Original driver written by James McKenzie
6 * Ported to recent 2.6 kernel versions by Greg Kroah-Hartman <gregkh@suse.de>
7 * Updated to support newer remotes by Bastien Nocera <hadess@hadess.net>
8 * Ported to HID subsystem by Benjamin Tissoires <benjamin.tissoires@gmail.com>
9 *
10 * Copyright (C) 2006 James McKenzie
11 * Copyright (C) 2008 Greg Kroah-Hartman <greg@kroah.com>
12 * Copyright (C) 2008 Novell Inc.
13 * Copyright (C) 2010, 2012 Bastien Nocera <hadess@hadess.net>
14 * Copyright (C) 2013 Benjamin Tissoires <benjamin.tissoires@gmail.com>
15 * Copyright (C) 2013 Red Hat Inc. All Rights Reserved
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 * James McKenzie has two devices both of which report the following
33 * 25 87 ee 83 0a +
34 * 25 87 ee 83 0c -
35 * 25 87 ee 83 09 <<
36 * 25 87 ee 83 06 >>
37 * 25 87 ee 83 05 >"
38 * 25 87 ee 83 03 menu
39 * 26 00 00 00 00 for key repeat
40 */
41
42 /*
43 * Thomas Glanzmann reports the following responses
44 * 25 87 ee ca 0b +
45 * 25 87 ee ca 0d -
46 * 25 87 ee ca 08 <<
47 * 25 87 ee ca 07 >>
48 * 25 87 ee ca 04 >"
49 * 25 87 ee ca 02 menu
50 * 26 00 00 00 00 for key repeat
51 *
52 * He also observes the following event sometimes
53 * sent after a key is release, which I interpret
54 * as a flat battery message
55 * 25 87 e0 ca 06 flat battery
56 */
57
58 /*
59 * Alexandre Karpenko reports the following responses for Device ID 0x8242
60 * 25 87 ee 47 0b +
61 * 25 87 ee 47 0d -
62 * 25 87 ee 47 08 <<
63 * 25 87 ee 47 07 >>
64 * 25 87 ee 47 04 >"
65 * 25 87 ee 47 02 menu
66 * 26 87 ee 47 ** for key repeat (** is the code of the key being held)
67 */
68
69 /*
70 * Bastien Nocera's remote
71 * 25 87 ee 91 5f followed by
72 * 25 87 ee 91 05 gives you >"
73 *
74 * 25 87 ee 91 5c followed by
75 * 25 87 ee 91 05 gives you the middle button
76 */
77
78 /*
79 * Fabien Andre's remote
80 * 25 87 ee a3 5e followed by
81 * 25 87 ee a3 04 gives you >"
82 *
83 * 25 87 ee a3 5d followed by
84 * 25 87 ee a3 04 gives you the middle button
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; /* timer for key up */
112 spinlock_t lock; /* protects .current_key, .removing */
113 int current_key; /* the currently pressed key */
114 int prev_key_idx; /* key index in a 2 packets message */
115 bool removing; /* set during teardown; gates input_dev access */
116 };
117
get_key(int data)118 static int get_key(int data)
119 {
120 /*
121 * The key is coded accross bits 2..9:
122 *
123 * 0x00 or 0x01 ( ) key: 0 -> KEY_RESERVED
124 * 0x02 or 0x03 ( menu ) key: 1 -> KEY_MENU
125 * 0x04 or 0x05 ( >" ) key: 2 -> KEY_PLAYPAUSE
126 * 0x06 or 0x07 ( >> ) key: 3 -> KEY_FORWARD
127 * 0x08 or 0x09 ( << ) key: 4 -> KEY_BACK
128 * 0x0a or 0x0b ( + ) key: 5 -> KEY_VOLUMEUP
129 * 0x0c or 0x0d ( - ) key: 6 -> KEY_VOLUMEDOWN
130 * 0x0e or 0x0f ( ) key: 7 -> KEY_RESERVED
131 * 0x50 or 0x51 ( ) key: 8 -> KEY_RESERVED
132 * 0x52 or 0x53 ( ) key: 9 -> KEY_RESERVED
133 * 0x54 or 0x55 ( ) key: 10 -> KEY_RESERVED
134 * 0x56 or 0x57 ( ) key: 11 -> KEY_RESERVED
135 * 0x58 or 0x59 ( ) key: 12 -> KEY_RESERVED
136 * 0x5a or 0x5b ( ) key: 13 -> KEY_RESERVED
137 * 0x5c or 0x5d ( middle ) key: 14 -> KEY_ENTER
138 * 0x5e or 0x5f ( >" ) key: 15 -> KEY_PLAYPAUSE
139 *
140 * Packets starting with 0x5 are part of a two-packets message,
141 * we notify the caller by sending a negative value.
142 */
143 int key = (data >> 1) & KEY_MASK;
144
145 if ((data & TWO_PACKETS_MASK))
146 /* Part of a 2 packets-command */
147 key = -key;
148
149 return key;
150 }
151
key_up(struct hid_device * hid,struct appleir * appleir,int key)152 static void key_up(struct hid_device *hid, struct appleir *appleir, int key)
153 {
154 input_report_key(appleir->input_dev, key, 0);
155 input_sync(appleir->input_dev);
156 }
157
key_down(struct hid_device * hid,struct appleir * appleir,int key)158 static void key_down(struct hid_device *hid, struct appleir *appleir, int key)
159 {
160 input_report_key(appleir->input_dev, key, 1);
161 input_sync(appleir->input_dev);
162 }
163
battery_flat(struct appleir * appleir)164 static void battery_flat(struct appleir *appleir)
165 {
166 dev_err(&appleir->input_dev->dev, "possible flat battery?\n");
167 }
168
key_up_tick(struct timer_list * t)169 static void key_up_tick(struct timer_list *t)
170 {
171 struct appleir *appleir = timer_container_of(appleir, t, key_up_timer);
172 struct hid_device *hid = appleir->hid;
173 unsigned long flags;
174
175 spin_lock_irqsave(&appleir->lock, flags);
176 if (!appleir->removing && appleir->current_key) {
177 key_up(hid, appleir, appleir->current_key);
178 appleir->current_key = 0;
179 }
180 spin_unlock_irqrestore(&appleir->lock, flags);
181 }
182
appleir_raw_event(struct hid_device * hid,struct hid_report * report,u8 * data,int len)183 static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
184 u8 *data, int len)
185 {
186 struct appleir *appleir = hid_get_drvdata(hid);
187 static const u8 keydown[] = { 0x25, 0x87, 0xee };
188 static const u8 keyrepeat[] = { 0x26, };
189 static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
190 unsigned long flags;
191
192 if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT))
193 goto out;
194
195 if (!memcmp(data, keydown, sizeof(keydown))) {
196 int index;
197
198 spin_lock_irqsave(&appleir->lock, flags);
199 if (appleir->removing) {
200 spin_unlock_irqrestore(&appleir->lock, flags);
201 goto out;
202 }
203 /*
204 * If we already have a key down, take it up before marking
205 * this one down
206 */
207 if (appleir->current_key)
208 key_up(hid, appleir, appleir->current_key);
209
210 /* Handle dual packet commands */
211 if (appleir->prev_key_idx > 0)
212 index = appleir->prev_key_idx;
213 else
214 index = get_key(data[4]);
215
216 if (index >= 0) {
217 appleir->current_key = appleir->keymap[index];
218
219 key_down(hid, appleir, appleir->current_key);
220 /*
221 * Remote doesn't do key up, either pull them up, in
222 * the test above, or here set a timer which pulls
223 * them up after 1/8 s
224 */
225 mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
226 appleir->prev_key_idx = 0;
227 } else
228 /* Remember key for next packet */
229 appleir->prev_key_idx = -index;
230 spin_unlock_irqrestore(&appleir->lock, flags);
231 goto out;
232 }
233
234 appleir->prev_key_idx = 0;
235
236 if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
237 spin_lock_irqsave(&appleir->lock, flags);
238 if (!appleir->removing) {
239 key_down(hid, appleir, appleir->current_key);
240 /*
241 * Remote doesn't do key up, either pull them up, in
242 * the test above, or here set a timer which pulls them
243 * up after 1/8 s
244 */
245 mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
246 }
247 spin_unlock_irqrestore(&appleir->lock, flags);
248 goto out;
249 }
250
251 if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
252 spin_lock_irqsave(&appleir->lock, flags);
253 if (!appleir->removing)
254 battery_flat(appleir);
255 spin_unlock_irqrestore(&appleir->lock, flags);
256 /* Fall through */
257 }
258
259 out:
260 /* let hidraw and hiddev handle the report */
261 return 0;
262 }
263
appleir_input_configured(struct hid_device * hid,struct hid_input * hidinput)264 static int appleir_input_configured(struct hid_device *hid,
265 struct hid_input *hidinput)
266 {
267 struct input_dev *input_dev = hidinput->input;
268 struct appleir *appleir = hid_get_drvdata(hid);
269 int i;
270
271 appleir->input_dev = input_dev;
272
273 input_dev->keycode = appleir->keymap;
274 input_dev->keycodesize = sizeof(unsigned short);
275 input_dev->keycodemax = ARRAY_SIZE(appleir->keymap);
276
277 input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
278
279 memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap));
280 for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
281 set_bit(appleir->keymap[i], input_dev->keybit);
282 clear_bit(KEY_RESERVED, input_dev->keybit);
283
284 return 0;
285 }
286
appleir_input_mapping(struct hid_device * hid,struct hid_input * hi,struct hid_field * field,struct hid_usage * usage,unsigned long ** bit,int * max)287 static int appleir_input_mapping(struct hid_device *hid,
288 struct hid_input *hi, struct hid_field *field,
289 struct hid_usage *usage, unsigned long **bit, int *max)
290 {
291 return -1;
292 }
293
appleir_probe(struct hid_device * hid,const struct hid_device_id * id)294 static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id)
295 {
296 int ret;
297 struct appleir *appleir;
298
299 appleir = devm_kzalloc(&hid->dev, sizeof(struct appleir), GFP_KERNEL);
300 if (!appleir)
301 return -ENOMEM;
302
303 appleir->hid = hid;
304
305 /* force input as some remotes bypass the input registration */
306 hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
307
308 spin_lock_init(&appleir->lock);
309 timer_setup(&appleir->key_up_timer, key_up_tick, 0);
310
311 hid_set_drvdata(hid, appleir);
312
313 ret = hid_parse(hid);
314 if (ret) {
315 hid_err(hid, "parse failed\n");
316 goto fail;
317 }
318
319 ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE);
320 if (ret) {
321 hid_err(hid, "hw start failed\n");
322 goto fail;
323 }
324
325 return 0;
326 fail:
327 devm_kfree(&hid->dev, appleir);
328 return ret;
329 }
330
appleir_remove(struct hid_device * hid)331 static void appleir_remove(struct hid_device *hid)
332 {
333 struct appleir *appleir = hid_get_drvdata(hid);
334 unsigned long flags;
335
336 /*
337 * Mark the driver as tearing down so that any concurrent raw_event
338 * (e.g. from a USB URB completion that hid_hw_stop() has not yet
339 * killed) and the key_up_timer softirq stop touching input_dev
340 * before hid_hw_stop() frees it via hidinput_disconnect().
341 */
342 spin_lock_irqsave(&appleir->lock, flags);
343 appleir->removing = true;
344 spin_unlock_irqrestore(&appleir->lock, flags);
345
346 timer_shutdown_sync(&appleir->key_up_timer);
347 hid_hw_stop(hid);
348 }
349
350 static const struct hid_device_id appleir_devices[] = {
351 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
352 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
353 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
354 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
355 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
356 { }
357 };
358 MODULE_DEVICE_TABLE(hid, appleir_devices);
359
360 static struct hid_driver appleir_driver = {
361 .name = "appleir",
362 .id_table = appleir_devices,
363 .raw_event = appleir_raw_event,
364 .input_configured = appleir_input_configured,
365 .probe = appleir_probe,
366 .remove = appleir_remove,
367 .input_mapping = appleir_input_mapping,
368 };
369 module_hid_driver(appleir_driver);
370