diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /drivers/acorn/char | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'drivers/acorn/char')
-rw-r--r-- | drivers/acorn/char/Config.in | 11 | ||||
-rw-r--r-- | drivers/acorn/char/Makefile | 13 | ||||
-rw-r--r-- | drivers/acorn/char/keyb_ps2.c | 355 | ||||
-rw-r--r-- | drivers/acorn/char/mouse_rpc.c | 86 |
4 files changed, 465 insertions, 0 deletions
diff --git a/drivers/acorn/char/Config.in b/drivers/acorn/char/Config.in index cbd70732d..ede0a8266 100644 --- a/drivers/acorn/char/Config.in +++ b/drivers/acorn/char/Config.in @@ -2,3 +2,14 @@ if [ "$CONFIG_SERIAL" != "n" ]; then tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL fi + +if [ "$CONFIG_MOUSE" = "y" ]; then + if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + if [ "$CONFIG_ARCH_RPC" != "y" ]; then + define_bool CONFIG_KBDMOUSE y + else + define_bool CONFIG_RPCMOUSE y + fi + fi +fi + diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile index ffc01825f..ecbbfe90c 100644 --- a/drivers/acorn/char/Makefile +++ b/drivers/acorn/char/Makefile @@ -13,6 +13,19 @@ L_TARGET := acorn-char.a M_OBJS := L_OBJS := +ifeq ($(MACHINE),rpc) + MOUSE_OBJS += mouse_rpc.o + L_OBJS += keyb_ps2.o +endif + +ifeq ($(CONFIG_MOUSE),y) + LX_OBJS += $(MOUSE_OBJS) +else + ifeq ($(CONFIG_MOUSE),m) + MX_OBJS += $(MOUSE_OBJS) + endif +endif + ifeq ($(CONFIG_ATOMWIDE_SERIAL),y) L_OBJS += serial-atomwide.o else diff --git a/drivers/acorn/char/keyb_ps2.c b/drivers/acorn/char/keyb_ps2.c new file mode 100644 index 000000000..c3ef33363 --- /dev/null +++ b/drivers/acorn/char/keyb_ps2.c @@ -0,0 +1,355 @@ +/* + * linux/arch/arm/drivers/block/keyb_ps2.c + * + * Keyboard driver for RPC ARM Linux. + * + * Note!!! This driver talks directly to the keyboard. + */ + +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/mm.h> +#include <linux/malloc.h> +#include <linux/ptrace.h> +#include <linux/signal.h> +#include <linux/timer.h> +#include <linux/random.h> +#include <linux/ctype.h> +#include <linux/kbd_ll.h> +#include <linux/init.h> + +#include <asm/bitops.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/system.h> + +extern void kbd_reset_kdown(void); +int kbd_read_mask; + +#define IRQ_KEYBOARDRX 15 + +#define VERSION 100 + +#define KBD_REPORT_ERR +#define KBD_REPORT_UNKN + +#define KBD_ESCAPEE0 0xe0 /* in */ +#define KBD_ESCAPEE1 0xe1 /* in */ + +#define ESCE0(x) (0xe000|(x)) +#define ESCE1(x) (0xe100|(x)) + +#define KBD_BAT 0xaa /* in */ +#define KBD_SETLEDS 0xed /* out */ +#define KBD_ECHO 0xee /* in/out */ +#define KBD_BREAK 0xf0 /* in */ +#define KBD_TYPRATEDLY 0xf3 /* out */ +#define KBD_SCANENABLE 0xf4 /* out */ +#define KBD_DEFDISABLE 0xf5 /* out */ +#define KBD_DEFAULT 0xf6 /* out */ +#define KBD_ACK 0xfa /* in */ +#define KBD_DIAGFAIL 0xfd /* in */ +#define KBD_RESEND 0xfe /* in/out */ +#define KBD_RESET 0xff /* out */ + +#define CODE_BREAK 1 +#define CODE_ESCAPEE0 2 +#define CODE_ESCAPEE1 4 +#define CODE_ESCAPE12 8 + +#define K_NONE 0x7f +#define K_ESC 0x00 +#define K_F1 0x01 +#define K_F2 0x02 +#define K_F3 0x03 +#define K_F4 0x04 +#define K_F5 0x05 +#define K_F6 0x06 +#define K_F7 0x07 +#define K_F8 0x08 +#define K_F9 0x09 +#define K_F10 0x0a +#define K_F11 0x0b +#define K_F12 0x0c +#define K_PRNT 0x0d +#define K_SCRL 0x0e +#define K_BRK 0x0f +#define K_AGR 0x10 +#define K_1 0x11 +#define K_2 0x12 +#define K_3 0x13 +#define K_4 0x14 +#define K_5 0x15 +#define K_6 0x16 +#define K_7 0x17 +#define K_8 0x18 +#define K_9 0x19 +#define K_0 0x1a +#define K_MINS 0x1b +#define K_EQLS 0x1c +#define K_BKSP 0x1e +#define K_INS 0x1f +#define K_HOME 0x20 +#define K_PGUP 0x21 +#define K_NUML 0x22 +#define KP_SLH 0x23 +#define KP_STR 0x24 +#define KP_MNS 0x3a +#define K_TAB 0x26 +#define K_Q 0x27 +#define K_W 0x28 +#define K_E 0x29 +#define K_R 0x2a +#define K_T 0x2b +#define K_Y 0x2c +#define K_U 0x2d +#define K_I 0x2e +#define K_O 0x2f +#define K_P 0x30 +#define K_LSBK 0x31 +#define K_RSBK 0x32 +#define K_ENTR 0x47 +#define K_DEL 0x34 +#define K_END 0x35 +#define K_PGDN 0x36 +#define KP_7 0x37 +#define KP_8 0x38 +#define KP_9 0x39 +#define KP_PLS 0x4b +#define K_CAPS 0x5d +#define K_A 0x3c +#define K_S 0x3d +#define K_D 0x3e +#define K_F 0x3f +#define K_G 0x40 +#define K_H 0x41 +#define K_J 0x42 +#define K_K 0x43 +#define K_L 0x44 +#define K_SEMI 0x45 +#define K_SQOT 0x46 +#define K_HASH 0x1d +#define KP_4 0x48 +#define KP_5 0x49 +#define KP_6 0x4a +#define K_LSFT 0x4c +#define K_BSLH 0x33 +#define K_Z 0x4e +#define K_X 0x4f +#define K_C 0x50 +#define K_V 0x51 +#define K_B 0x52 +#define K_N 0x53 +#define K_M 0x54 +#define K_COMA 0x55 +#define K_DOT 0x56 +#define K_FSLH 0x57 +#define K_RSFT 0x58 +#define K_UP 0x59 +#define KP_1 0x5a +#define KP_2 0x5b +#define KP_3 0x5c +#define KP_ENT 0x67 +#define K_LCTL 0x3b +#define K_LALT 0x5e +#define K_SPCE 0x5f +#define K_RALT 0x60 +#define K_RCTL 0x61 +#define K_LEFT 0x62 +#define K_DOWN 0x63 +#define K_RGHT 0x64 +#define KP_0 0x65 +#define KP_DOT 0x66 + +static unsigned char keycode_translate[256] = +{ +/* 00 */ K_NONE, K_F9 , K_NONE, K_F5 , K_F3 , K_F1 , K_F2 , K_F12 , +/* 08 */ K_NONE, K_F10 , K_F8 , K_F6 , K_F4 , K_TAB , K_AGR , K_NONE, +/* 10 */ K_NONE, K_LALT, K_LSFT, K_NONE, K_LCTL, K_Q , K_1 , K_NONE, +/* 18 */ K_NONE, K_NONE, K_Z , K_S , K_A , K_W , K_2 , K_NONE, +/* 20 */ K_NONE, K_C , K_X , K_D , K_E , K_4 , K_3 , K_NONE, +/* 28 */ K_NONE, K_SPCE, K_V , K_F , K_T , K_R , K_5 , K_NONE, +/* 30 */ K_NONE, K_N , K_B , K_H , K_G , K_Y , K_6 , K_NONE, +/* 38 */ K_NONE, K_NONE, K_M , K_J , K_U , K_7 , K_8 , K_NONE, +/* 40 */ K_NONE, K_COMA, K_K , K_I , K_O , K_0 , K_9 , K_NONE, +/* 48 */ K_NONE, K_DOT , K_FSLH, K_L , K_SEMI, K_P , K_MINS, K_NONE, +/* 50 */ K_NONE, K_NONE, K_SQOT, K_NONE, K_LSBK, K_EQLS, K_NONE, K_NONE, +/* 58 */ K_CAPS, K_RSFT, K_ENTR, K_RSBK, K_NONE, K_HASH, K_NONE, K_NONE, +/* 60 */ K_NONE, K_BSLH, K_NONE, K_NONE, K_NONE, K_NONE, K_BKSP, K_NONE, +/* 68 */ K_NONE, KP_1 , K_NONE, KP_4 , KP_7 , K_NONE, K_NONE, K_NONE, +/* 70 */ KP_0 , KP_DOT, KP_2 , KP_5 , KP_6 , KP_8 , K_ESC , K_NUML, +/* 78 */ K_F11 , KP_PLS, KP_3 , KP_MNS, KP_STR, KP_9 , K_SCRL, K_NONE, + K_NONE, K_NONE, K_NONE, K_F7 , K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, + K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE, K_NONE +}; + +#ifdef CONFIG_MAGIC_SYSRQ +unsigned char ps2kbd_sysrq_xlate[] = +{ + 27, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + '`', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '0', '-', '=', '£', 127, 0, + 0, 0, 0, '/', '*', '#', 9, 'q', + 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', + 'p', '[', ']', '\\', 22, 23, 25, '7', + '8', '9', '-', 0, 'a', 's', 'd', 'f', + 'g', 'h', 'j', 'k', 'l', ';', '\'', 13, + '4', '5', '6', '+', 0, 0, 'z', 'x', + 'c', 'v', 'b', 'n', 'm', ',', '.', '/', + 0, 0, '1', '2', '3', 0, 0, ' ', + 0, 0, 0, 0, 0, '0', '.', 10, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; +#endif + +int ps2kbd_pretranslate(unsigned char scancode) +{ + return 1; +} + +int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *uf_p) +{ + *uf_p = scancode & 0200; + *keycode_p = scancode & 0x7f; + return 1; +} + +static void ps2kbd_key(unsigned int keycode, unsigned int up_flag) +{ + handle_scancode(keycode + (up_flag ? 0x80 : 0)); +} + +static inline void ps2kbd_sendbyte(unsigned char val) +{ + while(!(inb(IOMD_KCTRL) & (1 << 7))); + outb(val, IOMD_KARTTX); +} + +static unsigned char status; +static unsigned char ncodes; +static unsigned char bi; +static unsigned char buffer[4]; + +static inline void ps2kbd_reset(void) +{ + status = 0; + kbd_reset_kdown(); +} + +static void handle_rawcode(int keyval) +{ + int keysym; + + if (keyval > 0x83) { + switch (keyval) { + case KBD_ESCAPEE0: + ncodes = 2; + bi = 0; + break; + case KBD_ESCAPEE1: + ncodes = 3; + bi = 0; + break; + case KBD_BREAK: + status |= CODE_BREAK; + default: + return; + } + } + + if (ncodes) { + buffer[bi++] = keyval; + ncodes -= 1; + if (ncodes) + return; + keysym = K_NONE; + switch (buffer[0] << 8 | buffer[1]) { + case ESCE0(0x11): keysym = K_RALT; break; + case ESCE0(0x14): keysym = K_RCTL; break; + case ESCE0(0x4a): keysym = KP_SLH; break; + case ESCE0(0x5a): keysym = KP_ENT; break; + case ESCE0(0x69): keysym = K_END; break; + case ESCE0(0x6b): keysym = K_LEFT; break; + case ESCE0(0x6c): keysym = K_HOME; break; + case ESCE0(0x70): keysym = K_INS; break; + case ESCE0(0x71): keysym = K_DEL; break; + case ESCE0(0x72): keysym = K_DOWN; break; + case ESCE0(0x74): keysym = K_RGHT; break; + case ESCE0(0x75): keysym = K_UP; break; + case ESCE0(0x7a): keysym = K_PGDN; break; + case ESCE0(0x7c): keysym = K_PRNT; break; + case ESCE0(0x7d): keysym = K_PGUP; break; + case ESCE1(0x14): + if (buffer[2] == 0x77) + keysym = K_BRK; + break; + case ESCE0(0x12): /* ignore escaped shift key */ + status = 0; + return; + } + } else { + bi = 0; + keysym = keycode_translate[keyval]; + } + + if (keysym != K_NONE) + ps2kbd_key(keysym, status & CODE_BREAK); + status = 0; +} + +void ps2kbd_leds(unsigned int leds) +{ + ps2kbd_sendbyte(KBD_SETLEDS); + ps2kbd_sendbyte(leds); + ps2kbd_sendbyte(KBD_SCANENABLE); +} + +static void ps2kbd_rx(int irq, void *dev_id, struct pt_regs *regs) +{ + kbd_pt_regs = regs; + + while (inb(IOMD_KCTRL) & (1 << 5)) + handle_rawcode(inb(IOMD_KARTRX)); + mark_bh(KEYBOARD_BH); +} + +static void ps2kbd_tx(int irq, void *dev_id, struct pt_regs *regs) +{ +} + +__initfunc(int ps2kbd_init_hw(void)) +{ + unsigned long flags; + + save_flags_cli (flags); + if (request_irq (IRQ_KEYBOARDRX, ps2kbd_rx, 0, "keyboard", NULL) != 0) + panic("Could not allocate keyboard receive IRQ!"); + if (request_irq (IRQ_KEYBOARDTX, ps2kbd_tx, 0, "keyboard", NULL) != 0) + panic("Could not allocate keyboard transmit IRQ!"); + disable_irq (IRQ_KEYBOARDTX); + (void)IOMD_KARTRX; + restore_flags (flags); + + printk (KERN_INFO "PS/2 keyboard driver v%d.%02d\n", VERSION/100, VERSION%100); + return 0; +} + diff --git a/drivers/acorn/char/mouse_rpc.c b/drivers/acorn/char/mouse_rpc.c new file mode 100644 index 000000000..a5c2b2bff --- /dev/null +++ b/drivers/acorn/char/mouse_rpc.c @@ -0,0 +1,86 @@ +/* + * linux/drivers/char/rpcmouse.c + * + * Copyright (C) 1996-1998 Russell King + * + * This handles the Acorn RiscPCs mouse. We basically have a couple + * of hardware registers that track the sensor count for the X-Y movement + * and another register holding the button state. On every VSYNC interrupt + * we read the complete state and then work out if something has changed. + */ +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/ptrace.h> +#include <linux/interrupt.h> + +#include <asm/hardware.h> +#include <asm/irq.h> +#include <asm/io.h> + +#include "../../char/mouse.h" + +static short old_x, old_y, old_b; +static int mousedev; + +void +mouse_rpc_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + short x, y, dx, dy; + int buttons; + + x = (short)inl(IOMD_MOUSEX); + y = (short)inl(IOMD_MOUSEY); + buttons = (inl (0x800C4000) >> 4) & 7; + + dx = x - old_x; + old_x = x; + dy = y - old_y; + old_y = y; + + if (dx || dy || buttons != old_b) { + busmouse_add_movementbuttons(mousedev, dx, dy, buttons); + old_b = buttons; + } +} + +static struct busmouse rpcmouse = { + 6, "arcmouse", NULL, NULL, 7 +}; + +int +mouse_rpc_init(void) +{ + mousedev = register_busmouse(&rpcmouse); + + if (mousedev < 0) + printk("rpcmouse: could not register mouse driver\n"); + else { + old_x = (short)inl(IOMD_MOUSEX); + old_y = (short)inl(IOMD_MOUSEY); + old_b = (inl (0x800C4000) >> 4) & 7; + if (request_irq(IRQ_VSYNCPULSE, mouse_rpc_irq, SA_SHIRQ, "mouse", &mousedev)) { + printk("rpcmouse: unable to allocate VSYNC interrupt\n"); + unregister_busmouse(mousedev); + mousedev = -1; + } + } + + return mousedev >= 0 ? 0 : -ENODEV; +} + +#ifdef MODULE +int +init_module(void) +{ + return mouse_rpc_init(); +} + +int +cleanup_module(void) +{ + if (mousedev >= 0) { + unregister_busmouse(mousedev); + free_irq(IRQ_VSYNCPULSE, &mousedev); + } +} +#endif |