hid-appleir.c 9.5 KB

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