summaryrefslogtreecommitdiffstats
path: root/drivers/acorn/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acorn/char')
-rw-r--r--drivers/acorn/char/Config.in11
-rw-r--r--drivers/acorn/char/Makefile13
-rw-r--r--drivers/acorn/char/keyb_ps2.c355
-rw-r--r--drivers/acorn/char/mouse_rpc.c86
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