(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
cmd_drivers/input/keyboard/atkbd.o := gcc -Wp,-MD,drivers/input/keyboard/.atkbd.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=atkbd -DKBUILD_MODNAME=atkbd -c -o drivers/input/keyboard/atkbd.o drivers/input/keyboard/atkbd.c
deps_drivers/input/keyboard/atkbd.o := \
drivers/input/keyboard/atkbd.c \
include/linux/delay.h \
include/asm/delay.h \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/input.h \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/serio.h \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
drivers/input/keyboard/atkbd.o: $(deps_drivers/input/keyboard/atkbd.o)
$(deps_drivers/input/keyboard/atkbd.o):

View File

@@ -0,0 +1 @@
cmd_drivers/input/keyboard/built-in.o := ld -m elf_i386 -r -o drivers/input/keyboard/built-in.o drivers/input/keyboard/atkbd.o

View File

@@ -0,0 +1,98 @@
#
# Input core configuration
#
config INPUT_KEYBOARD
bool "Keyboards" if EMBEDDED || !X86
default y
depends on INPUT
help
Say Y here, and a list of supported keyboards will be displayed.
This option doesn't affect the kernel.
If unsure, say Y.
config KEYBOARD_ATKBD
tristate "AT keyboard support" if !PC
default y
depends on INPUT && INPUT_KEYBOARD
select SERIO
select SERIO_I8042 if PC
select SERIO_GSCPS2 if GSC
help
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
you'll need this, unless you have a different type keyboard (USB, ADB
or other). This also works for AT and PS/2 keyboards connected over a
PS/2 to serial converter.
If unsure, say Y.
To compile this driver as a module, choose M here: the
module will be called atkbd.
config KEYBOARD_SUNKBD
tristate "Sun Type 4 and Type 5 keyboard support"
depends on INPUT && INPUT_KEYBOARD
select SERIO
help
Say Y here if you want to use a Sun Type 4 or Type 5 keyboard,
connected either to the Sun keyboard connector or to an serial
(RS-232) port via a simple adapter.
To compile this driver as a module, choose M here: the
module will be called sunkbd.
config KEYBOARD_LKKBD
tristate "DECstation/VAXstation LK201/LK401 keyboard support"
depends on INPUT && INPUT_KEYBOARD
select SERIO
help
Say Y here if you want to use a LK201 or LK401 style serial
keyboard. This keyboard is also useable on PCs if you attach
it with the inputattach program. The connector pinout is
described within lkkbd.c.
To compile this driver as a module, choose M here: the
module will be called lkkbd.
config KEYBOARD_XTKBD
tristate "XT Keyboard support"
depends on INPUT && INPUT_KEYBOARD
select SERIO
help
Say Y here if you want to use the old IBM PC/XT keyboard (or
compatible) on your system. This is only possible with a
parallel port keyboard adapter, you cannot connect it to the
keyboard port on a PC that runs Linux.
To compile this driver as a module, choose M here: the
module will be called xtkbd.
config KEYBOARD_NEWTON
tristate "Newton keyboard"
depends on INPUT && INPUT_KEYBOARD
select SERIO
help
Say Y here if you have a Newton keyboard on a serial port.
To compile this driver as a module, choose M here: the
module will be called newtonkbd.
config KEYBOARD_MAPLE
tristate "Maple bus keyboard support"
depends on SH_DREAMCAST && INPUT && INPUT_KEYBOARD && MAPLE
help
Say Y here if you have a DreamCast console running Linux and have
a keyboard attached to its Maple bus.
To compile this driver as a module, choose M here: the
module will be called maple_keyb.
config KEYBOARD_AMIGA
tristate "Amiga keyboard"
depends on AMIGA && INPUT && INPUT_KEYBOARD
help
Say Y here if you are running Linux on any AMIGA and have a keyboard
attached.
To compile this driver as a module, choose M here: the
module will be called amikbd.

View File

@@ -0,0 +1,14 @@
#
# Makefile for the input core drivers.
#
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYBOARD_ATKBD) += atkbd.o
obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_AMIGA) += amikbd.o
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
obj-$(CONFIG_KEYBOARD_98KBD) += 98kbd.o

View File

@@ -0,0 +1,241 @@
/*
* $Id: amikbd.c,v 1.13 2002/02/01 16:02:24 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Based on the work of:
* Hamish Macdonald
*/
/*
* Amiga keyboard driver for Linux/m68k
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>
#include <asm/irq.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Amiga keyboard driver");
MODULE_LICENSE("GPL");
static unsigned char amikbd_keycode[0x78] = {
[0] = KEY_GRAVE,
[1] = KEY_1,
[2] = KEY_2,
[3] = KEY_3,
[4] = KEY_4,
[5] = KEY_5,
[6] = KEY_6,
[7] = KEY_7,
[8] = KEY_8,
[9] = KEY_9,
[10] = KEY_0,
[11] = KEY_MINUS,
[12] = KEY_EQUAL,
[13] = KEY_BACKSLASH,
[15] = KEY_KP0,
[16] = KEY_Q,
[17] = KEY_W,
[18] = KEY_E,
[19] = KEY_R,
[20] = KEY_T,
[21] = KEY_Y,
[22] = KEY_U,
[23] = KEY_I,
[24] = KEY_O,
[25] = KEY_P,
[26] = KEY_LEFTBRACE,
[27] = KEY_RIGHTBRACE,
[29] = KEY_KP1,
[30] = KEY_KP2,
[31] = KEY_KP3,
[32] = KEY_A,
[33] = KEY_S,
[34] = KEY_D,
[35] = KEY_F,
[36] = KEY_G,
[37] = KEY_H,
[38] = KEY_J,
[39] = KEY_K,
[40] = KEY_L,
[41] = KEY_SEMICOLON,
[42] = KEY_APOSTROPHE,
[43] = KEY_BACKSLASH,
[45] = KEY_KP4,
[46] = KEY_KP5,
[47] = KEY_KP6,
[48] = KEY_102ND,
[49] = KEY_Z,
[50] = KEY_X,
[51] = KEY_C,
[52] = KEY_V,
[53] = KEY_B,
[54] = KEY_N,
[55] = KEY_M,
[56] = KEY_COMMA,
[57] = KEY_DOT,
[58] = KEY_SLASH,
[60] = KEY_KPDOT,
[61] = KEY_KP7,
[62] = KEY_KP8,
[63] = KEY_KP9,
[64] = KEY_SPACE,
[65] = KEY_BACKSPACE,
[66] = KEY_TAB,
[67] = KEY_KPENTER,
[68] = KEY_ENTER,
[69] = KEY_ESC,
[70] = KEY_DELETE,
[74] = KEY_KPMINUS,
[76] = KEY_UP,
[77] = KEY_DOWN,
[78] = KEY_RIGHT,
[79] = KEY_LEFT,
[80] = KEY_F1,
[81] = KEY_F2,
[82] = KEY_F3,
[83] = KEY_F4,
[84] = KEY_F5,
[85] = KEY_F6,
[86] = KEY_F7,
[87] = KEY_F8,
[88] = KEY_F9,
[89] = KEY_F10,
[90] = KEY_KPLEFTPAREN,
[91] = KEY_KPRIGHTPAREN,
[92] = KEY_KPSLASH,
[93] = KEY_KPASTERISK,
[94] = KEY_KPPLUS,
[95] = KEY_HELP,
[96] = KEY_LEFTSHIFT,
[97] = KEY_RIGHTSHIFT,
[98] = KEY_CAPSLOCK,
[99] = KEY_LEFTCTRL,
[100] = KEY_LEFTALT,
[101] = KEY_RIGHTALT,
[102] = KEY_LEFTMETA,
[103] = KEY_RIGHTMETA
};
static const char *amikbd_messages[8] = {
[0] = KERN_ALERT "amikbd: Ctrl-Amiga-Amiga reset warning!!\n",
[1] = KERN_WARNING "amikbd: keyboard lost sync\n",
[2] = KERN_WARNING "amikbd: keyboard buffer overflow\n",
[3] = KERN_WARNING "amikbd: keyboard controller failure\n",
[4] = KERN_ERR "amikbd: keyboard selftest failure\n",
[5] = KERN_INFO "amikbd: initiate power-up key stream\n",
[6] = KERN_INFO "amikbd: terminate power-up key stream\n",
[7] = KERN_WARNING "amikbd: keyboard interrupt\n"
};
static struct input_dev amikbd_dev;
static char *amikbd_name = "Amiga keyboard";
static char *amikbd_phys = "amikbd/input0";
static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
{
unsigned char scancode, down;
scancode = ~ciaa.sdr; /* get and invert scancode (keyboard is active low) */
ciaa.cra |= 0x40; /* switch SP pin to output for handshake */
udelay(85); /* wait until 85 us have expired */
ciaa.cra &= ~0x40; /* switch CIA serial port to input mode */
down = !(scancode & 1); /* lowest bit is release bit */
scancode >>= 1;
if (scancode < 0x78) { /* scancodes < 0x78 are keys */
scancode = amikbd_keycode[scancode];
input_regs(&amikbd_dev, fp);
if (scancode == KEY_CAPSLOCK) { /* CapsLock is a toggle switch key on Amiga */
input_report_key(&amikbd_dev, scancode, 1);
input_report_key(&amikbd_dev, scancode, 0);
input_sync(&amikbd_dev);
} else {
input_report_key(&amikbd_dev, scancode, down);
input_sync(&amikbd_dev);
}
} else /* scancodes >= 0x78 are error codes */
printk(amikbd_messages[scancode - 0x78]);
return IRQ_HANDLED;
}
static int __init amikbd_init(void)
{
int i;
if (!AMIGAHW_PRESENT(AMI_KEYBOARD))
return -EIO;
if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
return -EBUSY;
init_input_dev(&amikbd_dev);
amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
amikbd_dev.keycode = amikbd_keycode;
amikbd_dev.keycodesize = sizeof(unsigned char);
amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
for (i = 0; i < 0x78; i++)
if (amikbd_keycode[i])
set_bit(amikbd_keycode[i], amikbd_dev.keybit);
ciaa.cra &= ~0x41; /* serial data in, turn off TA */
request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
amikbd_dev.name = amikbd_name;
amikbd_dev.phys = amikbd_phys;
amikbd_dev.id.bustype = BUS_AMIGA;
amikbd_dev.id.vendor = 0x0001;
amikbd_dev.id.product = 0x0001;
amikbd_dev.id.version = 0x0100;
input_register_device(&amikbd_dev);
printk(KERN_INFO "input: %s\n", amikbd_name);
return 0;
}
static void __exit amikbd_exit(void)
{
input_unregister_device(&amikbd_dev);
free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100);
}
module_init(amikbd_init);
module_exit(amikbd_exit);

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,113 @@
/*
* drivers/input/keyboard/hpps2atkbd.h
*
* Copyright (c) 2004 Helge Deller <deller@gmx.de>
* Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
* Copyright (c) 2002 Thibaut Varene <varenet@esiee.fr>
* Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
*
* HP PS/2 AT-compatible Keyboard, found in PA/RISC Workstations & Laptops
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
/* undefine if you have a RDI PRECISIONBOOK */
#define STANDARD_KEYBOARD
#if defined(STANDARD_KEYBOARD)
# define CONFLICT(x,y) x
#else
# define CONFLICT(x,y) y
#endif
/* sadly RDI (Tadpole) decided to ship a different keyboard layout
than HP for their PS/2 laptop keyboard which leads to conflicting
keycodes between a normal HP PS/2 keyboard and a RDI Precisionbook.
HP: RDI: */
#define C_07 CONFLICT( KEY_F12, KEY_F1 )
#define C_11 CONFLICT( KEY_LEFTALT, KEY_LEFTCTRL )
#define C_14 CONFLICT( KEY_LEFTCTRL, KEY_CAPSLOCK )
#define C_58 CONFLICT( KEY_CAPSLOCK, KEY_RIGHTCTRL )
#define C_61 CONFLICT( KEY_102ND, KEY_LEFT )
/* Raw SET 2 scancode table */
/* 00 */ KEY_RESERVED, KEY_F9, KEY_RESERVED, KEY_F5, KEY_F3, KEY_F1, KEY_F2, C_07,
/* 08 */ KEY_ESC, KEY_F10, KEY_F8, KEY_F6, KEY_F4, KEY_TAB, KEY_GRAVE, KEY_F2,
/* 10 */ KEY_RESERVED, C_11, KEY_LEFTSHIFT, KEY_RESERVED, C_14, KEY_Q, KEY_1, KEY_F3,
/* 18 */ KEY_RESERVED, KEY_LEFTALT, KEY_Z, KEY_S, KEY_A, KEY_W, KEY_2, KEY_F4,
/* 20 */ KEY_RESERVED, KEY_C, KEY_X, KEY_D, KEY_E, KEY_4, KEY_3, KEY_F5,
/* 28 */ KEY_RESERVED, KEY_SPACE, KEY_V, KEY_F, KEY_T, KEY_R, KEY_5, KEY_F6,
/* 30 */ KEY_RESERVED, KEY_N, KEY_B, KEY_H, KEY_G, KEY_Y, KEY_6, KEY_F7,
/* 38 */ KEY_RESERVED, KEY_RIGHTALT, KEY_M, KEY_J, KEY_U, KEY_7, KEY_8, KEY_F8,
/* 40 */ KEY_RESERVED, KEY_COMMA, KEY_K, KEY_I, KEY_O, KEY_0, KEY_9, KEY_F9,
/* 48 */ KEY_RESERVED, KEY_DOT, KEY_SLASH, KEY_L, KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_F10,
/* 50 */ KEY_RESERVED, KEY_RESERVED, KEY_APOSTROPHE,KEY_RESERVED, KEY_LEFTBRACE, KEY_EQUAL, KEY_F11, KEY_SYSRQ,
/* 58 */ C_58, KEY_RIGHTSHIFT,KEY_ENTER, KEY_RIGHTBRACE,KEY_BACKSLASH, KEY_BACKSLASH,KEY_F12, KEY_SCROLLLOCK,
/* 60 */ KEY_DOWN, C_61, KEY_PAUSE, KEY_UP, KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT,
/* 68 */ KEY_RESERVED, KEY_KP1, KEY_RIGHT, KEY_KP4, KEY_KP7, KEY_PAGEDOWN, KEY_HOME, KEY_PAGEUP,
/* 70 */ KEY_KP0, KEY_KPDOT, KEY_KP2, KEY_KP5, KEY_KP6, KEY_KP8, KEY_ESC, KEY_NUMLOCK,
/* 78 */ KEY_F11, KEY_KPPLUS, KEY_KP3, KEY_KPMINUS, KEY_KPASTERISK,KEY_KP9, KEY_SCROLLLOCK,KEY_103RD,
/* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 90 */ KEY_RESERVED, KEY_RIGHTALT, KEY_SYSRQ, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_CAPSLOCK, KEY_RESERVED, KEY_LEFTMETA,
/* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTMETA,
/* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_COMPOSE,
/* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPSLASH, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_KPENTER, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e8 */ KEY_RESERVED, KEY_END, KEY_RESERVED, KEY_LEFT, KEY_HOME, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* f0 */ KEY_INSERT, KEY_DELETE, KEY_DOWN, KEY_RESERVED, KEY_RIGHT, KEY_UP, KEY_RESERVED, KEY_PAUSE,
/* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_PAGEDOWN, KEY_RESERVED, KEY_SYSRQ, KEY_PAGEUP, KEY_RESERVED, KEY_RESERVED,
/* These are offset for escaped keycodes: */
/* 00 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_F7, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 08 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_LEFTMETA, KEY_RIGHTMETA, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 10 */ KEY_RESERVED, KEY_RIGHTALT, KEY_RESERVED, KEY_RESERVED, KEY_RIGHTCTRL, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 18 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 20 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 28 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 30 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 38 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 40 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 48 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 50 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 58 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 60 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 68 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 70 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 78 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 80 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 88 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 90 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* 98 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* a0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* a8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* b0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* b8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* c8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* d8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* e8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* f0 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,
/* f8 */ KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
#undef STANDARD_KEYBOARD
#undef CONFLICT
#undef C_07
#undef C_11
#undef C_14
#undef C_58
#undef C_61

View File

@@ -0,0 +1,736 @@
/*
* Copyright (C) 2004 by Jan-Benedict Glaw <jbglaw@lug-owl.de>
*/
/*
* LK keyboard driver for Linux, based on sunkbd.c (C) by Vojtech Pavlik
*/
/*
* DEC LK201 and LK401 keyboard driver for Linux (primary for DECstations
* and VAXstations, but can also be used on any standard RS232 with an
* adaptor).
*
* DISCLAIMER: This works for _me_. If you break anything by using the
* information given below, I will _not_ be liable!
*
* RJ11 pinout: To DB9: Or DB25:
* 1 - RxD <----> Pin 3 (TxD) <-> Pin 2 (TxD)
* 2 - GND <----> Pin 5 (GND) <-> Pin 7 (GND)
* 4 - TxD <----> Pin 2 (RxD) <-> Pin 3 (RxD)
* 3 - +12V (from HDD drive connector), DON'T connect to DB9 or DB25!!!
*
* Pin numbers for DB9 and DB25 are noted on the plug (quite small:). For
* RJ11, it's like this:
*
* __=__ Hold the plug in front of you, cable downwards,
* /___/| nose is hidden behind the plug. Now, pin 1 is at
* |1234|| the left side, pin 4 at the right and 2 and 3 are
* |IIII|| in between, of course:)
* | ||
* |____|/
* || So the adaptor consists of three connected cables
* || for data transmission (RxD and TxD) and signal ground.
* Additionally, you have to get +12V from somewhere.
* Most easily, you'll get that from a floppy or HDD power connector.
* It's the yellow cable there (black is ground and red is +5V).
*
* The keyboard and all the commands it understands are documented in
* "VCB02 Video Subsystem - Technical Manual", EK-104AA-TM-001. This
* document is LK201 specific, but LK401 is mostly compatible. It comes
* up in LK201 mode and doesn't report any of the additional keys it
* has. These need to be switched on with the LK_CMD_ENABLE_LK401
* command. You'll find this document (scanned .pdf file) on MANX,
* a search engine specific to DEC documentation. Try
* http://www.vt100.net/manx/details?pn=EK-104AA-TM-001;id=21;cp=1
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* email or by paper mail:
* Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.),
* Germany.
*/
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
#define DRIVER_DESC "LK keyboard driver"
MODULE_AUTHOR ("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
MODULE_DESCRIPTION (DRIVER_DESC);
MODULE_LICENSE ("GPL");
/*
* Known parameters:
* bell_volume
* keyclick_volume
* ctrlclick_volume
*
* Please notice that there's not yet an API to set these at runtime.
*/
static int bell_volume = 100; /* % */
module_param (bell_volume, int, 0);
MODULE_PARM_DESC (bell_volume, "Bell volume (in %). default is 100%");
static int keyclick_volume = 100; /* % */
module_param (keyclick_volume, int, 0);
MODULE_PARM_DESC (keyclick_volume, "Keyclick volume (in %), default is 100%");
static int ctrlclick_volume = 100; /* % */
module_param (ctrlclick_volume, int, 0);
MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
static int lk201_compose_is_alt = 0;
module_param (lk201_compose_is_alt, int, 0);
MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
"will act as an Alt key");
#undef LKKBD_DEBUG
#ifdef LKKBD_DEBUG
#define DBG(x...) printk (x)
#else
#define DBG(x...) do {} while (0)
#endif
/* LED control */
#define LK_LED_WAIT 0x81
#define LK_LED_COMPOSE 0x82
#define LK_LED_SHIFTLOCK 0x84
#define LK_LED_SCROLLLOCK 0x88
#define LK_CMD_LED_ON 0x13
#define LK_CMD_LED_OFF 0x11
/* Mode control */
#define LK_MODE_DOWN 0x80
#define LK_MODE_AUTODOWN 0x82
#define LK_MODE_UPDOWN 0x86
#define LK_CMD_SET_MODE(mode,div) ((mode) | ((div) << 3))
/* Misc commands */
#define LK_CMD_ENABLE_KEYCLICK 0x1b
#define LK_CMD_DISABLE_KEYCLICK 0x99
#define LK_CMD_DISABLE_BELL 0xa1
#define LK_CMD_SOUND_BELL 0xa7
#define LK_CMD_ENABLE_BELL 0x23
#define LK_CMD_DISABLE_CTRCLICK 0xb9
#define LK_CMD_ENABLE_CTRCLICK 0xbb
#define LK_CMD_SET_DEFAULTS 0xd3
#define LK_CMD_POWERCYCLE_RESET 0xfd
#define LK_CMD_ENABLE_LK401 0xe9
#define LK_CMD_REQUEST_ID 0xab
/* Misc responses from keyboard */
#define LK_STUCK_KEY 0x3d
#define LK_SELFTEST_FAILED 0x3e
#define LK_ALL_KEYS_UP 0xb3
#define LK_METRONOME 0xb4
#define LK_OUTPUT_ERROR 0xb5
#define LK_INPUT_ERROR 0xb6
#define LK_KBD_LOCKED 0xb7
#define LK_KBD_TEST_MODE_ACK 0xb8
#define LK_PREFIX_KEY_DOWN 0xb9
#define LK_MODE_CHANGE_ACK 0xba
#define LK_RESPONSE_RESERVED 0xbb
#define LK_NUM_KEYCODES 256
#define LK_NUM_IGNORE_BYTES 6
typedef u_int16_t lk_keycode_t;
static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
[0x56] = KEY_F1,
[0x57] = KEY_F2,
[0x58] = KEY_F3,
[0x59] = KEY_F4,
[0x5a] = KEY_F5,
[0x64] = KEY_F6,
[0x65] = KEY_F7,
[0x66] = KEY_F8,
[0x67] = KEY_F9,
[0x68] = KEY_F10,
[0x71] = KEY_F11,
[0x72] = KEY_F12,
[0x73] = KEY_F13,
[0x74] = KEY_F14,
[0x7c] = KEY_F15,
[0x7d] = KEY_F16,
[0x80] = KEY_F17,
[0x81] = KEY_F18,
[0x82] = KEY_F19,
[0x83] = KEY_F20,
[0x8a] = KEY_FIND,
[0x8b] = KEY_INSERT,
[0x8c] = KEY_DELETE,
[0x8d] = KEY_SELECT,
[0x8e] = KEY_PAGEUP,
[0x8f] = KEY_PAGEDOWN,
[0x92] = KEY_KP0,
[0x94] = KEY_KPDOT,
[0x95] = KEY_KPENTER,
[0x96] = KEY_KP1,
[0x97] = KEY_KP2,
[0x98] = KEY_KP3,
[0x99] = KEY_KP4,
[0x9a] = KEY_KP5,
[0x9b] = KEY_KP6,
[0x9c] = KEY_KPCOMMA,
[0x9d] = KEY_KP7,
[0x9e] = KEY_KP8,
[0x9f] = KEY_KP9,
[0xa0] = KEY_KPMINUS,
[0xa1] = KEY_PROG1,
[0xa2] = KEY_PROG2,
[0xa3] = KEY_PROG3,
[0xa4] = KEY_PROG4,
[0xa7] = KEY_LEFT,
[0xa8] = KEY_RIGHT,
[0xa9] = KEY_DOWN,
[0xaa] = KEY_UP,
[0xab] = KEY_RIGHTSHIFT,
[0xac] = KEY_LEFTALT,
[0xad] = KEY_COMPOSE, /* Right Compose, that is. */
[0xae] = KEY_LEFTSHIFT, /* Same as KEY_RIGHTSHIFT on LK201 */
[0xaf] = KEY_LEFTCTRL,
[0xb0] = KEY_CAPSLOCK,
[0xb1] = KEY_COMPOSE, /* Left Compose, that is. */
[0xb2] = KEY_RIGHTALT,
[0xbc] = KEY_BACKSPACE,
[0xbd] = KEY_ENTER,
[0xbe] = KEY_TAB,
[0xbf] = KEY_ESC,
[0xc0] = KEY_1,
[0xc1] = KEY_Q,
[0xc2] = KEY_A,
[0xc3] = KEY_Z,
[0xc5] = KEY_2,
[0xc6] = KEY_W,
[0xc7] = KEY_S,
[0xc8] = KEY_X,
[0xc9] = KEY_102ND,
[0xcb] = KEY_3,
[0xcc] = KEY_E,
[0xcd] = KEY_D,
[0xce] = KEY_C,
[0xd0] = KEY_4,
[0xd1] = KEY_R,
[0xd2] = KEY_F,
[0xd3] = KEY_V,
[0xd4] = KEY_SPACE,
[0xd6] = KEY_5,
[0xd7] = KEY_T,
[0xd8] = KEY_G,
[0xd9] = KEY_B,
[0xdb] = KEY_6,
[0xdc] = KEY_Y,
[0xdd] = KEY_H,
[0xde] = KEY_N,
[0xe0] = KEY_7,
[0xe1] = KEY_U,
[0xe2] = KEY_J,
[0xe3] = KEY_M,
[0xe5] = KEY_8,
[0xe6] = KEY_I,
[0xe7] = KEY_K,
[0xe8] = KEY_COMMA,
[0xea] = KEY_9,
[0xeb] = KEY_O,
[0xec] = KEY_L,
[0xed] = KEY_DOT,
[0xef] = KEY_0,
[0xf0] = KEY_P,
[0xf2] = KEY_SEMICOLON,
[0xf3] = KEY_SLASH,
[0xf5] = KEY_EQUAL,
[0xf6] = KEY_RIGHTBRACE,
[0xf7] = KEY_BACKSLASH,
[0xf9] = KEY_MINUS,
[0xfa] = KEY_LEFTBRACE,
[0xfb] = KEY_APOSTROPHE,
};
#define CHECK_LED(LED, BITS) do { \
if (test_bit (LED, lk->dev.led)) \
leds_on |= BITS; \
else \
leds_off |= BITS; \
} while (0)
/*
* Per-keyboard data
*/
struct lkkbd {
lk_keycode_t keycode[LK_NUM_KEYCODES];
int ignore_bytes;
unsigned char id[LK_NUM_IGNORE_BYTES];
struct input_dev dev;
struct serio *serio;
struct work_struct tq;
char name[64];
char phys[32];
char type;
int bell_volume;
int keyclick_volume;
int ctrlclick_volume;
};
/*
* Calculate volume parameter byte for a given volume.
*/
static unsigned char
volume_to_hw (int volume_percent)
{
unsigned char ret = 0;
if (volume_percent < 0)
volume_percent = 0;
if (volume_percent > 100)
volume_percent = 100;
if (volume_percent >= 0)
ret = 7;
if (volume_percent >= 13) /* 12.5 */
ret = 6;
if (volume_percent >= 25)
ret = 5;
if (volume_percent >= 38) /* 37.5 */
ret = 4;
if (volume_percent >= 50)
ret = 3;
if (volume_percent >= 63) /* 62.5 */
ret = 2; /* This is the default volume */
if (volume_percent >= 75)
ret = 1;
if (volume_percent >= 88) /* 87.5 */
ret = 0;
ret |= 0x80;
return ret;
}
static void
lkkbd_detection_done (struct lkkbd *lk)
{
int i;
/*
* Reset setting for Compose key. Let Compose be KEY_COMPOSE.
*/
lk->keycode[0xb1] = KEY_COMPOSE;
/*
* Print keyboard name and modify Compose=Alt on user's request.
*/
switch (lk->id[4]) {
case 1:
sprintf (lk->name, "DEC LK201 keyboard");
if (lk201_compose_is_alt)
lk->keycode[0xb1] = KEY_LEFTALT;
break;
case 2:
sprintf (lk->name, "DEC LK401 keyboard");
break;
default:
sprintf (lk->name, "Unknown DEC keyboard");
printk (KERN_ERR "lkkbd: keyboard on %s is unknown, "
"please report to Jan-Benedict Glaw "
"<jbglaw@lug-owl.de>\n", lk->phys);
printk (KERN_ERR "lkkbd: keyboard ID'ed as:");
for (i = 0; i < LK_NUM_IGNORE_BYTES; i++)
printk (" 0x%02x", lk->id[i]);
printk ("\n");
break;
}
printk (KERN_INFO "lkkbd: keyboard on %s identified as: %s\n",
lk->phys, lk->name);
/*
* Report errors during keyboard boot-up.
*/
switch (lk->id[2]) {
case 0x00:
/* All okay */
break;
case LK_STUCK_KEY:
printk (KERN_ERR "lkkbd: Stuck key on keyboard at "
"%s\n", lk->phys);
break;
case LK_SELFTEST_FAILED:
printk (KERN_ERR "lkkbd: Selftest failed on keyboard "
"at %s, keyboard may not work "
"properly\n", lk->phys);
break;
default:
printk (KERN_ERR "lkkbd: Unknown error %02x on "
"keyboard at %s\n", lk->id[2],
lk->phys);
break;
}
/*
* Try to hint user if there's a stuck key.
*/
if (lk->id[2] == LK_STUCK_KEY && lk->id[3] != 0)
printk (KERN_ERR "Scancode of stuck key is 0x%02x, keycode "
"is 0x%04x\n", lk->id[3],
lk->keycode[lk->id[3]]);
return;
}
/*
* lkkbd_interrupt() is called by the low level driver when a character
* is received.
*/
static irqreturn_t
lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
struct pt_regs *regs)
{
struct lkkbd *lk = serio->private;
int i;
DBG (KERN_INFO "Got byte 0x%02x\n", data);
if (lk->ignore_bytes > 0) {
DBG (KERN_INFO "Ignoring a byte on %s\n",
lk->name);
lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
if (lk->ignore_bytes == 0)
lkkbd_detection_done (lk);
return IRQ_HANDLED;
}
switch (data) {
case LK_ALL_KEYS_UP:
input_regs (&lk->dev, regs);
for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
if (lk->keycode[i] != KEY_RESERVED)
input_report_key (&lk->dev, lk->keycode[i], 0);
input_sync (&lk->dev);
break;
case LK_METRONOME:
DBG (KERN_INFO "Got LK_METRONOME and don't "
"know how to handle...\n");
break;
case LK_OUTPUT_ERROR:
DBG (KERN_INFO "Got LK_OUTPUT_ERROR and don't "
"know how to handle...\n");
break;
case LK_INPUT_ERROR:
DBG (KERN_INFO "Got LK_INPUT_ERROR and don't "
"know how to handle...\n");
break;
case LK_KBD_LOCKED:
DBG (KERN_INFO "Got LK_KBD_LOCKED and don't "
"know how to handle...\n");
break;
case LK_KBD_TEST_MODE_ACK:
DBG (KERN_INFO "Got LK_KBD_TEST_MODE_ACK and don't "
"know how to handle...\n");
break;
case LK_PREFIX_KEY_DOWN:
DBG (KERN_INFO "Got LK_PREFIX_KEY_DOWN and don't "
"know how to handle...\n");
break;
case LK_MODE_CHANGE_ACK:
DBG (KERN_INFO "Got LK_MODE_CHANGE_ACK and ignored "
"it properly...\n");
break;
case LK_RESPONSE_RESERVED:
DBG (KERN_INFO "Got LK_RESPONSE_RESERVED and don't "
"know how to handle...\n");
break;
case 0x01:
DBG (KERN_INFO "Got 0x01, scheduling re-initialization\n");
lk->ignore_bytes = LK_NUM_IGNORE_BYTES;
lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
schedule_work (&lk->tq);
break;
default:
if (lk->keycode[data] != KEY_RESERVED) {
input_regs (&lk->dev, regs);
if (!test_bit (lk->keycode[data], lk->dev.key))
input_report_key (&lk->dev, lk->keycode[data], 1);
else
input_report_key (&lk->dev, lk->keycode[data], 0);
input_sync (&lk->dev);
} else
printk (KERN_WARNING "%s: Unknown key with "
"scancode 0x%02x on %s.\n",
__FILE__, data, lk->name);
}
return IRQ_HANDLED;
}
/*
* lkkbd_event() handles events from the input module.
*/
static int
lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code,
int value)
{
struct lkkbd *lk = dev->private;
unsigned char leds_on = 0;
unsigned char leds_off = 0;
switch (type) {
case EV_LED:
CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
CHECK_LED (LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
}
if (leds_off != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_OFF);
lk->serio->write (lk->serio, leds_off);
}
return 0;
case EV_SND:
switch (code) {
case SND_CLICK:
if (value == 0) {
DBG ("%s: Deactivating key clicks\n", __FUNCTION__);
lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
} else {
DBG ("%s: Activating key clicks\n", __FUNCTION__);
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
}
return 0;
case SND_BELL:
if (value != 0)
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
return 0;
}
break;
default:
printk (KERN_ERR "%s (): Got unknown type %d, code %d, value %d\n",
__FUNCTION__, type, code, value);
}
return -1;
}
/*
* lkkbd_reinit() sets leds and beeps to a state the computer remembers they
* were in.
*/
static void
lkkbd_reinit (void *data)
{
struct lkkbd *lk = data;
int division;
unsigned char leds_on = 0;
unsigned char leds_off = 0;
/* Ask for ID */
lk->serio->write (lk->serio, LK_CMD_REQUEST_ID);
/* Reset parameters */
lk->serio->write (lk->serio, LK_CMD_SET_DEFAULTS);
/* Set LEDs */
CHECK_LED (LED_CAPSL, LK_LED_SHIFTLOCK);
CHECK_LED (LED_COMPOSE, LK_LED_COMPOSE);
CHECK_LED (LED_SCROLLL, LK_LED_SCROLLLOCK);
CHECK_LED (LED_SLEEP, LK_LED_WAIT);
if (leds_on != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_ON);
lk->serio->write (lk->serio, leds_on);
}
if (leds_off != 0) {
lk->serio->write (lk->serio, LK_CMD_LED_OFF);
lk->serio->write (lk->serio, leds_off);
}
/*
* Try to activate extended LK401 mode. This command will
* only work with a LK401 keyboard and grants access to
* LAlt, RAlt, RCompose and RShift.
*/
lk->serio->write (lk->serio, LK_CMD_ENABLE_LK401);
/* Set all keys to UPDOWN mode */
for (division = 1; division <= 14; division++)
lk->serio->write (lk->serio, LK_CMD_SET_MODE (LK_MODE_UPDOWN,
division));
/* Enable bell and set volume */
lk->serio->write (lk->serio, LK_CMD_ENABLE_BELL);
lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
/* Enable/disable keyclick (and possibly set volume) */
if (test_bit (SND_CLICK, lk->dev.snd)) {
lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
lk->serio->write (lk->serio, volume_to_hw (lk->ctrlclick_volume));
} else {
lk->serio->write (lk->serio, LK_CMD_DISABLE_KEYCLICK);
lk->serio->write (lk->serio, LK_CMD_DISABLE_CTRCLICK);
}
/* Sound the bell if needed */
if (test_bit (SND_BELL, lk->dev.snd))
lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
}
/*
* lkkbd_connect() probes for a LK keyboard and fills the necessary structures.
*/
static void
lkkbd_connect (struct serio *serio, struct serio_driver *drv)
{
struct lkkbd *lk;
int i;
if ((serio->type & SERIO_TYPE) != SERIO_RS232)
return;
if ((serio->type & SERIO_PROTO) != SERIO_LKKBD)
return;
if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
return;
memset (lk, 0, sizeof (struct lkkbd));
init_input_dev (&lk->dev);
set_bit (EV_KEY, lk->dev.evbit);
set_bit (EV_LED, lk->dev.evbit);
set_bit (EV_SND, lk->dev.evbit);
set_bit (EV_REP, lk->dev.evbit);
set_bit (LED_CAPSL, lk->dev.ledbit);
set_bit (LED_SLEEP, lk->dev.ledbit);
set_bit (LED_COMPOSE, lk->dev.ledbit);
set_bit (LED_SCROLLL, lk->dev.ledbit);
set_bit (SND_BELL, lk->dev.sndbit);
set_bit (SND_CLICK, lk->dev.sndbit);
lk->serio = serio;
INIT_WORK (&lk->tq, lkkbd_reinit, lk);
lk->bell_volume = bell_volume;
lk->keyclick_volume = keyclick_volume;
lk->ctrlclick_volume = ctrlclick_volume;
lk->dev.keycode = lk->keycode;
lk->dev.keycodesize = sizeof (lk_keycode_t);
lk->dev.keycodemax = LK_NUM_KEYCODES;
lk->dev.event = lkkbd_event;
lk->dev.private = lk;
serio->private = lk;
if (serio_open (serio, drv)) {
kfree (lk);
return;
}
sprintf (lk->name, "DEC LK keyboard");
sprintf (lk->phys, "%s/input0", serio->phys);
memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
for (i = 0; i < LK_NUM_KEYCODES; i++)
set_bit (lk->keycode[i], lk->dev.keybit);
lk->dev.name = lk->name;
lk->dev.phys = lk->phys;
lk->dev.id.bustype = BUS_RS232;
lk->dev.id.vendor = SERIO_LKKBD;
lk->dev.id.product = 0;
lk->dev.id.version = 0x0100;
input_register_device (&lk->dev);
printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
}
/*
* lkkbd_disconnect() unregisters and closes behind us.
*/
static void
lkkbd_disconnect (struct serio *serio)
{
struct lkkbd *lk = serio->private;
input_unregister_device (&lk->dev);
serio_close (serio);
kfree (lk);
}
static struct serio_driver lkkbd_drv = {
.driver = {
.name = "lkkbd",
},
.description = DRIVER_DESC,
.connect = lkkbd_connect,
.disconnect = lkkbd_disconnect,
.interrupt = lkkbd_interrupt,
};
/*
* The functions for insering/removing us as a module.
*/
int __init
lkkbd_init (void)
{
serio_register_driver(&lkkbd_drv);
return 0;
}
void __exit
lkkbd_exit (void)
{
serio_unregister_driver(&lkkbd_drv);
}
module_init (lkkbd_init);
module_exit (lkkbd_exit);

View File

@@ -0,0 +1,190 @@
/*
* $Id: maple_keyb.c,v 1.4 2004/03/22 01:18:15 lethal Exp $
* SEGA Dreamcast keyboard driver
* Based on drivers/usb/usbkbd.c
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/maple.h>
MODULE_AUTHOR("YAEGASHI Takeshi <t@keshi.org>");
MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
MODULE_LICENSE("GPL");
static unsigned char dc_kbd_keycode[256] = {
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
150,158,159,128,136,177,178,176,142,152,173,140
};
struct dc_kbd {
struct input_dev dev;
unsigned char new[8];
unsigned char old[8];
int open;
};
static void dc_scan_kbd(struct dc_kbd *kbd)
{
int i;
struct input_dev *dev = &kbd->dev;
for(i=0; i<8; i++)
input_report_key(dev,
dc_kbd_keycode[i+224],
(kbd->new[0]>>i)&1);
for(i=2; i<8; i++) {
if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) {
if(dc_kbd_keycode[kbd->old[i]])
input_report_key(dev,
dc_kbd_keycode[kbd->old[i]],
0);
else
printk("Unknown key (scancode %#x) released.",
kbd->old[i]);
}
if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) {
if(dc_kbd_keycode[kbd->new[i]])
input_report_key(dev,
dc_kbd_keycode[kbd->new[i]],
1);
else
printk("Unknown key (scancode %#x) pressed.",
kbd->new[i]);
}
}
input_sync(dev);
memcpy(kbd->old, kbd->new, 8);
}
static void dc_kbd_callback(struct mapleq *mq)
{
struct maple_device *mapledev = mq->dev;
struct dc_kbd *kbd = mapledev->private_data;
unsigned long *buf = mq->recvbuf;
if (buf[1] == mapledev->function) {
memcpy(kbd->new, buf+2, 8);
dc_scan_kbd(kbd);
}
}
static int dc_kbd_open(struct input_dev *dev)
{
struct dc_kbd *kbd = dev->private;
kbd->open++;
return 0;
}
static void dc_kbd_close(struct input_dev *dev)
{
struct dc_kbd *kbd = dev->private;
kbd->open--;
}
static int dc_kbd_connect(struct maple_device *dev)
{
int i;
unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
struct dc_kbd *kbd;
if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL)))
return -1;
memset(kbd, 0, sizeof(struct dc_kbd));
dev->private_data = kbd;
kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
init_input_dev(&kbd->dev);
for (i=0; i<255; i++)
set_bit(dc_kbd_keycode[i], kbd->dev.keybit);
clear_bit(0, kbd->dev.keybit);
kbd->dev.private = kbd;
kbd->dev.open = dc_kbd_open;
kbd->dev.close = dc_kbd_close;
kbd->dev.event = NULL;
kbd->dev.name = dev->product_name;
kbd->dev.id.bustype = BUS_MAPLE;
input_register_device(&kbd->dev);
maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name);
return 0;
}
static void dc_kbd_disconnect(struct maple_device *dev)
{
struct dc_kbd *kbd = dev->private_data;
input_unregister_device(&kbd->dev);
kfree(kbd);
}
static struct maple_driver dc_kbd_driver = {
.function = MAPLE_FUNC_KEYBOARD,
.name = "Dreamcast keyboard",
.connect = dc_kbd_connect,
.disconnect = dc_kbd_disconnect,
};
static int __init dc_kbd_init(void)
{
maple_register_driver(&dc_kbd_driver);
return 0;
}
static void __exit dc_kbd_exit(void)
{
maple_unregister_driver(&dc_kbd_driver);
}
module_init(dc_kbd_init);
module_exit(dc_kbd_exit);
/*
* Local variables:
* c-basic-offset: 8
* End:
*/

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) 2000 Justin Cormack
*/
/*
* Newton keyboard driver for Linux
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <j.cormack@doc.ic.ac.uk>, or by paper mail:
* Justin Cormack, 68 Dartmouth Park Road, London NW5 1SN, UK.
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#define DRIVER_DESC "Newton keyboard driver"
MODULE_AUTHOR("Justin Cormack <j.cormack@doc.ic.ac.uk>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define NKBD_KEY 0x7f
#define NKBD_PRESS 0x80
static unsigned char nkbd_keycode[128] = {
KEY_A, KEY_S, KEY_D, KEY_F, KEY_H, KEY_G, KEY_Z, KEY_X,
KEY_C, KEY_V, 0, KEY_B, KEY_Q, KEY_W, KEY_E, KEY_R,
KEY_Y, KEY_T, KEY_1, KEY_2, KEY_3, KEY_4, KEY_6, KEY_5,
KEY_EQUAL, KEY_9, KEY_7, KEY_MINUS, KEY_8, KEY_0, KEY_RIGHTBRACE, KEY_O,
KEY_U, KEY_LEFTBRACE, KEY_I, KEY_P, KEY_ENTER, KEY_L, KEY_J, KEY_APOSTROPHE,
KEY_K, KEY_SEMICOLON, KEY_BACKSLASH, KEY_COMMA, KEY_SLASH, KEY_N, KEY_M, KEY_DOT,
KEY_TAB, KEY_SPACE, KEY_GRAVE, KEY_DELETE, 0, 0, 0, KEY_LEFTMETA,
KEY_LEFTSHIFT, KEY_CAPSLOCK, KEY_LEFTALT, KEY_LEFTCTRL, KEY_RIGHTSHIFT, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
};
static char *nkbd_name = "Newton Keyboard";
struct nkbd {
unsigned char keycode[128];
struct input_dev dev;
struct serio *serio;
char phys[32];
};
irqreturn_t nkbd_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct nkbd *nkbd = serio->private;
/* invalid scan codes are probably the init sequence, so we ignore them */
if (nkbd->keycode[data & NKBD_KEY]) {
input_regs(&nkbd->dev, regs);
input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
input_sync(&nkbd->dev);
}
else if (data == 0xe7) /* end of init sequence */
printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
return IRQ_HANDLED;
}
void nkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct nkbd *nkbd;
int i;
if (serio->type != (SERIO_RS232 | SERIO_NEWTON))
return;
if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
return;
memset(nkbd, 0, sizeof(struct nkbd));
nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
nkbd->serio = serio;
init_input_dev(&nkbd->dev);
nkbd->dev.keycode = nkbd->keycode;
nkbd->dev.keycodesize = sizeof(unsigned char);
nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
nkbd->dev.private = nkbd;
serio->private = nkbd;
if (serio_open(serio, drv)) {
kfree(nkbd);
return;
}
memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
for (i = 0; i < 128; i++)
set_bit(nkbd->keycode[i], nkbd->dev.keybit);
clear_bit(0, nkbd->dev.keybit);
sprintf(nkbd->phys, "%s/input0", serio->phys);
nkbd->dev.name = nkbd_name;
nkbd->dev.phys = nkbd->phys;
nkbd->dev.id.bustype = BUS_RS232;
nkbd->dev.id.vendor = SERIO_NEWTON;
nkbd->dev.id.product = 0x0001;
nkbd->dev.id.version = 0x0100;
input_register_device(&nkbd->dev);
printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
}
void nkbd_disconnect(struct serio *serio)
{
struct nkbd *nkbd = serio->private;
input_unregister_device(&nkbd->dev);
serio_close(serio);
kfree(nkbd);
}
struct serio_driver nkbd_drv = {
.driver = {
.name = "newtonkbd",
},
.description = DRIVER_DESC,
.interrupt = nkbd_interrupt,
.connect = nkbd_connect,
.disconnect = nkbd_disconnect,
};
int __init nkbd_init(void)
{
serio_register_driver(&nkbd_drv);
return 0;
}
void __exit nkbd_exit(void)
{
serio_unregister_driver(&nkbd_drv);
}
module_init(nkbd_init);
module_exit(nkbd_exit);

View File

@@ -0,0 +1,332 @@
/*
* $Id: sunkbd.c,v 1.14 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/
/*
* Sun keyboard driver for Linux
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/workqueue.h>
#define DRIVER_DESC "Sun keyboard driver"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static unsigned char sunkbd_keycode[128] = {
0,128,114,129,115, 59, 60, 68, 61, 87, 62, 88, 63,100, 64, 0,
65, 66, 67, 56,103,119, 99, 70,105,130,131,108,106, 1, 2, 3,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 41, 14,110,113, 98, 55,
116,132, 83,133,102, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27,111,127, 71, 72, 73, 74,134,135,107, 0, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 43, 28, 96, 75, 76, 77, 82,136,
104,137, 69, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,101,
79, 80, 81, 0, 0, 0,138, 58,125, 57,126,109, 86, 78
};
#define SUNKBD_CMD_RESET 0x1
#define SUNKBD_CMD_BELLON 0x2
#define SUNKBD_CMD_BELLOFF 0x3
#define SUNKBD_CMD_CLICK 0xa
#define SUNKBD_CMD_NOCLICK 0xb
#define SUNKBD_CMD_SETLED 0xe
#define SUNKBD_CMD_LAYOUT 0xf
#define SUNKBD_RET_RESET 0xff
#define SUNKBD_RET_ALLUP 0x7f
#define SUNKBD_RET_LAYOUT 0xfe
#define SUNKBD_LAYOUT_5_MASK 0x20
#define SUNKBD_RELEASE 0x80
#define SUNKBD_KEY 0x7f
/*
* Per-keyboard data.
*/
struct sunkbd {
unsigned char keycode[128];
struct input_dev dev;
struct serio *serio;
struct work_struct tq;
wait_queue_head_t wait;
char name[64];
char phys[32];
char type;
volatile s8 reset;
volatile s8 layout;
};
/*
* sunkbd_interrupt() is called by the low level driver when a character
* is received.
*/
static irqreturn_t sunkbd_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct sunkbd* sunkbd = serio->private;
if (sunkbd->reset <= -1) { /* If cp[i] is 0xff, sunkbd->reset will stay -1. */
sunkbd->reset = data; /* The keyboard sends 0xff 0xff 0xID on powerup */
wake_up_interruptible(&sunkbd->wait);
goto out;
}
if (sunkbd->layout == -1) {
sunkbd->layout = data;
wake_up_interruptible(&sunkbd->wait);
goto out;
}
switch (data) {
case SUNKBD_RET_RESET:
schedule_work(&sunkbd->tq);
sunkbd->reset = -1;
break;
case SUNKBD_RET_LAYOUT:
sunkbd->layout = -1;
break;
case SUNKBD_RET_ALLUP: /* All keys released */
break;
default:
if (sunkbd->keycode[data & SUNKBD_KEY]) {
input_regs(&sunkbd->dev, regs);
input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
input_sync(&sunkbd->dev);
} else {
printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
}
}
out:
return IRQ_HANDLED;
}
/*
* sunkbd_event() handles events from the input module.
*/
static int sunkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct sunkbd *sunkbd = dev->private;
switch (type) {
case EV_LED:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, dev->led) << 3) | (!!test_bit(LED_SCROLLL, dev->led) << 2) |
(!!test_bit(LED_COMPOSE, dev->led) << 1) | !!test_bit(LED_NUML, dev->led));
return 0;
case EV_SND:
switch (code) {
case SND_CLICK:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - value);
return 0;
case SND_BELL:
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - value);
return 0;
}
break;
}
return -1;
}
/*
* sunkbd_initialize() checks for a Sun keyboard attached, and determines
* its type.
*/
static int sunkbd_initialize(struct sunkbd *sunkbd)
{
sunkbd->reset = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
if (sunkbd->reset <0)
return -1;
sunkbd->type = sunkbd->reset;
if (sunkbd->type == 4) { /* Type 4 keyboard */
sunkbd->layout = -2;
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_LAYOUT);
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->layout >= 0, HZ/4);
if (sunkbd->layout < 0) return -1;
if (sunkbd->layout & SUNKBD_LAYOUT_5_MASK) sunkbd->type = 5;
}
return 0;
}
/*
* sunkbd_reinit() sets leds and beeps to a state the computer remembers they
* were in.
*/
static void sunkbd_reinit(void *data)
{
struct sunkbd *sunkbd = data;
wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
sunkbd->serio->write(sunkbd->serio,
(!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
(!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev.snd));
}
/*
* sunkbd_connect() probes for a Sun keyboard and fills the necessary structures.
*/
static void sunkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct sunkbd *sunkbd;
int i;
if ((serio->type & SERIO_TYPE) != SERIO_RS232)
return;
if ((serio->type & SERIO_PROTO) && (serio->type & SERIO_PROTO) != SERIO_SUNKBD)
return;
if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
return;
memset(sunkbd, 0, sizeof(struct sunkbd));
init_input_dev(&sunkbd->dev);
init_waitqueue_head(&sunkbd->wait);
sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
sunkbd->serio = serio;
INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
sunkbd->dev.keycode = sunkbd->keycode;
sunkbd->dev.keycodesize = sizeof(unsigned char);
sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
sunkbd->dev.event = sunkbd_event;
sunkbd->dev.private = sunkbd;
serio->private = sunkbd;
if (serio_open(serio, drv)) {
kfree(sunkbd);
return;
}
if (sunkbd_initialize(sunkbd) < 0) {
serio_close(serio);
kfree(sunkbd);
return;
}
sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
for (i = 0; i < 128; i++)
set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
clear_bit(0, sunkbd->dev.keybit);
sprintf(sunkbd->phys, "%s/input0", serio->phys);
sunkbd->dev.name = sunkbd->name;
sunkbd->dev.phys = sunkbd->phys;
sunkbd->dev.id.bustype = BUS_RS232;
sunkbd->dev.id.vendor = SERIO_SUNKBD;
sunkbd->dev.id.product = sunkbd->type;
sunkbd->dev.id.version = 0x0100;
input_register_device(&sunkbd->dev);
printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
}
/*
* sunkbd_disconnect() unregisters and closes behind us.
*/
static void sunkbd_disconnect(struct serio *serio)
{
struct sunkbd *sunkbd = serio->private;
input_unregister_device(&sunkbd->dev);
serio_close(serio);
kfree(sunkbd);
}
static struct serio_driver sunkbd_drv = {
.driver = {
.name = "sunkbd",
},
.description = DRIVER_DESC,
.interrupt = sunkbd_interrupt,
.connect = sunkbd_connect,
.disconnect = sunkbd_disconnect,
};
/*
* The functions for insering/removing us as a module.
*/
int __init sunkbd_init(void)
{
serio_register_driver(&sunkbd_drv);
return 0;
}
void __exit sunkbd_exit(void)
{
serio_unregister_driver(&sunkbd_drv);
}
module_init(sunkbd_init);
module_exit(sunkbd_exit);

View File

@@ -0,0 +1,170 @@
/*
* $Id: xtkbd.c,v 1.11 2001/09/25 10:12:07 vojtech Exp $
*
* Copyright (c) 1999-2001 Vojtech Pavlik
*/
/*
* XT keyboard driver for Linux
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#define DRIVER_DESC "XT keyboard driver"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
#define XTKBD_EMUL0 0xe0
#define XTKBD_EMUL1 0xe1
#define XTKBD_KEY 0x7f
#define XTKBD_RELEASE 0x80
static unsigned char xtkbd_keycode[256] = {
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, 0, 0, 0, 87, 88, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 87, 88, 0, 0, 0, 0,110,111,103,108,105,
106
};
static char *xtkbd_name = "XT Keyboard";
struct xtkbd {
unsigned char keycode[256];
struct input_dev dev;
struct serio *serio;
char phys[32];
};
irqreturn_t xtkbd_interrupt(struct serio *serio,
unsigned char data, unsigned int flags, struct pt_regs *regs)
{
struct xtkbd *xtkbd = serio->private;
switch (data) {
case XTKBD_EMUL0:
case XTKBD_EMUL1:
break;
default:
if (xtkbd->keycode[data & XTKBD_KEY]) {
input_regs(&xtkbd->dev, regs);
input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
input_sync(&xtkbd->dev);
} else {
printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
}
}
return IRQ_HANDLED;
}
void xtkbd_connect(struct serio *serio, struct serio_driver *drv)
{
struct xtkbd *xtkbd;
int i;
if ((serio->type & SERIO_TYPE) != SERIO_XT)
return;
if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
return;
memset(xtkbd, 0, sizeof(struct xtkbd));
xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
xtkbd->serio = serio;
init_input_dev(&xtkbd->dev);
xtkbd->dev.keycode = xtkbd->keycode;
xtkbd->dev.keycodesize = sizeof(unsigned char);
xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
xtkbd->dev.private = xtkbd;
serio->private = xtkbd;
if (serio_open(serio, drv)) {
kfree(xtkbd);
return;
}
memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
for (i = 0; i < 255; i++)
set_bit(xtkbd->keycode[i], xtkbd->dev.keybit);
clear_bit(0, xtkbd->dev.keybit);
sprintf(xtkbd->phys, "%s/input0", serio->phys);
xtkbd->dev.name = xtkbd_name;
xtkbd->dev.phys = xtkbd->phys;
xtkbd->dev.id.bustype = BUS_XTKBD;
xtkbd->dev.id.vendor = 0x0001;
xtkbd->dev.id.product = 0x0001;
xtkbd->dev.id.version = 0x0100;
input_register_device(&xtkbd->dev);
printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
}
void xtkbd_disconnect(struct serio *serio)
{
struct xtkbd *xtkbd = serio->private;
input_unregister_device(&xtkbd->dev);
serio_close(serio);
kfree(xtkbd);
}
struct serio_driver xtkbd_drv = {
.driver = {
.name = "xtkbd",
},
.description = DRIVER_DESC,
.interrupt = xtkbd_interrupt,
.connect = xtkbd_connect,
.disconnect = xtkbd_disconnect,
};
int __init xtkbd_init(void)
{
serio_register_driver(&xtkbd_drv);
return 0;
}
void __exit xtkbd_exit(void)
{
serio_unregister_driver(&xtkbd_drv);
}
module_init(xtkbd_init);
module_exit(xtkbd_exit);