mac_hid.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:17k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * drivers/macintosh/mac_hid.c
  3.  *
  4.  * HID support stuff for Macintosh computers.
  5.  *
  6.  * Copyright (C) 2000 Franz Sirl.
  7.  *
  8.  * Stuff inside CONFIG_MAC_ADBKEYCODES should go away during 2.5 when all
  9.  * major distributions are using the Linux keycodes.
  10.  * Stuff inside CONFIG_MAC_EMUMOUSEBTN should really be moved to userspace.
  11.  */
  12. #include <linux/config.h>
  13. #include <linux/init.h>
  14. #include <linux/proc_fs.h>
  15. #include <linux/sysctl.h>
  16. #include <linux/input.h>
  17. #include <linux/module.h>
  18. #ifdef CONFIG_MAC_ADBKEYCODES
  19. #include <linux/keyboard.h>
  20. #include <asm/keyboard.h>
  21. #include <asm/machdep.h>
  22. #endif
  23. #ifdef CONFIG_MAC_ADBKEYCODES
  24. /* Simple translation table for the SysRq keys */
  25. #ifdef CONFIG_MAGIC_SYSRQ
  26. unsigned char mac_hid_kbd_sysrq_xlate[128] =
  27. "asdfhgzxcv00bqwer" /* 0x00 - 0x0f */
  28. "yt123465=97-80o]" /* 0x10 - 0x1f */
  29. "u[iprlj'k;\,/nm." /* 0x20 - 0x2f */
  30. "t `177003300000000000000000000"
  31. /* 0x30 - 0x3f */
  32. "000000*00+0000000000/r00-00"
  33. /* 0x40 - 0x4f */
  34. "00000123456789000000" /* 0x50 - 0x5f */
  35. "2052062072032102110021300215000000000021200214";
  36. /* 0x60 - 0x6f */
  37. extern unsigned char pckbd_sysrq_xlate[128];
  38. #endif
  39. static u_short macplain_map[NR_KEYS] = {
  40. 0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
  41. 0xfb63, 0xfb76, 0xf200, 0xfb62, 0xfb71, 0xfb77, 0xfb65, 0xfb72,
  42. 0xfb79, 0xfb74, 0xf031, 0xf032, 0xf033, 0xf034, 0xf036, 0xf035,
  43. 0xf03d, 0xf039, 0xf037, 0xf02d, 0xf038, 0xf030, 0xf05d, 0xfb6f,
  44. 0xfb75, 0xf05b, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf027,
  45. 0xfb6b, 0xf03b, 0xf05c, 0xf02c, 0xf02f, 0xfb6e, 0xfb6d, 0xf02e,
  46. 0xf009, 0xf020, 0xf060, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
  47. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  48. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  49. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  50. 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
  51. 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
  52. 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
  53. 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf109, 0xf200, 0xf10b,
  54. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
  55. 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  56. };
  57. static u_short macshift_map[NR_KEYS] = {
  58. 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb48, 0xfb47, 0xfb5a, 0xfb58,
  59. 0xfb43, 0xfb56, 0xf200, 0xfb42, 0xfb51, 0xfb57, 0xfb45, 0xfb52,
  60. 0xfb59, 0xfb54, 0xf021, 0xf040, 0xf023, 0xf024, 0xf05e, 0xf025,
  61. 0xf02b, 0xf028, 0xf026, 0xf05f, 0xf02a, 0xf029, 0xf07d, 0xfb4f,
  62. 0xfb55, 0xf07b, 0xfb49, 0xfb50, 0xf201, 0xfb4c, 0xfb4a, 0xf022,
  63. 0xfb4b, 0xf03a, 0xf07c, 0xf03c, 0xf03f, 0xfb4e, 0xfb4d, 0xf03e,
  64. 0xf009, 0xf020, 0xf07e, 0xf07f, 0xf200, 0xf01b, 0xf702, 0xf703,
  65. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  66. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  67. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  68. 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
  69. 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
  70. 0xf10e, 0xf10f, 0xf110, 0xf10c, 0xf111, 0xf112, 0xf200, 0xf10a,
  71. 0xf200, 0xf10c, 0xf200, 0xf203, 0xf200, 0xf113, 0xf200, 0xf10b,
  72. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf20b, 0xf116, 0xf10d, 0xf117,
  73. 0xf10b, 0xf20a, 0xf10a, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  74. };
  75. static u_short macaltgr_map[NR_KEYS] = {
  76. 0xf914, 0xfb73, 0xf917, 0xf919, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
  77. 0xf916, 0xfb76, 0xf200, 0xf915, 0xfb71, 0xfb77, 0xf918, 0xfb72,
  78. 0xfb79, 0xfb74, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
  79. 0xf200, 0xf05d, 0xf07b, 0xf05c, 0xf05b, 0xf07d, 0xf07e, 0xfb6f,
  80. 0xfb75, 0xf200, 0xfb69, 0xfb70, 0xf201, 0xfb6c, 0xfb6a, 0xf200,
  81. 0xfb6b, 0xf200, 0xf200, 0xf200, 0xf200, 0xfb6e, 0xfb6d, 0xf200,
  82. 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
  83. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  84. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  85. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  86. 0xf200, 0xf200, 0xf90a, 0xf90b, 0xf90c, 0xf90d, 0xf90e, 0xf90f,
  87. 0xf910, 0xf911, 0xf200, 0xf912, 0xf913, 0xf200, 0xf200, 0xf200,
  88. 0xf510, 0xf511, 0xf512, 0xf50e, 0xf513, 0xf514, 0xf200, 0xf516,
  89. 0xf200, 0xf10c, 0xf200, 0xf202, 0xf200, 0xf515, 0xf200, 0xf517,
  90. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf50f, 0xf117,
  91. 0xf50d, 0xf119, 0xf50c, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  92. };
  93. static u_short macctrl_map[NR_KEYS] = {
  94. 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
  95. 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
  96. 0xf019, 0xf014, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01e, 0xf01d,
  97. 0xf200, 0xf200, 0xf01f, 0xf01f, 0xf07f, 0xf200, 0xf01d, 0xf00f,
  98. 0xf015, 0xf01b, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf007,
  99. 0xf00b, 0xf200, 0xf01c, 0xf200, 0xf07f, 0xf00e, 0xf00d, 0xf20e,
  100. 0xf200, 0xf000, 0xf000, 0xf008, 0xf200, 0xf200, 0xf702, 0xf703,
  101. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  102. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  103. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  104. 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
  105. 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
  106. 0xf104, 0xf105, 0xf106, 0xf102, 0xf107, 0xf108, 0xf200, 0xf10a,
  107. 0xf200, 0xf10c, 0xf200, 0xf204, 0xf200, 0xf109, 0xf200, 0xf10b,
  108. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf103, 0xf117,
  109. 0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  110. };
  111. static u_short macshift_ctrl_map[NR_KEYS] = {
  112. 0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
  113. 0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
  114. 0xf019, 0xf014, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
  115. 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200, 0xf00f,
  116. 0xf015, 0xf200, 0xf009, 0xf010, 0xf201, 0xf00c, 0xf00a, 0xf200,
  117. 0xf00b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf00e, 0xf00d, 0xf200,
  118. 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
  119. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  120. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  121. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  122. 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
  123. 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
  124. 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
  125. 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
  126. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf200, 0xf117,
  127. 0xf200, 0xf119, 0xf200, 0xf700, 0xf701, 0xf702, 0xf200, 0xf20c,
  128. };
  129. static u_short macalt_map[NR_KEYS] = {
  130. 0xf861, 0xf873, 0xf864, 0xf866, 0xf868, 0xf867, 0xf87a, 0xf878,
  131. 0xf863, 0xf876, 0xf200, 0xf862, 0xf871, 0xf877, 0xf865, 0xf872,
  132. 0xf879, 0xf874, 0xf831, 0xf832, 0xf833, 0xf834, 0xf836, 0xf835,
  133. 0xf83d, 0xf839, 0xf837, 0xf82d, 0xf838, 0xf830, 0xf85d, 0xf86f,
  134. 0xf875, 0xf85b, 0xf869, 0xf870, 0xf80d, 0xf86c, 0xf86a, 0xf827,
  135. 0xf86b, 0xf83b, 0xf85c, 0xf82c, 0xf82f, 0xf86e, 0xf86d, 0xf82e,
  136. 0xf809, 0xf820, 0xf860, 0xf87f, 0xf200, 0xf81b, 0xf702, 0xf703,
  137. 0xf700, 0xf207, 0xf701, 0xf210, 0xf211, 0xf600, 0xf603, 0xf200,
  138. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  139. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  140. 0xf200, 0xf200, 0xf900, 0xf901, 0xf902, 0xf903, 0xf904, 0xf905,
  141. 0xf906, 0xf907, 0xf200, 0xf908, 0xf909, 0xf200, 0xf200, 0xf200,
  142. 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
  143. 0xf200, 0xf10c, 0xf200, 0xf209, 0xf200, 0xf509, 0xf200, 0xf50b,
  144. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
  145. 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  146. };
  147. static u_short macctrl_alt_map[NR_KEYS] = {
  148. 0xf801, 0xf813, 0xf804, 0xf806, 0xf808, 0xf807, 0xf81a, 0xf818,
  149. 0xf803, 0xf816, 0xf200, 0xf802, 0xf811, 0xf817, 0xf805, 0xf812,
  150. 0xf819, 0xf814, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
  151. 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80f,
  152. 0xf815, 0xf200, 0xf809, 0xf810, 0xf201, 0xf80c, 0xf80a, 0xf200,
  153. 0xf80b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf80e, 0xf80d, 0xf200,
  154. 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf703,
  155. 0xf700, 0xf207, 0xf701, 0xf601, 0xf602, 0xf600, 0xf603, 0xf200,
  156. 0xf200, 0xf310, 0xf200, 0xf30c, 0xf200, 0xf30a, 0xf200, 0xf208,
  157. 0xf200, 0xf200, 0xf200, 0xf30d, 0xf30e, 0xf200, 0xf30b, 0xf200,
  158. 0xf200, 0xf200, 0xf300, 0xf301, 0xf302, 0xf303, 0xf304, 0xf305,
  159. 0xf306, 0xf307, 0xf200, 0xf308, 0xf309, 0xf200, 0xf200, 0xf200,
  160. 0xf504, 0xf505, 0xf506, 0xf502, 0xf507, 0xf508, 0xf200, 0xf50a,
  161. 0xf200, 0xf10c, 0xf200, 0xf200, 0xf200, 0xf509, 0xf200, 0xf50b,
  162. 0xf200, 0xf11d, 0xf115, 0xf114, 0xf118, 0xf116, 0xf503, 0xf117,
  163. 0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
  164. };
  165. static unsigned short *mac_key_maps_save[MAX_NR_KEYMAPS] = {
  166. macplain_map, macshift_map, macaltgr_map, 0,
  167. macctrl_map, macshift_ctrl_map, 0, 0,
  168. macalt_map, 0, 0, 0,
  169. macctrl_alt_map,   0
  170. };
  171. static unsigned short *pc_key_maps_save[MAX_NR_KEYMAPS];
  172. int mac_hid_kbd_translate(unsigned char keycode, unsigned char *keycodep,
  173.   char raw_mode);
  174. static int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
  175.    void *buffer, size_t *lenp);
  176. char mac_hid_kbd_unexpected_up(unsigned char keycode);
  177. static int keyboard_lock_keycodes = 0;
  178. int keyboard_sends_linux_keycodes = 0;
  179. #else
  180. int keyboard_sends_linux_keycodes = 1;
  181. #endif
  182. static unsigned char e0_keys[128] = {
  183. 0, 0, 0, KEY_KPCOMMA, 0, KEY_INTL3, 0, 0, /* 0x00-0x07 */
  184. 0, 0, 0, 0, KEY_LANG1, KEY_LANG2, 0, 0, /* 0x08-0x0f */
  185. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
  186. 0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, KEY_VOLUMEUP, 0,/* 0x18-0x1f */
  187. 0, 0, 0, 0, 0, KEY_VOLUMEDOWN, KEY_MUTE, 0, /* 0x20-0x27 */
  188. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
  189. 0, 0, 0, 0, 0, KEY_KPSLASH, 0, KEY_SYSRQ, /* 0x30-0x37 */
  190. KEY_RIGHTALT, 0, 0, KEY_EJECTCD, 0, 0, 0, 0, /* 0x38-0x3f */
  191. 0, 0, 0, 0, 0, 0, 0, KEY_HOME, /* 0x40-0x47 */
  192. KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END, /* 0x48-0x4f */
  193. KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0, /* 0x50-0x57 */
  194. 0, 0, 0, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_COMPOSE, KEY_POWER, 0, /* 0x58-0x5f */
  195. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
  196. 0, 0, 0, 0, 0, 0, 0, KEY_MACRO, /* 0x68-0x6f */
  197. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
  198. 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
  199. };
  200. #ifdef CONFIG_MAC_EMUMOUSEBTN
  201. static struct input_dev emumousebtn;
  202. static void emumousebtn_input_register(void);
  203. static int mouse_emulate_buttons = 0;
  204. static int mouse_button2_keycode = KEY_RIGHTCTRL; /* right control key */
  205. static int mouse_button3_keycode = KEY_RIGHTALT; /* right option key */
  206. static int mouse_last_keycode = 0;
  207. #endif
  208. extern void pckbd_init_hw(void);
  209. #if defined CONFIG_SYSCTL && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
  210. /* file(s) in /proc/sys/dev/mac_hid */
  211. ctl_table mac_hid_files[] =
  212. {
  213. #ifdef CONFIG_MAC_ADBKEYCODES
  214.   {
  215.     DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES,
  216.     "keyboard_sends_linux_keycodes", &keyboard_sends_linux_keycodes, sizeof(int),
  217.     0644, NULL, &mac_hid_sysctl_keycodes
  218.   },
  219.   {
  220.     DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES,
  221.     "keyboard_lock_keycodes", &keyboard_lock_keycodes, sizeof(int),
  222.     0644, NULL, &proc_dointvec
  223.   },
  224. #endif
  225. #ifdef CONFIG_MAC_EMUMOUSEBTN
  226.   {
  227.     DEV_MAC_HID_MOUSE_BUTTON_EMULATION,
  228.     "mouse_button_emulation", &mouse_emulate_buttons, sizeof(int),
  229.     0644, NULL, &proc_dointvec
  230.   },
  231.   {
  232.     DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE,
  233.     "mouse_button2_keycode", &mouse_button2_keycode, sizeof(int),
  234.     0644, NULL, &proc_dointvec
  235.   },
  236.   {
  237.     DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE,
  238.     "mouse_button3_keycode", &mouse_button3_keycode, sizeof(int),
  239.     0644, NULL, &proc_dointvec
  240.   },
  241. #endif
  242.   { 0 }
  243. };
  244. /* dir in /proc/sys/dev */
  245. ctl_table mac_hid_dir[] =
  246. {
  247.   { DEV_MAC_HID, "mac_hid", NULL, 0, 0555, mac_hid_files },
  248.   { 0 }
  249. };
  250. /* /proc/sys/dev itself, in case that is not there yet */
  251. ctl_table mac_hid_root_dir[] =
  252. {
  253.   { CTL_DEV, "dev", NULL, 0, 0555, mac_hid_dir },
  254.   { 0 }
  255. };
  256. static struct ctl_table_header *mac_hid_sysctl_header;
  257. #ifdef CONFIG_MAC_ADBKEYCODES
  258. static
  259. int mac_hid_sysctl_keycodes(ctl_table *ctl, int write, struct file * filp,
  260.     void *buffer, size_t *lenp)
  261. {
  262. int val = keyboard_sends_linux_keycodes;
  263. int ret = 0;
  264. if (!write
  265.     || (write && !keyboard_lock_keycodes))
  266. ret = proc_dointvec(ctl, write, filp, buffer, lenp);
  267. if (write
  268.     && keyboard_sends_linux_keycodes != val) {
  269. if (!keyboard_sends_linux_keycodes) {
  270. #ifdef CONFIG_MAGIC_SYSRQ
  271. ppc_md.ppc_kbd_sysrq_xlate   = mac_hid_kbd_sysrq_xlate;
  272. SYSRQ_KEY                = 0x69;
  273. #endif
  274. memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
  275. memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
  276. } else {
  277. #ifdef CONFIG_MAGIC_SYSRQ
  278. ppc_md.ppc_kbd_sysrq_xlate   = pckbd_sysrq_xlate;
  279. SYSRQ_KEY                = 0x54;
  280. #endif
  281. memcpy(mac_key_maps_save, key_maps, sizeof(key_maps));
  282. memcpy(key_maps, pc_key_maps_save, sizeof(key_maps));
  283. }
  284. }
  285. return ret;
  286. }
  287. #endif
  288. #endif /* endif CONFIG_SYSCTL */
  289. int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode,
  290.   char raw_mode)
  291. {
  292. #ifdef CONFIG_MAC_ADBKEYCODES
  293. if (!keyboard_sends_linux_keycodes) {
  294. if (!raw_mode) {
  295. /*
  296.  * Convert R-shift/control/option to L version.
  297.  */
  298. switch (scancode) {
  299. case 0x7b: scancode = 0x38; break; /* R-shift */
  300. case 0x7c: scancode = 0x3a; break; /* R-option */
  301. case 0x7d: scancode = 0x36; break; /* R-control */
  302. }
  303. }
  304. *keycode = scancode;
  305. return 1;
  306. } else
  307. #endif
  308. {
  309. /* This code was copied from char/pc_keyb.c and will be
  310.  * superflous when the input layer is fully integrated.
  311.  * We don't need the high_keys handling, so this part
  312.  * has been removed.
  313.  */
  314. static int prev_scancode = 0;
  315. /* special prefix scancodes.. */
  316. if (scancode == 0xe0 || scancode == 0xe1) {
  317. prev_scancode = scancode;
  318. return 0;
  319. }
  320. scancode &= 0x7f;
  321. if (prev_scancode) {
  322. if (prev_scancode != 0xe0) {
  323. if (prev_scancode == 0xe1 && scancode == 0x1d) {
  324. prev_scancode = 0x100;
  325. return 0;
  326. } else if (prev_scancode == 0x100 && scancode == 0x45) {
  327. *keycode = KEY_PAUSE;
  328. prev_scancode = 0;
  329. } else {
  330. if (!raw_mode)
  331. printk(KERN_INFO "keyboard: unknown e1 escape sequencen");
  332. prev_scancode = 0;
  333. return 0;
  334. }
  335. } else {
  336. prev_scancode = 0;
  337. if (scancode == 0x2a || scancode == 0x36)
  338. return 0;
  339. }
  340. if (e0_keys[scancode])
  341. *keycode = e0_keys[scancode];
  342. else {
  343. if (!raw_mode)
  344. printk(KERN_INFO "keyboard: unknown scancode e0 %02xn",
  345.        scancode);
  346. return 0;
  347. }
  348. } else {
  349. switch (scancode) {
  350. case  91: scancode = KEY_LINEFEED; break;
  351. case  92: scancode = KEY_KPEQUAL; break;
  352. case 125: scancode = KEY_INTL1; break;
  353. }
  354. *keycode = scancode;
  355. }
  356. return 1;
  357. }
  358. }
  359. char mac_hid_kbd_unexpected_up(unsigned char keycode)
  360. {
  361. if (keyboard_sends_linux_keycodes && keycode == KEY_F13)
  362. return 0;
  363. else
  364. return 0x80;
  365. }
  366. #ifdef CONFIG_MAC_ADBKEYCODES
  367. int mac_hid_keyboard_sends_linux_keycodes(void)
  368. {
  369. return keyboard_sends_linux_keycodes;
  370. }
  371. EXPORT_SYMBOL(mac_hid_keyboard_sends_linux_keycodes);
  372. static int __init mac_hid_setup(char *str)
  373. {
  374. int ints[2];
  375. str = get_options(str, ARRAY_SIZE(ints), ints);
  376. if (ints[0] == 1) {
  377. keyboard_sends_linux_keycodes = ints[1] != 0;
  378. keyboard_lock_keycodes = 1;
  379. }
  380. return 1;
  381. }
  382. __setup("keyboard_sends_linux_keycodes=", mac_hid_setup);
  383. #endif
  384. #ifdef CONFIG_MAC_EMUMOUSEBTN
  385. int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
  386. {
  387. switch (caller) {
  388. case 1:
  389. /* Called from keybdev.c */
  390. if (mouse_emulate_buttons
  391.     && (keycode == mouse_button2_keycode
  392. || keycode == mouse_button3_keycode)) {
  393. if (mouse_emulate_buttons == 1) {
  394.   input_report_key(&emumousebtn,
  395.  keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
  396.  down);
  397. return 1;
  398. }
  399. mouse_last_keycode = down ? keycode : 0;
  400. }
  401. break;
  402. case 2:
  403. /* Called from mousedev.c */
  404. if (mouse_emulate_buttons == 2 && keycode == 0) {
  405. if (mouse_last_keycode == mouse_button2_keycode)
  406. return 1; /* map to middle button */
  407. if (mouse_last_keycode == mouse_button3_keycode)
  408. return 2; /* map to right button */
  409. }
  410. return keycode; /* keep button */
  411. }
  412. return 0;
  413. }
  414. EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
  415. static void emumousebtn_input_register(void)
  416. {
  417. emumousebtn.name = "Macintosh mouse button emulation";
  418. emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
  419. emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
  420. emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
  421. emumousebtn.idbus = BUS_ADB;
  422. emumousebtn.idvendor = 0x0001;
  423. emumousebtn.idproduct = 0x0001;
  424. emumousebtn.idversion = 0x0100;
  425. input_register_device(&emumousebtn);
  426. printk(KERN_INFO "input%d: Macintosh mouse button emulationn", emumousebtn.number);
  427. }
  428. #endif
  429. void __init mac_hid_init_hw(void)
  430. {
  431. #ifdef CONFIG_MAC_ADBKEYCODES
  432. memcpy(pc_key_maps_save, key_maps, sizeof(key_maps));
  433. if (!keyboard_sends_linux_keycodes) {
  434. #ifdef CONFIG_MAGIC_SYSRQ
  435. ppc_md.ppc_kbd_sysrq_xlate   = mac_hid_kbd_sysrq_xlate;
  436. SYSRQ_KEY                = 0x69;
  437. #endif
  438. memcpy(key_maps, mac_key_maps_save, sizeof(key_maps));
  439. } else {
  440. #ifdef CONFIG_MAGIC_SYSRQ
  441. ppc_md.ppc_kbd_sysrq_xlate   = pckbd_sysrq_xlate;
  442. SYSRQ_KEY                = 0x54;
  443. #endif
  444. }
  445. #endif /* CONFIG_MAC_ADBKEYCODES */
  446. #ifdef CONFIG_MAC_EMUMOUSEBTN
  447. emumousebtn_input_register();
  448. #endif
  449. #if CONFIG_PPC
  450. if (_machine != _MACH_Pmac)
  451. pckbd_init_hw();
  452. #endif
  453. #if defined(CONFIG_SYSCTL) && (defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_MAC_EMUMOUSEBTN))
  454. mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
  455. #endif /* CONFIG_SYSCTL */
  456. }