lk201.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. /*
  2. *
  3. * This file is subject to the terms and conditions of the GNU General Public
  4. * License. See the file "COPYING" in the main directory of this archive
  5. * for more details.
  6. *
  7. * Copyright (C) 1999-2002 Harald Koerfgen <hkoerfg@web.de>
  8. * Copyright (C) 2001, 2002, 2003, 2004 Maciej W. Rozycki
  9. */
  10. #include <linux/errno.h>
  11. #include <linux/tty.h>
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/delay.h>
  15. #include <linux/kbd_ll.h>
  16. #include <linux/kbd_kern.h>
  17. #include <linux/vt_kern.h>
  18. #include <asm/keyboard.h>
  19. #include <asm/dec/tc.h>
  20. #include <asm/dec/machtype.h>
  21. #include <asm/dec/serial.h>
  22. #include "lk201.h"
  23. /*
  24. * Only handle DECstations that have an LK201 interface.
  25. * Maxine uses LK501 at the Access.Bus and various DECsystems
  26. * have no keyboard interface at all.
  27. */
  28. #define LK_IFACE (mips_machtype == MACH_DS23100 || \
  29. mips_machtype == MACH_DS5000_200 || \
  30. mips_machtype == MACH_DS5000_1XX || \
  31. mips_machtype == MACH_DS5000_2X0)
  32. /*
  33. * These use the Z8530 SCC. Others use the DZ11.
  34. */
  35. #define LK_IFACE_ZS (mips_machtype == MACH_DS5000_1XX || \
  36. mips_machtype == MACH_DS5000_2X0)
  37. /* Simple translation table for the SysRq keys */
  38. #ifdef CONFIG_MAGIC_SYSRQ
  39. /*
  40. * Actually no translation at all, at least until we figure out
  41. * how to define SysRq for LK201 and friends. --macro
  42. */
  43. unsigned char lk201_sysrq_xlate[128];
  44. unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
  45. unsigned char kbd_sysrq_key = -1;
  46. #endif
  47. #define KEYB_LINE 3
  48. static int __init lk201_init(void *);
  49. static void __init lk201_info(void *);
  50. static void lk201_rx_char(unsigned char, unsigned char);
  51. static struct dec_serial_hook lk201_hook = {
  52. .init_channel = lk201_init,
  53. .init_info = lk201_info,
  54. .rx_char = NULL,
  55. .poll_rx_char = NULL,
  56. .poll_tx_char = NULL,
  57. .cflags = B4800 | CS8 | CSTOPB | CLOCAL,
  58. };
  59. /*
  60. * This is used during keyboard initialisation
  61. */
  62. static unsigned char lk201_reset_string[] = {
  63. LK_CMD_SET_DEFAULTS,
  64. LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
  65. LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
  66. LK_CMD_MODE(LK_MODE_RPT_DOWN, 3),
  67. LK_CMD_MODE(LK_MODE_RPT_DOWN, 4),
  68. LK_CMD_MODE(LK_MODE_DOWN_UP, 5),
  69. LK_CMD_MODE(LK_MODE_DOWN_UP, 6),
  70. LK_CMD_MODE(LK_MODE_RPT_DOWN, 7),
  71. LK_CMD_MODE(LK_MODE_RPT_DOWN, 8),
  72. LK_CMD_MODE(LK_MODE_RPT_DOWN, 9),
  73. LK_CMD_MODE(LK_MODE_RPT_DOWN, 10),
  74. LK_CMD_MODE(LK_MODE_RPT_DOWN, 11),
  75. LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
  76. LK_CMD_MODE(LK_MODE_DOWN, 13),
  77. LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
  78. LK_CMD_DIS_KEYCLK,
  79. LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
  80. };
  81. static void *lk201_handle;
  82. static int lk201_send(unsigned char ch)
  83. {
  84. if (lk201_hook.poll_tx_char(lk201_handle, ch)) {
  85. printk(KERN_ERR "lk201: transmit timeout\n");
  86. return -EIO;
  87. }
  88. return 0;
  89. }
  90. static inline int lk201_get_id(void)
  91. {
  92. return lk201_send(LK_CMD_REQ_ID);
  93. }
  94. static int lk201_reset(void)
  95. {
  96. int i, r;
  97. for (i = 0; i < sizeof(lk201_reset_string); i++) {
  98. r = lk201_send(lk201_reset_string[i]);
  99. if (r < 0)
  100. return r;
  101. }
  102. return 0;
  103. }
  104. static void lk201_report(unsigned char id[6])
  105. {
  106. char *report = "lk201: keyboard attached, ";
  107. switch (id[2]) {
  108. case LK_STAT_PWRUP_OK:
  109. printk(KERN_INFO "%sself-test OK\n", report);
  110. break;
  111. case LK_STAT_PWRUP_KDOWN:
  112. /* The keyboard will resend the power-up ID
  113. after all keys are released, so we don't
  114. bother handling the error specially. Still
  115. there may be a short-circuit inside.
  116. */
  117. printk(KERN_ERR "%skey down (stuck?), code: 0x%02x\n",
  118. report, id[3]);
  119. break;
  120. case LK_STAT_PWRUP_ERROR:
  121. printk(KERN_ERR "%sself-test failure\n", report);
  122. break;
  123. default:
  124. printk(KERN_ERR "%sunknown error: 0x%02x\n",
  125. report, id[2]);
  126. }
  127. }
  128. static void lk201_id(unsigned char id[6])
  129. {
  130. /*
  131. * Report whether there is an LK201 or an LK401
  132. * The LK401 has ALT keys...
  133. */
  134. switch (id[4]) {
  135. case 1:
  136. printk(KERN_INFO "lk201: LK201 detected\n");
  137. break;
  138. case 2:
  139. printk(KERN_INFO "lk201: LK401 detected\n");
  140. break;
  141. case 3:
  142. printk(KERN_INFO "lk201: LK443 detected\n");
  143. break;
  144. case 4:
  145. printk(KERN_INFO "lk201: LK421 detected\n");
  146. break;
  147. default:
  148. printk(KERN_WARNING
  149. "lk201: unknown keyboard detected, ID %d\n", id[4]);
  150. printk(KERN_WARNING "lk201: ... please report to "
  151. "<linux-mips@linux-mips.org>\n");
  152. }
  153. }
  154. #define DEFAULT_KEYB_REP_DELAY (250/5) /* [5ms] */
  155. #define DEFAULT_KEYB_REP_RATE 30 /* [cps] */
  156. static struct kbd_repeat kbdrate = {
  157. DEFAULT_KEYB_REP_DELAY,
  158. DEFAULT_KEYB_REP_RATE
  159. };
  160. static void parse_kbd_rate(struct kbd_repeat *r)
  161. {
  162. if (r->delay <= 0)
  163. r->delay = kbdrate.delay;
  164. if (r->rate <= 0)
  165. r->rate = kbdrate.rate;
  166. if (r->delay < 5)
  167. r->delay = 5;
  168. if (r->delay > 630)
  169. r->delay = 630;
  170. if (r->rate < 12)
  171. r->rate = 12;
  172. if (r->rate > 127)
  173. r->rate = 127;
  174. if (r->rate == 125)
  175. r->rate = 124;
  176. }
  177. static int write_kbd_rate(struct kbd_repeat *rep)
  178. {
  179. int delay, rate;
  180. int i;
  181. delay = rep->delay / 5;
  182. rate = rep->rate;
  183. for (i = 0; i < 4; i++) {
  184. if (lk201_hook.poll_tx_char(lk201_handle,
  185. LK_CMD_RPT_RATE(i)))
  186. return 1;
  187. if (lk201_hook.poll_tx_char(lk201_handle,
  188. LK_PARAM_DELAY(delay)))
  189. return 1;
  190. if (lk201_hook.poll_tx_char(lk201_handle,
  191. LK_PARAM_RATE(rate)))
  192. return 1;
  193. }
  194. return 0;
  195. }
  196. static int lk201_kbd_rate(struct kbd_repeat *rep)
  197. {
  198. if (rep == NULL)
  199. return -EINVAL;
  200. parse_kbd_rate(rep);
  201. if (write_kbd_rate(rep)) {
  202. memcpy(rep, &kbdrate, sizeof(struct kbd_repeat));
  203. return -EIO;
  204. }
  205. memcpy(&kbdrate, rep, sizeof(struct kbd_repeat));
  206. return 0;
  207. }
  208. static void lk201_kd_mksound(unsigned int hz, unsigned int ticks)
  209. {
  210. if (!ticks)
  211. return;
  212. /*
  213. * Can't set frequency and we "approximate"
  214. * duration by volume. ;-)
  215. */
  216. ticks /= HZ / 32;
  217. if (ticks > 7)
  218. ticks = 7;
  219. ticks = 7 - ticks;
  220. if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_ENB_BELL))
  221. return;
  222. if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_VOLUME(ticks)))
  223. return;
  224. if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_BELL))
  225. return;
  226. }
  227. void kbd_leds(unsigned char leds)
  228. {
  229. unsigned char l = 0;
  230. if (!lk201_handle) /* FIXME */
  231. return;
  232. /* FIXME -- Only Hold and Lock LEDs for now. --macro */
  233. if (leds & LED_SCR)
  234. l |= LK_LED_HOLD;
  235. if (leds & LED_CAP)
  236. l |= LK_LED_LOCK;
  237. if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_ON))
  238. return;
  239. if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(l)))
  240. return;
  241. if (lk201_hook.poll_tx_char(lk201_handle, LK_CMD_LEDS_OFF))
  242. return;
  243. if (lk201_hook.poll_tx_char(lk201_handle, LK_PARAM_LED_MASK(~l)))
  244. return;
  245. }
  246. int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
  247. {
  248. return -EINVAL;
  249. }
  250. int kbd_getkeycode(unsigned int scancode)
  251. {
  252. return -EINVAL;
  253. }
  254. int kbd_translate(unsigned char scancode, unsigned char *keycode,
  255. char raw_mode)
  256. {
  257. *keycode = scancode;
  258. return 1;
  259. }
  260. char kbd_unexpected_up(unsigned char keycode)
  261. {
  262. return 0x80;
  263. }
  264. static void lk201_rx_char(unsigned char ch, unsigned char fl)
  265. {
  266. static unsigned char id[6];
  267. static int id_i;
  268. static int shift_state = 0;
  269. static int prev_scancode;
  270. unsigned char c = scancodeRemap[ch];
  271. if (fl != TTY_NORMAL && fl != TTY_OVERRUN) {
  272. printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl);
  273. return;
  274. }
  275. /* Assume this is a power-up ID. */
  276. if (ch == LK_STAT_PWRUP_ID && !id_i) {
  277. id[id_i++] = ch;
  278. return;
  279. }
  280. /* Handle the power-up sequence. */
  281. if (id_i) {
  282. id[id_i++] = ch;
  283. if (id_i == 4) {
  284. /* OK, the power-up concluded. */
  285. lk201_report(id);
  286. if (id[2] == LK_STAT_PWRUP_OK)
  287. lk201_get_id();
  288. else {
  289. id_i = 0;
  290. printk(KERN_ERR "lk201: keyboard power-up "
  291. "error, skipping initialization\n");
  292. }
  293. } else if (id_i == 6) {
  294. /* We got the ID; report it and start operation. */
  295. id_i = 0;
  296. lk201_id(id);
  297. lk201_reset();
  298. }
  299. return;
  300. }
  301. /* Everything else is a scancode/status response. */
  302. id_i = 0;
  303. switch (ch) {
  304. case LK_STAT_RESUME_ERR:
  305. case LK_STAT_ERROR:
  306. case LK_STAT_INHIBIT_ACK:
  307. case LK_STAT_TEST_ACK:
  308. case LK_STAT_MODE_KEYDOWN:
  309. case LK_STAT_MODE_ACK:
  310. break;
  311. case LK_KEY_LOCK:
  312. shift_state ^= LK_LOCK;
  313. handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0);
  314. break;
  315. case LK_KEY_SHIFT:
  316. shift_state ^= LK_SHIFT;
  317. handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0);
  318. break;
  319. case LK_KEY_CTRL:
  320. shift_state ^= LK_CTRL;
  321. handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0);
  322. break;
  323. case LK_KEY_COMP:
  324. shift_state ^= LK_COMP;
  325. handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0);
  326. break;
  327. case LK_KEY_RELEASE:
  328. if (shift_state & LK_SHIFT)
  329. handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
  330. if (shift_state & LK_CTRL)
  331. handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
  332. if (shift_state & LK_COMP)
  333. handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
  334. if (shift_state & LK_LOCK)
  335. handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
  336. shift_state = 0;
  337. break;
  338. case LK_KEY_REPEAT:
  339. handle_scancode(prev_scancode, 1);
  340. break;
  341. default:
  342. prev_scancode = c;
  343. handle_scancode(c, 1);
  344. break;
  345. }
  346. tasklet_schedule(&keyboard_tasklet);
  347. }
  348. static void __init lk201_info(void *handle)
  349. {
  350. }
  351. static int __init lk201_init(void *handle)
  352. {
  353. /* First install handlers. */
  354. lk201_handle = handle;
  355. kbd_rate = lk201_kbd_rate;
  356. kd_mksound = lk201_kd_mksound;
  357. lk201_hook.rx_char = lk201_rx_char;
  358. /* Then just issue a reset -- the handlers will do the rest. */
  359. lk201_send(LK_CMD_POWER_UP);
  360. return 0;
  361. }
  362. void __init kbd_init_hw(void)
  363. {
  364. /* Maxine uses LK501 at the Access.Bus. */
  365. if (!LK_IFACE)
  366. return;
  367. printk(KERN_INFO "lk201: DECstation LK keyboard driver v0.05.\n");
  368. if (LK_IFACE_ZS) {
  369. /*
  370. * kbd_init_hw() is being called before
  371. * rs_init() so just register the kbd hook
  372. * and let zs_init do the rest :-)
  373. */
  374. if (!register_dec_serial_hook(KEYB_LINE, &lk201_hook))
  375. unregister_dec_serial_hook(KEYB_LINE);
  376. } else {
  377. /*
  378. * TODO: modify dz.c to allow similar hooks
  379. * for LK201 handling on DS2100, DS3100, and DS5000/200
  380. */
  381. printk(KERN_ERR "lk201: support for DZ11 not yet ready.\n");
  382. }
  383. }