From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 24 Nov 2007 18:46:45 +0000 (+0100) Subject: drivers/input : move input drivers to drivers/input X-Git-Tag: v1.3.1-rc1~1^2~7 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=16b195c82a18cbfd164800f17a1ef9db2e48331a;p=oweals%2Fu-boot.git drivers/input : move input drivers to drivers/input Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- diff --git a/Makefile b/Makefile index 24a351d61a..160b9066bb 100644 --- a/Makefile +++ b/Makefile @@ -210,6 +210,7 @@ LIBS += dtt/libdtt.a LIBS += drivers/libdrivers.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/i2c/libi2c.a +LIBS += drivers/input/libinput.a LIBS += drivers/nand/libnand.a LIBS += drivers/nand_legacy/libnand_legacy.a LIBS += drivers/net/libnet.a diff --git a/drivers/Makefile b/drivers/Makefile index 666957dff7..745a5ccb6c 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -45,15 +45,6 @@ COBJS-y += sil680.o COBJS-y += sym53c8xx.o COBJS-y += systemace.o -# -# Console Drivers -# -COBJS-y += i8042.o -COBJS-y += keyboard.o -COBJS-y += pc_keyb.o -COBJS-y += ps2ser.o -COBJS-y += ps2mult.o - # # Miscellaneous Drivers # diff --git a/drivers/i8042.c b/drivers/i8042.c deleted file mode 100644 index 22c2a4e3a0..0000000000 --- a/drivers/i8042.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * (C) Copyright 2002 ELTEC Elektronik AG - * Frank Gottschling - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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 - */ - -/* i8042.c - Intel 8042 keyboard driver routines */ - -/* includes */ - -#include - -#ifdef CONFIG_I8042_KBD - -#ifdef CONFIG_USE_CPCIDVI -extern u8 gt_cpcidvi_in8(u32 offset); -extern void gt_cpcidvi_out8(u32 offset, u8 data); - -#define in8(a) gt_cpcidvi_in8(a) -#define out8(a, b) gt_cpcidvi_out8(a,b) -#endif - -#include - -/* defines */ - -#ifdef CONFIG_CONSOLE_CURSOR -extern void console_cursor (int state); -static int blinkCount = CFG_CONSOLE_BLINK_COUNT; -static int cursor_state = 0; -#endif - -/* locals */ - -static int kbd_input = -1; /* no input yet */ -static int kbd_mapping = KBD_US; /* default US keyboard */ -static int kbd_flags = NORMAL; /* after reset */ -static int kbd_state = 0; /* unshift code */ - -static void kbd_conv_char (unsigned char scan_code); -static void kbd_led_set (void); -static void kbd_normal (unsigned char scan_code); -static void kbd_shift (unsigned char scan_code); -static void kbd_ctrl (unsigned char scan_code); -static void kbd_num (unsigned char scan_code); -static void kbd_caps (unsigned char scan_code); -static void kbd_scroll (unsigned char scan_code); -static void kbd_alt (unsigned char scan_code); -static int kbd_input_empty (void); -static int kbd_reset (void); - -static unsigned char kbd_fct_map [144] = - { /* kbd_fct_map table for scan code */ - 0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */ - AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */ - AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */ - AS, AS, SH, AS, AS, AS, AS, AS, /* scan 28-2F */ - AS, AS, AS, AS, AS, AS, SH, AS, /* scan 30-37 */ - AS, AS, CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, ES, /* scan 40-47 */ - ES, ES, ES, ES, ES, ES, ES, ES, /* scan 48-4F */ - ES, ES, ES, ES, 0, 0, AS, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - AS, 0, 0, AS, 0, 0, AS, 0, /* scan 70-77 */ - 0, AS, 0, 0, 0, AS, 0, 0, /* scan 78-7F */ - AS, CN, AS, AS, AK, ST, EX, EX, /* enhanced */ - AS, EX, EX, AS, EX, AS, EX, EX /* enhanced */ - }; - -static unsigned char kbd_key_map [2][5][144] = - { - { /* US keyboard */ - { /* unshift code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ - 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ - '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* shift code */ - 0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */ - '&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */ - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */ - 'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */ - '"', '~', SH, '|', 'Z', 'X', 'C', 'V', /* scan 28-2F */ - 'B', 'N', 'M', '<', '>', '?', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* control code */ - 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ - 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ - 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ - 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ - 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ - 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ - 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ - 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ - }, - { /* non numeric code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ - 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ - '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ - 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ - 'r', 's', 'p', 'n', 0, 0, 0, 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* right alt mode - not used in US keyboard */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ - } - }, - { /* german keyboard */ - { /* unshift code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ - 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ - 0x84, '^', SH, '#', 'y', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', ',', 0, 0, '<', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* shift code */ - 0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */ - '/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */ - 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */ - 'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */ - 0x8e, 0xf8, SH, '\'', 'Y', 'X', 'C', 'V', /* scan 28-2F */ - 'B', 'N', 'M', ';', ':', '_', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ - '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ - '2', '3', '0', ',', 0, 0, '>', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* control code */ - 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ - 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ - 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ - 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ - 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ - 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ - 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ - 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ - }, - { /* non numeric code */ - 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ - '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ - 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ - 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ - 0x84, '^', SH, 0, 'y', 'x', 'c', 'v', /* scan 28-2F */ - 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ - ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ - 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ - 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ - 'r', 's', 'p', 'n', 0, 0, '<', 0, /* scan 50-57 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ - '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ - 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ - }, - { /* Right alt mode - is used in German keyboard */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ - '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */ - '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ - 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ - 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ - } - } - }; - -static unsigned char ext_key_map [] = - { - 0x1c, /* keypad enter */ - 0x1d, /* right control */ - 0x35, /* keypad slash */ - 0x37, /* print screen */ - 0x38, /* right alt */ - 0x46, /* break */ - 0x47, /* editpad home */ - 0x48, /* editpad up */ - 0x49, /* editpad pgup */ - 0x4b, /* editpad left */ - 0x4d, /* editpad right */ - 0x4f, /* editpad end */ - 0x50, /* editpad dn */ - 0x51, /* editpad pgdn */ - 0x52, /* editpad ins */ - 0x53, /* editpad del */ - 0x00 /* map end */ - }; - -/******************************************************************************* - * - * i8042_kbd_init - reset keyboard and init state flags - */ -int i8042_kbd_init (void) -{ - int keymap, try; - char *penv; - -#ifdef CONFIG_USE_CPCIDVI - if ((penv = getenv ("console")) != NULL) { - if (strncmp (penv, "serial", 7) == 0) { - return -1; - } - } -#endif - /* Init keyboard device (default US layout) */ - keymap = KBD_US; - if ((penv = getenv ("keymap")) != NULL) - { - if (strncmp (penv, "de", 3) == 0) - keymap = KBD_GER; - } - - for (try = 0; try < KBD_RESET_TRIES; try++) - { - if (kbd_reset() == 0) - { - kbd_mapping = keymap; - kbd_flags = NORMAL; - kbd_state = 0; - kbd_led_set(); - return 0; - } - } - return -1; -} - - -/******************************************************************************* - * - * i8042_tstc - test if keyboard input is available - * option: cursor blinking if called in a loop - */ -int i8042_tstc (void) -{ - unsigned char scan_code = 0; - -#ifdef CONFIG_CONSOLE_CURSOR - if (--blinkCount == 0) - { - cursor_state ^= 1; - console_cursor (cursor_state); - blinkCount = CFG_CONSOLE_BLINK_COUNT; - udelay (10); - } -#endif - - if ((in8 (I8042_STATUS_REG) & 0x01) == 0) - return 0; - else - { - scan_code = in8 (I8042_DATA_REG); - if (scan_code == 0xfa) - return 0; - - kbd_conv_char(scan_code); - - if (kbd_input != -1) - return 1; - } - return 0; -} - - -/******************************************************************************* - * - * i8042_getc - wait till keyboard input is available - * option: turn on/off cursor while waiting - */ -int i8042_getc (void) -{ - int ret_chr; - unsigned char scan_code; - - while (kbd_input == -1) - { - while ((in8 (I8042_STATUS_REG) & 0x01) == 0) - { -#ifdef CONFIG_CONSOLE_CURSOR - if (--blinkCount==0) - { - cursor_state ^= 1; - console_cursor (cursor_state); - blinkCount = CFG_CONSOLE_BLINK_COUNT; - } - udelay (10); -#endif - } - - scan_code = in8 (I8042_DATA_REG); - - if (scan_code != 0xfa) - kbd_conv_char (scan_code); - } - ret_chr = kbd_input; - kbd_input = -1; - return ret_chr; -} - - -/******************************************************************************/ - -static void kbd_conv_char (unsigned char scan_code) -{ - if (scan_code == 0xe0) - { - kbd_flags |= EXT; - return; - } - - /* if high bit of scan_code, set break flag */ - if (scan_code & 0x80) - kbd_flags |= BRK; - else - kbd_flags &= ~BRK; - - if ((scan_code == 0xe1) || (kbd_flags & E1)) - { - if (scan_code == 0xe1) - { - kbd_flags ^= BRK; /* reset the break flag */ - kbd_flags ^= E1; /* bitwise EXOR with E1 flag */ - } - return; - } - - scan_code &= 0x7f; - - if (kbd_flags & EXT) - { - int i; - - kbd_flags ^= EXT; - for (i=0; ext_key_map[i]; i++) - { - if (ext_key_map[i] == scan_code) - { - scan_code = 0x80 + i; - break; - } - } - /* not found ? */ - if (!ext_key_map[i]) - return; - } - - switch (kbd_fct_map [scan_code]) - { - case AS: kbd_normal (scan_code); - break; - case SH: kbd_shift (scan_code); - break; - case CN: kbd_ctrl (scan_code); - break; - case NM: kbd_num (scan_code); - break; - case CP: kbd_caps (scan_code); - break; - case ST: kbd_scroll (scan_code); - break; - case AK: kbd_alt (scan_code); - break; - } - return; -} - - -/******************************************************************************/ - -static void kbd_normal (unsigned char scan_code) -{ - unsigned char chr; - - if ((kbd_flags & BRK) == NORMAL) - { - chr = kbd_key_map [kbd_mapping][kbd_state][scan_code]; - if ((chr == 0xff) || (chr == 0x00)) - { - return; - } - - /* if caps lock convert upper to lower */ - if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z')) - { - chr -= 'a' - 'A'; - } - kbd_input = chr; - } -} - - -/******************************************************************************/ - -static void kbd_shift (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == BRK) - { - kbd_state = AS; - kbd_flags &= (~SHIFT); - } - else - { - kbd_state = SH; - kbd_flags |= SHIFT; - } -} - - -/******************************************************************************/ - -static void kbd_ctrl (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == BRK) - { - kbd_state = AS; - kbd_flags &= (~CTRL); - } - else - { - kbd_state = CN; - kbd_flags |= CTRL; - } -} - - -/******************************************************************************/ - -static void kbd_caps (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == NORMAL) - { - kbd_flags ^= CAPS; - kbd_led_set (); /* update keyboard LED */ - } -} - - -/******************************************************************************/ - -static void kbd_num (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == NORMAL) - { - kbd_flags ^= NUM; - kbd_state = (kbd_flags & NUM) ? AS : NM; - kbd_led_set (); /* update keyboard LED */ - } -} - - -/******************************************************************************/ - -static void kbd_scroll (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == NORMAL) - { - kbd_flags ^= STP; - kbd_led_set (); /* update keyboard LED */ - if (kbd_flags & STP) - kbd_input = 0x13; - else - kbd_input = 0x11; - } -} - -/******************************************************************************/ - -static void kbd_alt (unsigned char scan_code) -{ - if ((kbd_flags & BRK) == BRK) - { - kbd_state = AS; - kbd_flags &= (~ALT); - } - else - { - kbd_state = AK; - kbd_flags &= ALT; - } -} - - -/******************************************************************************/ - -static void kbd_led_set (void) -{ - kbd_input_empty(); - out8 (I8042_DATA_REG, 0xed); /* SET LED command */ - kbd_input_empty(); - out8 (I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */ -} - - -/******************************************************************************/ - -static int kbd_input_empty (void) -{ - int kbdTimeout = KBD_TIMEOUT; - - /* wait for input buf empty */ - while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--) - udelay(1000); - - return kbdTimeout; -} - -/******************************************************************************/ - -static int kbd_reset (void) -{ - if (kbd_input_empty() == 0) - return -1; - - out8 (I8042_DATA_REG, 0xff); - - udelay(250000); - - if (kbd_input_empty() == 0) - return -1; - -#ifdef CONFIG_USE_CPCIDVI - out8 (I8042_COMMAND_REG, 0x60); -#else - out8 (I8042_DATA_REG, 0x60); -#endif - - if (kbd_input_empty() == 0) - return -1; - - out8 (I8042_DATA_REG, 0x45); - - - if (kbd_input_empty() == 0) - return -1; - - out8 (I8042_COMMAND_REG, 0xae); - - if (kbd_input_empty() == 0) - return -1; - - return 0; -} - -#endif /* CONFIG_I8042_KBD */ diff --git a/drivers/input/Makefile b/drivers/input/Makefile new file mode 100644 index 0000000000..df22cf9c6d --- /dev/null +++ b/drivers/input/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libinput.a + +COBJS-y += i8042.o +COBJS-y += keyboard.o +COBJS-y += pc_keyb.o ps2ser.o ps2mult.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c new file mode 100644 index 0000000000..22c2a4e3a0 --- /dev/null +++ b/drivers/input/i8042.c @@ -0,0 +1,674 @@ +/* + * (C) Copyright 2002 ELTEC Elektronik AG + * Frank Gottschling + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +/* i8042.c - Intel 8042 keyboard driver routines */ + +/* includes */ + +#include + +#ifdef CONFIG_I8042_KBD + +#ifdef CONFIG_USE_CPCIDVI +extern u8 gt_cpcidvi_in8(u32 offset); +extern void gt_cpcidvi_out8(u32 offset, u8 data); + +#define in8(a) gt_cpcidvi_in8(a) +#define out8(a, b) gt_cpcidvi_out8(a,b) +#endif + +#include + +/* defines */ + +#ifdef CONFIG_CONSOLE_CURSOR +extern void console_cursor (int state); +static int blinkCount = CFG_CONSOLE_BLINK_COUNT; +static int cursor_state = 0; +#endif + +/* locals */ + +static int kbd_input = -1; /* no input yet */ +static int kbd_mapping = KBD_US; /* default US keyboard */ +static int kbd_flags = NORMAL; /* after reset */ +static int kbd_state = 0; /* unshift code */ + +static void kbd_conv_char (unsigned char scan_code); +static void kbd_led_set (void); +static void kbd_normal (unsigned char scan_code); +static void kbd_shift (unsigned char scan_code); +static void kbd_ctrl (unsigned char scan_code); +static void kbd_num (unsigned char scan_code); +static void kbd_caps (unsigned char scan_code); +static void kbd_scroll (unsigned char scan_code); +static void kbd_alt (unsigned char scan_code); +static int kbd_input_empty (void); +static int kbd_reset (void); + +static unsigned char kbd_fct_map [144] = + { /* kbd_fct_map table for scan code */ + 0, AS, AS, AS, AS, AS, AS, AS, /* scan 0- 7 */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 8- F */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 10-17 */ + AS, AS, AS, AS, AS, CN, AS, AS, /* scan 18-1F */ + AS, AS, AS, AS, AS, AS, AS, AS, /* scan 20-27 */ + AS, AS, SH, AS, AS, AS, AS, AS, /* scan 28-2F */ + AS, AS, AS, AS, AS, AS, SH, AS, /* scan 30-37 */ + AS, AS, CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, ES, /* scan 40-47 */ + ES, ES, ES, ES, ES, ES, ES, ES, /* scan 48-4F */ + ES, ES, ES, ES, 0, 0, AS, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + AS, 0, 0, AS, 0, 0, AS, 0, /* scan 70-77 */ + 0, AS, 0, 0, 0, AS, 0, 0, /* scan 78-7F */ + AS, CN, AS, AS, AK, ST, EX, EX, /* enhanced */ + AS, EX, EX, AS, EX, AS, EX, EX /* enhanced */ + }; + +static unsigned char kbd_key_map [2][5][144] = + { + { /* US keyboard */ + { /* unshift code */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ + 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ + '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* shift code */ + 0, 0x1b, '!', '@', '#', '$', '%', '^', /* scan 0- 7 */ + '&', '*', '(', ')', '_', '+', 0x08, '\t', /* scan 8- F */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* scan 10-17 */ + 'O', 'P', '{', '}', '\r', CN, 'A', 'S', /* scan 18-1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* scan 20-27 */ + '"', '~', SH, '|', 'Z', 'X', 'C', 'V', /* scan 28-2F */ + 'B', 'N', 'M', '<', '>', '?', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', '.', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* control code */ + 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ + 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ + 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ + 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ + 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ + 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ + 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + }, + { /* non numeric code */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', '-', '=', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* scan 10-17 */ + 'o', 'p', '[', ']', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* scan 20-27 */ + '\'', '`', SH, '\\', 'z', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '/', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ + 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ + 'r', 's', 'p', 'n', 0, 0, 0, 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* right alt mode - not used in US keyboard */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 8 - F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50 -57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + } + }, + { /* german keyboard */ + { /* unshift code */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ + 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ + 0x84, '^', SH, '#', 'y', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', ',', 0, 0, '<', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* shift code */ + 0, 0x1b, '!', '"', 0x15, '$', '%', '&', /* scan 0- 7 */ + '/', '(', ')', '=', '?', '`', 0x08, '\t', /* scan 8- F */ + 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', /* scan 10-17 */ + 'O', 'P', 0x9a, '*', '\r', CN, 'A', 'S', /* scan 18-1F */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0x99, /* scan 20-27 */ + 0x8e, 0xf8, SH, '\'', 'Y', 'X', 'C', 'V', /* scan 28-2F */ + 'B', 'N', 'M', ';', ':', '_', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, '7', /* scan 40-47 */ + '8', '9', '-', '4', '5', '6', '+', '1', /* scan 48-4F */ + '2', '3', '0', ',', 0, 0, '>', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* control code */ + 0xff, 0x1b, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, /* scan 0- 7 */ + 0x1e, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, '\t', /* scan 8- F */ + 0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* scan 10-17 */ + 0x0f, 0x10, 0x1b, 0x1d, '\r', CN, 0x01, 0x13, /* scan 18-1F */ + 0x04, 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0xff, /* scan 20-27 */ + 0xff, 0x1c, SH, 0xff, 0x1a, 0x18, 0x03, 0x16, /* scan 28-2F */ + 0x02, 0x0e, 0x0d, 0xff, 0xff, 0xff, SH, 0xff, /* scan 30-37 */ + 0xff, 0xff, CP, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38-3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, NM, ST, 0xff, /* scan 40-47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48-4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 50-57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58-5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60-67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68-6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70-77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + }, + { /* non numeric code */ + 0, 0x1b, '1', '2', '3', '4', '5', '6', /* scan 0- 7 */ + '7', '8', '9', '0', 0xe1, '\'', 0x08, '\t', /* scan 8- F */ + 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', /* scan 10-17 */ + 'o', 'p', 0x81, '+', '\r', CN, 'a', 's', /* scan 18-1F */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0x94, /* scan 20-27 */ + 0x84, '^', SH, 0, 'y', 'x', 'c', 'v', /* scan 28-2F */ + 'b', 'n', 'm', ',', '.', '-', SH, '*', /* scan 30-37 */ + ' ', ' ', CP, 0, 0, 0, 0, 0, /* scan 38-3F */ + 0, 0, 0, 0, 0, NM, ST, 'w', /* scan 40-47 */ + 'x', 'y', 'l', 't', 'u', 'v', 'm', 'q', /* scan 48-4F */ + 'r', 's', 'p', 'n', 0, 0, '<', 0, /* scan 50-57 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 58-5F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 60-67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 68-6F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 70-77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* scan 78-7F */ + '\r', CN, '/', '*', ' ', ST, 'F', 'A', /* extended */ + 0, 'D', 'C', 0, 'B', 0, '@', 'P' /* extended */ + }, + { /* Right alt mode - is used in German keyboard */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 0 - 7 */ + '{', '[', ']', '}', '\\', 0xff, 0xff, 0xff, /* scan 8 - F */ + '@', 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 10 -17 */ + 0xff, 0xff, 0xff, '~', 0xff, 0xff, 0xff, 0xff, /* scan 18 -1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 20 -27 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 28 -2F */ + 0xff, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 30 -37 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 38 -3F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 40 -47 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 48 -4F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, '|', 0xff, /* scan 50 -57 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 58 -5F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 60 -67 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 68 -6F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 70 -77 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* scan 78 -7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* extended */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff /* extended */ + } + } + }; + +static unsigned char ext_key_map [] = + { + 0x1c, /* keypad enter */ + 0x1d, /* right control */ + 0x35, /* keypad slash */ + 0x37, /* print screen */ + 0x38, /* right alt */ + 0x46, /* break */ + 0x47, /* editpad home */ + 0x48, /* editpad up */ + 0x49, /* editpad pgup */ + 0x4b, /* editpad left */ + 0x4d, /* editpad right */ + 0x4f, /* editpad end */ + 0x50, /* editpad dn */ + 0x51, /* editpad pgdn */ + 0x52, /* editpad ins */ + 0x53, /* editpad del */ + 0x00 /* map end */ + }; + +/******************************************************************************* + * + * i8042_kbd_init - reset keyboard and init state flags + */ +int i8042_kbd_init (void) +{ + int keymap, try; + char *penv; + +#ifdef CONFIG_USE_CPCIDVI + if ((penv = getenv ("console")) != NULL) { + if (strncmp (penv, "serial", 7) == 0) { + return -1; + } + } +#endif + /* Init keyboard device (default US layout) */ + keymap = KBD_US; + if ((penv = getenv ("keymap")) != NULL) + { + if (strncmp (penv, "de", 3) == 0) + keymap = KBD_GER; + } + + for (try = 0; try < KBD_RESET_TRIES; try++) + { + if (kbd_reset() == 0) + { + kbd_mapping = keymap; + kbd_flags = NORMAL; + kbd_state = 0; + kbd_led_set(); + return 0; + } + } + return -1; +} + + +/******************************************************************************* + * + * i8042_tstc - test if keyboard input is available + * option: cursor blinking if called in a loop + */ +int i8042_tstc (void) +{ + unsigned char scan_code = 0; + +#ifdef CONFIG_CONSOLE_CURSOR + if (--blinkCount == 0) + { + cursor_state ^= 1; + console_cursor (cursor_state); + blinkCount = CFG_CONSOLE_BLINK_COUNT; + udelay (10); + } +#endif + + if ((in8 (I8042_STATUS_REG) & 0x01) == 0) + return 0; + else + { + scan_code = in8 (I8042_DATA_REG); + if (scan_code == 0xfa) + return 0; + + kbd_conv_char(scan_code); + + if (kbd_input != -1) + return 1; + } + return 0; +} + + +/******************************************************************************* + * + * i8042_getc - wait till keyboard input is available + * option: turn on/off cursor while waiting + */ +int i8042_getc (void) +{ + int ret_chr; + unsigned char scan_code; + + while (kbd_input == -1) + { + while ((in8 (I8042_STATUS_REG) & 0x01) == 0) + { +#ifdef CONFIG_CONSOLE_CURSOR + if (--blinkCount==0) + { + cursor_state ^= 1; + console_cursor (cursor_state); + blinkCount = CFG_CONSOLE_BLINK_COUNT; + } + udelay (10); +#endif + } + + scan_code = in8 (I8042_DATA_REG); + + if (scan_code != 0xfa) + kbd_conv_char (scan_code); + } + ret_chr = kbd_input; + kbd_input = -1; + return ret_chr; +} + + +/******************************************************************************/ + +static void kbd_conv_char (unsigned char scan_code) +{ + if (scan_code == 0xe0) + { + kbd_flags |= EXT; + return; + } + + /* if high bit of scan_code, set break flag */ + if (scan_code & 0x80) + kbd_flags |= BRK; + else + kbd_flags &= ~BRK; + + if ((scan_code == 0xe1) || (kbd_flags & E1)) + { + if (scan_code == 0xe1) + { + kbd_flags ^= BRK; /* reset the break flag */ + kbd_flags ^= E1; /* bitwise EXOR with E1 flag */ + } + return; + } + + scan_code &= 0x7f; + + if (kbd_flags & EXT) + { + int i; + + kbd_flags ^= EXT; + for (i=0; ext_key_map[i]; i++) + { + if (ext_key_map[i] == scan_code) + { + scan_code = 0x80 + i; + break; + } + } + /* not found ? */ + if (!ext_key_map[i]) + return; + } + + switch (kbd_fct_map [scan_code]) + { + case AS: kbd_normal (scan_code); + break; + case SH: kbd_shift (scan_code); + break; + case CN: kbd_ctrl (scan_code); + break; + case NM: kbd_num (scan_code); + break; + case CP: kbd_caps (scan_code); + break; + case ST: kbd_scroll (scan_code); + break; + case AK: kbd_alt (scan_code); + break; + } + return; +} + + +/******************************************************************************/ + +static void kbd_normal (unsigned char scan_code) +{ + unsigned char chr; + + if ((kbd_flags & BRK) == NORMAL) + { + chr = kbd_key_map [kbd_mapping][kbd_state][scan_code]; + if ((chr == 0xff) || (chr == 0x00)) + { + return; + } + + /* if caps lock convert upper to lower */ + if (((kbd_flags & CAPS) == CAPS) && (chr >= 'a' && chr <= 'z')) + { + chr -= 'a' - 'A'; + } + kbd_input = chr; + } +} + + +/******************************************************************************/ + +static void kbd_shift (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == BRK) + { + kbd_state = AS; + kbd_flags &= (~SHIFT); + } + else + { + kbd_state = SH; + kbd_flags |= SHIFT; + } +} + + +/******************************************************************************/ + +static void kbd_ctrl (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == BRK) + { + kbd_state = AS; + kbd_flags &= (~CTRL); + } + else + { + kbd_state = CN; + kbd_flags |= CTRL; + } +} + + +/******************************************************************************/ + +static void kbd_caps (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == NORMAL) + { + kbd_flags ^= CAPS; + kbd_led_set (); /* update keyboard LED */ + } +} + + +/******************************************************************************/ + +static void kbd_num (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == NORMAL) + { + kbd_flags ^= NUM; + kbd_state = (kbd_flags & NUM) ? AS : NM; + kbd_led_set (); /* update keyboard LED */ + } +} + + +/******************************************************************************/ + +static void kbd_scroll (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == NORMAL) + { + kbd_flags ^= STP; + kbd_led_set (); /* update keyboard LED */ + if (kbd_flags & STP) + kbd_input = 0x13; + else + kbd_input = 0x11; + } +} + +/******************************************************************************/ + +static void kbd_alt (unsigned char scan_code) +{ + if ((kbd_flags & BRK) == BRK) + { + kbd_state = AS; + kbd_flags &= (~ALT); + } + else + { + kbd_state = AK; + kbd_flags &= ALT; + } +} + + +/******************************************************************************/ + +static void kbd_led_set (void) +{ + kbd_input_empty(); + out8 (I8042_DATA_REG, 0xed); /* SET LED command */ + kbd_input_empty(); + out8 (I8042_DATA_REG, (kbd_flags & 0x7)); /* LED bits only */ +} + + +/******************************************************************************/ + +static int kbd_input_empty (void) +{ + int kbdTimeout = KBD_TIMEOUT; + + /* wait for input buf empty */ + while ((in8 (I8042_STATUS_REG) & 0x02) && kbdTimeout--) + udelay(1000); + + return kbdTimeout; +} + +/******************************************************************************/ + +static int kbd_reset (void) +{ + if (kbd_input_empty() == 0) + return -1; + + out8 (I8042_DATA_REG, 0xff); + + udelay(250000); + + if (kbd_input_empty() == 0) + return -1; + +#ifdef CONFIG_USE_CPCIDVI + out8 (I8042_COMMAND_REG, 0x60); +#else + out8 (I8042_DATA_REG, 0x60); +#endif + + if (kbd_input_empty() == 0) + return -1; + + out8 (I8042_DATA_REG, 0x45); + + + if (kbd_input_empty() == 0) + return -1; + + out8 (I8042_COMMAND_REG, 0xae); + + if (kbd_input_empty() == 0) + return -1; + + return 0; +} + +#endif /* CONFIG_I8042_KBD */ diff --git a/drivers/input/keyboard.c b/drivers/input/keyboard.c new file mode 100644 index 0000000000..9975202d7a --- /dev/null +++ b/drivers/input/keyboard.c @@ -0,0 +1,305 @@ +/*********************************************************************** + * + * (C) Copyright 2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * Keyboard driver + * + ***********************************************************************/ + +#include + +#ifdef CONFIG_PS2KBD + +#include +#include + +#undef KBG_DEBUG + +#ifdef KBG_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + + +#define DEVNAME "kbd" + +#define LED_SCR 0x01 /* scroll lock led */ +#define LED_CAP 0x04 /* caps lock led */ +#define LED_NUM 0x02 /* num lock led */ + +#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */ + +#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) +int ps2ser_check(void); +#endif + +static volatile char kbd_buffer[KBD_BUFFER_LEN]; +static volatile int in_pointer = 0; +static volatile int out_pointer = 0; + +static unsigned char leds = 0; +static unsigned char num_lock = 0; +static unsigned char caps_lock = 0; +static unsigned char scroll_lock = 0; +static unsigned char shift = 0; +static unsigned char ctrl = 0; +static unsigned char alt = 0; +static unsigned char e0 = 0; + +/****************************************************************** + * Queue handling + ******************************************************************/ + +/* puts character in the queue and sets up the in and out pointer */ +static void kbd_put_queue(char data) +{ + if((in_pointer+1)==KBD_BUFFER_LEN) { + if(out_pointer==0) { + return; /* buffer full */ + } else{ + in_pointer=0; + } + } else { + if((in_pointer+1)==out_pointer) + return; /* buffer full */ + in_pointer++; + } + kbd_buffer[in_pointer]=data; + return; +} + +/* test if a character is in the queue */ +static int kbd_testc(void) +{ +#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + /* no ISR is used, so received chars must be polled */ + ps2ser_check(); +#endif + if(in_pointer==out_pointer) + return(0); /* no data */ + else + return(1); +} + +/* gets the character from the queue */ +static int kbd_getc(void) +{ + char c; + while(in_pointer==out_pointer) { +#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + /* no ISR is used, so received chars must be polled */ + ps2ser_check(); +#endif + ;} + if((out_pointer+1)==KBD_BUFFER_LEN) + out_pointer=0; + else + out_pointer++; + c=kbd_buffer[out_pointer]; + return (int)c; + +} + +/* Simple translation table for the keys */ + +static unsigned char kbd_plain_xlate[] = { + 0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ + 'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + +static unsigned char kbd_shift_xlate[] = { + 0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */ + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */ + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */ + 'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + +static unsigned char kbd_ctrl_xlate[] = { + 0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */ + 0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */ + 0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */ + 0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ + 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ + '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ + '\r',0xff,0xff + }; + + +void handle_scancode(unsigned char scancode) +{ + unsigned char keycode; + + /* Convert scancode to keycode */ + PRINTF("scancode %x\n",scancode); + if(scancode==0xe0) { + e0=1; /* special charakters */ + return; + } + if(e0==1) { + e0=0; /* delete flag */ + if(!( ((scancode&0x7F)==0x38)|| /* the right ctrl key */ + ((scancode&0x7F)==0x1D)|| /* the right alt key */ + ((scancode&0x7F)==0x35)|| /* the right '/' key */ + ((scancode&0x7F)==0x1C) )) /* the right enter key */ + /* we swallow unknown e0 codes */ + return; + } + /* special cntrl keys */ + switch(scancode) { + case 0x2A: + case 0x36: /* shift pressed */ + shift=1; + return; /* do nothing else */ + case 0xAA: + case 0xB6: /* shift released */ + shift=0; + return; /* do nothing else */ + case 0x38: /* alt pressed */ + alt=1; + return; /* do nothing else */ + case 0xB8: /* alt released */ + alt=0; + return; /* do nothing else */ + case 0x1d: /* ctrl pressed */ + ctrl=1; + return; /* do nothing else */ + case 0x9d: /* ctrl released */ + ctrl=0; + return; /* do nothing else */ + case 0x46: /* scrollock pressed */ + scroll_lock=~scroll_lock; + if(scroll_lock==0) + leds&=~LED_SCR; /* switch LED off */ + else + leds|=LED_SCR; /* switch on LED */ + pckbd_leds(leds); + return; /* do nothing else */ + case 0x3A: /* capslock pressed */ + caps_lock=~caps_lock; + if(caps_lock==0) + leds&=~LED_CAP; /* switch caps_lock off */ + else + leds|=LED_CAP; /* switch on LED */ + pckbd_leds(leds); + return; + case 0x45: /* numlock pressed */ + num_lock=~num_lock; + if(num_lock==0) + leds&=~LED_NUM; /* switch LED off */ + else + leds|=LED_NUM; /* switch on LED */ + pckbd_leds(leds); + return; + case 0xC6: /* scroll lock released */ + case 0xC5: /* num lock released */ + case 0xBA: /* caps lock released */ + return; /* just swallow */ + } +#if 1 + if((scancode&0x80)==0x80) /* key released */ + return; +#else + if((scancode&0x80)==0x00) /* key pressed */ + return; + scancode &= ~0x80; +#endif + /* now, decide which table we need */ + if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown scancode %X\n",scancode); + return; /* swallow it */ + } + /* setup plain code first */ + keycode=kbd_plain_xlate[scancode]; + if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */ + if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown caps-locked scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_shift_xlate[scancode]; + if(keycode<'A') { /* we only want the alphas capital */ + keycode=kbd_plain_xlate[scancode]; + } + } + if(shift==1) { /* shift overwrites caps_lock */ + if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown shifted scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_shift_xlate[scancode]; + } + if(ctrl==1) { /* ctrl overwrites caps_lock and shift */ + if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */ + PRINTF("unkown ctrl scancode %X\n",scancode); + return; /* swallow it */ + } + keycode=kbd_ctrl_xlate[scancode]; + } + /* check if valid keycode */ + if(keycode==0xff) { + PRINTF("unkown scancode %X\n",scancode); + return; /* swallow unknown codes */ + } + + kbd_put_queue(keycode); + PRINTF("%x\n",keycode); +} + +/****************************************************************** + * Init + ******************************************************************/ + +#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE +extern int overwrite_console (void); +#define OVERWRITE_CONSOLE overwrite_console () +#else +#define OVERWRITE_CONSOLE 0 +#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */ + +int kbd_init (void) +{ + int error; + device_t kbddev ; + char *stdinname = getenv ("stdin"); + + if(kbd_init_hw()==-1) + return -1; + memset (&kbddev, 0, sizeof(kbddev)); + strcpy(kbddev.name, DEVNAME); + kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + kbddev.putc = NULL ; + kbddev.puts = NULL ; + kbddev.getc = kbd_getc ; + kbddev.tstc = kbd_testc ; + + error = device_register (&kbddev); + if(error==0) { + /* check if this is the standard input device */ + if(strcmp(stdinname,DEVNAME)==0) { + /* reassign the console */ + if(OVERWRITE_CONSOLE) { + return 1; + } + error=console_assign(stdin,DEVNAME); + if(error==0) + return 1; + else + return error; + } + return 1; + } + return error; +} + +#endif /* CONFIG_PS2KBD */ diff --git a/drivers/input/pc_keyb.c b/drivers/input/pc_keyb.c new file mode 100644 index 0000000000..81d3e98934 --- /dev/null +++ b/drivers/input/pc_keyb.c @@ -0,0 +1,256 @@ +/*********************************************************************** + * + * (C) Copyright 2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * PS/2 keyboard driver + * + * Originally from linux source (drivers/char/pc_keyb.c) + * + ***********************************************************************/ + +#include + +#ifdef CONFIG_PS2KBD + +#include +#include + +#undef KBG_DEBUG + +#ifdef KBG_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + + +/* + * This reads the keyboard status port, and does the + * appropriate action. + * + */ +static unsigned char handle_kbd_event(void) +{ + unsigned char status = kbd_read_status(); + unsigned int work = 10000; + + while ((--work > 0) && (status & KBD_STAT_OBF)) { + unsigned char scancode; + + scancode = kbd_read_input(); + + /* Error bytes must be ignored to make the + Synaptics touchpads compaq use work */ + /* Ignore error bytes */ + if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) { + if (status & KBD_STAT_MOUSE_OBF) + ; /* not supported: handle_mouse_event(scancode); */ + else + handle_scancode(scancode); + } + status = kbd_read_status(); + } + if (!work) + PRINTF("pc_keyb: controller jammed (0x%02X).\n", status); + return status; +} + + +static int kbd_read_data(void) +{ + int val; + unsigned char status; + + val=-1; + status = kbd_read_status(); + if (status & KBD_STAT_OBF) { + val = kbd_read_input(); + if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) + val = -2; + } + return val; +} + +static int kbd_wait_for_input(void) +{ + unsigned long timeout; + int val; + + timeout = KBD_TIMEOUT; + val=kbd_read_data(); + while(val < 0) { + if(timeout--==0) + return -1; + udelay(1000); + val=kbd_read_data(); + } + return val; +} + + +static int kb_wait(void) +{ + unsigned long timeout = KBC_TIMEOUT * 10; + + do { + unsigned char status = handle_kbd_event(); + if (!(status & KBD_STAT_IBF)) + return 0; /* ok */ + udelay(1000); + timeout--; + } while (timeout); + return 1; +} + +static void kbd_write_command_w(int data) +{ + if(kb_wait()) + PRINTF("timeout in kbd_write_command_w\n"); + kbd_write_command(data); +} + +static void kbd_write_output_w(int data) +{ + if(kb_wait()) + PRINTF("timeout in kbd_write_output_w\n"); + kbd_write_output(data); +} + +static void kbd_send_data(unsigned char data) +{ + kbd_write_output_w(data); + kbd_wait_for_input(); +} + + +static char * kbd_initialize(void) +{ + int status; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) + return "Kbd: failed self test"; + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write_command_w(KBD_CCMD_KBD_TEST); + if (kbd_wait_for_input() != 0x00) + return "Kbd: interface failed self test"; + /* + * Enable the keyboard by allowing the keyboard clock to run. + */ + kbd_write_command_w(KBD_CCMD_KBD_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_RESET); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) { + PRINTF("status: %X\n",status); + return "Kbd: reset failed, no ACK"; + } + } while (1); + if (kbd_wait_for_input() != KBD_REPLY_POR) + return "Kbd: reset failed, no POR"; + + /* + * Set keyboard controller mode. During this, the keyboard should be + * in the disabled state. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write_output_w(KBD_CMD_DISABLE); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Kbd: disable keyboard: no ACK"; + } while (1); + + kbd_write_command_w(KBD_CCMD_WRITE_MODE); + kbd_write_output_w(KBD_MODE_KBD_INT + | KBD_MODE_SYS + | KBD_MODE_DISABLE_MOUSE + | KBD_MODE_KCC); + + /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */ + kbd_write_command_w(KBD_CCMD_READ_MODE); + if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { + /* + * If the controller does not support conversion, + * Set the keyboard to scan-code set 1. + */ + kbd_write_output_w(0xF0); + kbd_wait_for_input(); + kbd_write_output_w(0x01); + kbd_wait_for_input(); + } + kbd_write_output_w(KBD_CMD_ENABLE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Kbd: enable keyboard: no ACK"; + + /* + * Finally, set the typematic rate to maximum. + */ + kbd_write_output_w(KBD_CMD_SET_RATE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Kbd: Set rate: no ACK"; + kbd_write_output_w(0x00); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Kbd: Set rate: no ACK"; + return NULL; +} + +static void kbd_interrupt(void *dev_id) +{ + handle_kbd_event(); +} + +/****************************************************************** + * Init + ******************************************************************/ + +int kbd_init_hw(void) +{ + char* result; + + kbd_request_region(); + + result=kbd_initialize(); + if (result==NULL) { + PRINTF("AT Keyboard initialized\n"); + kbd_request_irq(kbd_interrupt); + return (1); + } else { + printf("%s\n",result); + return (-1); + } +} + +void pckbd_leds(unsigned char leds) +{ + kbd_send_data(KBD_CMD_SET_LEDS); + kbd_send_data(leds); +} + +#endif /* CONFIG_PS2KBD */ diff --git a/drivers/input/ps2mult.c b/drivers/input/ps2mult.c new file mode 100644 index 0000000000..9515a0fbf5 --- /dev/null +++ b/drivers/input/ps2mult.c @@ -0,0 +1,466 @@ +/*********************************************************************** + * + * (C) Copyright 2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * PS/2 multiplexer driver + * + * Originally from linux source (drivers/char/ps2mult.c) + * + * Uses simple serial driver (ps2ser.c) to access the multiplexer + * Used by PS/2 keyboard driver (pc_keyb.c) + * + ***********************************************************************/ + +#include + +#ifdef CONFIG_PS2MULT + +#include +#include +#include + +/* #define DEBUG_MULT */ +/* #define DEBUG_KEYB */ + +#define KBD_STAT_DEFAULT (KBD_STAT_SELFTEST | KBD_STAT_UNLOCKED) + +#define PRINTF(format, args...) printf("ps2mult.c: " format, ## args) + +#ifdef DEBUG_MULT +#define PRINTF_MULT(format, args...) printf("PS2MULT: " format, ## args) +#else +#define PRINTF_MULT(format, args...) +#endif + +#ifdef DEBUG_KEYB +#define PRINTF_KEYB(format, args...) printf("KEYB: " format, ## args) +#else +#define PRINTF_KEYB(format, args...) +#endif + + +static ulong start_time; +static int init_done = 0; + +static int received_escape = 0; +static int received_bsync = 0; +static int received_selector = 0; + +static int kbd_command_active = 0; +static int mouse_command_active = 0; +static int ctl_command_active = 0; + +static u_char command_byte = 0; + +static void (*keyb_handler)(void *dev_id); + +static u_char ps2mult_buf [PS2BUF_SIZE]; +static atomic_t ps2mult_buf_cnt; +static int ps2mult_buf_in_idx; +static int ps2mult_buf_out_idx; + +static u_char ps2mult_buf_status [PS2BUF_SIZE]; + +#ifndef CONFIG_BOARD_EARLY_INIT_R +#error #define CONFIG_BOARD_EARLY_INIT_R and call ps2mult_early_init() in board_early_init_r() +#endif +void ps2mult_early_init (void) +{ + start_time = get_timer(0); +} + +static void ps2mult_send_byte(u_char byte, u_char sel) +{ + ps2ser_putc(sel); + + if (sel == PS2MULT_KB_SELECTOR) { + PRINTF_MULT("0x%02x send KEYBOARD\n", byte); + kbd_command_active = 1; + } else { + PRINTF_MULT("0x%02x send MOUSE\n", byte); + mouse_command_active = 1; + } + + switch (byte) { + case PS2MULT_ESCAPE: + case PS2MULT_BSYNC: + case PS2MULT_KB_SELECTOR: + case PS2MULT_MS_SELECTOR: + case PS2MULT_SESSION_START: + case PS2MULT_SESSION_END: + ps2ser_putc(PS2MULT_ESCAPE); + break; + default: + break; + } + + ps2ser_putc(byte); +} + +static void ps2mult_receive_byte(u_char byte, u_char sel) +{ + u_char status = KBD_STAT_DEFAULT; + +#if 1 /* Ignore mouse in U-Boot */ + if (sel == PS2MULT_MS_SELECTOR) return; +#endif + + if (sel == PS2MULT_KB_SELECTOR) { + if (kbd_command_active) { + if (!received_bsync) { + PRINTF_MULT("0x%02x lost KEYBOARD !!!\n", byte); + return; + } else { + kbd_command_active = 0; + received_bsync = 0; + } + } + PRINTF_MULT("0x%02x receive KEYBOARD\n", byte); + status |= KBD_STAT_IBF | KBD_STAT_OBF; + } else { + if (mouse_command_active) { + if (!received_bsync) { + PRINTF_MULT("0x%02x lost MOUSE !!!\n", byte); + return; + } else { + mouse_command_active = 0; + received_bsync = 0; + } + } + PRINTF_MULT("0x%02x receive MOUSE\n", byte); + status |= KBD_STAT_IBF | KBD_STAT_OBF | KBD_STAT_MOUSE_OBF; + } + + if (atomic_read(&ps2mult_buf_cnt) < PS2BUF_SIZE) { + ps2mult_buf_status[ps2mult_buf_in_idx] = status; + ps2mult_buf[ps2mult_buf_in_idx++] = byte; + ps2mult_buf_in_idx &= (PS2BUF_SIZE - 1); + atomic_inc(&ps2mult_buf_cnt); + } else { + PRINTF("buffer overflow\n"); + } + + if (received_bsync) { + PRINTF("unexpected BSYNC\n"); + received_bsync = 0; + } +} + +void ps2mult_callback (int in_cnt) +{ + int i; + u_char byte; + static int keyb_handler_active = 0; + + if (!init_done) { + return; + } + + for (i = 0; i < in_cnt; i ++) { + byte = ps2ser_getc(); + + if (received_escape) { + ps2mult_receive_byte(byte, received_selector); + received_escape = 0; + } else switch (byte) { + case PS2MULT_ESCAPE: + PRINTF_MULT("ESCAPE receive\n"); + received_escape = 1; + break; + + case PS2MULT_BSYNC: + PRINTF_MULT("BSYNC receive\n"); + received_bsync = 1; + break; + + case PS2MULT_KB_SELECTOR: + case PS2MULT_MS_SELECTOR: + PRINTF_MULT("%s receive\n", + byte == PS2MULT_KB_SELECTOR ? "KB_SEL" : "MS_SEL"); + received_selector = byte; + break; + + case PS2MULT_SESSION_START: + case PS2MULT_SESSION_END: + PRINTF_MULT("%s receive\n", + byte == PS2MULT_SESSION_START ? + "SESSION_START" : "SESSION_END"); + break; + + default: + ps2mult_receive_byte(byte, received_selector); + } + } + + if (keyb_handler && !keyb_handler_active && + atomic_read(&ps2mult_buf_cnt)) { + keyb_handler_active = 1; + keyb_handler(NULL); + keyb_handler_active = 0; + } +} + +u_char ps2mult_read_status(void) +{ + u_char byte; + + if (atomic_read(&ps2mult_buf_cnt) == 0) { + ps2ser_check(); + } + + if (atomic_read(&ps2mult_buf_cnt)) { + byte = ps2mult_buf_status[ps2mult_buf_out_idx]; + } else { + byte = KBD_STAT_DEFAULT; + } + PRINTF_KEYB("read_status()=0x%02x\n", byte); + return byte; +} + +u_char ps2mult_read_input(void) +{ + u_char byte = 0; + + if (atomic_read(&ps2mult_buf_cnt) == 0) { + ps2ser_check(); + } + + if (atomic_read(&ps2mult_buf_cnt)) { + byte = ps2mult_buf[ps2mult_buf_out_idx++]; + ps2mult_buf_out_idx &= (PS2BUF_SIZE - 1); + atomic_dec(&ps2mult_buf_cnt); + } + PRINTF_KEYB("read_input()=0x%02x\n", byte); + return byte; +} + +void ps2mult_write_output(u_char val) +{ + int i; + + PRINTF_KEYB("write_output(0x%02x)\n", val); + + for (i = 0; i < KBD_TIMEOUT; i++) { + if (!kbd_command_active && !mouse_command_active) { + break; + } + udelay(1000); + ps2ser_check(); + } + + if (kbd_command_active) { + PRINTF("keyboard command not acknoledged\n"); + kbd_command_active = 0; + } + + if (mouse_command_active) { + PRINTF("mouse command not acknoledged\n"); + mouse_command_active = 0; + } + + if (ctl_command_active) { + switch (ctl_command_active) { + case KBD_CCMD_WRITE_MODE: + /* Scan code conversion not supported */ + command_byte = val & ~KBD_MODE_KCC; + break; + + case KBD_CCMD_WRITE_AUX_OBUF: + ps2mult_receive_byte(val, PS2MULT_MS_SELECTOR); + break; + + case KBD_CCMD_WRITE_MOUSE: + ps2mult_send_byte(val, PS2MULT_MS_SELECTOR); + break; + + default: + PRINTF("invalid controller command\n"); + break; + } + + ctl_command_active = 0; + return; + } + + ps2mult_send_byte(val, PS2MULT_KB_SELECTOR); +} + +void ps2mult_write_command(u_char val) +{ + ctl_command_active = 0; + + PRINTF_KEYB("write_command(0x%02x)\n", val); + + switch (val) { + case KBD_CCMD_READ_MODE: + ps2mult_receive_byte(command_byte, PS2MULT_KB_SELECTOR); + break; + + case KBD_CCMD_WRITE_MODE: + ctl_command_active = val; + break; + + case KBD_CCMD_MOUSE_DISABLE: + break; + + case KBD_CCMD_MOUSE_ENABLE: + break; + + case KBD_CCMD_SELF_TEST: + ps2mult_receive_byte(0x55, PS2MULT_KB_SELECTOR); + break; + + case KBD_CCMD_KBD_TEST: + ps2mult_receive_byte(0x00, PS2MULT_KB_SELECTOR); + break; + + case KBD_CCMD_KBD_DISABLE: + break; + + case KBD_CCMD_KBD_ENABLE: + break; + + case KBD_CCMD_WRITE_AUX_OBUF: + ctl_command_active = val; + break; + + case KBD_CCMD_WRITE_MOUSE: + ctl_command_active = val; + break; + + default: + PRINTF("invalid controller command\n"); + break; + } +} + +static int ps2mult_getc_w (void) +{ + int res = -1; + int i; + + for (i = 0; i < KBD_TIMEOUT; i++) { + if (ps2ser_check()) { + res = ps2ser_getc(); + break; + } + udelay(1000); + } + + switch (res) { + case PS2MULT_KB_SELECTOR: + case PS2MULT_MS_SELECTOR: + received_selector = res; + break; + default: + break; + } + + return res; +} + +int ps2mult_init (void) +{ + int byte; + int kbd_found = 0; + int mouse_found = 0; + + while (get_timer(start_time) < CONFIG_PS2MULT_DELAY); + + ps2ser_init(); + + ps2ser_putc(PS2MULT_SESSION_START); + + ps2ser_putc(PS2MULT_KB_SELECTOR); + ps2ser_putc(KBD_CMD_RESET); + + do { + byte = ps2mult_getc_w(); + } while (byte >= 0 && byte != KBD_REPLY_ACK); + + if (byte == KBD_REPLY_ACK) { + byte = ps2mult_getc_w(); + if (byte == 0xaa) { + kbd_found = 1; + puts("keyboard"); + } + } + + if (!kbd_found) { + while (byte >= 0) { + byte = ps2mult_getc_w(); + } + } + +#if 1 /* detect mouse */ + ps2ser_putc(PS2MULT_MS_SELECTOR); + ps2ser_putc(AUX_RESET); + + do { + byte = ps2mult_getc_w(); + } while (byte >= 0 && byte != AUX_ACK); + + if (byte == AUX_ACK) { + byte = ps2mult_getc_w(); + if (byte == 0xaa) { + byte = ps2mult_getc_w(); + if (byte == 0x00) { + mouse_found = 1; + puts(", mouse"); + } + } + } + + if (!mouse_found) { + while (byte >= 0) { + byte = ps2mult_getc_w(); + } + } +#endif + + if (mouse_found || kbd_found) { + if (!received_selector) { + if (mouse_found) { + received_selector = PS2MULT_MS_SELECTOR; + } else { + received_selector = PS2MULT_KB_SELECTOR; + } + } + + init_done = 1; + } else { + puts("No device found"); + } + + puts("\n"); + +#if 0 /* for testing */ + { + int i; + u_char key[] = { + 0x1f, 0x12, 0x14, 0x12, 0x31, 0x2f, 0x39, /* setenv */ + 0x1f, 0x14, 0x20, 0x17, 0x31, 0x39, /* stdin */ + 0x1f, 0x12, 0x13, 0x17, 0x1e, 0x26, 0x1c, /* serial */ + }; + + for (i = 0; i < sizeof (key); i++) { + ps2mult_receive_byte (key[i], PS2MULT_KB_SELECTOR); + ps2mult_receive_byte (key[i] | 0x80, PS2MULT_KB_SELECTOR); + } + } +#endif + + return init_done ? 0 : -1; +} + +int ps2mult_request_irq(void (*handler)(void *)) +{ + keyb_handler = handler; + + return 0; +} + +#endif /* CONFIG_PS2MULT */ diff --git a/drivers/input/ps2ser.c b/drivers/input/ps2ser.c new file mode 100644 index 0000000000..4e304f7407 --- /dev/null +++ b/drivers/input/ps2ser.c @@ -0,0 +1,319 @@ +/*********************************************************************** + * + * (C) Copyright 2004 + * DENX Software Engineering + * Wolfgang Denk, wd@denx.de + * All rights reserved. + * + * Simple 16550A serial driver + * + * Originally from linux source (drivers/char/ps2ser.c) + * + * Used by the PS/2 multiplexer driver (ps2mult.c) + * + ***********************************************************************/ + +#include + +#ifdef CONFIG_PS2SERIAL + +#include +#include +#include +#if defined(CFG_NS16550) || defined(CONFIG_MPC85xx) +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* #define DEBUG */ + +#define PS2SER_BAUD 57600 + +#ifdef CONFIG_MPC5xxx +#if CONFIG_PS2SERIAL == 1 +#define PSC_BASE MPC5XXX_PSC1 +#elif CONFIG_PS2SERIAL == 2 +#define PSC_BASE MPC5XXX_PSC2 +#elif CONFIG_PS2SERIAL == 3 +#define PSC_BASE MPC5XXX_PSC3 +#elif defined(CONFIG_MGT5100) +#error CONFIG_PS2SERIAL must be in 1, 2 or 3 +#elif CONFIG_PS2SERIAL == 4 +#define PSC_BASE MPC5XXX_PSC4 +#elif CONFIG_PS2SERIAL == 5 +#define PSC_BASE MPC5XXX_PSC5 +#elif CONFIG_PS2SERIAL == 6 +#define PSC_BASE MPC5XXX_PSC6 +#else +#error CONFIG_PS2SERIAL must be in 1 ... 6 +#endif + +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + +#if CONFIG_PS2SERIAL == 1 +#define COM_BASE (CFG_CCSRBAR+0x4500) +#elif CONFIG_PS2SERIAL == 2 +#define COM_BASE (CFG_CCSRBAR+0x4600) +#else +#error CONFIG_PS2SERIAL must be in 1 ... 2 +#endif + +#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */ + +static int ps2ser_getc_hw(void); +static void ps2ser_interrupt(void *dev_id); + +extern struct serial_state rs_table[]; /* in serial.c */ +#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8555) +static struct serial_state *state; +#endif + +static u_char ps2buf[PS2BUF_SIZE]; +static atomic_t ps2buf_cnt; +static int ps2buf_in_idx; +static int ps2buf_out_idx; + +#ifdef CONFIG_MPC5xxx +int ps2ser_init(void) +{ + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; + unsigned long baseclk; + int div; + + /* reset PSC */ + psc->command = PSC_SEL_MODE_REG_1; + + /* select clock sources */ +#if defined(CONFIG_MGT5100) + psc->psc_clock_select = 0xdd00; + baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32; +#elif defined(CONFIG_MPC5200) + psc->psc_clock_select = 0; + baseclk = (gd->ipb_clk + 16) / 32; +#endif + + /* switch to UART mode */ + psc->sicr = 0; + + /* configure parity, bit length and so on */ +#if defined(CONFIG_MGT5100) + psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE; +#elif defined(CONFIG_MPC5200) + psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; +#endif + psc->mode = PSC_MODE_ONE_STOP; + + /* set up UART divisor */ + div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD; + psc->ctur = (div >> 8) & 0xff; + psc->ctlr = div & 0xff; + + /* disable all interrupts */ + psc->psc_imr = 0; + + /* reset and enable Rx/Tx */ + psc->command = PSC_RST_RX; + psc->command = PSC_RST_TX; + psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; + + return (0); +} + +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) +int ps2ser_init(void) +{ + NS16550_t com_port = (NS16550_t)COM_BASE; + + com_port->ier = 0x00; + com_port->lcr = LCR_BKSE | LCR_8N1; + com_port->dll = (CFG_NS16550_CLK / 16 / PS2SER_BAUD) & 0xff; + com_port->dlm = ((CFG_NS16550_CLK / 16 / PS2SER_BAUD) >> 8) & 0xff; + com_port->lcr = LCR_8N1; + com_port->mcr = (MCR_DTR | MCR_RTS); + com_port->fcr = (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR); + + return (0); +} + +#else /* !CONFIG_MPC5xxx && !CONFIG_MPC8540 / other */ + +static inline unsigned int ps2ser_in(int offset) +{ + return readb((unsigned long) state->iomem_base + offset); +} + +static inline void ps2ser_out(int offset, int value) +{ + writeb(value, (unsigned long) state->iomem_base + offset); +} + +int ps2ser_init(void) +{ + int quot; + unsigned cval; + + state = rs_table + CONFIG_PS2SERIAL; + + quot = state->baud_base / PS2SER_BAUD; + cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */ + + /* Set speed, enable interrupts, enable FIFO + */ + ps2ser_out(UART_LCR, cval | UART_LCR_DLAB); + ps2ser_out(UART_DLL, quot & 0xff); + ps2ser_out(UART_DLM, quot >> 8); + ps2ser_out(UART_LCR, cval); + ps2ser_out(UART_IER, UART_IER_RDI); + ps2ser_out(UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS); + ps2ser_out(UART_FCR, + UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); + + /* If we read 0xff from the LSR, there is no UART here + */ + if (ps2ser_in(UART_LSR) == 0xff) { + printf ("ps2ser.c: no UART found\n"); + return -1; + } + + irq_install_handler(state->irq, ps2ser_interrupt, NULL); + + return 0; +} +#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */ + +void ps2ser_putc(int chr) +{ +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif +#ifdef DEBUG + printf(">>>> 0x%02x\n", chr); +#endif + +#ifdef CONFIG_MPC5xxx + while (!(psc->psc_status & PSC_SR_TXRDY)); + + psc->psc_buffer_8 = chr; +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + while ((com_port->lsr & LSR_THRE) == 0); + com_port->thr = chr; +#else + while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE)); + + ps2ser_out(UART_TX, chr); +#endif +} + +static int ps2ser_getc_hw(void) +{ +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif + int res = -1; + +#ifdef CONFIG_MPC5xxx + if (psc->psc_status & PSC_SR_RXRDY) { + res = (psc->psc_buffer_8); + } +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + if (com_port->lsr & LSR_DR) { + res = com_port->rbr; + } +#else + if (ps2ser_in(UART_LSR) & UART_LSR_DR) { + res = (ps2ser_in(UART_RX)); + } +#endif + + return res; +} + +int ps2ser_getc(void) +{ + volatile int chr; + int flags; + +#ifdef DEBUG + printf("<< "); +#endif + + flags = disable_interrupts(); + + do { + if (atomic_read(&ps2buf_cnt) != 0) { + chr = ps2buf[ps2buf_out_idx++]; + ps2buf_out_idx &= (PS2BUF_SIZE - 1); + atomic_dec(&ps2buf_cnt); + } else { + chr = ps2ser_getc_hw(); + } + } + while (chr < 0); + + if (flags) enable_interrupts(); + +#ifdef DEBUG + printf("0x%02x\n", chr); +#endif + + return chr; +} + +int ps2ser_check(void) +{ + int flags; + + flags = disable_interrupts(); + ps2ser_interrupt(NULL); + if (flags) enable_interrupts(); + + return atomic_read(&ps2buf_cnt); +} + +static void ps2ser_interrupt(void *dev_id) +{ +#ifdef CONFIG_MPC5xxx + volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + NS16550_t com_port = (NS16550_t)COM_BASE; +#endif + int chr; + int status; + + do { + chr = ps2ser_getc_hw(); +#ifdef CONFIG_MPC5xxx + status = psc->psc_status; +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + status = com_port->lsr; +#else + status = ps2ser_in(UART_IIR); +#endif + if (chr < 0) continue; + + if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) { + ps2buf[ps2buf_in_idx++] = chr; + ps2buf_in_idx &= (PS2BUF_SIZE - 1); + atomic_inc(&ps2buf_cnt); + } else { + printf ("ps2ser.c: buffer overflow\n"); + } +#ifdef CONFIG_MPC5xxx + } while (status & PSC_SR_RXRDY); +#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) + } while (status & LSR_DR); +#else + } while (status & UART_IIR_RDI); +#endif + + if (atomic_read(&ps2buf_cnt)) { + ps2mult_callback(atomic_read(&ps2buf_cnt)); + } +} + +#endif /* CONFIG_PS2SERIAL */ diff --git a/drivers/keyboard.c b/drivers/keyboard.c deleted file mode 100644 index 9975202d7a..0000000000 --- a/drivers/keyboard.c +++ /dev/null @@ -1,305 +0,0 @@ -/*********************************************************************** - * - * (C) Copyright 2004 - * DENX Software Engineering - * Wolfgang Denk, wd@denx.de - * All rights reserved. - * - * Keyboard driver - * - ***********************************************************************/ - -#include - -#ifdef CONFIG_PS2KBD - -#include -#include - -#undef KBG_DEBUG - -#ifdef KBG_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - - -#define DEVNAME "kbd" - -#define LED_SCR 0x01 /* scroll lock led */ -#define LED_CAP 0x04 /* caps lock led */ -#define LED_NUM 0x02 /* num lock led */ - -#define KBD_BUFFER_LEN 0x20 /* size of the keyboardbuffer */ - -#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) -int ps2ser_check(void); -#endif - -static volatile char kbd_buffer[KBD_BUFFER_LEN]; -static volatile int in_pointer = 0; -static volatile int out_pointer = 0; - -static unsigned char leds = 0; -static unsigned char num_lock = 0; -static unsigned char caps_lock = 0; -static unsigned char scroll_lock = 0; -static unsigned char shift = 0; -static unsigned char ctrl = 0; -static unsigned char alt = 0; -static unsigned char e0 = 0; - -/****************************************************************** - * Queue handling - ******************************************************************/ - -/* puts character in the queue and sets up the in and out pointer */ -static void kbd_put_queue(char data) -{ - if((in_pointer+1)==KBD_BUFFER_LEN) { - if(out_pointer==0) { - return; /* buffer full */ - } else{ - in_pointer=0; - } - } else { - if((in_pointer+1)==out_pointer) - return; /* buffer full */ - in_pointer++; - } - kbd_buffer[in_pointer]=data; - return; -} - -/* test if a character is in the queue */ -static int kbd_testc(void) -{ -#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - /* no ISR is used, so received chars must be polled */ - ps2ser_check(); -#endif - if(in_pointer==out_pointer) - return(0); /* no data */ - else - return(1); -} - -/* gets the character from the queue */ -static int kbd_getc(void) -{ - char c; - while(in_pointer==out_pointer) { -#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - /* no ISR is used, so received chars must be polled */ - ps2ser_check(); -#endif - ;} - if((out_pointer+1)==KBD_BUFFER_LEN) - out_pointer=0; - else - out_pointer++; - c=kbd_buffer[out_pointer]; - return (int)c; - -} - -/* Simple translation table for the keys */ - -static unsigned char kbd_plain_xlate[] = { - 0xff,0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=','\b','\t', /* 0x00 - 0x0f */ - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\r',0xff, 'a', 's', /* 0x10 - 0x1f */ - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`',0xff,'\\', 'z', 'x', 'c', 'v', /* 0x20 - 0x2f */ - 'b', 'n', 'm', ',', '.', '/',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ - '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ - '\r',0xff,0xff - }; - -static unsigned char kbd_shift_xlate[] = { - 0xff,0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+','\b','\t', /* 0x00 - 0x0f */ - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}','\r',0xff, 'A', 'S', /* 0x10 - 0x1f */ - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',0xff, '|', 'Z', 'X', 'C', 'V', /* 0x20 - 0x2f */ - 'B', 'N', 'M', '<', '>', '?',0xff,0xff,0xff, ' ',0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ - '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ - '\r',0xff,0xff - }; - -static unsigned char kbd_ctrl_xlate[] = { - 0xff,0x1b, '1',0x00, '3', '4', '5',0x1E, '7', '8', '9', '0',0x1F, '=','\b','\t', /* 0x00 - 0x0f */ - 0x11,0x17,0x05,0x12,0x14,0x18,0x15,0x09,0x0f,0x10,0x1b,0x1d,'\n',0xff,0x01,0x13, /* 0x10 - 0x1f */ - 0x04,0x06,0x08,0x09,0x0a,0x0b,0x0c, ';','\'', '~',0x00,0x1c,0x1a,0x18,0x03,0x16, /* 0x20 - 0x2f */ - 0x02,0x0e,0x0d, '<', '>', '?',0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x30 - 0x3f */ - 0xff,0xff,0xff,0xff,0xff,0xff,0xff, '7', '8', '9', '-', '4', '5', '6', '+', '1', /* 0x40 - 0x4f */ - '2', '3', '0', '.',0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x50 - 0x5F */ - '\r',0xff,0xff - }; - - -void handle_scancode(unsigned char scancode) -{ - unsigned char keycode; - - /* Convert scancode to keycode */ - PRINTF("scancode %x\n",scancode); - if(scancode==0xe0) { - e0=1; /* special charakters */ - return; - } - if(e0==1) { - e0=0; /* delete flag */ - if(!( ((scancode&0x7F)==0x38)|| /* the right ctrl key */ - ((scancode&0x7F)==0x1D)|| /* the right alt key */ - ((scancode&0x7F)==0x35)|| /* the right '/' key */ - ((scancode&0x7F)==0x1C) )) /* the right enter key */ - /* we swallow unknown e0 codes */ - return; - } - /* special cntrl keys */ - switch(scancode) { - case 0x2A: - case 0x36: /* shift pressed */ - shift=1; - return; /* do nothing else */ - case 0xAA: - case 0xB6: /* shift released */ - shift=0; - return; /* do nothing else */ - case 0x38: /* alt pressed */ - alt=1; - return; /* do nothing else */ - case 0xB8: /* alt released */ - alt=0; - return; /* do nothing else */ - case 0x1d: /* ctrl pressed */ - ctrl=1; - return; /* do nothing else */ - case 0x9d: /* ctrl released */ - ctrl=0; - return; /* do nothing else */ - case 0x46: /* scrollock pressed */ - scroll_lock=~scroll_lock; - if(scroll_lock==0) - leds&=~LED_SCR; /* switch LED off */ - else - leds|=LED_SCR; /* switch on LED */ - pckbd_leds(leds); - return; /* do nothing else */ - case 0x3A: /* capslock pressed */ - caps_lock=~caps_lock; - if(caps_lock==0) - leds&=~LED_CAP; /* switch caps_lock off */ - else - leds|=LED_CAP; /* switch on LED */ - pckbd_leds(leds); - return; - case 0x45: /* numlock pressed */ - num_lock=~num_lock; - if(num_lock==0) - leds&=~LED_NUM; /* switch LED off */ - else - leds|=LED_NUM; /* switch on LED */ - pckbd_leds(leds); - return; - case 0xC6: /* scroll lock released */ - case 0xC5: /* num lock released */ - case 0xBA: /* caps lock released */ - return; /* just swallow */ - } -#if 1 - if((scancode&0x80)==0x80) /* key released */ - return; -#else - if((scancode&0x80)==0x00) /* key pressed */ - return; - scancode &= ~0x80; -#endif - /* now, decide which table we need */ - if(scancode > (sizeof(kbd_plain_xlate)/sizeof(kbd_plain_xlate[0]))) { /* scancode not in list */ - PRINTF("unkown scancode %X\n",scancode); - return; /* swallow it */ - } - /* setup plain code first */ - keycode=kbd_plain_xlate[scancode]; - if(caps_lock==1) { /* caps_lock is pressed, overwrite plain code */ - if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ - PRINTF("unkown caps-locked scancode %X\n",scancode); - return; /* swallow it */ - } - keycode=kbd_shift_xlate[scancode]; - if(keycode<'A') { /* we only want the alphas capital */ - keycode=kbd_plain_xlate[scancode]; - } - } - if(shift==1) { /* shift overwrites caps_lock */ - if(scancode > (sizeof(kbd_shift_xlate)/sizeof(kbd_shift_xlate[0]))) { /* scancode not in list */ - PRINTF("unkown shifted scancode %X\n",scancode); - return; /* swallow it */ - } - keycode=kbd_shift_xlate[scancode]; - } - if(ctrl==1) { /* ctrl overwrites caps_lock and shift */ - if(scancode > (sizeof(kbd_ctrl_xlate)/sizeof(kbd_ctrl_xlate[0]))) { /* scancode not in list */ - PRINTF("unkown ctrl scancode %X\n",scancode); - return; /* swallow it */ - } - keycode=kbd_ctrl_xlate[scancode]; - } - /* check if valid keycode */ - if(keycode==0xff) { - PRINTF("unkown scancode %X\n",scancode); - return; /* swallow unknown codes */ - } - - kbd_put_queue(keycode); - PRINTF("%x\n",keycode); -} - -/****************************************************************** - * Init - ******************************************************************/ - -#ifdef CFG_CONSOLE_OVERWRITE_ROUTINE -extern int overwrite_console (void); -#define OVERWRITE_CONSOLE overwrite_console () -#else -#define OVERWRITE_CONSOLE 0 -#endif /* CFG_CONSOLE_OVERWRITE_ROUTINE */ - -int kbd_init (void) -{ - int error; - device_t kbddev ; - char *stdinname = getenv ("stdin"); - - if(kbd_init_hw()==-1) - return -1; - memset (&kbddev, 0, sizeof(kbddev)); - strcpy(kbddev.name, DEVNAME); - kbddev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - kbddev.putc = NULL ; - kbddev.puts = NULL ; - kbddev.getc = kbd_getc ; - kbddev.tstc = kbd_testc ; - - error = device_register (&kbddev); - if(error==0) { - /* check if this is the standard input device */ - if(strcmp(stdinname,DEVNAME)==0) { - /* reassign the console */ - if(OVERWRITE_CONSOLE) { - return 1; - } - error=console_assign(stdin,DEVNAME); - if(error==0) - return 1; - else - return error; - } - return 1; - } - return error; -} - -#endif /* CONFIG_PS2KBD */ diff --git a/drivers/pc_keyb.c b/drivers/pc_keyb.c deleted file mode 100644 index 81d3e98934..0000000000 --- a/drivers/pc_keyb.c +++ /dev/null @@ -1,256 +0,0 @@ -/*********************************************************************** - * - * (C) Copyright 2004 - * DENX Software Engineering - * Wolfgang Denk, wd@denx.de - * All rights reserved. - * - * PS/2 keyboard driver - * - * Originally from linux source (drivers/char/pc_keyb.c) - * - ***********************************************************************/ - -#include - -#ifdef CONFIG_PS2KBD - -#include -#include - -#undef KBG_DEBUG - -#ifdef KBG_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - - -/* - * This reads the keyboard status port, and does the - * appropriate action. - * - */ -static unsigned char handle_kbd_event(void) -{ - unsigned char status = kbd_read_status(); - unsigned int work = 10000; - - while ((--work > 0) && (status & KBD_STAT_OBF)) { - unsigned char scancode; - - scancode = kbd_read_input(); - - /* Error bytes must be ignored to make the - Synaptics touchpads compaq use work */ - /* Ignore error bytes */ - if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) { - if (status & KBD_STAT_MOUSE_OBF) - ; /* not supported: handle_mouse_event(scancode); */ - else - handle_scancode(scancode); - } - status = kbd_read_status(); - } - if (!work) - PRINTF("pc_keyb: controller jammed (0x%02X).\n", status); - return status; -} - - -static int kbd_read_data(void) -{ - int val; - unsigned char status; - - val=-1; - status = kbd_read_status(); - if (status & KBD_STAT_OBF) { - val = kbd_read_input(); - if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) - val = -2; - } - return val; -} - -static int kbd_wait_for_input(void) -{ - unsigned long timeout; - int val; - - timeout = KBD_TIMEOUT; - val=kbd_read_data(); - while(val < 0) { - if(timeout--==0) - return -1; - udelay(1000); - val=kbd_read_data(); - } - return val; -} - - -static int kb_wait(void) -{ - unsigned long timeout = KBC_TIMEOUT * 10; - - do { - unsigned char status = handle_kbd_event(); - if (!(status & KBD_STAT_IBF)) - return 0; /* ok */ - udelay(1000); - timeout--; - } while (timeout); - return 1; -} - -static void kbd_write_command_w(int data) -{ - if(kb_wait()) - PRINTF("timeout in kbd_write_command_w\n"); - kbd_write_command(data); -} - -static void kbd_write_output_w(int data) -{ - if(kb_wait()) - PRINTF("timeout in kbd_write_output_w\n"); - kbd_write_output(data); -} - -static void kbd_send_data(unsigned char data) -{ - kbd_write_output_w(data); - kbd_wait_for_input(); -} - - -static char * kbd_initialize(void) -{ - int status; - - /* - * Test the keyboard interface. - * This seems to be the only way to get it going. - * If the test is successful a x55 is placed in the input buffer. - */ - kbd_write_command_w(KBD_CCMD_SELF_TEST); - if (kbd_wait_for_input() != 0x55) - return "Kbd: failed self test"; - /* - * Perform a keyboard interface test. This causes the controller - * to test the keyboard clock and data lines. The results of the - * test are placed in the input buffer. - */ - kbd_write_command_w(KBD_CCMD_KBD_TEST); - if (kbd_wait_for_input() != 0x00) - return "Kbd: interface failed self test"; - /* - * Enable the keyboard by allowing the keyboard clock to run. - */ - kbd_write_command_w(KBD_CCMD_KBD_ENABLE); - - /* - * Reset keyboard. If the read times out - * then the assumption is that no keyboard is - * plugged into the machine. - * This defaults the keyboard to scan-code set 2. - * - * Set up to try again if the keyboard asks for RESEND. - */ - do { - kbd_write_output_w(KBD_CMD_RESET); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - if (status != KBD_REPLY_RESEND) { - PRINTF("status: %X\n",status); - return "Kbd: reset failed, no ACK"; - } - } while (1); - if (kbd_wait_for_input() != KBD_REPLY_POR) - return "Kbd: reset failed, no POR"; - - /* - * Set keyboard controller mode. During this, the keyboard should be - * in the disabled state. - * - * Set up to try again if the keyboard asks for RESEND. - */ - do { - kbd_write_output_w(KBD_CMD_DISABLE); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - if (status != KBD_REPLY_RESEND) - return "Kbd: disable keyboard: no ACK"; - } while (1); - - kbd_write_command_w(KBD_CCMD_WRITE_MODE); - kbd_write_output_w(KBD_MODE_KBD_INT - | KBD_MODE_SYS - | KBD_MODE_DISABLE_MOUSE - | KBD_MODE_KCC); - - /* AMCC powerpc portables need this to use scan-code set 1 -- Cort */ - kbd_write_command_w(KBD_CCMD_READ_MODE); - if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { - /* - * If the controller does not support conversion, - * Set the keyboard to scan-code set 1. - */ - kbd_write_output_w(0xF0); - kbd_wait_for_input(); - kbd_write_output_w(0x01); - kbd_wait_for_input(); - } - kbd_write_output_w(KBD_CMD_ENABLE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Kbd: enable keyboard: no ACK"; - - /* - * Finally, set the typematic rate to maximum. - */ - kbd_write_output_w(KBD_CMD_SET_RATE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Kbd: Set rate: no ACK"; - kbd_write_output_w(0x00); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Kbd: Set rate: no ACK"; - return NULL; -} - -static void kbd_interrupt(void *dev_id) -{ - handle_kbd_event(); -} - -/****************************************************************** - * Init - ******************************************************************/ - -int kbd_init_hw(void) -{ - char* result; - - kbd_request_region(); - - result=kbd_initialize(); - if (result==NULL) { - PRINTF("AT Keyboard initialized\n"); - kbd_request_irq(kbd_interrupt); - return (1); - } else { - printf("%s\n",result); - return (-1); - } -} - -void pckbd_leds(unsigned char leds) -{ - kbd_send_data(KBD_CMD_SET_LEDS); - kbd_send_data(leds); -} - -#endif /* CONFIG_PS2KBD */ diff --git a/drivers/ps2mult.c b/drivers/ps2mult.c deleted file mode 100644 index 9515a0fbf5..0000000000 --- a/drivers/ps2mult.c +++ /dev/null @@ -1,466 +0,0 @@ -/*********************************************************************** - * - * (C) Copyright 2004 - * DENX Software Engineering - * Wolfgang Denk, wd@denx.de - * All rights reserved. - * - * PS/2 multiplexer driver - * - * Originally from linux source (drivers/char/ps2mult.c) - * - * Uses simple serial driver (ps2ser.c) to access the multiplexer - * Used by PS/2 keyboard driver (pc_keyb.c) - * - ***********************************************************************/ - -#include - -#ifdef CONFIG_PS2MULT - -#include -#include -#include - -/* #define DEBUG_MULT */ -/* #define DEBUG_KEYB */ - -#define KBD_STAT_DEFAULT (KBD_STAT_SELFTEST | KBD_STAT_UNLOCKED) - -#define PRINTF(format, args...) printf("ps2mult.c: " format, ## args) - -#ifdef DEBUG_MULT -#define PRINTF_MULT(format, args...) printf("PS2MULT: " format, ## args) -#else -#define PRINTF_MULT(format, args...) -#endif - -#ifdef DEBUG_KEYB -#define PRINTF_KEYB(format, args...) printf("KEYB: " format, ## args) -#else -#define PRINTF_KEYB(format, args...) -#endif - - -static ulong start_time; -static int init_done = 0; - -static int received_escape = 0; -static int received_bsync = 0; -static int received_selector = 0; - -static int kbd_command_active = 0; -static int mouse_command_active = 0; -static int ctl_command_active = 0; - -static u_char command_byte = 0; - -static void (*keyb_handler)(void *dev_id); - -static u_char ps2mult_buf [PS2BUF_SIZE]; -static atomic_t ps2mult_buf_cnt; -static int ps2mult_buf_in_idx; -static int ps2mult_buf_out_idx; - -static u_char ps2mult_buf_status [PS2BUF_SIZE]; - -#ifndef CONFIG_BOARD_EARLY_INIT_R -#error #define CONFIG_BOARD_EARLY_INIT_R and call ps2mult_early_init() in board_early_init_r() -#endif -void ps2mult_early_init (void) -{ - start_time = get_timer(0); -} - -static void ps2mult_send_byte(u_char byte, u_char sel) -{ - ps2ser_putc(sel); - - if (sel == PS2MULT_KB_SELECTOR) { - PRINTF_MULT("0x%02x send KEYBOARD\n", byte); - kbd_command_active = 1; - } else { - PRINTF_MULT("0x%02x send MOUSE\n", byte); - mouse_command_active = 1; - } - - switch (byte) { - case PS2MULT_ESCAPE: - case PS2MULT_BSYNC: - case PS2MULT_KB_SELECTOR: - case PS2MULT_MS_SELECTOR: - case PS2MULT_SESSION_START: - case PS2MULT_SESSION_END: - ps2ser_putc(PS2MULT_ESCAPE); - break; - default: - break; - } - - ps2ser_putc(byte); -} - -static void ps2mult_receive_byte(u_char byte, u_char sel) -{ - u_char status = KBD_STAT_DEFAULT; - -#if 1 /* Ignore mouse in U-Boot */ - if (sel == PS2MULT_MS_SELECTOR) return; -#endif - - if (sel == PS2MULT_KB_SELECTOR) { - if (kbd_command_active) { - if (!received_bsync) { - PRINTF_MULT("0x%02x lost KEYBOARD !!!\n", byte); - return; - } else { - kbd_command_active = 0; - received_bsync = 0; - } - } - PRINTF_MULT("0x%02x receive KEYBOARD\n", byte); - status |= KBD_STAT_IBF | KBD_STAT_OBF; - } else { - if (mouse_command_active) { - if (!received_bsync) { - PRINTF_MULT("0x%02x lost MOUSE !!!\n", byte); - return; - } else { - mouse_command_active = 0; - received_bsync = 0; - } - } - PRINTF_MULT("0x%02x receive MOUSE\n", byte); - status |= KBD_STAT_IBF | KBD_STAT_OBF | KBD_STAT_MOUSE_OBF; - } - - if (atomic_read(&ps2mult_buf_cnt) < PS2BUF_SIZE) { - ps2mult_buf_status[ps2mult_buf_in_idx] = status; - ps2mult_buf[ps2mult_buf_in_idx++] = byte; - ps2mult_buf_in_idx &= (PS2BUF_SIZE - 1); - atomic_inc(&ps2mult_buf_cnt); - } else { - PRINTF("buffer overflow\n"); - } - - if (received_bsync) { - PRINTF("unexpected BSYNC\n"); - received_bsync = 0; - } -} - -void ps2mult_callback (int in_cnt) -{ - int i; - u_char byte; - static int keyb_handler_active = 0; - - if (!init_done) { - return; - } - - for (i = 0; i < in_cnt; i ++) { - byte = ps2ser_getc(); - - if (received_escape) { - ps2mult_receive_byte(byte, received_selector); - received_escape = 0; - } else switch (byte) { - case PS2MULT_ESCAPE: - PRINTF_MULT("ESCAPE receive\n"); - received_escape = 1; - break; - - case PS2MULT_BSYNC: - PRINTF_MULT("BSYNC receive\n"); - received_bsync = 1; - break; - - case PS2MULT_KB_SELECTOR: - case PS2MULT_MS_SELECTOR: - PRINTF_MULT("%s receive\n", - byte == PS2MULT_KB_SELECTOR ? "KB_SEL" : "MS_SEL"); - received_selector = byte; - break; - - case PS2MULT_SESSION_START: - case PS2MULT_SESSION_END: - PRINTF_MULT("%s receive\n", - byte == PS2MULT_SESSION_START ? - "SESSION_START" : "SESSION_END"); - break; - - default: - ps2mult_receive_byte(byte, received_selector); - } - } - - if (keyb_handler && !keyb_handler_active && - atomic_read(&ps2mult_buf_cnt)) { - keyb_handler_active = 1; - keyb_handler(NULL); - keyb_handler_active = 0; - } -} - -u_char ps2mult_read_status(void) -{ - u_char byte; - - if (atomic_read(&ps2mult_buf_cnt) == 0) { - ps2ser_check(); - } - - if (atomic_read(&ps2mult_buf_cnt)) { - byte = ps2mult_buf_status[ps2mult_buf_out_idx]; - } else { - byte = KBD_STAT_DEFAULT; - } - PRINTF_KEYB("read_status()=0x%02x\n", byte); - return byte; -} - -u_char ps2mult_read_input(void) -{ - u_char byte = 0; - - if (atomic_read(&ps2mult_buf_cnt) == 0) { - ps2ser_check(); - } - - if (atomic_read(&ps2mult_buf_cnt)) { - byte = ps2mult_buf[ps2mult_buf_out_idx++]; - ps2mult_buf_out_idx &= (PS2BUF_SIZE - 1); - atomic_dec(&ps2mult_buf_cnt); - } - PRINTF_KEYB("read_input()=0x%02x\n", byte); - return byte; -} - -void ps2mult_write_output(u_char val) -{ - int i; - - PRINTF_KEYB("write_output(0x%02x)\n", val); - - for (i = 0; i < KBD_TIMEOUT; i++) { - if (!kbd_command_active && !mouse_command_active) { - break; - } - udelay(1000); - ps2ser_check(); - } - - if (kbd_command_active) { - PRINTF("keyboard command not acknoledged\n"); - kbd_command_active = 0; - } - - if (mouse_command_active) { - PRINTF("mouse command not acknoledged\n"); - mouse_command_active = 0; - } - - if (ctl_command_active) { - switch (ctl_command_active) { - case KBD_CCMD_WRITE_MODE: - /* Scan code conversion not supported */ - command_byte = val & ~KBD_MODE_KCC; - break; - - case KBD_CCMD_WRITE_AUX_OBUF: - ps2mult_receive_byte(val, PS2MULT_MS_SELECTOR); - break; - - case KBD_CCMD_WRITE_MOUSE: - ps2mult_send_byte(val, PS2MULT_MS_SELECTOR); - break; - - default: - PRINTF("invalid controller command\n"); - break; - } - - ctl_command_active = 0; - return; - } - - ps2mult_send_byte(val, PS2MULT_KB_SELECTOR); -} - -void ps2mult_write_command(u_char val) -{ - ctl_command_active = 0; - - PRINTF_KEYB("write_command(0x%02x)\n", val); - - switch (val) { - case KBD_CCMD_READ_MODE: - ps2mult_receive_byte(command_byte, PS2MULT_KB_SELECTOR); - break; - - case KBD_CCMD_WRITE_MODE: - ctl_command_active = val; - break; - - case KBD_CCMD_MOUSE_DISABLE: - break; - - case KBD_CCMD_MOUSE_ENABLE: - break; - - case KBD_CCMD_SELF_TEST: - ps2mult_receive_byte(0x55, PS2MULT_KB_SELECTOR); - break; - - case KBD_CCMD_KBD_TEST: - ps2mult_receive_byte(0x00, PS2MULT_KB_SELECTOR); - break; - - case KBD_CCMD_KBD_DISABLE: - break; - - case KBD_CCMD_KBD_ENABLE: - break; - - case KBD_CCMD_WRITE_AUX_OBUF: - ctl_command_active = val; - break; - - case KBD_CCMD_WRITE_MOUSE: - ctl_command_active = val; - break; - - default: - PRINTF("invalid controller command\n"); - break; - } -} - -static int ps2mult_getc_w (void) -{ - int res = -1; - int i; - - for (i = 0; i < KBD_TIMEOUT; i++) { - if (ps2ser_check()) { - res = ps2ser_getc(); - break; - } - udelay(1000); - } - - switch (res) { - case PS2MULT_KB_SELECTOR: - case PS2MULT_MS_SELECTOR: - received_selector = res; - break; - default: - break; - } - - return res; -} - -int ps2mult_init (void) -{ - int byte; - int kbd_found = 0; - int mouse_found = 0; - - while (get_timer(start_time) < CONFIG_PS2MULT_DELAY); - - ps2ser_init(); - - ps2ser_putc(PS2MULT_SESSION_START); - - ps2ser_putc(PS2MULT_KB_SELECTOR); - ps2ser_putc(KBD_CMD_RESET); - - do { - byte = ps2mult_getc_w(); - } while (byte >= 0 && byte != KBD_REPLY_ACK); - - if (byte == KBD_REPLY_ACK) { - byte = ps2mult_getc_w(); - if (byte == 0xaa) { - kbd_found = 1; - puts("keyboard"); - } - } - - if (!kbd_found) { - while (byte >= 0) { - byte = ps2mult_getc_w(); - } - } - -#if 1 /* detect mouse */ - ps2ser_putc(PS2MULT_MS_SELECTOR); - ps2ser_putc(AUX_RESET); - - do { - byte = ps2mult_getc_w(); - } while (byte >= 0 && byte != AUX_ACK); - - if (byte == AUX_ACK) { - byte = ps2mult_getc_w(); - if (byte == 0xaa) { - byte = ps2mult_getc_w(); - if (byte == 0x00) { - mouse_found = 1; - puts(", mouse"); - } - } - } - - if (!mouse_found) { - while (byte >= 0) { - byte = ps2mult_getc_w(); - } - } -#endif - - if (mouse_found || kbd_found) { - if (!received_selector) { - if (mouse_found) { - received_selector = PS2MULT_MS_SELECTOR; - } else { - received_selector = PS2MULT_KB_SELECTOR; - } - } - - init_done = 1; - } else { - puts("No device found"); - } - - puts("\n"); - -#if 0 /* for testing */ - { - int i; - u_char key[] = { - 0x1f, 0x12, 0x14, 0x12, 0x31, 0x2f, 0x39, /* setenv */ - 0x1f, 0x14, 0x20, 0x17, 0x31, 0x39, /* stdin */ - 0x1f, 0x12, 0x13, 0x17, 0x1e, 0x26, 0x1c, /* serial */ - }; - - for (i = 0; i < sizeof (key); i++) { - ps2mult_receive_byte (key[i], PS2MULT_KB_SELECTOR); - ps2mult_receive_byte (key[i] | 0x80, PS2MULT_KB_SELECTOR); - } - } -#endif - - return init_done ? 0 : -1; -} - -int ps2mult_request_irq(void (*handler)(void *)) -{ - keyb_handler = handler; - - return 0; -} - -#endif /* CONFIG_PS2MULT */ diff --git a/drivers/ps2ser.c b/drivers/ps2ser.c deleted file mode 100644 index 4e304f7407..0000000000 --- a/drivers/ps2ser.c +++ /dev/null @@ -1,319 +0,0 @@ -/*********************************************************************** - * - * (C) Copyright 2004 - * DENX Software Engineering - * Wolfgang Denk, wd@denx.de - * All rights reserved. - * - * Simple 16550A serial driver - * - * Originally from linux source (drivers/char/ps2ser.c) - * - * Used by the PS/2 multiplexer driver (ps2mult.c) - * - ***********************************************************************/ - -#include - -#ifdef CONFIG_PS2SERIAL - -#include -#include -#include -#if defined(CFG_NS16550) || defined(CONFIG_MPC85xx) -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -/* #define DEBUG */ - -#define PS2SER_BAUD 57600 - -#ifdef CONFIG_MPC5xxx -#if CONFIG_PS2SERIAL == 1 -#define PSC_BASE MPC5XXX_PSC1 -#elif CONFIG_PS2SERIAL == 2 -#define PSC_BASE MPC5XXX_PSC2 -#elif CONFIG_PS2SERIAL == 3 -#define PSC_BASE MPC5XXX_PSC3 -#elif defined(CONFIG_MGT5100) -#error CONFIG_PS2SERIAL must be in 1, 2 or 3 -#elif CONFIG_PS2SERIAL == 4 -#define PSC_BASE MPC5XXX_PSC4 -#elif CONFIG_PS2SERIAL == 5 -#define PSC_BASE MPC5XXX_PSC5 -#elif CONFIG_PS2SERIAL == 6 -#define PSC_BASE MPC5XXX_PSC6 -#else -#error CONFIG_PS2SERIAL must be in 1 ... 6 -#endif - -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - -#if CONFIG_PS2SERIAL == 1 -#define COM_BASE (CFG_CCSRBAR+0x4500) -#elif CONFIG_PS2SERIAL == 2 -#define COM_BASE (CFG_CCSRBAR+0x4600) -#else -#error CONFIG_PS2SERIAL must be in 1 ... 2 -#endif - -#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */ - -static int ps2ser_getc_hw(void); -static void ps2ser_interrupt(void *dev_id); - -extern struct serial_state rs_table[]; /* in serial.c */ -#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540) && !defined(CONFIG_MPC8541) && !defined(CONFIG_MPC8555) -static struct serial_state *state; -#endif - -static u_char ps2buf[PS2BUF_SIZE]; -static atomic_t ps2buf_cnt; -static int ps2buf_in_idx; -static int ps2buf_out_idx; - -#ifdef CONFIG_MPC5xxx -int ps2ser_init(void) -{ - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; - unsigned long baseclk; - int div; - - /* reset PSC */ - psc->command = PSC_SEL_MODE_REG_1; - - /* select clock sources */ -#if defined(CONFIG_MGT5100) - psc->psc_clock_select = 0xdd00; - baseclk = (CFG_MPC5XXX_CLKIN + 16) / 32; -#elif defined(CONFIG_MPC5200) - psc->psc_clock_select = 0; - baseclk = (gd->ipb_clk + 16) / 32; -#endif - - /* switch to UART mode */ - psc->sicr = 0; - - /* configure parity, bit length and so on */ -#if defined(CONFIG_MGT5100) - psc->mode = PSC_MODE_ERR | PSC_MODE_8_BITS | PSC_MODE_PARNONE; -#elif defined(CONFIG_MPC5200) - psc->mode = PSC_MODE_8_BITS | PSC_MODE_PARNONE; -#endif - psc->mode = PSC_MODE_ONE_STOP; - - /* set up UART divisor */ - div = (baseclk + (PS2SER_BAUD/2)) / PS2SER_BAUD; - psc->ctur = (div >> 8) & 0xff; - psc->ctlr = div & 0xff; - - /* disable all interrupts */ - psc->psc_imr = 0; - - /* reset and enable Rx/Tx */ - psc->command = PSC_RST_RX; - psc->command = PSC_RST_TX; - psc->command = PSC_RX_ENABLE | PSC_TX_ENABLE; - - return (0); -} - -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) -int ps2ser_init(void) -{ - NS16550_t com_port = (NS16550_t)COM_BASE; - - com_port->ier = 0x00; - com_port->lcr = LCR_BKSE | LCR_8N1; - com_port->dll = (CFG_NS16550_CLK / 16 / PS2SER_BAUD) & 0xff; - com_port->dlm = ((CFG_NS16550_CLK / 16 / PS2SER_BAUD) >> 8) & 0xff; - com_port->lcr = LCR_8N1; - com_port->mcr = (MCR_DTR | MCR_RTS); - com_port->fcr = (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR); - - return (0); -} - -#else /* !CONFIG_MPC5xxx && !CONFIG_MPC8540 / other */ - -static inline unsigned int ps2ser_in(int offset) -{ - return readb((unsigned long) state->iomem_base + offset); -} - -static inline void ps2ser_out(int offset, int value) -{ - writeb(value, (unsigned long) state->iomem_base + offset); -} - -int ps2ser_init(void) -{ - int quot; - unsigned cval; - - state = rs_table + CONFIG_PS2SERIAL; - - quot = state->baud_base / PS2SER_BAUD; - cval = 0x3; /* 8N1 - 8 data bits, no parity bits, 1 stop bit */ - - /* Set speed, enable interrupts, enable FIFO - */ - ps2ser_out(UART_LCR, cval | UART_LCR_DLAB); - ps2ser_out(UART_DLL, quot & 0xff); - ps2ser_out(UART_DLM, quot >> 8); - ps2ser_out(UART_LCR, cval); - ps2ser_out(UART_IER, UART_IER_RDI); - ps2ser_out(UART_MCR, UART_MCR_OUT2 | UART_MCR_DTR | UART_MCR_RTS); - ps2ser_out(UART_FCR, - UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - - /* If we read 0xff from the LSR, there is no UART here - */ - if (ps2ser_in(UART_LSR) == 0xff) { - printf ("ps2ser.c: no UART found\n"); - return -1; - } - - irq_install_handler(state->irq, ps2ser_interrupt, NULL); - - return 0; -} -#endif /* CONFIG_MPC5xxx / CONFIG_MPC8540 / other */ - -void ps2ser_putc(int chr) -{ -#ifdef CONFIG_MPC5xxx - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - NS16550_t com_port = (NS16550_t)COM_BASE; -#endif -#ifdef DEBUG - printf(">>>> 0x%02x\n", chr); -#endif - -#ifdef CONFIG_MPC5xxx - while (!(psc->psc_status & PSC_SR_TXRDY)); - - psc->psc_buffer_8 = chr; -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - while ((com_port->lsr & LSR_THRE) == 0); - com_port->thr = chr; -#else - while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE)); - - ps2ser_out(UART_TX, chr); -#endif -} - -static int ps2ser_getc_hw(void) -{ -#ifdef CONFIG_MPC5xxx - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - NS16550_t com_port = (NS16550_t)COM_BASE; -#endif - int res = -1; - -#ifdef CONFIG_MPC5xxx - if (psc->psc_status & PSC_SR_RXRDY) { - res = (psc->psc_buffer_8); - } -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - if (com_port->lsr & LSR_DR) { - res = com_port->rbr; - } -#else - if (ps2ser_in(UART_LSR) & UART_LSR_DR) { - res = (ps2ser_in(UART_RX)); - } -#endif - - return res; -} - -int ps2ser_getc(void) -{ - volatile int chr; - int flags; - -#ifdef DEBUG - printf("<< "); -#endif - - flags = disable_interrupts(); - - do { - if (atomic_read(&ps2buf_cnt) != 0) { - chr = ps2buf[ps2buf_out_idx++]; - ps2buf_out_idx &= (PS2BUF_SIZE - 1); - atomic_dec(&ps2buf_cnt); - } else { - chr = ps2ser_getc_hw(); - } - } - while (chr < 0); - - if (flags) enable_interrupts(); - -#ifdef DEBUG - printf("0x%02x\n", chr); -#endif - - return chr; -} - -int ps2ser_check(void) -{ - int flags; - - flags = disable_interrupts(); - ps2ser_interrupt(NULL); - if (flags) enable_interrupts(); - - return atomic_read(&ps2buf_cnt); -} - -static void ps2ser_interrupt(void *dev_id) -{ -#ifdef CONFIG_MPC5xxx - volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE; -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - NS16550_t com_port = (NS16550_t)COM_BASE; -#endif - int chr; - int status; - - do { - chr = ps2ser_getc_hw(); -#ifdef CONFIG_MPC5xxx - status = psc->psc_status; -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - status = com_port->lsr; -#else - status = ps2ser_in(UART_IIR); -#endif - if (chr < 0) continue; - - if (atomic_read(&ps2buf_cnt) < PS2BUF_SIZE) { - ps2buf[ps2buf_in_idx++] = chr; - ps2buf_in_idx &= (PS2BUF_SIZE - 1); - atomic_inc(&ps2buf_cnt); - } else { - printf ("ps2ser.c: buffer overflow\n"); - } -#ifdef CONFIG_MPC5xxx - } while (status & PSC_SR_RXRDY); -#elif defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || defined(CONFIG_MPC8555) - } while (status & LSR_DR); -#else - } while (status & UART_IIR_RDI); -#endif - - if (atomic_read(&ps2buf_cnt)) { - ps2mult_callback(atomic_read(&ps2buf_cnt)); - } -} - -#endif /* CONFIG_PS2SERIAL */