lk201.c 9.8 KB

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