2 * NEC PC-9801 keyboard controller driver for Linux
4 * Copyright (c) 1999-2002 Osamu Tomita <tomita@cinet.co.jp>
5 * Based on i8042.c written by Vojtech Pavlik
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as published by
11 * the Free Software Foundation.
14 #include <linux/config.h>
15 #include <linux/delay.h>
16 #include <linux/module.h>
17 #include <linux/interrupt.h>
18 #include <linux/ioport.h>
19 #include <linux/init.h>
20 #include <linux/serio.h>
21 #include <linux/sched.h>
25 MODULE_AUTHOR("Osamu Tomita <tomita@cinet.co.jp>");
26 MODULE_DESCRIPTION("NEC PC-9801 keyboard controller driver");
27 MODULE_LICENSE("GPL");
33 #define KBD98_PHYS_DESC "isa0041/serio0"
45 #define KBD98_COMMAND_REG 0x43
46 #define KBD98_STATUS_REG 0x43
47 #define KBD98_DATA_REG 0x41
49 spinlock_t kbd98io_lock = SPIN_LOCK_UNLOCKED;
51 static struct serio kbd98_port;
52 extern struct pt_regs *kbd_pt_regs;
54 static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
57 * kbd98_flush() flushes all data that may be in the keyboard buffers
60 static int kbd98_flush(void)
64 spin_lock_irqsave(&kbd98io_lock, flags);
66 while (inb(KBD98_STATUS_REG) & 0x02) /* RxRDY */
69 if (inb(KBD98_STATUS_REG) & 0x38)
70 printk("98kbd-io: Keyboard error!\n");
72 spin_unlock_irqrestore(&kbd98io_lock, flags);
78 * kbd98_write() sends a byte out through the keyboard interface.
81 static int kbd98_write(struct serio *port, unsigned char c)
85 spin_lock_irqsave(&kbd98io_lock, flags);
87 outb(0, 0x5f); /* wait */
88 outb(0x17, KBD98_COMMAND_REG); /* enable send command */
89 outb(0, 0x5f); /* wait */
90 outb(c, KBD98_DATA_REG);
91 outb(0, 0x5f); /* wait */
92 outb(0x16, KBD98_COMMAND_REG); /* disable send command */
93 outb(0, 0x5f); /* wait */
95 spin_unlock_irqrestore(&kbd98io_lock, flags);
101 * kbd98_open() is called when a port is open by the higher layer.
102 * It allocates the interrupt and enables in in the chip.
105 static int kbd98_open(struct serio *port)
109 if (request_irq(KBD98_IRQ, kbd98io_interrupt, 0, "kbd98", NULL)) {
110 printk(KERN_ERR "98kbd-io.c: Can't get irq %d for %s, unregistering the port.\n", KBD98_IRQ, "KBD");
111 serio_unregister_port(port);
118 static void kbd98_close(struct serio *port)
120 free_irq(KBD98_IRQ, NULL);
126 * Structures for registering the devices in the serio.c module.
129 static struct serio kbd98_port =
131 .type = SERIO_PC9800,
132 .write = kbd98_write,
134 .close = kbd98_close,
136 .name = "PC-9801 Kbd Port",
137 .phys = KBD98_PHYS_DESC,
141 * kbd98io_interrupt() is the most important function in this driver -
142 * it handles the interrupts from keyboard, and sends incoming bytes
143 * to the upper layers.
146 static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
151 spin_lock_irqsave(&kbd98io_lock, flags);
153 data = inb(KBD98_DATA_REG);
154 spin_unlock_irqrestore(&kbd98io_lock, flags);
155 serio_interrupt(&kbd98_port, data, 0, regs);
160 int __init kbd98io_init(void)
162 serio_register_port(&kbd98_port);
164 printk(KERN_INFO "serio: PC-9801 %s port at %#lx,%#lx irq %d\n",
166 (unsigned long) KBD98_DATA_REG,
167 (unsigned long) KBD98_COMMAND_REG,
173 void __exit kbd98io_exit(void)
175 serio_unregister_port(&kbd98_port);
178 module_init(kbd98io_init);
179 module_exit(kbd98io_exit);