linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][RFC] add support for PC-9800 architecture (11/26) input
@ 2002-10-17 11:40 Osamu Tomita
  2002-10-22 10:29 ` Vojtech Pavlik
  0 siblings, 1 reply; 2+ messages in thread
From: Osamu Tomita @ 2002-10-17 11:40 UTC (permalink / raw)
  To: LKML; +Cc: Linus Torvalds

This is part 11/26 of patchset for add support NEC PC-9800 architecture,
against 2.5.43.

Summary:
 input modules
  - add new driver for PC-9800 standard keyboard and mouse.

 input.h changes are temporally hack.
 I'll remove this hack using propery keycode.
 To do this, I need "kbd" utility that can make keymap even if keycode > 127.

diffstat:
 drivers/input/keyboard/98kbd.c   |  359 +++++++++++++++++++++++++++++++++++++++
 drivers/input/keyboard/Config.in |    4 
 drivers/input/keyboard/Makefile  |    1 
 drivers/input/misc/pcspkr.c      |   24 ++
 drivers/input/mouse/Config.in    |    7 
 drivers/input/mouse/logibm.c     |   48 +++++
 drivers/input/serio/Config.in    |    3 
 drivers/input/serio/Makefile     |    1 
 drivers/input/serio/i8042-98.c   |  346 +++++++++++++++++++++++++++++++++++++
 drivers/input/serio/i8042-98io.h |   74 ++++++++
 drivers/input/serio/i8042.h      |    2 
 include/linux/input.h            |   21 ++
 12 files changed, 890 insertions(+)

patch:
diff -urN linux/drivers/input/keyboard/Config.in linux98/drivers/input/keyboard/Config.in
--- linux/drivers/input/keyboard/Config.in	Sat Oct 12 13:22:45 2002
+++ linux98/drivers/input/keyboard/Config.in	Sun Oct 13 11:29:55 2002
@@ -9,6 +9,10 @@
 dep_tristate '  XT Keyboard support' CONFIG_KEYBOARD_XTKBD $CONFIG_INPUT $CONFIG_INPUT_KEYBOARD $CONFIG_SERIO
 dep_tristate '  Newton keyboard' CONFIG_KEYBOARD_NEWTON $CONFIG_INPUT $CONFIG_INPUT_KEYBOARD $CONFIG_SERIO
 
+if [ "$CONFIG_PC9800" = "y" ]; then
+   dep_tristate '  NEC PC-9801 keyboard support' CONFIG_KEYBOARD_98KBD $CONFIG_INPUT $CONFIG_INPUT_KEYBOARD $CONFIG_SERIO
+fi
+
 if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then
    dep_tristate '  Maple bus keyboard support' CONFIG_KEYBOARD_MAPLE $CONFIG_INPUT $CONFIG_INPUT_KEYBOARD $CONFIG_MAPLE
 fi
diff -urN linux/drivers/input/keyboard/Makefile linux98/drivers/input/keyboard/Makefile
--- linux/drivers/input/keyboard/Makefile	Sat Oct 12 13:21:42 2002
+++ linux98/drivers/input/keyboard/Makefile	Sun Oct 13 11:27:15 2002
@@ -10,6 +10,7 @@
 obj-$(CONFIG_KEYBOARD_XTKBD)		+= xtkbd.o
 obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
+obj-$(CONFIG_KEYBOARD_98KBD)		+= 98kbd.o
 
 # The global Rules.make.
 
diff -urN linux/drivers/input/keyboard/98kbd.c linux98/drivers/input/keyboard/98kbd.c
--- linux/drivers/input/keyboard/98kbd.c	Thu Jan  1 09:00:00 1970
+++ linux98/drivers/input/keyboard/98kbd.c	Sun Oct 13 12:25:32 2002
@@ -0,0 +1,359 @@
+/*
+ * NEC PC-9801/9821 keyboard driver
+ *
+ * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Modify for NEC PC-9801 by Osamu Tomita <tomita@cinet.co.jp>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/workqueue.h>
+
+#include <asm/io.h>
+#include <asm/pc9800.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("NEC PC-9801 keyboard driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Scancode to keycode tables. These are just the default setting, and
+ * are loadable via an userland utility.
+ */
+
+#if 0	/* Waiting for kbd utility support keycode > 127 */
+static unsigned char atkbd_set2_keycode[512] = {
+	  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 43, 14, 15,
+	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32,
+	 33, 34, 35, 36, 37, 38, 39, 40, 84, 44, 45, 46, 47, 48, 49, 50,
+	 51, 52, 53,181, 57,184,109,104,110,111,103,105,106,108,102,107,
+	 74, 98, 71, 72, 73, 55, 75, 76, 77, 78, 79, 80, 81,117, 82,124,
+	 83,185, 87, 88, 85, 89, 90,  0,  0,  0,  0,  0,  0,  0,102,  0,
+	 99,133, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,  0,  0,  0,  0,
+	 42, 58,190, 56, 29
+#else
+static unsigned char atkbd_set2_keycode[512] = {
+	  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+	 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+	 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+	 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+	 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+	 96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
+	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127
+};
+#endif
+
+#define ATKBD_CMD_SETEXKEY	0x1095	/* Enable/Disable Windows, Appli key */
+#define ATKBD_CMD_SETRATE	0x109c	/* Set typematic rate */
+#define ATKBD_CMD_SETLEDS	0x109d	/* Set keyboard leds */
+#define ATKBD_CMD_GETLEDS	0x119d	/* Get keyboard leds */
+#define ATKBD_CMD_GETID		0x019f
+
+#define ATKBD_RET_ACK		0xfa
+#define ATKBD_RET_NAK		0xfc	/* Command NACK, send the cmd again */
+
+#define ATKBD_KEY_UNKNOWN	  0
+#define ATKBD_KEY_BAT		251
+#define ATKBD_KEY_EMUL0		252
+#define ATKBD_KEY_EMUL1		253
+#define ATKBD_KEY_RELEASE	254
+#define ATKBD_KEY_NULL		255
+
+/*
+ * The atkbd control structure
+ */
+
+struct atkbd {
+	unsigned char keycode[512];
+	struct input_dev dev;
+	struct serio *serio;
+	char name[64];
+	char phys[32];
+	unsigned char cmdbuf[4];
+	unsigned char cmdcnt;
+	unsigned char set;
+	unsigned char oldset;
+	unsigned char release;
+	signed char ack;
+	unsigned char emul;
+	unsigned short id;
+	unsigned char write;
+};
+
+/*
+ * atkbd_interrupt(). Here takes place processing of data received from
+ * the keyboard into events.
+ */
+
+static void atkbd_interrupt(struct serio *serio, unsigned char data, unsigned int flags)
+{
+	struct atkbd *atkbd = serio->private;
+	int code = data;
+
+#ifdef ATKBD_DEBUG
+	printk(KERN_DEBUG "atkbd.c: Received %02x flags %02x\n", data, flags);
+#endif
+
+	switch (code) {
+		case ATKBD_RET_ACK:
+			atkbd->ack = 1;
+			return;
+		case ATKBD_RET_NAK:
+			atkbd->ack = -1;
+			return;
+	}
+
+	if (atkbd->cmdcnt) {
+		atkbd->cmdbuf[--atkbd->cmdcnt] = code;
+		return;
+	}
+
+	atkbd->release = (code & 0x80) ? 1 : 0;
+	code &= 0x7f;
+
+	switch (atkbd->keycode[code]) {
+		case ATKBD_KEY_NULL:
+			break;
+#if 0
+		case ATKBD_KEY_UNKNOWN:
+			printk(KERN_WARNING "98kbd.c: Unknown key (set %d, scancode %#x, on %s) %s.\n",
+				atkbd->set, code, serio->phys, atkbd->release ? "released" : "pressed");
+			break;
+#endif
+		default:
+			input_report_key(&atkbd->dev, atkbd->keycode[code], !atkbd->release);
+			input_sync(&atkbd->dev);
+	}
+		
+	atkbd->release = 0;
+}
+
+/*
+ * atkbd_sendbyte() sends a byte to the keyboard, and waits for
+ * acknowledge. It doesn't handle resends according to the keyboard
+ * protocol specs, because if these are needed, the keyboard needs
+ * replacement anyway, and they only make a mess in the protocol.
+ */
+
+static int atkbd_sendbyte(struct atkbd *atkbd, unsigned char byte)
+{
+	int timeout = 10000; /* 100 msec */
+	atkbd->ack = 0;
+
+#ifdef ATKBD_DEBUG
+	printk(KERN_DEBUG "atkbd.c: Sent: %02x\n", byte);
+#endif
+	if (serio_write(atkbd->serio, byte))
+		return -1;
+
+	while (!atkbd->ack && timeout--) udelay(10);
+
+	return -(atkbd->ack <= 0);
+}
+
+/*
+ * atkbd_command() sends a command, and its parameters to the keyboard,
+ * then waits for the response and puts it in the param array.
+ */
+
+static int atkbd_command(struct atkbd *atkbd, unsigned char *param, int command)
+{
+	int timeout = 50000; /* 500 msec */
+	int send = (command >> 12) & 0xf;
+	int receive = (command >> 8) & 0xf;
+	int i;
+
+	atkbd->cmdcnt = receive;
+	
+	if (command & 0xff)
+		if (atkbd_sendbyte(atkbd, command & 0xff))
+			return (atkbd->cmdcnt = 0) - 1;
+
+	for (i = 0; i < send; i++)
+		if (atkbd_sendbyte(atkbd, param[i]))
+			return (atkbd->cmdcnt = 0) - 1;
+
+	while (atkbd->cmdcnt && timeout--) udelay(10);
+
+	if (param)
+		for (i = 0; i < receive; i++)
+			param[i] = atkbd->cmdbuf[(receive - 1) - i];
+
+	if (atkbd->cmdcnt) 
+		return (atkbd->cmdcnt = 0) - 1;
+
+	return 0;
+}
+
+/*
+ * Event callback from the input module. Events that change the state of
+ * the hardware are processed here.
+ */
+
+static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+{
+	struct atkbd *atkbd = dev->private;
+	char param[2];
+
+	if (!atkbd->write)
+		return -1;
+
+	switch (type) {
+
+		case EV_LED:
+
+			if (__PC9800SCA_TEST_BIT(0x481, 3)) {
+				/* 98note with Num Lock key */
+				/* keep Num Lock status     */
+				*param = 0x60;
+				if (atkbd_command(atkbd, param,
+							ATKBD_CMD_GETLEDS))
+					printk(KERN_DEBUG
+						"atkbd: Get keyboard LED"
+						" status Error\n");
+
+				*param &= 1;
+			} else {
+				/* desktop PC-9801 */
+				*param = 1;	/* Allways set Num Lock */
+			}
+
+			*param |= 0x70
+			       | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0)
+			       | (test_bit(LED_KANA,    dev->led) ? 8 : 0);
+		        atkbd_command(atkbd, param, ATKBD_CMD_SETLEDS);
+
+			return 0;
+	}
+
+	return -1;
+}
+
+/*
+ * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
+ * reboot.
+ */
+
+static void atkbd_cleanup(struct serio *serio)
+{
+}
+
+/*
+ * atkbd_disconnect() closes and frees.
+ */
+
+static void atkbd_disconnect(struct serio *serio)
+{
+	struct atkbd *atkbd = serio->private;
+	input_unregister_device(&atkbd->dev);
+	serio_close(serio);
+	kfree(atkbd);
+}
+
+/*
+ * atkbd_connect() is called when the serio module finds and interface
+ * that isn't handled yet by an appropriate device driver. We check if
+ * there is an AT keyboard out there and if yes, we register ourselves
+ * to the input module.
+ */
+
+static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
+{
+	struct atkbd *atkbd;
+	int i;
+
+	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
+		(((serio->type & SERIO_TYPE) != SERIO_RS232) || (serio->type & SERIO_PROTO) != SERIO_PS2SER))
+		        return;
+
+	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
+		return;
+
+	memset(atkbd, 0, sizeof(struct atkbd));
+
+	if ((serio->type & SERIO_TYPE) == SERIO_8042 && serio->write)
+		atkbd->write = 1;
+
+	if (atkbd->write) {
+		atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_KANA);
+	} else  atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+
+	atkbd->serio = serio;
+
+	init_input_dev(&atkbd->dev);
+
+	atkbd->dev.keycode = atkbd->keycode;
+	atkbd->dev.keycodesize = sizeof(unsigned char);
+	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+	atkbd->dev.event = atkbd_event;
+	atkbd->dev.private = atkbd;
+
+	serio->private = atkbd;
+
+	if (serio_open(serio, dev)) {
+		kfree(atkbd);
+		return;
+	}
+
+	atkbd->set = 2;
+	atkbd->id = 0x9800;
+	sprintf(atkbd->name, "NEC PC-9801 keyboard");
+
+	sprintf(atkbd->phys, "%s/input0", serio->phys);
+
+	memcpy(atkbd->keycode, atkbd_set2_keycode, sizeof(atkbd->keycode));
+
+	atkbd->dev.name = atkbd->name;
+	atkbd->dev.phys = atkbd->phys;
+	atkbd->dev.id.bustype = BUS_I8042;
+	atkbd->dev.id.vendor = 0x0001;
+	atkbd->dev.id.product = atkbd->set;
+	atkbd->dev.id.version = atkbd->id;
+
+	for (i = 0; i < 512; i++)
+#if 0
+		if (atkbd->keycode[i] && atkbd->keycode[i] <= 250)
+#else
+		if (atkbd->keycode[i] <= 250)
+#endif
+			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+
+	input_register_device(&atkbd->dev);
+
+	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
+}
+
+
+static struct serio_dev atkbd_dev = {
+	.interrupt =	atkbd_interrupt,
+	.connect =	atkbd_connect,
+	.disconnect =	atkbd_disconnect,
+	.cleanup =	atkbd_cleanup,
+};
+
+int __init pc98kbd_init(void)
+{
+	serio_register_device(&atkbd_dev);
+	return 0;
+}
+
+void __exit pc98kbd_exit(void)
+{
+	serio_unregister_device(&atkbd_dev);
+}
+
+module_init(pc98kbd_init);
+module_exit(pc98kbd_exit);
diff -urN linux/drivers/input/misc/pcspkr.c linux98/drivers/input/misc/pcspkr.c
--- linux/drivers/input/misc/pcspkr.c	Mon Sep 16 11:18:31 2002
+++ linux98/drivers/input/misc/pcspkr.c	Mon Sep 16 16:04:05 2002
@@ -12,6 +12,7 @@
  * the Free Software Foundation
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -23,7 +24,11 @@
 MODULE_LICENSE("GPL");
 
 static char pcspkr_name[] = "PC Speaker";
+#ifndef CONFIG_PC9800
 static char pcspkr_phys[] = "isa0061/input0";
+#else
+static char pcspkr_phys[] = "isa3fdb/input0";
+#endif
 static struct input_dev pcspkr_dev;
 
 spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED;
@@ -43,11 +48,16 @@
 	} 
 
 	if (value > 20 && value < 32767)
+#ifndef CONFIG_PC9800
 		count = 1193182 / value;
+#else
+		count = CLOCK_TICK_RATE / value;
+#endif
 	
 	spin_lock_irqsave(&i8253_beep_lock, flags);
 
 	if (count) {
+#ifndef CONFIG_PC9800
 		/* enable counter 2 */
 		outb_p(inb_p(0x61) | 3, 0x61);
 		/* set command for counter 2, 2 byte write */
@@ -55,9 +65,23 @@
 		/* select desired HZ */
 		outb_p(count & 0xff, 0x42);
 		outb((count >> 8) & 0xff, 0x42);
+#else /* CONFIG_PC9800 */
+		outb(0x76, 0x3fdf);
+		outb(0, 0x5f);
+		outb(count & 0xff, 0x3fdb);
+		outb(0, 0x5f);
+		outb((count >> 8) & 0xff, 0x3fdb);
+		/* beep on */
+		outb(6, 0x37);
+#endif /* !CONFIG_PC9800 */
 	} else {
 		/* disable counter 2 */
+#ifndef CONFIG_PC9800
 		outb(inb_p(0x61) & 0xFC, 0x61);
+#else
+		/* beep off */
+		outb(7, 0x37);
+#endif
 	}
 
 	spin_unlock_irqrestore(&i8253_beep_lock, flags);
diff -urN linux/drivers/input/mouse/Config.in linux98/drivers/input/mouse/Config.in
--- linux/drivers/input/mouse/Config.in	Wed Jul 17 08:49:29 2002
+++ linux98/drivers/input/mouse/Config.in	Fri Jul 19 14:52:11 2002
@@ -7,6 +7,12 @@
 dep_tristate '  PS/2 mouse' CONFIG_MOUSE_PS2 $CONFIG_INPUT $CONFIG_INPUT_MOUSE $CONFIG_SERIO
 dep_tristate '  Serial mouse' CONFIG_MOUSE_SERIAL $CONFIG_INPUT $CONFIG_INPUT_MOUSE $CONFIG_SERIO
 
+if [ "$CONFIG_PC9800" = "y" ]; then
+   dep_tristate '  NEC PC-9801 busmouse' CONFIG_MOUSE_LOGIBM $CONFIG_INPUT $CONFIG_INPUT_MOUSE $CONFIG_ISA
+   if [ "$CONFIG_MOUSE_LOGIBM" != "n" ]; then
+      define_bool CONFIG_LOGIBUSMOUSE_PC9800 y
+   fi
+else
 dep_tristate '  InPort/MS/ATIXL busmouse' CONFIG_MOUSE_INPORT $CONFIG_INPUT $CONFIG_INPUT_MOUSE $CONFIG_ISA
 if [ "$CONFIG_MOUSE_INPORT" != "n" ]; then
    bool '  ATI XL variant' CONFIG_MOUSE_ATIXL
@@ -22,3 +28,4 @@
 if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
    dep_tristate '  Acorn RiscPC mouse' CONFIG_MOUSE_ACORN $CONFIG_INPUT $CONFIG_INPUT_MOUSE
 fi
+fi
diff -urN linux/drivers/input/mouse/logibm.c linux98/drivers/input/mouse/logibm.c
--- linux/drivers/input/mouse/logibm.c	Sat Oct 12 13:22:08 2002
+++ linux98/drivers/input/mouse/logibm.c	Sat Oct 12 17:40:15 2002
@@ -38,6 +38,7 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
@@ -48,6 +49,7 @@
 MODULE_DESCRIPTION("Logitech busmouse driver");
 MODULE_LICENSE("GPL");
 
+#ifndef CONFIG_LOGIBUSMOUSE_PC9800
 #define	LOGIBM_BASE		0x23c
 #define	LOGIBM_EXTENT		4
 
@@ -55,6 +57,15 @@
 #define	LOGIBM_SIGNATURE_PORT	LOGIBM_BASE + 1
 #define	LOGIBM_CONTROL_PORT	LOGIBM_BASE + 2
 #define	LOGIBM_CONFIG_PORT	LOGIBM_BASE + 3
+#else /* CONFIG_LOGIBUSMOUSE_PC9800 */
+#define	LOGIBM_BASE		0x7fd9
+#define	LOGIBM_DATA_PORT	LOGIBM_BASE + 0
+/*	LOGIBM_SIGNATURE_PORT	does not exist */
+#define	LOGIBM_CONTROL_PORT	LOGIBM_BASE + 4
+/*	LOGIBM_INTERRUPT_PORT	does not exist */
+#define	LOGIBM_CONFIG_PORT	LOGIBM_BASE + 6
+#define	LOGIBM_EXTENT		(-7)
+#endif /* !CONFIG_LOGIBUSMOUSE_PC9800 */
 
 #define	LOGIBM_ENABLE_IRQ	0x00
 #define	LOGIBM_DISABLE_IRQ	0x10
@@ -63,11 +74,24 @@
 #define	LOGIBM_READ_Y_LOW	0xc0
 #define	LOGIBM_READ_Y_HIGH	0xe0
 
+#ifndef CONFIG_LOGIBUSMOUSE_PC9800
 #define LOGIBM_DEFAULT_MODE	0x90
 #define LOGIBM_CONFIG_BYTE	0x91
 #define LOGIBM_SIGNATURE_BYTE	0xa5
+#else /* CONFIG_LOGIBUSMOUSE_PC9800 */
+#define LOGIBM_DEFAULT_MODE	0x93
+/*	LOGIBM_CONFIG_BYTE	is not used */
+/*	LOGIBM_SIGNATURE_BYTE	is not used */
+
+#define LOGIBM_TIMER_PORT	0xbfdb
+#define LOGIBM_DEFAULT_TIMER_VAL	0x00
+#endif /* !CONFIG_LOGIBUSMOUSE_PC9800 */
 
+#ifndef CONFIG_LOGIBUSMOUSE_PC9800
 #define LOGIBM_IRQ		5
+#else
+#define LOGIBM_IRQ		13
+#endif
 
 MODULE_PARM(logibm_irq, "i");
 
@@ -104,7 +128,11 @@
 	.open	= logibm_open,
 	.close	= logibm_close,
 	.name	= "Logitech bus mouse",
+#ifndef CONFIG_LOGIBUSMOUSE_PC9800
 	.phys	= "isa023c/input0",
+#else
+	.phys	= "isa7fd9/input0",
+#endif
 	.id	= {
 		.bustype = BUS_ISA,
 		.vendor  = 0x0003,
@@ -157,6 +185,18 @@
 		return -EBUSY;
 	}
 
+#ifdef CONFIG_LOGIBUSMOUSE_PC9800
+	if (!request_region(LOGIBM_TIMER_PORT, 1, "logibm")) {
+		printk(KERN_ERR "logibm.c: Can't allocate ports at %#x\n", LOGIBM_TIMER_PORT);
+		return -EBUSY;
+	}
+#endif
+
+#ifndef CONFIG_LOGIBUSMOUSE_PC9800
+	/* For PC-9800,  necessary I/O ports are already reserved by
+	   arch/i386/kernel/setup.c since mouse interface ALWAYS
+	   exist on PC-9800.  */
+
 	outb(LOGIBM_CONFIG_BYTE, LOGIBM_CONFIG_PORT);
 	outb(LOGIBM_SIGNATURE_BYTE, LOGIBM_SIGNATURE_PORT);
 	udelay(100);
@@ -166,10 +206,15 @@
 		printk(KERN_ERR "logibm.c: Didn't find Logitech busmouse at %#x\n", LOGIBM_BASE);
 		return -ENODEV;
 	}
+#endif /* CONFIG_LOGIBUSMOUSE_PC9800 */
 
 	outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT);
 	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
 
+#ifdef CONFIG_LOGIBUSMOUSE_PC9800
+	outb(LOGIBM_DEFAULT_TIMER_VAL, LOGIBM_TIMER_PORT);
+#endif
+
 	input_register_device(&logibm_dev);
 	
 	printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
@@ -181,6 +226,9 @@
 {
 	input_unregister_device(&logibm_dev);
 	release_region(LOGIBM_BASE, LOGIBM_EXTENT);
+#ifdef CONFIG_LOGIBUSMOUSE_PC9800
+	release_region(LOGIBM_TIMER_PORT, 1);
+#endif
 }
 
 module_init(logibm_init);
diff -urN linux/drivers/input/serio/Config.in linux98/drivers/input/serio/Config.in
--- linux/drivers/input/serio/Config.in	Sat Oct 12 13:22:11 2002
+++ linux98/drivers/input/serio/Config.in	Sun Oct 13 12:59:05 2002
@@ -21,3 +21,6 @@
 if [ "$CONFIG_SA1111" = "y" ]; then
    dep_tristate '  Intel SA1111 keyboard controller' CONFIG_SERIO_SA1111 $CONFIG_SERIO
 fi
+if [ "$CONFIG_PC9800" = "y" ]; then
+   dep_tristate '  NEC PC-9801 keyboard controller' CONFIG_SERIO_98KBD $CONFIG_SERIO
+fi
diff -urN linux/drivers/input/serio/Makefile linux98/drivers/input/serio/Makefile
--- linux/drivers/input/serio/Makefile	Sat Oct 12 13:21:30 2002
+++ linux98/drivers/input/serio/Makefile	Sun Oct 13 12:59:59 2002
@@ -17,6 +17,7 @@
 obj-$(CONFIG_SERIO_SA1111)	+= sa1111ps2.o
 obj-$(CONFIG_SERIO_AMBAKMI)	+= ambakmi.o
 obj-$(CONFIG_SERIO_Q40KBD)	+= q40kbd.o
+obj-$(CONFIG_SERIO_98KBD)	+= i8042-98.o
 
 # The global Rules.make.
 
diff -urN linux/drivers/input/serio/i8042-98.c linux98/drivers/input/serio/i8042-98.c
--- linux/drivers/input/serio/i8042-98.c	Thu Jan  1 09:00:00 1970
+++ linux98/drivers/input/serio/i8042-98.c	Thu Oct 17 16:54:05 2002
@@ -0,0 +1,346 @@
+/*
+ *  NEC PC-9801 keyboard controller driver for Linux
+ *
+ *  Copyright (c) 1999-2002 Vojtech Pavlik
+ *  Modify for NEC PC-9801 by Osamu Tomita <tomita@cinet.co.jp>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <asm/io.h>
+
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/sched.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("NEC PC-9801 keyboard controller driver");
+MODULE_LICENSE("GPL");
+
+#undef DEBUG
+#include "i8042.h"
+
+spinlock_t i8042_lock = SPIN_LOCK_UNLOCKED;
+
+struct i8042_values {
+	int irq;
+	unsigned char disable;
+	unsigned char irqen;
+	unsigned char exists;
+	signed char mux;
+	unsigned char *name;
+	unsigned char *phys;
+};
+
+static struct serio i8042_kbd_port;
+static unsigned char i8042_initial_ctr;
+static unsigned char i8042_ctr;
+
+extern struct pt_regs *kbd_pt_regs;
+
+static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * The i8042_wait_read() and i8042_wait_write functions wait for the i8042 to
+ * be ready for reading values from it / writing values to it.
+ */
+
+#if 0
+static int i8042_wait_read(void)
+{
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	return 0;
+}
+#endif
+
+static int i8042_wait_write(void)
+{
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	outb_p(0x00, 0x5f);
+	return 0;
+}
+
+/*
+ * i8042_flush() flushes all data that may be in the keyboard and mouse buffers
+ * of the i8042 down the toilet.
+ */
+
+static int i8042_flush(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	while (i8042_read_status() & 0x02) /* RxRDY */
+		i8042_read_data();
+
+	if (i8042_read_status() & 0x38)
+		printk("i8042-98: Keyboard error!\n");
+
+	spin_unlock_irqrestore(&i8042_lock, flags);
+
+	return 0;
+}
+
+/*
+ * i8042_kbd_write() sends a byte out through the keyboard interface.
+ */
+
+static int i8042_kbd_write(struct serio *port, unsigned char c)
+{
+	unsigned long flags;
+	int retval = 0;
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	if(!(retval = i8042_wait_write())) {
+		dbg("%02x -> i8042-98 (kbd-data)", c);
+		i8042_write_data(c);
+	}
+
+	spin_unlock_irqrestore(&i8042_lock, flags);
+
+	return retval;
+}
+
+/*
+ * i8042_open() is called when a port is open by the higher layer.
+ * It allocates the interrupt and enables in in the chip.
+ */
+
+static int i8042_open(struct serio *port)
+{
+	struct i8042_values *values = port->driver;
+
+	i8042_flush();
+
+	if (request_irq(values->irq, i8042_interrupt, 0, "i8042-98", NULL)) {
+		printk(KERN_ERR "i8042-98.c: Can't get irq %d for %s, unregistering the port.\n", values->irq, values->name);
+		values->exists = 0;
+		serio_unregister_port(port);
+		return -1;
+	}
+
+	i8042_ctr |= values->irqen;
+
+	return 0;
+}
+
+/*
+ * i8042_close() frees the interrupt, so that it can possibly be used
+ * by another driver. We never know - if the user doesn't have a mouse,
+ * the BIOS could have used the AUX interupt for PCI.
+ */
+
+static void i8042_close(struct serio *port)
+{
+	struct i8042_values *values = port->driver;
+
+	i8042_ctr &= ~values->irqen;
+
+	free_irq(values->irq, NULL);
+
+	i8042_flush();
+}
+
+/*
+ * Structures for registering the devices in the serio.c module.
+ */
+
+static struct i8042_values i8042_kbd_values = {
+	.irqen =	I8042_CTR_KBDINT,
+	.disable =	I8042_CTR_KBDDIS,
+	.name =		"KBD",
+	.mux =		-1,
+};
+
+static struct serio i8042_kbd_port =
+{
+	.type =		SERIO_8042,
+	.write =	i8042_kbd_write,
+	.open =		i8042_open,
+	.close =	i8042_close,
+	.driver =	&i8042_kbd_values,
+	.name =		"PC-9801 Kbd Port",
+	.phys =		I8042_KBD_PHYS_DESC,
+};
+
+/*
+ * i8042_interrupt() is the most important function in this driver -
+ * it handles the interrupts from the i8042, and sends incoming bytes
+ * to the upper layers.
+ */
+
+static void i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned char data;
+
+#ifdef CONFIG_VT
+	kbd_pt_regs = regs;
+#endif
+
+	spin_lock_irqsave(&i8042_lock, flags);
+
+	data = i8042_read_data();
+	spin_unlock_irqrestore(&i8042_lock, flags);
+	serio_interrupt(&i8042_kbd_port, data, 0);
+
+}
+
+/*
+ * i8042_controller init initializes the i8042 controller, and,
+ * most importantly, sets it into non-xlated mode if that's
+ * desired.
+ */
+	
+static int __init i8042_controller_init(void)
+{
+
+/*
+ * Test the i8042. We need to know if it thinks it's working correctly
+ * before doing anything else.
+ */
+
+	i8042_flush();
+
+	i8042_initial_ctr = i8042_ctr;
+
+/*
+ * Disable the keyboard interface and interrupt. 
+ */
+
+	i8042_ctr |= I8042_CTR_KBDDIS;
+	i8042_ctr &= ~I8042_CTR_KBDINT;
+
+/*
+ * Set nontranslated mode for the kbd interface if requested by an option.
+ * After this the kbd interface becomes a simple serial in/out, like the aux
+ * interface is. We don't do this by default, since it can confuse notebook
+ * BIOSes.
+ */
+
+	i8042_ctr &= ~I8042_CTR_XLATE;	/* i8042_direct = 1; */
+
+	return 0;
+}
+
+/*
+ * Here we try to reset everything back to a state in which the BIOS will be
+ * able to talk to the hardware when rebooting.
+ */
+
+void i8042_controller_cleanup(void)
+{
+	i8042_flush();
+
+/*
+ * Reset anything that is connected to the ports.
+ */
+
+	if (i8042_kbd_values.exists)
+		serio_cleanup(&i8042_kbd_port);
+
+/*
+ * Restore the original control register setting.
+ */
+
+	i8042_ctr = i8042_initial_ctr;
+
+}
+
+/*
+ * i8042_port_register() marks the device as existing,
+ * registers it, and reports to the user.
+ */
+
+static int __init i8042_port_register(struct i8042_values *values, struct serio *port)
+{
+	values->exists = 1;
+
+	i8042_ctr &= ~values->disable;
+
+	serio_register_port(port);
+
+	printk(KERN_INFO "serio: i8042-98 %s port at %#lx,%#lx irq %d\n",
+	       values->name,
+	       (unsigned long) I8042_DATA_REG,
+	       (unsigned long) I8042_COMMAND_REG,
+	       values->irq);
+
+	return 0;
+}
+
+/*
+ * We need to reset the 8042 back to original mode on system shutdown,
+ * because otherwise BIOSes will be confused.
+ */
+
+static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
+        		    void *unused)
+{
+        if (code==SYS_DOWN || code==SYS_HALT) 
+        	i8042_controller_cleanup();
+        return NOTIFY_DONE;
+}
+
+static struct notifier_block i8042_notifier=
+{
+        i8042_notify_sys,
+        NULL,
+        0
+};
+
+int __init i8042_98init(void)
+{
+	dbg_init();
+
+	if (i8042_platform_init())
+		return -EBUSY;
+
+	i8042_kbd_values.irq = I8042_KBD_IRQ;
+
+	if (i8042_controller_init())
+		return -ENODEV;
+
+	i8042_port_register(&i8042_kbd_values, &i8042_kbd_port);
+
+	register_reboot_notifier(&i8042_notifier);
+
+	return 0;
+}
+
+void __exit i8042_98exit(void)
+{
+	unregister_reboot_notifier(&i8042_notifier);
+
+	i8042_controller_cleanup();
+	
+	if (i8042_kbd_values.exists)
+		serio_unregister_port(&i8042_kbd_port);
+
+	i8042_platform_exit();
+}
+
+module_init(i8042_98init);
+module_exit(i8042_98exit);
diff -urN linux/drivers/input/serio/i8042-98io.h linux98/drivers/input/serio/i8042-98io.h
--- linux/drivers/input/serio/i8042-98io.h	Thu Jan  1 09:00:00 1970
+++ linux98/drivers/input/serio/i8042-98io.h	Sun Oct 13 13:21:58 2002
@@ -0,0 +1,74 @@
+#ifndef _I8042_IO_H
+#define _I8042_IO_H
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by 
+ * the Free Software Foundation.
+ */
+
+/*
+ * Names.
+ */
+
+#define I8042_KBD_PHYS_DESC "isa0041/serio0"
+#define I8042_AUX_PHYS_DESC "isa0041/serio1"
+#define I8042_MUX_PHYS_DESC "isa0041/serio%d"
+
+/*
+ * IRQs.
+ */
+
+#define I8042_KBD_IRQ	1
+#define I8042_AUX_IRQ	0	/* nothing */
+
+/*
+ * Register numbers.
+ */
+
+#define I8042_COMMAND_REG	0x43	
+#define I8042_STATUS_REG	0x43	
+#define I8042_DATA_REG		0x41
+
+static inline int i8042_read_data(void)
+{
+	return inb(I8042_DATA_REG);
+}
+
+static inline int i8042_read_status(void)
+{
+	return inb(I8042_STATUS_REG);
+}
+
+static inline void i8042_write_data(int val)
+{
+	outb(0, 0x5f);			/* wait */
+	outb(0x17, I8042_COMMAND_REG);	/* enable send command */
+	outb(0, 0x5f);			/* wait */
+	outb(val, I8042_DATA_REG);
+	outb(0, 0x5f);			/* wait */
+	outb(0x16, I8042_COMMAND_REG);	/* disable send command */
+	outb(0, 0x5f);			/* wait */
+	return;
+}
+
+static inline void i8042_write_command(int val)
+{
+	outb(val, I8042_COMMAND_REG);
+	return;
+}
+
+static inline int i8042_platform_init(void)
+{
+/*
+ * On ix86 platforms touching the i8042 data register region can do really
+ * bad things. Because of this the region is always reserved on ix86 boxes.
+ */
+	return 0;
+}
+
+static inline void i8042_platform_exit(void)
+{
+}
+
+#endif /* _I8042_IO_H */
diff -urN linux/drivers/input/serio/i8042.h linux98/drivers/input/serio/i8042.h
--- linux/drivers/input/serio/i8042.h	Sat Oct 12 13:22:17 2002
+++ linux98/drivers/input/serio/i8042.h	Sun Oct 13 13:30:09 2002
@@ -17,6 +17,8 @@
 #include "i8042-ppcio.h"
 #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
 #include "i8042-sparcio.h"
+#elif defined(CONFIG_PC9800)
+#include "i8042-98io.h"
 #else
 #include "i8042-io.h"
 #endif
diff -urN linux/include/linux/input.h linux98/include/linux/input.h
--- linux/include/linux/input.h	Sat Oct 12 13:22:06 2002
+++ linux98/include/linux/input.h	Sat Oct 12 14:18:54 2002
@@ -9,6 +9,7 @@
  * the Free Software Foundation.
  */
 
+#include <linux/config.h>
 #ifdef __KERNEL__
 #include <linux/time.h>
 #include <linux/list.h>
@@ -134,7 +135,11 @@
 #define KEY_LEFTBRACE		26
 #define KEY_RIGHTBRACE		27
 #define KEY_ENTER		28
+#ifndef CONFIG_PC9800
 #define KEY_LEFTCTRL		29
+#else
+#define KEY_LEFTCTRL		116
+#endif
 #define KEY_A			30
 #define KEY_S			31
 #define KEY_D			32
@@ -147,7 +152,11 @@
 #define KEY_SEMICOLON		39
 #define KEY_APOSTROPHE		40
 #define KEY_GRAVE		41
+#ifndef CONFIG_PC9800
 #define KEY_LEFTSHIFT		42
+#else
+#define KEY_LEFTSHIFT		112
+#endif
 #define KEY_BACKSLASH		43
 #define KEY_Z			44
 #define KEY_X			45
@@ -161,9 +170,17 @@
 #define KEY_SLASH		53
 #define KEY_RIGHTSHIFT		54
 #define KEY_KPASTERISK		55
+#ifndef CONFIG_PC9800
 #define KEY_LEFTALT		56
+#else
+#define KEY_LEFTALT		115
+#endif
 #define KEY_SPACE		57
+#ifndef CONFIG_PC9800
 #define KEY_CAPSLOCK		58
+#else
+#define KEY_CAPSLOCK		113
+#endif
 #define KEY_F1			59
 #define KEY_F2			60
 #define KEY_F3			61
@@ -204,7 +221,11 @@
 #define KEY_KPENTER		96
 #define KEY_RIGHTCTRL		97
 #define KEY_KPSLASH		98
+#ifndef CONFIG_PC9800
 #define KEY_SYSRQ		99
+#else
+#define KEY_SYSRQ		96
+#endif
 #define KEY_RIGHTALT		100
 #define KEY_LINEFEED		101
 #define KEY_HOME		102

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH][RFC] add support for PC-9800 architecture (11/26) input
  2002-10-17 11:40 [PATCH][RFC] add support for PC-9800 architecture (11/26) input Osamu Tomita
@ 2002-10-22 10:29 ` Vojtech Pavlik
  0 siblings, 0 replies; 2+ messages in thread
From: Vojtech Pavlik @ 2002-10-22 10:29 UTC (permalink / raw)
  To: Osamu Tomita; +Cc: LKML, Linus Torvalds

On Thu, Oct 17, 2002 at 08:40:02PM +0900, Osamu Tomita wrote:
> This is part 11/26 of patchset for add support NEC PC-9800 architecture,
> against 2.5.43.
> 
> Summary:
>  input modules
>   - add new driver for PC-9800 standard keyboard and mouse.

Before I'll think of merging this, it has to be seriously cleaned up.
Comments below.

(Summary: use your own SERIO_TYPE for the PC-98 keyboard, remove dead
code and definitions, fix naming, make as little #ifdefs as possible,
and maybe you can put the PC-98 keyboard code into xtkbd.c (in which
case you may get away with SERIO_XT).

>  input.h changes are temporally hack.
>  I'll remove this hack using propery keycode.
>  To do this, I need "kbd" utility that can make keymap even if keycode > 127.

Fix the 'kbd' package first, then. No way I'm going to merge the patches
to input.h.

> +static unsigned char atkbd_set2_keycode[512] = {
> +	  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 43, 14, 15,
> +	 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32,
> +	 33, 34, 35, 36, 37, 38, 39, 40, 84, 44, 45, 46, 47, 48, 49, 50,
> +	 51, 52, 53,181, 57,184,109,104,110,111,103,105,106,108,102,107,
> +	 74, 98, 71, 72, 73, 55, 75, 76, 77, 78, 79, 80, 81,117, 82,124,
> +	 83,185, 87, 88, 85, 89, 90,  0,  0,  0,  0,  0,  0,  0,102,  0,
> +	 99,133, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,  0,  0,  0,  0,
> +	 42, 58,190, 56, 29

This either is AT keyboard set2 keycode table or it is not. And looking
at the numbers, it obviously is not. It might be something like set1 ...?
So, call it the right name then!

Same applies for all the other identifiers - if it is not AT keyboard,
don't call it ATKBD.

You may as well be able to extend xtkbd.c instead for your use - it's
much more similar to the PC-98 keyboard than atkbd.c.

> +#define ATKBD_KEY_UNKNOWN	  0
> +#define ATKBD_KEY_BAT		251
> +#define ATKBD_KEY_EMUL0		252
> +#define ATKBD_KEY_EMUL1		253
> +#define ATKBD_KEY_RELEASE	254
> +#define ATKBD_KEY_NULL		255

Where are you using these?

> +/*
> + * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a
> + * reboot.
> + */
> +
> +static void atkbd_cleanup(struct serio *serio)
> +{
> +}

Why do you define the function at all?

> +/*
> + * atkbd_connect() is called when the serio module finds and interface
> + * that isn't handled yet by an appropriate device driver. We check if
> + * there is an AT keyboard out there and if yes, we register ourselves
> + * to the input module.
> + */
> +
> +static void atkbd_connect(struct serio *serio, struct serio_dev *dev)
> +{
> +	struct atkbd *atkbd;
> +	int i;
> +
> +	if ((serio->type & SERIO_TYPE) != SERIO_8042 &&
> +		(((serio->type & SERIO_TYPE) != SERIO_RS232) || (serio->type & SERIO_PROTO) != SERIO_PS2SER))
> +		        return;

Gee, this just doesn't make sense at all here!

> diff -urN linux/drivers/input/mouse/logibm.c linux98/drivers/input/mouse/logibm.c
> --- linux/drivers/input/mouse/logibm.c	Sat Oct 12 13:22:08 2002
> +++ linux98/drivers/input/mouse/logibm.c	Sat Oct 12 17:40:15 2002
> @@ -38,6 +38,7 @@
>  #include <asm/io.h>
>  #include <asm/irq.h>
>  
> +#include <linux/config.h>
>  #include <linux/module.h>
>  #include <linux/delay.h>
>  #include <linux/ioport.h>
> @@ -48,6 +49,7 @@
>  MODULE_DESCRIPTION("Logitech busmouse driver");
>  MODULE_LICENSE("GPL");
>  
> +#ifndef CONFIG_LOGIBUSMOUSE_PC9800
>  #define	LOGIBM_BASE		0x23c
>  #define	LOGIBM_EXTENT		4
>  
> @@ -55,6 +57,15 @@
>  #define	LOGIBM_SIGNATURE_PORT	LOGIBM_BASE + 1
>  #define	LOGIBM_CONTROL_PORT	LOGIBM_BASE + 2
>  #define	LOGIBM_CONFIG_PORT	LOGIBM_BASE + 3
> +#else /* CONFIG_LOGIBUSMOUSE_PC9800 */
> +#define	LOGIBM_BASE		0x7fd9
> +#define	LOGIBM_DATA_PORT	LOGIBM_BASE + 0
> +/*	LOGIBM_SIGNATURE_PORT	does not exist */
> +#define	LOGIBM_CONTROL_PORT	LOGIBM_BASE + 4
> +/*	LOGIBM_INTERRUPT_PORT	does not exist */
> +#define	LOGIBM_CONFIG_PORT	LOGIBM_BASE + 6
> +#define	LOGIBM_EXTENT		(-7)
> +#endif /* !CONFIG_LOGIBUSMOUSE_PC9800 */

Same comments as Russell had for the serial driver.

> diff -urN linux/drivers/input/serio/i8042-98.c linux98/drivers/input/serio/i8042-98.c
> --- linux/drivers/input/serio/i8042-98.c	Thu Jan  1 09:00:00 1970
> +++ linux98/drivers/input/serio/i8042-98.c	Thu Oct 17 16:54:05 2002
> @@ -0,0 +1,346 @@
> +/*
> + *  NEC PC-9801 keyboard controller driver for Linux
> + *
> + *  Copyright (c) 1999-2002 Vojtech Pavlik
> + *  Modify for NEC PC-9801 by Osamu Tomita <tomita@cinet.co.jp>
> + */
> +
> +struct i8042_values {
> +	int irq;
> +	unsigned char disable;
> +	unsigned char irqen;
> +	unsigned char exists;
> +	signed char mux;
> +	unsigned char *name;
> +	unsigned char *phys;
> +};

Don't call it i8042, when it ain't no i8042 ... again. 

> +static int i8042_wait_write(void)
> +{
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	outb_p(0x00, 0x5f);
> +	return 0;
> +}

This doesn't look very good, either.

> +static int __init i8042_controller_init(void)
> +{
> +
> +/*
> + * Test the i8042. We need to know if it thinks it's working correctly
> + * before doing anything else.
> + */
> +
> +	i8042_flush();
> +
> +	i8042_initial_ctr = i8042_ctr;

This is completely useless.

> +
> +/*
> + * Disable the keyboard interface and interrupt. 
> + */
> +
> +	i8042_ctr |= I8042_CTR_KBDDIS;
> +	i8042_ctr &= ~I8042_CTR_KBDINT;
> +
> +/*
> + * Set nontranslated mode for the kbd interface if requested by an option.
> + * After this the kbd interface becomes a simple serial in/out, like the aux
> + * interface is. We don't do this by default, since it can confuse notebook
> + * BIOSes.
> + */
> +
> +	i8042_ctr &= ~I8042_CTR_XLATE;	/* i8042_direct = 1; */

As is all this, when you don't ever set the CTR ... ?
I assume the chip doesn't have a CTR at all?

> + * Here we try to reset everything back to a state in which the BIOS will be
> + * able to talk to the hardware when rebooting.
> + */
> +
> +void i8042_controller_cleanup(void)
> +{
> +	i8042_flush();
> +
> +/*
> + * Reset anything that is connected to the ports.
> + */
> +
> +	if (i8042_kbd_values.exists)
> +		serio_cleanup(&i8042_kbd_port);

Why?

> +/*
> + * Restore the original control register setting.
> + */
> +
> +	i8042_ctr = i8042_initial_ctr;
> +
> +}

Oh, my.

> +static int i8042_notify_sys(struct notifier_block *this, unsigned long code,
> +        		    void *unused)
> +{
> +        if (code==SYS_DOWN || code==SYS_HALT) 
> +        	i8042_controller_cleanup();
> +        return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block i8042_notifier=
> +{
> +        i8042_notify_sys,
> +        NULL,
> +        0
> +};

Again, completely unnecessary.


> +	if (i8042_platform_init())
> +		return -EBUSY;

platform_init ... ?!?!? You expect this to run on something else than a pc-98?

> diff -urN linux/drivers/input/serio/i8042-98io.h linux98/drivers/input/serio/i8042-98io.h
> --- linux/drivers/input/serio/i8042-98io.h	Thu Jan  1 09:00:00 1970
> +++ linux98/drivers/input/serio/i8042-98io.h	Sun Oct 13 13:21:58 2002
> @@ -0,0 +1,74 @@
> +#ifndef _I8042_IO_H
> +#define _I8042_IO_H
> +
> +/*
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by 
> + * the Free Software Foundation.
> + */
> +
> +/*
> + * Names.
> + */
> +
> +#define I8042_KBD_PHYS_DESC "isa0041/serio0"
> +#define I8042_AUX_PHYS_DESC "isa0041/serio1"
> +#define I8042_MUX_PHYS_DESC "isa0041/serio%d"

You're not using these. Why are you defining them. Ahh, cut'n'paste ...

> +
> +/*
> + * IRQs.
> + */
> +
> +#define I8042_KBD_IRQ	1
> +#define I8042_AUX_IRQ	0	/* nothing */

Cool. We don't have an AUX port, but we keep the definitions.

> diff -urN linux/drivers/input/serio/i8042.h linux98/drivers/input/serio/i8042.h
> --- linux/drivers/input/serio/i8042.h	Sat Oct 12 13:22:17 2002
> +++ linux98/drivers/input/serio/i8042.h	Sun Oct 13 13:30:09 2002
> @@ -17,6 +17,8 @@
>  #include "i8042-ppcio.h"
>  #elif defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
>  #include "i8042-sparcio.h"
> +#elif defined(CONFIG_PC9800)
> +#include "i8042-98io.h"
>  #else
>  #include "i8042-io.h"
>  #endif

Why are you changing i8042.h, when you don't need it at all?

> diff -urN linux/include/linux/input.h linux98/include/linux/input.h
> --- linux/include/linux/input.h	Sat Oct 12 13:22:06 2002
> +++ linux98/include/linux/input.h	Sat Oct 12 14:18:54 2002
> @@ -9,6 +9,7 @@
>   * the Free Software Foundation.
>   */
>  
> +#include <linux/config.h>
>  #ifdef __KERNEL__
>  #include <linux/time.h>
>  #include <linux/list.h>
> @@ -134,7 +135,11 @@
>  #define KEY_LEFTBRACE		26
>  #define KEY_RIGHTBRACE		27
>  #define KEY_ENTER		28
> +#ifndef CONFIG_PC9800
>  #define KEY_LEFTCTRL		29
> +#else
> +#define KEY_LEFTCTRL		116
> +#endif

No way are these ever going to change depending on the architecture.
They are defined to be constant. I don't like variable constants.

-- 
Vojtech Pavlik
SuSE Labs

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-10-22 10:23 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-17 11:40 [PATCH][RFC] add support for PC-9800 architecture (11/26) input Osamu Tomita
2002-10-22 10:29 ` Vojtech Pavlik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).