Add support for PS/2 keyboard on TQM8540 board
Patch by Martin Krause, 02 Dez 2005

This is tested on a STK85XX baseboard. Make sure the PS/2 controller
is programmed. Jumper Settings: X66 1-2, 9-10; X61 2-3

---
commit 50a82c5c5422ffc4b06e52af37e2c84462cbdf37
tree 648edeea60f16d356370c172bd2db87eb26595d9
parent c75eba3b4140187cd0d9bd8049f5df4c49b6889b
author Martin Krause <mkr@tq-sewsrv-4.tq-net.de> Fri, 02 Dec 2005 12:25:05 +0100
committer Martin Krause <mkr@tq-sewsrv-4.tq-net.de> Fri, 02 Dec 2005 12:25:05 +0100

 board/tqm85xx/tqm85xx.c   |   13 ++++++++++
 drivers/keyboard.c        |    6 ++---
 drivers/ps2ser.c          |   56 ++++++++++++++++++++++++++++++++++++++++++---
 include/configs/TQM85xx.h |   11 +++++++++
 4 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/board/tqm85xx/tqm85xx.c b/board/tqm85xx/tqm85xx.c
index 13ea6f4..cd2aa9c 100644
--- a/board/tqm85xx/tqm85xx.c
+++ b/board/tqm85xx/tqm85xx.c
@@ -41,6 +41,9 @@ extern flash_info_t flash_info[];	/* FLA
 void local_bus_init (void);
 long int fixed_sdram (void);
 ulong flash_get_size (ulong base, int banknum);
+#ifdef CONFIG_PS2MULT
+void ps2mult_early_init(void);
+#endif
 
 #ifdef CONFIG_CPM2
 /*
@@ -409,3 +412,13 @@ void pci_init_board (void)
 	pci_mpc85xx_init (&hose);
 #endif /* CONFIG_PCI */
 }
+
+#ifdef CONFIG_BOARD_EARLY_INIT_R
+int board_early_init_r (void)
+{
+#ifdef CONFIG_PS2MULT
+	ps2mult_early_init();
+#endif /* CONFIG_PS2MULT */
+	return (0);
+}
+#endif /* CONFIG_BOARD_EARLY_INIT_R */
diff --git a/drivers/keyboard.c b/drivers/keyboard.c
index 1579095..079b27d 100644
--- a/drivers/keyboard.c
+++ b/drivers/keyboard.c
@@ -33,7 +33,7 @@
 
 #define	KBD_BUFFER_LEN		0x20  /* size of the keyboardbuffer */
 
-#ifdef CONFIG_MPC5xxx
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540)
 int ps2ser_check(void);
 #endif
 
@@ -75,7 +75,7 @@ static void kbd_put_queue(char data)
 /* test if a character is in the queue */
 static int kbd_testc(void)
 {
-#ifdef CONFIG_MPC5xxx
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540)
 	/* no ISR is used, so received chars must be polled */
 	ps2ser_check();
 #endif
@@ -90,7 +90,7 @@ static int kbd_getc(void)
 {
 	char c;
 	while(in_pointer==out_pointer) {
-#ifdef CONFIG_MPC5xxx
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8540)
 	/* no ISR is used, so received chars must be polled */
 	ps2ser_check();
 #endif
diff --git a/drivers/ps2ser.c b/drivers/ps2ser.c
index e2a38dc..ba42886 100644
--- a/drivers/ps2ser.c
+++ b/drivers/ps2ser.c
@@ -20,12 +20,16 @@
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <ps2mult.h>
+#ifdef CFG_NS16550
+#include <ns16550.h>
+#endif
 
 /* #define	DEBUG */
 
 #define PS2SER_BAUD	57600
 
 #ifdef CONFIG_MPC5xxx
+
 #if CONFIG_PS2SERIAL == 1
 #define PSC_BASE MPC5XXX_PSC1
 #elif CONFIG_PS2SERIAL == 2
@@ -43,13 +47,24 @@
 #else
 #error CONFIG_PS2SERIAL must be in 1 ... 6
 #endif
-#endif /* CONFIG_MPC5xxx */
+
+#elif defined(CONFIG_MPC8540)
+
+#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 */
 
 static int	ps2ser_getc_hw(void);
 static void	ps2ser_interrupt(void *dev_id);
 
 extern struct	serial_state rs_table[]; /* in serial.c */
-#ifndef CONFIG_MPC5xxx
+#if !defined(CONFIG_MPC5xxx) && !defined(CONFIG_MPC8540)
 static struct	serial_state *state;
 #endif
 
@@ -106,7 +121,23 @@ int ps2ser_init(void)
 	return (0);
 }
 
-#else /* !CONFIG_MPC5xxx */
+#elif defined(CONFIG_MPC8540)
+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 */
 
 static inline unsigned int ps2ser_in(int offset)
 {
@@ -150,12 +181,14 @@ int ps2ser_init(void)
 
 	return 0;
 }
-#endif /* CONFIG_MPC5xxx */
+#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)
+	NS16550_t com_port = (NS16550_t)COM_BASE;
 #endif
 #ifdef DEBUG
 	printf(">>>> 0x%02x\n", chr);
@@ -165,6 +198,9 @@ void ps2ser_putc(int chr)
 	while (!(psc->psc_status & PSC_SR_TXRDY));
 
 	psc->psc_buffer_8 = chr;
+#elif defined(CONFIG_MPC8540)
+	while ((com_port->lsr & LSR_THRE) == 0);
+	com_port->thr = chr;
 #else
 	while (!(ps2ser_in(UART_LSR) & UART_LSR_THRE));
 
@@ -176,6 +212,8 @@ static int ps2ser_getc_hw(void)
 {
 #ifdef CONFIG_MPC5xxx
 	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#elif defined(CONFIG_MPC8540)
+	NS16550_t com_port = (NS16550_t)COM_BASE;
 #endif
 	int res = -1;
 
@@ -183,6 +221,10 @@ static int ps2ser_getc_hw(void)
 	if (psc->psc_status & PSC_SR_RXRDY) {
 		res = (psc->psc_buffer_8);
 	}
+#elif defined(CONFIG_MPC8540)
+	if (com_port->lsr & LSR_DR) {
+		res = com_port->rbr;
+	}
 #else
 	if (ps2ser_in(UART_LSR) & UART_LSR_DR) {
 		res = (ps2ser_in(UART_RX));
@@ -238,6 +280,8 @@ static void ps2ser_interrupt(void *dev_i
 {
 #ifdef CONFIG_MPC5xxx
 	volatile struct mpc5xxx_psc *psc = (struct mpc5xxx_psc *)PSC_BASE;
+#elif defined(CONFIG_MPC8540)
+	NS16550_t com_port = (NS16550_t)COM_BASE;
 #endif
 	int chr;
 	int status;
@@ -246,6 +290,8 @@ static void ps2ser_interrupt(void *dev_i
 		chr = ps2ser_getc_hw();
 #ifdef CONFIG_MPC5xxx
 		status = psc->psc_status;
+#elif defined(CONFIG_MPC8540)
+		status = com_port->lsr;
 #else
 		status = ps2ser_in(UART_IIR);
 #endif
@@ -260,6 +306,8 @@ static void ps2ser_interrupt(void *dev_i
 		}
 #ifdef CONFIG_MPC5xxx
 	} while (status & PSC_SR_RXRDY);
+#elif defined(CONFIG_MPC8540)
+	} while (status & LSR_DR);
 #else
 	} while (status & UART_IIR_RDI);
 #endif
diff --git a/include/configs/TQM85xx.h b/include/configs/TQM85xx.h
index 18197f2..83bbc2f 100644
--- a/include/configs/TQM85xx.h
+++ b/include/configs/TQM85xx.h
@@ -172,6 +172,17 @@
 
 #endif /* CONFIG_TQM8560 */
 
+/* PS/2 Keyboard */
+#if defined(CONFIG_TQM8540)
+
+#define CONFIG_PS2KBD			/* AT-PS/2 Keyboard		*/
+#define CONFIG_PS2MULT			/* .. on PS/2 Multiplexer	*/
+#define CONFIG_PS2SERIAL	2	/* .. on DUART2			*/
+#define CONFIG_PS2MULT_DELAY	(CFG_HZ/2)	/* Initial delay	*/
+#define CONFIG_BOARD_EARLY_INIT_R	1
+
+#endif /* CONFIG_TQM8540 */
+
 #define CONFIG_BAUDRATE         115200
 
 #define CFG_BAUDRATE_TABLE  \
