lk201.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
- /*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- */
- #include <linux/errno.h>
- #include <linux/tty.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/kbd_ll.h>
- #include <asm/wbflush.h>
- #include <asm/dec/tc.h>
- #include <asm/dec/machtype.h>
- #include "zs.h"
- #include "lk201.h"
- /* Simple translation table for the SysRq keys */
- #ifdef CONFIG_MAGIC_SYSRQ
- /*
- * Actually no translation at all, at least until we figure out
- * how to define SysRq for LK201 and friends. --macro
- */
- unsigned char lk201_sysrq_xlate[128];
- unsigned char *kbd_sysrq_xlate = lk201_sysrq_xlate;
- #endif
- #define KEYB_LINE 3
- static int __init lk201_init(struct dec_serial *);
- static void __init lk201_info(struct dec_serial *);
- static void lk201_kbd_rx_char(unsigned char, unsigned char);
- struct zs_hook lk201_kbdhook = {
- init_channel: lk201_init,
- init_info: lk201_info,
- rx_char: NULL,
- poll_rx_char: NULL,
- poll_tx_char: NULL,
- cflags: B4800 | CS8 | CSTOPB | CLOCAL
- };
- /*
- * This is used during keyboard initialisation
- */
- static unsigned char lk201_reset_string[] = {
- LK_CMD_LEDS_ON, LK_PARAM_LED_MASK(0xf), /* show we are resetting */
- LK_CMD_SET_DEFAULTS,
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 1),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 2),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 3),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 4),
- LK_CMD_MODE(LK_MODE_DOWN_UP, 5),
- LK_CMD_MODE(LK_MODE_DOWN_UP, 6),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 7),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 8),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 9),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 10),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 11),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 12),
- LK_CMD_MODE(LK_MODE_DOWN, 13),
- LK_CMD_MODE(LK_MODE_RPT_DOWN, 14),
- LK_CMD_ENB_RPT,
- LK_CMD_DIS_KEYCLK,
- LK_CMD_RESUME,
- LK_CMD_ENB_BELL, LK_PARAM_VOLUME(4),
- LK_CMD_LEDS_OFF, LK_PARAM_LED_MASK(0xf)
- };
- static int __init lk201_reset(struct dec_serial *info)
- {
- int i;
- for (i = 0; i < sizeof(lk201_reset_string); i++)
- if (info->hook->poll_tx_char(info, lk201_reset_string[i])) {
- printk(__FUNCTION__" transmit timeoutn");
- return -EIO;
- }
- return 0;
- }
- void kbd_leds(unsigned char leds)
- {
- return;
- }
- int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
- {
- return -EINVAL;
- }
- int kbd_getkeycode(unsigned int scancode)
- {
- return -EINVAL;
- }
- int kbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode)
- {
- *keycode = scancode;
- return 1;
- }
- char kbd_unexpected_up(unsigned char keycode)
- {
- return 0x80;
- }
- static void lk201_kbd_rx_char(unsigned char ch, unsigned char stat)
- {
- static int shift_state = 0;
- static int prev_scancode;
- unsigned char c = scancodeRemap[ch];
- if (!stat || stat == 4) {
- switch (ch) {
- case LK_KEY_ACK:
- break;
- case LK_KEY_LOCK:
- shift_state ^= LK_LOCK;
- handle_scancode(c, shift_state && LK_LOCK ? 1 : 0);
- break;
- case LK_KEY_SHIFT:
- shift_state ^= LK_SHIFT;
- handle_scancode(c, shift_state && LK_SHIFT ? 1 : 0);
- break;
- case LK_KEY_CTRL:
- shift_state ^= LK_CTRL;
- handle_scancode(c, shift_state && LK_CTRL ? 1 : 0);
- break;
- case LK_KEY_COMP:
- shift_state ^= LK_COMP;
- handle_scancode(c, shift_state && LK_COMP ? 1 : 0);
- break;
- case LK_KEY_RELEASE:
- if (shift_state & LK_SHIFT)
- handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0);
- if (shift_state & LK_CTRL)
- handle_scancode(scancodeRemap[LK_KEY_CTRL], 0);
- if (shift_state & LK_COMP)
- handle_scancode(scancodeRemap[LK_KEY_COMP], 0);
- if (shift_state & LK_LOCK)
- handle_scancode(scancodeRemap[LK_KEY_LOCK], 0);
- shift_state = 0;
- break;
- case LK_KEY_REPEAT:
- handle_scancode(prev_scancode, 1);
- break;
- default:
- prev_scancode = c;
- handle_scancode(c, 1);
- break;
- }
- } else
- printk("Error reading LKx01 keyboard: 0x%02xn", stat);
- }
- static void __init lk201_info(struct dec_serial *info)
- {
- }
- static int __init lk201_init(struct dec_serial *info)
- {
- unsigned int ch, id = 0;
- int result;
- printk("DECstation LK keyboard driver v0.04... ");
- result = lk201_reset(info);
- if (result)
- return result;
- mdelay(10);
- /*
- * Detect whether there is an LK201 or an LK401
- * The LK401 has ALT keys...
- */
- info->hook->poll_tx_char(info, LK_CMD_REQ_ID);
- while ((ch = info->hook->poll_rx_char(info)) > 0)
- id = ch;
- switch (id) {
- case 1:
- printk("LK201 detectedn");
- break;
- case 2:
- printk("LK401 detectedn");
- break;
- default:
- printk("unknown keyboard, ID %d,n", id);
- printk("... please report to <linux-mips@oss.sgi.com>n");
- }
- /*
- * now we're ready
- */
- info->hook->rx_char = lk201_kbd_rx_char;
- return 0;
- }
- void __init kbd_init_hw(void)
- {
- extern int register_zs_hook(unsigned int, struct zs_hook *);
- extern int unregister_zs_hook(unsigned int);
- if (TURBOCHANNEL) {
- if (mips_machtype != MACH_DS5000_XX) {
- /*
- * This is not a MAXINE, so:
- *
- * kbd_init_hw() is being called before
- * rs_init() so just register the kbd hook
- * and let zs_init do the rest :-)
- */
- if (mips_machtype == MACH_DS5000_200)
- printk("LK201 Support for DS5000/200 not yet ready ...n");
- else
- if(!register_zs_hook(KEYB_LINE, &lk201_kbdhook))
- unregister_zs_hook(KEYB_LINE);
- }
- } else {
- /*
- * TODO: modify dz.c to allow similar hooks
- * for LK201 handling on DS2100, DS3100, and DS5000/200
- */
- printk("LK201 Support for DS3100 not yet ready ...n");
- }
- }