hid-appleir.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. #include <linux/device.h>
  18. #include <linux/hid.h>
  19. #include <linux/module.h>
  20. #include "hid-ids.h"
  21. MODULE_AUTHOR("James McKenzie");
  22. MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
  23. MODULE_DESCRIPTION("HID Apple IR remote controls");
  24. MODULE_LICENSE("GPL");
  25. #define KEY_MASK 0x0F
  26. #define TWO_PACKETS_MASK 0x40
  27. /*
  28. * James McKenzie has two devices both of which report the following
  29. * 25 87 ee 83 0a +
  30. * 25 87 ee 83 0c -
  31. * 25 87 ee 83 09 <<
  32. * 25 87 ee 83 06 >>
  33. * 25 87 ee 83 05 >"
  34. * 25 87 ee 83 03 menu
  35. * 26 00 00 00 00 for key repeat
  36. */
  37. /*
  38. * Thomas Glanzmann reports the following responses
  39. * 25 87 ee ca 0b +
  40. * 25 87 ee ca 0d -
  41. * 25 87 ee ca 08 <<
  42. * 25 87 ee ca 07 >>
  43. * 25 87 ee ca 04 >"
  44. * 25 87 ee ca 02 menu
  45. * 26 00 00 00 00 for key repeat
  46. *
  47. * He also observes the following event sometimes
  48. * sent after a key is release, which I interpret
  49. * as a flat battery message
  50. * 25 87 e0 ca 06 flat battery
  51. */
  52. /*
  53. * Alexandre Karpenko reports the following responses for Device ID 0x8242
  54. * 25 87 ee 47 0b +
  55. * 25 87 ee 47 0d -
  56. * 25 87 ee 47 08 <<
  57. * 25 87 ee 47 07 >>
  58. * 25 87 ee 47 04 >"
  59. * 25 87 ee 47 02 menu
  60. * 26 87 ee 47 ** for key repeat (** is the code of the key being held)
  61. */
  62. /*
  63. * Bastien Nocera's remote
  64. * 25 87 ee 91 5f followed by
  65. * 25 87 ee 91 05 gives you >"
  66. *
  67. * 25 87 ee 91 5c followed by
  68. * 25 87 ee 91 05 gives you the middle button
  69. */
  70. /*
  71. * Fabien Andre's remote
  72. * 25 87 ee a3 5e followed by
  73. * 25 87 ee a3 04 gives you >"
  74. *
  75. * 25 87 ee a3 5d followed by
  76. * 25 87 ee a3 04 gives you the middle button
  77. */
  78. static const unsigned short appleir_key_table[] = {
  79. KEY_RESERVED,
  80. KEY_MENU,
  81. KEY_PLAYPAUSE,
  82. KEY_FORWARD,
  83. KEY_BACK,
  84. KEY_VOLUMEUP,
  85. KEY_VOLUMEDOWN,
  86. KEY_RESERVED,
  87. KEY_RESERVED,
  88. KEY_RESERVED,
  89. KEY_RESERVED,
  90. KEY_RESERVED,
  91. KEY_RESERVED,
  92. KEY_RESERVED,
  93. KEY_ENTER,
  94. KEY_PLAYPAUSE,
  95. KEY_RESERVED,
  96. };
  97. struct appleir {
  98. struct input_dev *input_dev;
  99. struct hid_device *hid;
  100. unsigned short keymap[ARRAY_SIZE(appleir_key_table)];
  101. struct timer_list key_up_timer; /* timer for key up */
  102. spinlock_t lock; /* protects .current_key */
  103. int current_key; /* the currently pressed key */
  104. int prev_key_idx; /* key index in a 2 packets message */
  105. };
  106. static int get_key(int data)
  107. {
  108. /*
  109. * The key is coded accross bits 2..9:
  110. *
  111. * 0x00 or 0x01 ( ) key: 0 -> KEY_RESERVED
  112. * 0x02 or 0x03 ( menu ) key: 1 -> KEY_MENU
  113. * 0x04 or 0x05 ( >" ) key: 2 -> KEY_PLAYPAUSE
  114. * 0x06 or 0x07 ( >> ) key: 3 -> KEY_FORWARD
  115. * 0x08 or 0x09 ( << ) key: 4 -> KEY_BACK
  116. * 0x0a or 0x0b ( + ) key: 5 -> KEY_VOLUMEUP
  117. * 0x0c or 0x0d ( - ) key: 6 -> KEY_VOLUMEDOWN
  118. * 0x0e or 0x0f ( ) key: 7 -> KEY_RESERVED
  119. * 0x50 or 0x51 ( ) key: 8 -> KEY_RESERVED
  120. * 0x52 or 0x53 ( ) key: 9 -> KEY_RESERVED
  121. * 0x54 or 0x55 ( ) key: 10 -> KEY_RESERVED
  122. * 0x56 or 0x57 ( ) key: 11 -> KEY_RESERVED
  123. * 0x58 or 0x59 ( ) key: 12 -> KEY_RESERVED
  124. * 0x5a or 0x5b ( ) key: 13 -> KEY_RESERVED
  125. * 0x5c or 0x5d ( middle ) key: 14 -> KEY_ENTER
  126. * 0x5e or 0x5f ( >" ) key: 15 -> KEY_PLAYPAUSE
  127. *
  128. * Packets starting with 0x5 are part of a two-packets message,
  129. * we notify the caller by sending a negative value.
  130. */
  131. int key = (data >> 1) & KEY_MASK;
  132. if ((data & TWO_PACKETS_MASK))
  133. /* Part of a 2 packets-command */
  134. key = -key;
  135. return key;
  136. }
  137. static void key_up(struct hid_device *hid, struct appleir *appleir, int key)
  138. {
  139. input_report_key(appleir->input_dev, key, 0);
  140. input_sync(appleir->input_dev);
  141. }
  142. static void key_down(struct hid_device *hid, struct appleir *appleir, int key)
  143. {
  144. input_report_key(appleir->input_dev, key, 1);
  145. input_sync(appleir->input_dev);
  146. }
  147. static void battery_flat(struct appleir *appleir)
  148. {
  149. dev_err(&appleir->input_dev->dev, "possible flat battery?\n");
  150. }
  151. static void key_up_tick(struct timer_list *t)
  152. {
  153. struct appleir *appleir = from_timer(appleir, t, key_up_timer);
  154. struct hid_device *hid = appleir->hid;
  155. unsigned long flags;
  156. spin_lock_irqsave(&appleir->lock, flags);
  157. if (appleir->current_key) {
  158. key_up(hid, appleir, appleir->current_key);
  159. appleir->current_key = 0;
  160. }
  161. spin_unlock_irqrestore(&appleir->lock, flags);
  162. }
  163. static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
  164. u8 *data, int len)
  165. {
  166. struct appleir *appleir = hid_get_drvdata(hid);
  167. static const u8 keydown[] = { 0x25, 0x87, 0xee };
  168. static const u8 keyrepeat[] = { 0x26, };
  169. static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
  170. unsigned long flags;
  171. if (len != 5)
  172. goto out;
  173. if (!memcmp(data, keydown, sizeof(keydown))) {
  174. int index;
  175. spin_lock_irqsave(&appleir->lock, flags);
  176. /*
  177. * If we already have a key down, take it up before marking
  178. * this one down
  179. */
  180. if (appleir->current_key)
  181. key_up(hid, appleir, appleir->current_key);
  182. /* Handle dual packet commands */
  183. if (appleir->prev_key_idx > 0)
  184. index = appleir->prev_key_idx;
  185. else
  186. index = get_key(data[4]);
  187. if (index >= 0) {
  188. appleir->current_key = appleir->keymap[index];
  189. key_down(hid, appleir, appleir->current_key);
  190. /*
  191. * Remote doesn't do key up, either pull them up, in
  192. * the test above, or here set a timer which pulls
  193. * them up after 1/8 s
  194. */
  195. mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
  196. appleir->prev_key_idx = 0;
  197. } else
  198. /* Remember key for next packet */
  199. appleir->prev_key_idx = -index;
  200. spin_unlock_irqrestore(&appleir->lock, flags);
  201. goto out;
  202. }
  203. appleir->prev_key_idx = 0;
  204. if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) {
  205. key_down(hid, appleir, appleir->current_key);
  206. /*
  207. * Remote doesn't do key up, either pull them up, in the test
  208. * above, or here set a timer which pulls them up after 1/8 s
  209. */
  210. mod_timer(&appleir->key_up_timer, jiffies + HZ / 8);
  211. goto out;
  212. }
  213. if (!memcmp(data, flatbattery, sizeof(flatbattery))) {
  214. battery_flat(appleir);
  215. /* Fall through */
  216. }
  217. out:
  218. /* let hidraw and hiddev handle the report */
  219. return 0;
  220. }
  221. static int appleir_input_configured(struct hid_device *hid,
  222. struct hid_input *hidinput)
  223. {
  224. struct input_dev *input_dev = hidinput->input;
  225. struct appleir *appleir = hid_get_drvdata(hid);
  226. int i;
  227. appleir->input_dev = input_dev;
  228. input_dev->keycode = appleir->keymap;
  229. input_dev->keycodesize = sizeof(unsigned short);
  230. input_dev->keycodemax = ARRAY_SIZE(appleir->keymap);
  231. input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
  232. memcpy(appleir->keymap, appleir_key_table, sizeof(appleir->keymap));
  233. for (i = 0; i < ARRAY_SIZE(appleir_key_table); i++)
  234. set_bit(appleir->keymap[i], input_dev->keybit);
  235. clear_bit(KEY_RESERVED, input_dev->keybit);
  236. return 0;
  237. }
  238. static int appleir_input_mapping(struct hid_device *hid,
  239. struct hid_input *hi, struct hid_field *field,
  240. struct hid_usage *usage, unsigned long **bit, int *max)
  241. {
  242. return -1;
  243. }
  244. static int appleir_probe(struct hid_device *hid, const struct hid_device_id *id)
  245. {
  246. int ret;
  247. struct appleir *appleir;
  248. appleir = devm_kzalloc(&hid->dev, sizeof(struct appleir), GFP_KERNEL);
  249. if (!appleir)
  250. return -ENOMEM;
  251. appleir->hid = hid;
  252. /* force input as some remotes bypass the input registration */
  253. hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
  254. spin_lock_init(&appleir->lock);
  255. timer_setup(&appleir->key_up_timer, key_up_tick, 0);
  256. hid_set_drvdata(hid, appleir);
  257. ret = hid_parse(hid);
  258. if (ret) {
  259. hid_err(hid, "parse failed\n");
  260. goto fail;
  261. }
  262. ret = hid_hw_start(hid, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE);
  263. if (ret) {
  264. hid_err(hid, "hw start failed\n");
  265. goto fail;
  266. }
  267. return 0;
  268. fail:
  269. devm_kfree(&hid->dev, appleir);
  270. return ret;
  271. }
  272. static void appleir_remove(struct hid_device *hid)
  273. {
  274. struct appleir *appleir = hid_get_drvdata(hid);
  275. hid_hw_stop(hid);
  276. del_timer_sync(&appleir->key_up_timer);
  277. }
  278. static const struct hid_device_id appleir_devices[] = {
  279. { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
  280. { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
  281. { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
  282. { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
  283. { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
  284. { }
  285. };
  286. MODULE_DEVICE_TABLE(hid, appleir_devices);
  287. static struct hid_driver appleir_driver = {
  288. .name = "appleir",
  289. .id_table = appleir_devices,
  290. .raw_event = appleir_raw_event,
  291. .input_configured = appleir_input_configured,
  292. .probe = appleir_probe,
  293. .remove = appleir_remove,
  294. .input_mapping = appleir_input_mapping,
  295. };
  296. module_hid_driver(appleir_driver);