139 lines
3.2 KiB
Diff
Executable File
139 lines
3.2 KiB
Diff
Executable File
Index: linux-2.6.22-source/drivers/input/serio/cokbd.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.22-source/drivers/input/serio/cokbd.c
|
|
@@ -0,0 +1,133 @@
|
|
+/*
|
|
+ * Cooperative Linux virtual keyboard controller driver
|
|
+ *
|
|
+ * Copyright (c) 1999-2002 Dan Aloni <da-x@colinux.org)
|
|
+ * Based on 98kbd-io.c written by Osamu Tomita>
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * 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/interrupt.h>
|
|
+#include <linux/ioport.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/serio.h>
|
|
+#include <linux/sched.h>
|
|
+#include <linux/kbd_kern.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
+#include <asm/io.h>
|
|
+
|
|
+MODULE_AUTHOR("Dan Aloni <da-x@colinux.org>");
|
|
+MODULE_DESCRIPTION("Cooperative Linux virtual keyboard controller driver");
|
|
+MODULE_LICENSE("GPL");
|
|
+
|
|
+/*
|
|
+ * Names.
|
|
+ */
|
|
+
|
|
+#define COKBD_PHYS_DESC "cokbd"
|
|
+
|
|
+static struct serio cokbd_port;
|
|
+
|
|
+static irqreturn_t cokbdio_interrupt(int irq, void *dev_id);
|
|
+
|
|
+/*
|
|
+ * cokbd_write() sends a byte out through the keyboard interface.
|
|
+ */
|
|
+
|
|
+#define ATKBD_CMD_GETID 0x02f2
|
|
+
|
|
+static int cokbd_write(struct serio *port, unsigned char c)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * cokbd_open() is called when a port is open by the higher layer.
|
|
+ * It allocates the interrupt and enables in in the chip.
|
|
+ */
|
|
+
|
|
+static int cokbd_open(struct serio *port)
|
|
+{
|
|
+ if (request_irq(KEYBOARD_IRQ, cokbdio_interrupt, 0, "cokbd", NULL)) {
|
|
+ printk(KERN_ERR "cobkd.c: Can't get irq %d for %s, unregistering the port.\n", KEYBOARD_IRQ, "KBD");
|
|
+ serio_unregister_port(port);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void cokbd_close(struct serio *port)
|
|
+{
|
|
+ printk(KERN_INFO "cokbd closed\n");
|
|
+
|
|
+ free_irq(KEYBOARD_IRQ, NULL);
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Structures for registering the devices in the serio.c module.
|
|
+ */
|
|
+
|
|
+static struct serio cokbd_port =
|
|
+{
|
|
+ .id.type = SERIO_8042_XL,
|
|
+ .write = cokbd_write,
|
|
+ .open = cokbd_open,
|
|
+ .close = cokbd_close,
|
|
+ .name = "cokbd port",
|
|
+ .phys = COKBD_PHYS_DESC,
|
|
+};
|
|
+
|
|
+/*
|
|
+ * cokbdio_interrupt() is the most important function in this driver -
|
|
+ * it handles the interrupts from keyboard, and sends incoming bytes
|
|
+ * to the upper layers.
|
|
+ */
|
|
+
|
|
+static irqreturn_t cokbdio_interrupt(int irq, void *dev_id)
|
|
+{
|
|
+ co_message_node_t *node_message;
|
|
+ while (co_get_message(&node_message, CO_DEVICE_KEYBOARD)) {
|
|
+ co_linux_message_t *message = (co_linux_message_t *)&node_message->msg.data;
|
|
+ co_scan_code_t *sc = (co_scan_code_t *)message->data;
|
|
+ unsigned long scancode = sc->code;
|
|
+
|
|
+ switch (sc->mode)
|
|
+ {
|
|
+ case CO_KBD_SCANCODE_RAW:
|
|
+ serio_interrupt(&cokbd_port, scancode, 0);
|
|
+ break;
|
|
+
|
|
+ case CO_KBD_SCANCODE_ASCII:
|
|
+ keyboard_inject_utf8(scancode);
|
|
+ break;
|
|
+ }
|
|
+ co_free_message(node_message);
|
|
+ }
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
+int __init cokbdio_init(void)
|
|
+{
|
|
+ serio_register_port(&cokbd_port);
|
|
+
|
|
+ printk(KERN_INFO "serio: cokbd at irq %d\n", KEYBOARD_IRQ);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void __exit cokbdio_exit(void)
|
|
+{
|
|
+ serio_unregister_port(&cokbd_port);
|
|
+}
|
|
+
|
|
+module_init(cokbdio_init);
|
|
+module_exit(cokbdio_exit);
|