PATCH: merge PC9800 keyboard controller chip support

Alan Cox (alan@lxorguk.ukuu.org.uk)
Sat, 22 Mar 2003 23:58:04 GMT


diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.65-bk3/drivers/input/serio/98kbd-io.c linux-2.5.65-ac3/drivers/input/serio/98kbd-io.c
--- linux-2.5.65-bk3/drivers/input/serio/98kbd-io.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.5.65-ac3/drivers/input/serio/98kbd-io.c 2003-02-20 16:30:36.000000000 +0000
@@ -0,0 +1,178 @@
+/*
+ * NEC PC-9801 keyboard controller driver for Linux
+ *
+ * Copyright (c) 1999-2002 Osamu Tomita <tomita@cinet.co.jp>
+ * Based on i8042.c written by Vojtech Pavlik
+ */
+
+/*
+ * 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/config.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/serio.h>
+#include <linux/sched.h>
+
+#include <asm/io.h>
+
+MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
+MODULE_DESCRIPTION("NEC PC-9801 keyboard controller driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Names.
+ */
+
+#define KBD98_PHYS_DESC "isa0041/serio0"
+
+/*
+ * IRQs.
+ */
+
+#define KBD98_IRQ 1
+
+/*
+ * Register numbers.
+ */
+
+#define KBD98_COMMAND_REG 0x43
+#define KBD98_STATUS_REG 0x43
+#define KBD98_DATA_REG 0x41
+
+spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED;
+
+static struct serio kbd98_port;
+extern struct pt_regs *kbd_pt_regs;
+
+static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/*
+ * kbd98_flush() flushes all data that may be in the keyboard buffers
+ */
+
+static int kbd98_flush(void)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&kbd98io_lock, flags);
+
+ while (inb(KBD98_STATUS_REG) & 0x02) /* RxRDY */
+ inb(KBD98_DATA_REG);
+
+ if (inb(KBD98_STATUS_REG) & 0x38)
+ printk("98kbd-io: Keyboard error!\n");
+
+ spin_unlock_irqrestore(&kbd98io_lock, flags);
+
+ return 0;
+}
+
+/*
+ * kbd98_write() sends a byte out through the keyboard interface.
+ */
+
+static int kbd98_write(struct serio *port, unsigned char c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&kbd98io_lock, flags);
+
+ outb(0, 0x5f); /* wait */
+ outb(0x17, KBD98_COMMAND_REG); /* enable send command */
+ outb(0, 0x5f); /* wait */
+ outb(c, KBD98_DATA_REG);
+ outb(0, 0x5f); /* wait */
+ outb(0x16, KBD98_COMMAND_REG); /* disable send command */
+ outb(0, 0x5f); /* wait */
+
+ spin_unlock_irqrestore(&kbd98io_lock, flags);
+
+ return 0;
+}
+
+/*
+ * kbd98_open() is called when a port is open by the higher layer.
+ * It allocates the interrupt and enables in in the chip.
+ */
+
+static int kbd98_open(struct serio *port)
+{
+ kbd98_flush();
+
+ if (request_irq(KBD98_IRQ, kbd98io_interrupt, 0, "kbd98", NULL)) {
+ printk(KERN_ERR "98kbd-io.c: Can't get irq %d for %s, unregistering the port.\n", KBD98_IRQ, "KBD");
+ serio_unregister_port(port);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void kbd98_close(struct serio *port)
+{
+ free_irq(KBD98_IRQ, NULL);
+
+ kbd98_flush();
+}
+
+/*
+ * Structures for registering the devices in the serio.c module.
+ */
+
+static struct serio kbd98_port =
+{
+ .type = SERIO_PC9800,
+ .write = kbd98_write,
+ .open = kbd98_open,
+ .close = kbd98_close,
+ .driver = NULL,
+ .name = "PC-9801 Kbd Port",
+ .phys = KBD98_PHYS_DESC,
+};
+
+/*
+ * kbd98io_interrupt() is the most important function in this driver -
+ * it handles the interrupts from keyboard, and sends incoming bytes
+ * to the upper layers.
+ */
+
+static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+ unsigned char data;
+
+ spin_lock_irqsave(&kbd98io_lock, flags);
+
+ data = inb(KBD98_DATA_REG);
+ spin_unlock_irqrestore(&kbd98io_lock, flags);
+ serio_interrupt(&kbd98_port, data, 0, regs);
+
+}
+
+int __init kbd98io_init(void)
+{
+ serio_register_port(&kbd98_port);
+
+ printk(KERN_INFO "serio: PC-9801 %s port at %#lx,%#lx irq %d\n",
+ "KBD",
+ (unsigned long) KBD98_DATA_REG,
+ (unsigned long) KBD98_COMMAND_REG,
+ KBD98_IRQ);
+
+ return 0;
+}
+
+void __exit kbd98io_exit(void)
+{
+ serio_unregister_port(&kbd98_port);
+}
+
+module_init(kbd98io_init);
+module_exit(kbd98io_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.65-bk3/drivers/input/serio/Kconfig linux-2.5.65-ac3/drivers/input/serio/Kconfig
--- linux-2.5.65-bk3/drivers/input/serio/Kconfig 2003-03-22 19:33:54.000000000 +0000
+++ linux-2.5.65-ac3/drivers/input/serio/Kconfig 2003-02-20 16:30:53.000000000 +0000
@@ -107,3 +107,15 @@
tristate "Intel SA1111 keyboard controller"
depends on SA1111 && SERIO

+config SERIO_98KBD
+ tristate "NEC PC-9800 keyboard controller"
+ depends on X86_PC9800 && SERIO
+ help
+ Say Y here if you have the NEC PC-9801/PC-9821 and want to use its
+ standard keyboard connected to its keyboard controller.
+
+ This driver is also available as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want).
+ The module will be called rpckbd.o. If you want to compile it as a
+ module, say M here and read <file:Documentation/modules.txt>.
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.65-bk3/drivers/input/serio/Makefile linux-2.5.65-ac3/drivers/input/serio/Makefile
--- linux-2.5.65-bk3/drivers/input/serio/Makefile 2003-03-22 19:33:54.000000000 +0000
+++ linux-2.5.65-ac3/drivers/input/serio/Makefile 2003-02-14 23:20:16.000000000 +0000
@@ -13,3 +13,4 @@
obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
+obj-$(CONFIG_SERIO_98KBD) += 98kbd-io.o
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/