From: Jean-Christophe PLAGNIOL-VILLARD Date: Sat, 24 Nov 2007 18:33:38 +0000 (+0100) Subject: drivers/serial : move serial drivers to drivers/serial X-Git-Tag: v1.3.1-rc1~1^2~9 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1378df792a7ff3abd1bf54a63f5475784f5b083c;p=u-boot drivers/serial : move serial drivers to drivers/serial Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- diff --git a/drivers/Makefile b/drivers/Makefile index 4b6f5f017f..cf8b584c72 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -48,18 +48,11 @@ COBJS-y += systemace.o # # Console Drivers # -COBJS-y += atmel_usart.o COBJS-y += i8042.o COBJS-y += keyboard.o -COBJS-y += ns16550.o COBJS-y += pc_keyb.o COBJS-y += ps2ser.o COBJS-y += ps2mult.o -COBJS-y += s3c4510b_uart.o -COBJS-y += serial.o -COBJS-y += serial_max3100.o -COBJS-y += serial_xuartlite.o -COBJS-y += usbtty.o # # USB Drivers diff --git a/drivers/atmel_usart.c b/drivers/atmel_usart.c deleted file mode 100644 index f35b99730f..0000000000 --- a/drivers/atmel_usart.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * 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 - -#ifdef CONFIG_ATMEL_USART -#include -#include -#include - -#if defined(CONFIG_USART0) -# define USART_ID 0 -# define USART_BASE USART0_BASE -#elif defined(CONFIG_USART1) -# define USART_ID 1 -# define USART_BASE USART1_BASE -#elif defined(CONFIG_USART2) -# define USART_ID 2 -# define USART_BASE USART2_BASE -#elif defined(CONFIG_USART3) -# define USART_ID 3 -# define USART_BASE USART3_BASE -#endif - -#include "atmel_usart.h" - -DECLARE_GLOBAL_DATA_PTR; - -void serial_setbrg(void) -{ - unsigned long divisor; - unsigned long usart_hz; - - /* - * Master Clock - * Baud Rate = -------------- - * 16 * CD - */ - usart_hz = get_usart_clk_rate(USART_ID); - divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate; - usart3_writel(BRGR, USART3_BF(CD, divisor)); -} - -int serial_init(void) -{ - usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX)); - - serial_setbrg(); - - usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN)); - usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) - | USART3_BF(USCLKS, USART3_USCLKS_MCK) - | USART3_BF(CHRL, USART3_CHRL_8) - | USART3_BF(PAR, USART3_PAR_NONE) - | USART3_BF(NBSTOP, USART3_NBSTOP_1))); - - return 0; -} - -void serial_putc(char c) -{ - if (c == '\n') - serial_putc('\r'); - - while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ; - usart3_writel(THR, c); -} - -void serial_puts(const char *s) -{ - while (*s) - serial_putc(*s++); -} - -int serial_getc(void) -{ - while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ; - return usart3_readl(RHR); -} - -int serial_tstc(void) -{ - return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0; -} - -#endif /* CONFIG_ATMEL_USART */ diff --git a/drivers/atmel_usart.h b/drivers/atmel_usart.h deleted file mode 100644 index af3773a99f..0000000000 --- a/drivers/atmel_usart.h +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Register definitions for the Atmel USART3 module. - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * 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 - */ -#ifndef __DRIVERS_ATMEL_USART_H__ -#define __DRIVERS_ATMEL_USART_H__ - -/* USART3 register offsets */ -#define USART3_CR 0x0000 -#define USART3_MR 0x0004 -#define USART3_IER 0x0008 -#define USART3_IDR 0x000c -#define USART3_IMR 0x0010 -#define USART3_CSR 0x0014 -#define USART3_RHR 0x0018 -#define USART3_THR 0x001c -#define USART3_BRGR 0x0020 -#define USART3_RTOR 0x0024 -#define USART3_TTGR 0x0028 -#define USART3_FIDI 0x0040 -#define USART3_NER 0x0044 -#define USART3_XXR 0x0048 -#define USART3_IFR 0x004c -#define USART3_RPR 0x0100 -#define USART3_RCR 0x0104 -#define USART3_TPR 0x0108 -#define USART3_TCR 0x010c -#define USART3_RNPR 0x0110 -#define USART3_RNCR 0x0114 -#define USART3_TNPR 0x0118 -#define USART3_TNCR 0x011c -#define USART3_PTCR 0x0120 -#define USART3_PTSR 0x0124 - -/* Bitfields in CR */ -#define USART3_RSTRX_OFFSET 2 -#define USART3_RSTRX_SIZE 1 -#define USART3_RSTTX_OFFSET 3 -#define USART3_RSTTX_SIZE 1 -#define USART3_RXEN_OFFSET 4 -#define USART3_RXEN_SIZE 1 -#define USART3_RXDIS_OFFSET 5 -#define USART3_RXDIS_SIZE 1 -#define USART3_TXEN_OFFSET 6 -#define USART3_TXEN_SIZE 1 -#define USART3_TXDIS_OFFSET 7 -#define USART3_TXDIS_SIZE 1 -#define USART3_RSTSTA_OFFSET 8 -#define USART3_RSTSTA_SIZE 1 -#define USART3_STTBRK_OFFSET 9 -#define USART3_STTBRK_SIZE 1 -#define USART3_STPBRK_OFFSET 10 -#define USART3_STPBRK_SIZE 1 -#define USART3_STTTO_OFFSET 11 -#define USART3_STTTO_SIZE 1 -#define USART3_SENDA_OFFSET 12 -#define USART3_SENDA_SIZE 1 -#define USART3_RSTIT_OFFSET 13 -#define USART3_RSTIT_SIZE 1 -#define USART3_RSTNACK_OFFSET 14 -#define USART3_RSTNACK_SIZE 1 -#define USART3_RETTO_OFFSET 15 -#define USART3_RETTO_SIZE 1 -#define USART3_DTREN_OFFSET 16 -#define USART3_DTREN_SIZE 1 -#define USART3_DTRDIS_OFFSET 17 -#define USART3_DTRDIS_SIZE 1 -#define USART3_RTSEN_OFFSET 18 -#define USART3_RTSEN_SIZE 1 -#define USART3_RTSDIS_OFFSET 19 -#define USART3_RTSDIS_SIZE 1 -#define USART3_COMM_TX_OFFSET 30 -#define USART3_COMM_TX_SIZE 1 -#define USART3_COMM_RX_OFFSET 31 -#define USART3_COMM_RX_SIZE 1 - -/* Bitfields in MR */ -#define USART3_USART_MODE_OFFSET 0 -#define USART3_USART_MODE_SIZE 4 -#define USART3_USCLKS_OFFSET 4 -#define USART3_USCLKS_SIZE 2 -#define USART3_CHRL_OFFSET 6 -#define USART3_CHRL_SIZE 2 -#define USART3_SYNC_OFFSET 8 -#define USART3_SYNC_SIZE 1 -#define USART3_PAR_OFFSET 9 -#define USART3_PAR_SIZE 3 -#define USART3_NBSTOP_OFFSET 12 -#define USART3_NBSTOP_SIZE 2 -#define USART3_CHMODE_OFFSET 14 -#define USART3_CHMODE_SIZE 2 -#define USART3_MSBF_OFFSET 16 -#define USART3_MSBF_SIZE 1 -#define USART3_MODE9_OFFSET 17 -#define USART3_MODE9_SIZE 1 -#define USART3_CLKO_OFFSET 18 -#define USART3_CLKO_SIZE 1 -#define USART3_OVER_OFFSET 19 -#define USART3_OVER_SIZE 1 -#define USART3_INACK_OFFSET 20 -#define USART3_INACK_SIZE 1 -#define USART3_DSNACK_OFFSET 21 -#define USART3_DSNACK_SIZE 1 -#define USART3_MAX_ITERATION_OFFSET 24 -#define USART3_MAX_ITERATION_SIZE 3 -#define USART3_FILTER_OFFSET 28 -#define USART3_FILTER_SIZE 1 - -/* Bitfields in CSR */ -#define USART3_RXRDY_OFFSET 0 -#define USART3_RXRDY_SIZE 1 -#define USART3_TXRDY_OFFSET 1 -#define USART3_TXRDY_SIZE 1 -#define USART3_RXBRK_OFFSET 2 -#define USART3_RXBRK_SIZE 1 -#define USART3_ENDRX_OFFSET 3 -#define USART3_ENDRX_SIZE 1 -#define USART3_ENDTX_OFFSET 4 -#define USART3_ENDTX_SIZE 1 -#define USART3_OVRE_OFFSET 5 -#define USART3_OVRE_SIZE 1 -#define USART3_FRAME_OFFSET 6 -#define USART3_FRAME_SIZE 1 -#define USART3_PARE_OFFSET 7 -#define USART3_PARE_SIZE 1 -#define USART3_TIMEOUT_OFFSET 8 -#define USART3_TIMEOUT_SIZE 1 -#define USART3_TXEMPTY_OFFSET 9 -#define USART3_TXEMPTY_SIZE 1 -#define USART3_ITERATION_OFFSET 10 -#define USART3_ITERATION_SIZE 1 -#define USART3_TXBUFE_OFFSET 11 -#define USART3_TXBUFE_SIZE 1 -#define USART3_RXBUFF_OFFSET 12 -#define USART3_RXBUFF_SIZE 1 -#define USART3_NACK_OFFSET 13 -#define USART3_NACK_SIZE 1 -#define USART3_RIIC_OFFSET 16 -#define USART3_RIIC_SIZE 1 -#define USART3_DSRIC_OFFSET 17 -#define USART3_DSRIC_SIZE 1 -#define USART3_DCDIC_OFFSET 18 -#define USART3_DCDIC_SIZE 1 -#define USART3_CTSIC_OFFSET 19 -#define USART3_CTSIC_SIZE 1 -#define USART3_RI_OFFSET 20 -#define USART3_RI_SIZE 1 -#define USART3_DSR_OFFSET 21 -#define USART3_DSR_SIZE 1 -#define USART3_DCD_OFFSET 22 -#define USART3_DCD_SIZE 1 -#define USART3_CTS_OFFSET 23 -#define USART3_CTS_SIZE 1 - -/* Bitfields in RHR */ -#define USART3_RXCHR_OFFSET 0 -#define USART3_RXCHR_SIZE 9 - -/* Bitfields in THR */ -#define USART3_TXCHR_OFFSET 0 -#define USART3_TXCHR_SIZE 9 - -/* Bitfields in BRGR */ -#define USART3_CD_OFFSET 0 -#define USART3_CD_SIZE 16 - -/* Bitfields in RTOR */ -#define USART3_TO_OFFSET 0 -#define USART3_TO_SIZE 16 - -/* Bitfields in TTGR */ -#define USART3_TG_OFFSET 0 -#define USART3_TG_SIZE 8 - -/* Bitfields in FIDI */ -#define USART3_FI_DI_RATIO_OFFSET 0 -#define USART3_FI_DI_RATIO_SIZE 11 - -/* Bitfields in NER */ -#define USART3_NB_ERRORS_OFFSET 0 -#define USART3_NB_ERRORS_SIZE 8 - -/* Bitfields in XXR */ -#define USART3_XOFF_OFFSET 0 -#define USART3_XOFF_SIZE 8 -#define USART3_XON_OFFSET 8 -#define USART3_XON_SIZE 8 - -/* Bitfields in IFR */ -#define USART3_IRDA_FILTER_OFFSET 0 -#define USART3_IRDA_FILTER_SIZE 8 - -/* Bitfields in RCR */ -#define USART3_RXCTR_OFFSET 0 -#define USART3_RXCTR_SIZE 16 - -/* Bitfields in TCR */ -#define USART3_TXCTR_OFFSET 0 -#define USART3_TXCTR_SIZE 16 - -/* Bitfields in RNCR */ -#define USART3_RXNCR_OFFSET 0 -#define USART3_RXNCR_SIZE 16 - -/* Bitfields in TNCR */ -#define USART3_TXNCR_OFFSET 0 -#define USART3_TXNCR_SIZE 16 - -/* Bitfields in PTCR */ -#define USART3_RXTEN_OFFSET 0 -#define USART3_RXTEN_SIZE 1 -#define USART3_RXTDIS_OFFSET 1 -#define USART3_RXTDIS_SIZE 1 -#define USART3_TXTEN_OFFSET 8 -#define USART3_TXTEN_SIZE 1 -#define USART3_TXTDIS_OFFSET 9 -#define USART3_TXTDIS_SIZE 1 - -/* Constants for USART_MODE */ -#define USART3_USART_MODE_NORMAL 0 -#define USART3_USART_MODE_RS485 1 -#define USART3_USART_MODE_HARDWARE 2 -#define USART3_USART_MODE_MODEM 3 -#define USART3_USART_MODE_ISO7816_T0 4 -#define USART3_USART_MODE_ISO7816_T1 6 -#define USART3_USART_MODE_IRDA 8 - -/* Constants for USCLKS */ -#define USART3_USCLKS_MCK 0 -#define USART3_USCLKS_MCK_DIV 1 -#define USART3_USCLKS_SCK 3 - -/* Constants for CHRL */ -#define USART3_CHRL_5 0 -#define USART3_CHRL_6 1 -#define USART3_CHRL_7 2 -#define USART3_CHRL_8 3 - -/* Constants for PAR */ -#define USART3_PAR_EVEN 0 -#define USART3_PAR_ODD 1 -#define USART3_PAR_SPACE 2 -#define USART3_PAR_MARK 3 -#define USART3_PAR_NONE 4 -#define USART3_PAR_MULTI 6 - -/* Constants for NBSTOP */ -#define USART3_NBSTOP_1 0 -#define USART3_NBSTOP_1_5 1 -#define USART3_NBSTOP_2 2 - -/* Constants for CHMODE */ -#define USART3_CHMODE_NORMAL 0 -#define USART3_CHMODE_ECHO 1 -#define USART3_CHMODE_LOCAL_LOOP 2 -#define USART3_CHMODE_REMOTE_LOOP 3 - -/* Constants for MSBF */ -#define USART3_MSBF_LSBF 0 -#define USART3_MSBF_MSBF 1 - -/* Constants for OVER */ -#define USART3_OVER_X16 0 -#define USART3_OVER_X8 1 - -/* Constants for CD */ -#define USART3_CD_DISABLE 0 -#define USART3_CD_BYPASS 1 - -/* Constants for TO */ -#define USART3_TO_DISABLE 0 - -/* Constants for TG */ -#define USART3_TG_DISABLE 0 - -/* Constants for FI_DI_RATIO */ -#define USART3_FI_DI_RATIO_DISABLE 0 - -/* Bit manipulation macros */ -#define USART3_BIT(name) \ - (1 << USART3_##name##_OFFSET) -#define USART3_BF(name,value) \ - (((value) & ((1 << USART3_##name##_SIZE) - 1)) \ - << USART3_##name##_OFFSET) -#define USART3_BFEXT(name,value) \ - (((value) >> USART3_##name##_OFFSET) \ - & ((1 << USART3_##name##_SIZE) - 1)) -#define USART3_BFINS(name,value,old) \ - (((old) & ~(((1 << USART3_##name##_SIZE) - 1) \ - << USART3_##name##_OFFSET)) \ - | USART3_BF(name,value)) - -/* Register access macros */ -#define usart3_readl(reg) \ - readl((void *)USART_BASE + USART3_##reg) -#define usart3_writel(reg,value) \ - writel((value), (void *)USART_BASE + USART3_##reg) - -#endif /* __DRIVERS_ATMEL_USART_H__ */ diff --git a/drivers/ns16550.c b/drivers/ns16550.c deleted file mode 100644 index 2429464d89..0000000000 --- a/drivers/ns16550.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * COM1 NS16550 support - * originally from linux source (arch/ppc/boot/ns16550.c) - * modified to use CFG_ISA_MEM and new defines - */ - -#include - -#ifdef CFG_NS16550 - -#include - -#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */ -#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */ -#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */ - -void NS16550_init (NS16550_t com_port, int baud_divisor) -{ - com_port->ier = 0x00; -#ifdef CONFIG_OMAP - com_port->mdr1 = 0x7; /* mode select reset TL16C750*/ -#endif - com_port->lcr = LCR_BKSE | LCRVAL; - com_port->dll = baud_divisor & 0xff; - com_port->dlm = (baud_divisor >> 8) & 0xff; - com_port->lcr = LCRVAL; - com_port->mcr = MCRVAL; - com_port->fcr = FCRVAL; -#if defined(CONFIG_OMAP) -#if defined(CONFIG_APTIX) - com_port->mdr1 = 3; /* /13 mode so Aptix 6MHz can hit 115200 */ -#else - com_port->mdr1 = 0; /* /16 is proper to hit 115200 with 48MHz */ -#endif -#endif -} - -void NS16550_reinit (NS16550_t com_port, int baud_divisor) -{ - com_port->ier = 0x00; - com_port->lcr = LCR_BKSE; - com_port->dll = baud_divisor & 0xff; - com_port->dlm = (baud_divisor >> 8) & 0xff; - com_port->lcr = LCRVAL; - com_port->mcr = MCRVAL; - com_port->fcr = FCRVAL; -} - -void NS16550_putc (NS16550_t com_port, char c) -{ - while ((com_port->lsr & LSR_THRE) == 0); - com_port->thr = c; -} - -char NS16550_getc (NS16550_t com_port) -{ - while ((com_port->lsr & LSR_DR) == 0) { -#ifdef CONFIG_USB_TTY - extern void usbtty_poll(void); - usbtty_poll(); -#endif - } - return (com_port->rbr); -} - -int NS16550_tstc (NS16550_t com_port) -{ - return ((com_port->lsr & LSR_DR) != 0); -} - -#endif diff --git a/drivers/ns9750_serial.c b/drivers/ns9750_serial.c deleted file mode 100644 index 02c0d39520..0000000000 --- a/drivers/ns9750_serial.c +++ /dev/null @@ -1,214 +0,0 @@ -/*********************************************************************** - * - * Copyright (C) 2004 by FS Forth-Systeme GmbH. - * All rights reserved. - * - * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ - * @Author: Markus Pietrek - * @Descr: Serial driver for the NS9750. Only one UART is supported yet. - * @References: [1] NS9750 Hardware Reference/December 2003 - * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass - * - * 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 - -#ifdef CFG_NS9750_UART - -#include "ns9750_bbus.h" /* for GPIOs */ -#include "ns9750_ser.h" /* for serial configuration */ - -DECLARE_GLOBAL_DATA_PTR; - -#if !defined(CONFIG_CONS_INDEX) -#error "No console index specified." -#endif - -#define CONSOLE CONFIG_CONS_INDEX - -static unsigned int calcBitrateRegister( void ); -static unsigned int calcRxCharGapRegister( void ); - -static char cCharsAvailable; /* Numbers of chars in unCharCache */ -static unsigned int unCharCache; /* unCharCache is only valid if - * cCharsAvailable > 0 */ - -/*********************************************************************** - * @Function: serial_init - * @Return: 0 - * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off - ***********************************************************************/ - -int serial_init( void ) -{ - unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 }; - unsigned int aunGPIORxD[] = { 1, 9, 41, 45 }; - - cCharsAvailable = 0; - - /* configure TxD and RxD pins for their special function */ - set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ], - NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT ); - set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ], - NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT ); - - /* configure serial engine */ - *get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) = - NS9750_SER_CTRL_A_CE | - NS9750_SER_CTRL_A_STOP | - NS9750_SER_CTRL_A_WLS_8; - - serial_setbrg(); - - *get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) = - NS9750_SER_CTRL_B_RCGT; - - return 0; -} - -/*********************************************************************** - * @Function: serial_putc - * @Return: n/a - * @Descr: writes one character to the FIFO. Blocks until FIFO is not full - ***********************************************************************/ - -void serial_putc( const char c ) -{ - if (c == '\n') - serial_putc( '\r' ); - - while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) & - NS9750_SER_STAT_A_TRDY ) ) { - /* do nothing, wait for characters in FIFO sent */ - } - - *(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO, - CONSOLE) = c; -} - -/*********************************************************************** - * @Function: serial_puts - * @Return: n/a - * @Descr: writes non-zero string to the FIFO. - ***********************************************************************/ - -void serial_puts( const char *s ) -{ - while (*s) { - serial_putc( *s++ ); - } -} - -/*********************************************************************** - * @Function: serial_getc - * @Return: the character read - * @Descr: performs only 8bit accesses to the FIFO. No error handling - ***********************************************************************/ - -int serial_getc( void ) -{ - int i; - - while (!serial_tstc() ) { - /* do nothing, wait for incoming characters */ - } - - /* at least one character in unCharCache */ - i = (int) (unCharCache & 0xff); - - unCharCache >>= 8; - cCharsAvailable--; - - return i; -} - -/*********************************************************************** - * @Function: serial_tstc - * @Return: 0 if no input available, otherwise != 0 - * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in - * unCharCache and the numbers of characters in cCharsAvailable - ***********************************************************************/ - -int serial_tstc( void ) -{ - unsigned int unRegCache; - - if ( cCharsAvailable ) - return 1; - - unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE ); - if( unRegCache & NS9750_SER_STAT_A_RBC ) { - *get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) = - NS9750_SER_STAT_A_RBC; - unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A, - CONSOLE ); - } - - if ( unRegCache & NS9750_SER_STAT_A_RRDY ) { - cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20; - if ( !cCharsAvailable ) - cCharsAvailable = 4; - - unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO, - CONSOLE ); - return 1; - } - - /* no chars available */ - return 0; -} - -void serial_setbrg( void ) -{ - *get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) = - calcBitrateRegister(); - *get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) = - calcRxCharGapRegister(); -} - -/*********************************************************************** - * @Function: calcBitrateRegister - * @Return: value for the serial bitrate register - * @Descr: register value depends on clock frequency and baudrate - ***********************************************************************/ - -static unsigned int calcBitrateRegister( void ) -{ - return ( NS9750_SER_BITRATE_EBIT | - NS9750_SER_BITRATE_CLKMUX_BCLK | - NS9750_SER_BITRATE_TMODE | - NS9750_SER_BITRATE_TCDR_16 | - NS9750_SER_BITRATE_RCDR_16 | - ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */ - ( gd->baudrate * 16 ) ) - 1 ) & - NS9750_SER_BITRATE_N_MA ) ); -} - -/*********************************************************************** - * @Function: calcRxCharGapRegister - * @Return: value for the character gap timer register - * @Descr: register value depends on clock frequency and baudrate. Currently 0 - * is used as there is a bug with the gap timer in PLL bypass mode. - ***********************************************************************/ - -static unsigned int calcRxCharGapRegister( void ) -{ - return NS9750_SER_RX_CHAR_TIMER_TRUN; -} - -#endif /* CFG_NS9750_UART */ diff --git a/drivers/s3c4510b_uart.c b/drivers/s3c4510b_uart.c deleted file mode 100644 index ddcd591f84..0000000000 --- a/drivers/s3c4510b_uart.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) - * Curt Brune - * - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * (C) Copyright 2002-2004 - * Wolfgang Denk, DENX Software Engineering, - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) - * - * 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 - * - * MODULE: $Id:$ - * Description: UART/Serial interface for Samsung S3C4510B SoC - * Runtime Env: ARM7TDMI - * Change History: - * 03-02-04 Create (Curt Brune) curt@cucy.com - * - */ - -#include - -#ifdef CONFIG_DRIVER_S3C4510_UART - -#include -#include "s3c4510b_uart.h" - -DECLARE_GLOBAL_DATA_PTR; - -static UART *uart; - -/* flush serial input queue. returns 0 on success or negative error - * number otherwise - */ -static int serial_flush_input(void) -{ - volatile u32 tmp; - - /* keep on reading as long as the receiver is not empty */ - while( uart->m_stat.bf.rxReady) { - tmp = uart->m_rx; - } - - return 0; -} - - -/* flush output queue. returns 0 on success or negative error number - * otherwise - */ -static int serial_flush_output(void) -{ - /* wait until the transmitter is no longer busy */ - while( !uart->m_stat.bf.txBufEmpty); - - return 0; -} - - -void serial_setbrg (void) -{ - UART_LINE_CTRL ulctrl; - UART_CTRL uctrl; - UART_BAUD_DIV ubd; - - serial_flush_output(); - serial_flush_input(); - - /* control register */ - uctrl.ui = 0x0; - uctrl.bf.rxMode = 0x1; - uctrl.bf.rxIrq = 0x0; - uctrl.bf.txMode = 0x1; - uctrl.bf.DSR = 0x0; - uctrl.bf.sendBreak = 0x0; - uctrl.bf.loopBack = 0x0; - uart->m_ctrl.ui = uctrl.ui; - - /* line control register */ - ulctrl.ui = 0x0; - ulctrl.bf.wordLen = 0x3; /* 8 bit data */ - ulctrl.bf.nStop = 0x0; /* 1 stop bit */ - ulctrl.bf.parity = 0x0; /* no parity */ - ulctrl.bf.clk = 0x0; /* internal clock */ - ulctrl.bf.infra_red = 0x0; /* no infra_red */ - uart->m_lineCtrl.ui = ulctrl.ui; - - ubd.ui = 0x0; - - /* see table on page 10-15 in SAMSUNG S3C4510B manual */ - /* get correct divisor */ - switch(gd->baudrate) { - case 1200: ubd.bf.cnt0 = 1301; break; - case 2400: ubd.bf.cnt0 = 650; break; - case 4800: ubd.bf.cnt0 = 324; break; - case 9600: ubd.bf.cnt0 = 162; break; - case 19200: ubd.bf.cnt0 = 80; break; - case 38400: ubd.bf.cnt0 = 40; break; - case 57600: ubd.bf.cnt0 = 26; break; - case 115200: ubd.bf.cnt0 = 13; break; - } - - uart->m_baudDiv.ui = ubd.ui; - uart->m_baudCnt = 0x0; - uart->m_baudClk = 0x0; - -} - - -/* - * Initialise the serial port with the given baudrate. The settings - * are always 8 data bits, no parity, 1 stop bit, no start bits. - * - */ -int serial_init (void) -{ - -#if CONFIG_SERIAL1 == 1 - uart = (UART *)UART0_BASE; -#elif CONFIG_SERIAL1 == 2 - uart = (UART *)UART1_BASE; -#else -#error CONFIG_SERIAL1 not equal to 1 or 2 -#endif - - serial_setbrg (); - - return (0); -} - - -/* - * Output a single byte to the serial port. - */ -void serial_putc (const char c) -{ - /* wait for room in the transmit FIFO */ - while( !uart->m_stat.bf.txBufEmpty); - - uart->m_tx = c; - - /* - to be polite with serial console add a line feed - to the carriage return character - */ - if (c=='\n') - serial_putc('\r'); -} - -/* - * Test if an input byte is ready from the serial port. Returns non-zero on - * success, 0 otherwise. - */ -int serial_tstc (void) -{ - return uart->m_stat.bf.rxReady; -} - -/* - * Read a single byte from the serial port. Returns 1 on success, 0 - * otherwise. When the function is succesfull, the character read is - * written into its argument c. - */ -int serial_getc (void) -{ - int rv; - - for(;;) { - rv = serial_tstc(); - - if (rv) { - return uart->m_rx & 0xFF; - } - } -} - -void serial_puts (const char *s) -{ - while (*s) { - serial_putc (*s++); - } - - /* busy wait for tx complete */ - while ( !uart->m_stat.bf.txComplete); - - /* clear break */ - uart->m_ctrl.bf.sendBreak = 0; - -} - -#endif diff --git a/drivers/s3c4510b_uart.h b/drivers/s3c4510b_uart.h deleted file mode 100644 index b06c76d84a..0000000000 --- a/drivers/s3c4510b_uart.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef __UART_H -#define __UART_H - -/* - * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) - * Curt Brune - * - * 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 - * - * Description: S3C4510B UART register layout - */ - -/* UART LINE CONTROL register */ -typedef struct __BF_UART_LINE_CTRL { - u32 wordLen: 2; - u32 nStop: 1; - u32 parity: 3; - u32 clk: 1; - u32 infra_red: 1; - u32 unused:24; -} BF_UART_LINE_CTRL; - -typedef union _UART_LINE_CTRL { - u32 ui; - BF_UART_LINE_CTRL bf; -} UART_LINE_CTRL; - -/* UART CONTROL register */ -typedef struct __BF_UART_CTRL { - u32 rxMode: 2; - u32 rxIrq: 1; - u32 txMode: 2; - u32 DSR: 1; - u32 sendBreak: 1; - u32 loopBack: 1; - u32 unused:24; -} BF_UART_CTRL; - -typedef union _UART_CTRL { - u32 ui; - BF_UART_CTRL bf; -} UART_CTRL; - -/* UART STATUS register */ -typedef struct __BF_UART_STAT { - u32 overrun: 1; - u32 parity: 1; - u32 frame: 1; - u32 breakIrq: 1; - u32 DTR: 1; - u32 rxReady: 1; - u32 txBufEmpty: 1; - u32 txComplete: 1; - u32 unused:24; -} BF_UART_STAT; - -typedef union _UART_STAT { - u32 ui; - BF_UART_STAT bf; -} UART_STAT; - -/* UART BAUD_DIV register */ -typedef struct __BF_UART_BAUD_DIV { - u32 cnt1: 4; - u32 cnt0:12; - u32 unused:16; -} BF_UART_BAUD_DIV; - -typedef union _UART_BAUD_DIV { - u32 ui; - BF_UART_BAUD_DIV bf; -} UART_BAUD_DIV; - -/* UART register block */ -typedef struct __UART { - volatile UART_LINE_CTRL m_lineCtrl; - volatile UART_CTRL m_ctrl; - volatile UART_STAT m_stat; - volatile u32 m_tx; - volatile u32 m_rx; - volatile UART_BAUD_DIV m_baudDiv; - volatile u32 m_baudCnt; - volatile u32 m_baudClk; -} UART; - -#define NL 0x0A -#define CR 0x0D -#define BSP 0x08 -#define ESC 0x1B -#define CTRLZ 0x1A -#define RUBOUT 0x7F - -#endif diff --git a/drivers/serial.c b/drivers/serial.c deleted file mode 100644 index 76425d8790..0000000000 --- a/drivers/serial.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * (C) Copyright 2000 - * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. - * - * 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 - -#ifdef CFG_NS16550_SERIAL - -#include -#ifdef CFG_NS87308 -#include -#endif - -#if defined (CONFIG_SERIAL_MULTI) -#include -#endif - -DECLARE_GLOBAL_DATA_PTR; - -#if !defined(CONFIG_CONS_INDEX) -#if defined (CONFIG_SERIAL_MULTI) -/* with CONFIG_SERIAL_MULTI we might have no console - * on these devices - */ -#else -#error "No console index specified." -#endif /* CONFIG_SERIAL_MULTI */ -#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4) -#error "Invalid console index value." -#endif - -#if CONFIG_CONS_INDEX == 1 && !defined(CFG_NS16550_COM1) -#error "Console port 1 defined but not configured." -#elif CONFIG_CONS_INDEX == 2 && !defined(CFG_NS16550_COM2) -#error "Console port 2 defined but not configured." -#elif CONFIG_CONS_INDEX == 3 && !defined(CFG_NS16550_COM3) -#error "Console port 3 defined but not configured." -#elif CONFIG_CONS_INDEX == 4 && !defined(CFG_NS16550_COM4) -#error "Console port 4 defined but not configured." -#endif - -/* Note: The port number specified in the functions is 1 based. - * the array is 0 based. - */ -static NS16550_t serial_ports[4] = { -#ifdef CFG_NS16550_COM1 - (NS16550_t)CFG_NS16550_COM1, -#else - NULL, -#endif -#ifdef CFG_NS16550_COM2 - (NS16550_t)CFG_NS16550_COM2, -#else - NULL, -#endif -#ifdef CFG_NS16550_COM3 - (NS16550_t)CFG_NS16550_COM3, -#else - NULL, -#endif -#ifdef CFG_NS16550_COM4 - (NS16550_t)CFG_NS16550_COM4 -#else - NULL -#endif -}; - -#define PORT serial_ports[port-1] -#if defined(CONFIG_CONS_INDEX) -#define CONSOLE (serial_ports[CONFIG_CONS_INDEX-1]) -#endif - -#if defined(CONFIG_SERIAL_MULTI) - -/* Multi serial device functions */ -#define DECLARE_ESERIAL_FUNCTIONS(port) \ - int eserial##port##_init (void) {\ - int clock_divisor; \ - clock_divisor = calc_divisor(serial_ports[port-1]); \ - NS16550_init(serial_ports[port-1], clock_divisor); \ - return(0);}\ - void eserial##port##_setbrg (void) {\ - serial_setbrg_dev(port);}\ - int eserial##port##_getc (void) {\ - return serial_getc_dev(port);}\ - int eserial##port##_tstc (void) {\ - return serial_tstc_dev(port);}\ - void eserial##port##_putc (const char c) {\ - serial_putc_dev(port, c);}\ - void eserial##port##_puts (const char *s) {\ - serial_puts_dev(port, s);} - -/* Serial device descriptor */ -#define INIT_ESERIAL_STRUCTURE(port,name,bus) {\ - name,\ - bus,\ - eserial##port##_init,\ - eserial##port##_setbrg,\ - eserial##port##_getc,\ - eserial##port##_tstc,\ - eserial##port##_putc,\ - eserial##port##_puts, } - -#endif /* CONFIG_SERIAL_MULTI */ - -static int calc_divisor (NS16550_t port) -{ -#ifdef CONFIG_OMAP1510 - /* If can't cleanly clock 115200 set div to 1 */ - if ((CFG_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) { - port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */ - return (1); /* return 1 for base divisor */ - } - port->osc_12m_sel = 0; /* clear if previsouly set */ -#endif -#ifdef CONFIG_OMAP1610 - /* If can't cleanly clock 115200 set div to 1 */ - if ((CFG_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) { - return (26); /* return 26 for base divisor */ - } -#endif - -#ifdef CONFIG_APTIX -#define MODE_X_DIV 13 -#else -#define MODE_X_DIV 16 -#endif - return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate); - -} - -#if !defined(CONFIG_SERIAL_MULTI) -int serial_init (void) -{ - int clock_divisor; - -#ifdef CFG_NS87308 - initialise_ns87308(); -#endif - -#ifdef CFG_NS16550_COM1 - clock_divisor = calc_divisor(serial_ports[0]); - NS16550_init(serial_ports[0], clock_divisor); -#endif -#ifdef CFG_NS16550_COM2 - clock_divisor = calc_divisor(serial_ports[1]); - NS16550_init(serial_ports[1], clock_divisor); -#endif -#ifdef CFG_NS16550_COM3 - clock_divisor = calc_divisor(serial_ports[2]); - NS16550_init(serial_ports[2], clock_divisor); -#endif -#ifdef CFG_NS16550_COM4 - clock_divisor = calc_divisor(serial_ports[3]); - NS16550_init(serial_ports[3], clock_divisor); -#endif - - return (0); -} -#endif - -void -_serial_putc(const char c,const int port) -{ - if (c == '\n') - NS16550_putc(PORT, '\r'); - - NS16550_putc(PORT, c); -} - -void -_serial_putc_raw(const char c,const int port) -{ - NS16550_putc(PORT, c); -} - -void -_serial_puts (const char *s,const int port) -{ - while (*s) { - _serial_putc (*s++,port); - } -} - - -int -_serial_getc(const int port) -{ - return NS16550_getc(PORT); -} - -int -_serial_tstc(const int port) -{ - return NS16550_tstc(PORT); -} - -void -_serial_setbrg (const int port) -{ - int clock_divisor; - - clock_divisor = calc_divisor(PORT); - NS16550_reinit(PORT, clock_divisor); -} - -#if defined(CONFIG_SERIAL_MULTI) -static inline void -serial_putc_dev(unsigned int dev_index,const char c) -{ - _serial_putc(c,dev_index); -} -#else -void -serial_putc(const char c) -{ - _serial_putc(c,CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) -static inline void -serial_putc_raw_dev(unsigned int dev_index,const char c) -{ - _serial_putc_raw(c,dev_index); -} -#else -void -serial_putc_raw(const char c) -{ - _serial_putc_raw(c,CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) -static inline void -serial_puts_dev(unsigned int dev_index,const char *s) -{ - _serial_puts(s,dev_index); -} -#else -void -serial_puts(const char *s) -{ - _serial_puts(s,CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) -static inline int -serial_getc_dev(unsigned int dev_index) -{ - return _serial_getc(dev_index); -} -#else -int -serial_getc(void) -{ - return _serial_getc(CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) -static inline int -serial_tstc_dev(unsigned int dev_index) -{ - return _serial_tstc(dev_index); -} -#else -int -serial_tstc(void) -{ - return _serial_tstc(CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) -static inline void -serial_setbrg_dev(unsigned int dev_index) -{ - _serial_setbrg(dev_index); -} -#else -void -serial_setbrg(void) -{ - _serial_setbrg(CONFIG_CONS_INDEX); -} -#endif - -#if defined(CONFIG_SERIAL_MULTI) - -DECLARE_ESERIAL_FUNCTIONS(1); -struct serial_device eserial1_device = - INIT_ESERIAL_STRUCTURE(1,"eserial0","EUART1"); -DECLARE_ESERIAL_FUNCTIONS(2); -struct serial_device eserial2_device = - INIT_ESERIAL_STRUCTURE(2,"eserial1","EUART2"); -DECLARE_ESERIAL_FUNCTIONS(3); -struct serial_device eserial3_device = - INIT_ESERIAL_STRUCTURE(3,"eserial2","EUART3"); -DECLARE_ESERIAL_FUNCTIONS(4); -struct serial_device eserial4_device = - INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4"); -#endif /* CONFIG_SERIAL_MULTI */ - -#endif diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 40f3d672ec..735c630006 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -25,8 +25,19 @@ include $(TOPDIR)/config.mk LIB := $(obj)libserial.a -COBJS := mcfuart.o serial_pl010.o serial_pl011.o - +COBJS-y += atmel_usart.o +COBJS-y += mcfuart.o +COBJS-y += ns9750_serial.o +COBJS-y += ns16550.o +COBJS-y += s3c4510b_uart.o +COBJS-y += serial.o +COBJS-y += serial_max3100.o +COBJS-y += serial_pl010.o +COBJS-y += serial_pl011.o +COBJS-y += serial_xuartlite.o +COBJS-y += usbtty.o + +COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c new file mode 100644 index 0000000000..f35b99730f --- /dev/null +++ b/drivers/serial/atmel_usart.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * 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 + +#ifdef CONFIG_ATMEL_USART +#include +#include +#include + +#if defined(CONFIG_USART0) +# define USART_ID 0 +# define USART_BASE USART0_BASE +#elif defined(CONFIG_USART1) +# define USART_ID 1 +# define USART_BASE USART1_BASE +#elif defined(CONFIG_USART2) +# define USART_ID 2 +# define USART_BASE USART2_BASE +#elif defined(CONFIG_USART3) +# define USART_ID 3 +# define USART_BASE USART3_BASE +#endif + +#include "atmel_usart.h" + +DECLARE_GLOBAL_DATA_PTR; + +void serial_setbrg(void) +{ + unsigned long divisor; + unsigned long usart_hz; + + /* + * Master Clock + * Baud Rate = -------------- + * 16 * CD + */ + usart_hz = get_usart_clk_rate(USART_ID); + divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate; + usart3_writel(BRGR, USART3_BF(CD, divisor)); +} + +int serial_init(void) +{ + usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX)); + + serial_setbrg(); + + usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN)); + usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) + | USART3_BF(USCLKS, USART3_USCLKS_MCK) + | USART3_BF(CHRL, USART3_CHRL_8) + | USART3_BF(PAR, USART3_PAR_NONE) + | USART3_BF(NBSTOP, USART3_NBSTOP_1))); + + return 0; +} + +void serial_putc(char c) +{ + if (c == '\n') + serial_putc('\r'); + + while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ; + usart3_writel(THR, c); +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc(*s++); +} + +int serial_getc(void) +{ + while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ; + return usart3_readl(RHR); +} + +int serial_tstc(void) +{ + return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0; +} + +#endif /* CONFIG_ATMEL_USART */ diff --git a/drivers/serial/atmel_usart.h b/drivers/serial/atmel_usart.h new file mode 100644 index 0000000000..af3773a99f --- /dev/null +++ b/drivers/serial/atmel_usart.h @@ -0,0 +1,314 @@ +/* + * Register definitions for the Atmel USART3 module. + * + * Copyright (C) 2005-2006 Atmel Corporation + * + * 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 + */ +#ifndef __DRIVERS_ATMEL_USART_H__ +#define __DRIVERS_ATMEL_USART_H__ + +/* USART3 register offsets */ +#define USART3_CR 0x0000 +#define USART3_MR 0x0004 +#define USART3_IER 0x0008 +#define USART3_IDR 0x000c +#define USART3_IMR 0x0010 +#define USART3_CSR 0x0014 +#define USART3_RHR 0x0018 +#define USART3_THR 0x001c +#define USART3_BRGR 0x0020 +#define USART3_RTOR 0x0024 +#define USART3_TTGR 0x0028 +#define USART3_FIDI 0x0040 +#define USART3_NER 0x0044 +#define USART3_XXR 0x0048 +#define USART3_IFR 0x004c +#define USART3_RPR 0x0100 +#define USART3_RCR 0x0104 +#define USART3_TPR 0x0108 +#define USART3_TCR 0x010c +#define USART3_RNPR 0x0110 +#define USART3_RNCR 0x0114 +#define USART3_TNPR 0x0118 +#define USART3_TNCR 0x011c +#define USART3_PTCR 0x0120 +#define USART3_PTSR 0x0124 + +/* Bitfields in CR */ +#define USART3_RSTRX_OFFSET 2 +#define USART3_RSTRX_SIZE 1 +#define USART3_RSTTX_OFFSET 3 +#define USART3_RSTTX_SIZE 1 +#define USART3_RXEN_OFFSET 4 +#define USART3_RXEN_SIZE 1 +#define USART3_RXDIS_OFFSET 5 +#define USART3_RXDIS_SIZE 1 +#define USART3_TXEN_OFFSET 6 +#define USART3_TXEN_SIZE 1 +#define USART3_TXDIS_OFFSET 7 +#define USART3_TXDIS_SIZE 1 +#define USART3_RSTSTA_OFFSET 8 +#define USART3_RSTSTA_SIZE 1 +#define USART3_STTBRK_OFFSET 9 +#define USART3_STTBRK_SIZE 1 +#define USART3_STPBRK_OFFSET 10 +#define USART3_STPBRK_SIZE 1 +#define USART3_STTTO_OFFSET 11 +#define USART3_STTTO_SIZE 1 +#define USART3_SENDA_OFFSET 12 +#define USART3_SENDA_SIZE 1 +#define USART3_RSTIT_OFFSET 13 +#define USART3_RSTIT_SIZE 1 +#define USART3_RSTNACK_OFFSET 14 +#define USART3_RSTNACK_SIZE 1 +#define USART3_RETTO_OFFSET 15 +#define USART3_RETTO_SIZE 1 +#define USART3_DTREN_OFFSET 16 +#define USART3_DTREN_SIZE 1 +#define USART3_DTRDIS_OFFSET 17 +#define USART3_DTRDIS_SIZE 1 +#define USART3_RTSEN_OFFSET 18 +#define USART3_RTSEN_SIZE 1 +#define USART3_RTSDIS_OFFSET 19 +#define USART3_RTSDIS_SIZE 1 +#define USART3_COMM_TX_OFFSET 30 +#define USART3_COMM_TX_SIZE 1 +#define USART3_COMM_RX_OFFSET 31 +#define USART3_COMM_RX_SIZE 1 + +/* Bitfields in MR */ +#define USART3_USART_MODE_OFFSET 0 +#define USART3_USART_MODE_SIZE 4 +#define USART3_USCLKS_OFFSET 4 +#define USART3_USCLKS_SIZE 2 +#define USART3_CHRL_OFFSET 6 +#define USART3_CHRL_SIZE 2 +#define USART3_SYNC_OFFSET 8 +#define USART3_SYNC_SIZE 1 +#define USART3_PAR_OFFSET 9 +#define USART3_PAR_SIZE 3 +#define USART3_NBSTOP_OFFSET 12 +#define USART3_NBSTOP_SIZE 2 +#define USART3_CHMODE_OFFSET 14 +#define USART3_CHMODE_SIZE 2 +#define USART3_MSBF_OFFSET 16 +#define USART3_MSBF_SIZE 1 +#define USART3_MODE9_OFFSET 17 +#define USART3_MODE9_SIZE 1 +#define USART3_CLKO_OFFSET 18 +#define USART3_CLKO_SIZE 1 +#define USART3_OVER_OFFSET 19 +#define USART3_OVER_SIZE 1 +#define USART3_INACK_OFFSET 20 +#define USART3_INACK_SIZE 1 +#define USART3_DSNACK_OFFSET 21 +#define USART3_DSNACK_SIZE 1 +#define USART3_MAX_ITERATION_OFFSET 24 +#define USART3_MAX_ITERATION_SIZE 3 +#define USART3_FILTER_OFFSET 28 +#define USART3_FILTER_SIZE 1 + +/* Bitfields in CSR */ +#define USART3_RXRDY_OFFSET 0 +#define USART3_RXRDY_SIZE 1 +#define USART3_TXRDY_OFFSET 1 +#define USART3_TXRDY_SIZE 1 +#define USART3_RXBRK_OFFSET 2 +#define USART3_RXBRK_SIZE 1 +#define USART3_ENDRX_OFFSET 3 +#define USART3_ENDRX_SIZE 1 +#define USART3_ENDTX_OFFSET 4 +#define USART3_ENDTX_SIZE 1 +#define USART3_OVRE_OFFSET 5 +#define USART3_OVRE_SIZE 1 +#define USART3_FRAME_OFFSET 6 +#define USART3_FRAME_SIZE 1 +#define USART3_PARE_OFFSET 7 +#define USART3_PARE_SIZE 1 +#define USART3_TIMEOUT_OFFSET 8 +#define USART3_TIMEOUT_SIZE 1 +#define USART3_TXEMPTY_OFFSET 9 +#define USART3_TXEMPTY_SIZE 1 +#define USART3_ITERATION_OFFSET 10 +#define USART3_ITERATION_SIZE 1 +#define USART3_TXBUFE_OFFSET 11 +#define USART3_TXBUFE_SIZE 1 +#define USART3_RXBUFF_OFFSET 12 +#define USART3_RXBUFF_SIZE 1 +#define USART3_NACK_OFFSET 13 +#define USART3_NACK_SIZE 1 +#define USART3_RIIC_OFFSET 16 +#define USART3_RIIC_SIZE 1 +#define USART3_DSRIC_OFFSET 17 +#define USART3_DSRIC_SIZE 1 +#define USART3_DCDIC_OFFSET 18 +#define USART3_DCDIC_SIZE 1 +#define USART3_CTSIC_OFFSET 19 +#define USART3_CTSIC_SIZE 1 +#define USART3_RI_OFFSET 20 +#define USART3_RI_SIZE 1 +#define USART3_DSR_OFFSET 21 +#define USART3_DSR_SIZE 1 +#define USART3_DCD_OFFSET 22 +#define USART3_DCD_SIZE 1 +#define USART3_CTS_OFFSET 23 +#define USART3_CTS_SIZE 1 + +/* Bitfields in RHR */ +#define USART3_RXCHR_OFFSET 0 +#define USART3_RXCHR_SIZE 9 + +/* Bitfields in THR */ +#define USART3_TXCHR_OFFSET 0 +#define USART3_TXCHR_SIZE 9 + +/* Bitfields in BRGR */ +#define USART3_CD_OFFSET 0 +#define USART3_CD_SIZE 16 + +/* Bitfields in RTOR */ +#define USART3_TO_OFFSET 0 +#define USART3_TO_SIZE 16 + +/* Bitfields in TTGR */ +#define USART3_TG_OFFSET 0 +#define USART3_TG_SIZE 8 + +/* Bitfields in FIDI */ +#define USART3_FI_DI_RATIO_OFFSET 0 +#define USART3_FI_DI_RATIO_SIZE 11 + +/* Bitfields in NER */ +#define USART3_NB_ERRORS_OFFSET 0 +#define USART3_NB_ERRORS_SIZE 8 + +/* Bitfields in XXR */ +#define USART3_XOFF_OFFSET 0 +#define USART3_XOFF_SIZE 8 +#define USART3_XON_OFFSET 8 +#define USART3_XON_SIZE 8 + +/* Bitfields in IFR */ +#define USART3_IRDA_FILTER_OFFSET 0 +#define USART3_IRDA_FILTER_SIZE 8 + +/* Bitfields in RCR */ +#define USART3_RXCTR_OFFSET 0 +#define USART3_RXCTR_SIZE 16 + +/* Bitfields in TCR */ +#define USART3_TXCTR_OFFSET 0 +#define USART3_TXCTR_SIZE 16 + +/* Bitfields in RNCR */ +#define USART3_RXNCR_OFFSET 0 +#define USART3_RXNCR_SIZE 16 + +/* Bitfields in TNCR */ +#define USART3_TXNCR_OFFSET 0 +#define USART3_TXNCR_SIZE 16 + +/* Bitfields in PTCR */ +#define USART3_RXTEN_OFFSET 0 +#define USART3_RXTEN_SIZE 1 +#define USART3_RXTDIS_OFFSET 1 +#define USART3_RXTDIS_SIZE 1 +#define USART3_TXTEN_OFFSET 8 +#define USART3_TXTEN_SIZE 1 +#define USART3_TXTDIS_OFFSET 9 +#define USART3_TXTDIS_SIZE 1 + +/* Constants for USART_MODE */ +#define USART3_USART_MODE_NORMAL 0 +#define USART3_USART_MODE_RS485 1 +#define USART3_USART_MODE_HARDWARE 2 +#define USART3_USART_MODE_MODEM 3 +#define USART3_USART_MODE_ISO7816_T0 4 +#define USART3_USART_MODE_ISO7816_T1 6 +#define USART3_USART_MODE_IRDA 8 + +/* Constants for USCLKS */ +#define USART3_USCLKS_MCK 0 +#define USART3_USCLKS_MCK_DIV 1 +#define USART3_USCLKS_SCK 3 + +/* Constants for CHRL */ +#define USART3_CHRL_5 0 +#define USART3_CHRL_6 1 +#define USART3_CHRL_7 2 +#define USART3_CHRL_8 3 + +/* Constants for PAR */ +#define USART3_PAR_EVEN 0 +#define USART3_PAR_ODD 1 +#define USART3_PAR_SPACE 2 +#define USART3_PAR_MARK 3 +#define USART3_PAR_NONE 4 +#define USART3_PAR_MULTI 6 + +/* Constants for NBSTOP */ +#define USART3_NBSTOP_1 0 +#define USART3_NBSTOP_1_5 1 +#define USART3_NBSTOP_2 2 + +/* Constants for CHMODE */ +#define USART3_CHMODE_NORMAL 0 +#define USART3_CHMODE_ECHO 1 +#define USART3_CHMODE_LOCAL_LOOP 2 +#define USART3_CHMODE_REMOTE_LOOP 3 + +/* Constants for MSBF */ +#define USART3_MSBF_LSBF 0 +#define USART3_MSBF_MSBF 1 + +/* Constants for OVER */ +#define USART3_OVER_X16 0 +#define USART3_OVER_X8 1 + +/* Constants for CD */ +#define USART3_CD_DISABLE 0 +#define USART3_CD_BYPASS 1 + +/* Constants for TO */ +#define USART3_TO_DISABLE 0 + +/* Constants for TG */ +#define USART3_TG_DISABLE 0 + +/* Constants for FI_DI_RATIO */ +#define USART3_FI_DI_RATIO_DISABLE 0 + +/* Bit manipulation macros */ +#define USART3_BIT(name) \ + (1 << USART3_##name##_OFFSET) +#define USART3_BF(name,value) \ + (((value) & ((1 << USART3_##name##_SIZE) - 1)) \ + << USART3_##name##_OFFSET) +#define USART3_BFEXT(name,value) \ + (((value) >> USART3_##name##_OFFSET) \ + & ((1 << USART3_##name##_SIZE) - 1)) +#define USART3_BFINS(name,value,old) \ + (((old) & ~(((1 << USART3_##name##_SIZE) - 1) \ + << USART3_##name##_OFFSET)) \ + | USART3_BF(name,value)) + +/* Register access macros */ +#define usart3_readl(reg) \ + readl((void *)USART_BASE + USART3_##reg) +#define usart3_writel(reg,value) \ + writel((value), (void *)USART_BASE + USART3_##reg) + +#endif /* __DRIVERS_ATMEL_USART_H__ */ diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c new file mode 100644 index 0000000000..2429464d89 --- /dev/null +++ b/drivers/serial/ns16550.c @@ -0,0 +1,71 @@ +/* + * COM1 NS16550 support + * originally from linux source (arch/ppc/boot/ns16550.c) + * modified to use CFG_ISA_MEM and new defines + */ + +#include + +#ifdef CFG_NS16550 + +#include + +#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */ +#define MCRVAL (MCR_DTR | MCR_RTS) /* RTS/DTR */ +#define FCRVAL (FCR_FIFO_EN | FCR_RXSR | FCR_TXSR) /* Clear & enable FIFOs */ + +void NS16550_init (NS16550_t com_port, int baud_divisor) +{ + com_port->ier = 0x00; +#ifdef CONFIG_OMAP + com_port->mdr1 = 0x7; /* mode select reset TL16C750*/ +#endif + com_port->lcr = LCR_BKSE | LCRVAL; + com_port->dll = baud_divisor & 0xff; + com_port->dlm = (baud_divisor >> 8) & 0xff; + com_port->lcr = LCRVAL; + com_port->mcr = MCRVAL; + com_port->fcr = FCRVAL; +#if defined(CONFIG_OMAP) +#if defined(CONFIG_APTIX) + com_port->mdr1 = 3; /* /13 mode so Aptix 6MHz can hit 115200 */ +#else + com_port->mdr1 = 0; /* /16 is proper to hit 115200 with 48MHz */ +#endif +#endif +} + +void NS16550_reinit (NS16550_t com_port, int baud_divisor) +{ + com_port->ier = 0x00; + com_port->lcr = LCR_BKSE; + com_port->dll = baud_divisor & 0xff; + com_port->dlm = (baud_divisor >> 8) & 0xff; + com_port->lcr = LCRVAL; + com_port->mcr = MCRVAL; + com_port->fcr = FCRVAL; +} + +void NS16550_putc (NS16550_t com_port, char c) +{ + while ((com_port->lsr & LSR_THRE) == 0); + com_port->thr = c; +} + +char NS16550_getc (NS16550_t com_port) +{ + while ((com_port->lsr & LSR_DR) == 0) { +#ifdef CONFIG_USB_TTY + extern void usbtty_poll(void); + usbtty_poll(); +#endif + } + return (com_port->rbr); +} + +int NS16550_tstc (NS16550_t com_port) +{ + return ((com_port->lsr & LSR_DR) != 0); +} + +#endif diff --git a/drivers/serial/ns9750_serial.c b/drivers/serial/ns9750_serial.c new file mode 100644 index 0000000000..02c0d39520 --- /dev/null +++ b/drivers/serial/ns9750_serial.c @@ -0,0 +1,214 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Serial driver for the NS9750. Only one UART is supported yet. + * @References: [1] NS9750 Hardware Reference/December 2003 + * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass + * + * 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 + +#ifdef CFG_NS9750_UART + +#include "ns9750_bbus.h" /* for GPIOs */ +#include "ns9750_ser.h" /* for serial configuration */ + +DECLARE_GLOBAL_DATA_PTR; + +#if !defined(CONFIG_CONS_INDEX) +#error "No console index specified." +#endif + +#define CONSOLE CONFIG_CONS_INDEX + +static unsigned int calcBitrateRegister( void ); +static unsigned int calcRxCharGapRegister( void ); + +static char cCharsAvailable; /* Numbers of chars in unCharCache */ +static unsigned int unCharCache; /* unCharCache is only valid if + * cCharsAvailable > 0 */ + +/*********************************************************************** + * @Function: serial_init + * @Return: 0 + * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off + ***********************************************************************/ + +int serial_init( void ) +{ + unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 }; + unsigned int aunGPIORxD[] = { 1, 9, 41, 45 }; + + cCharsAvailable = 0; + + /* configure TxD and RxD pins for their special function */ + set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ], + NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT ); + set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ], + NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT ); + + /* configure serial engine */ + *get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) = + NS9750_SER_CTRL_A_CE | + NS9750_SER_CTRL_A_STOP | + NS9750_SER_CTRL_A_WLS_8; + + serial_setbrg(); + + *get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) = + NS9750_SER_CTRL_B_RCGT; + + return 0; +} + +/*********************************************************************** + * @Function: serial_putc + * @Return: n/a + * @Descr: writes one character to the FIFO. Blocks until FIFO is not full + ***********************************************************************/ + +void serial_putc( const char c ) +{ + if (c == '\n') + serial_putc( '\r' ); + + while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) & + NS9750_SER_STAT_A_TRDY ) ) { + /* do nothing, wait for characters in FIFO sent */ + } + + *(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO, + CONSOLE) = c; +} + +/*********************************************************************** + * @Function: serial_puts + * @Return: n/a + * @Descr: writes non-zero string to the FIFO. + ***********************************************************************/ + +void serial_puts( const char *s ) +{ + while (*s) { + serial_putc( *s++ ); + } +} + +/*********************************************************************** + * @Function: serial_getc + * @Return: the character read + * @Descr: performs only 8bit accesses to the FIFO. No error handling + ***********************************************************************/ + +int serial_getc( void ) +{ + int i; + + while (!serial_tstc() ) { + /* do nothing, wait for incoming characters */ + } + + /* at least one character in unCharCache */ + i = (int) (unCharCache & 0xff); + + unCharCache >>= 8; + cCharsAvailable--; + + return i; +} + +/*********************************************************************** + * @Function: serial_tstc + * @Return: 0 if no input available, otherwise != 0 + * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in + * unCharCache and the numbers of characters in cCharsAvailable + ***********************************************************************/ + +int serial_tstc( void ) +{ + unsigned int unRegCache; + + if ( cCharsAvailable ) + return 1; + + unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE ); + if( unRegCache & NS9750_SER_STAT_A_RBC ) { + *get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) = + NS9750_SER_STAT_A_RBC; + unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A, + CONSOLE ); + } + + if ( unRegCache & NS9750_SER_STAT_A_RRDY ) { + cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20; + if ( !cCharsAvailable ) + cCharsAvailable = 4; + + unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO, + CONSOLE ); + return 1; + } + + /* no chars available */ + return 0; +} + +void serial_setbrg( void ) +{ + *get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) = + calcBitrateRegister(); + *get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) = + calcRxCharGapRegister(); +} + +/*********************************************************************** + * @Function: calcBitrateRegister + * @Return: value for the serial bitrate register + * @Descr: register value depends on clock frequency and baudrate + ***********************************************************************/ + +static unsigned int calcBitrateRegister( void ) +{ + return ( NS9750_SER_BITRATE_EBIT | + NS9750_SER_BITRATE_CLKMUX_BCLK | + NS9750_SER_BITRATE_TMODE | + NS9750_SER_BITRATE_TCDR_16 | + NS9750_SER_BITRATE_RCDR_16 | + ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */ + ( gd->baudrate * 16 ) ) - 1 ) & + NS9750_SER_BITRATE_N_MA ) ); +} + +/*********************************************************************** + * @Function: calcRxCharGapRegister + * @Return: value for the character gap timer register + * @Descr: register value depends on clock frequency and baudrate. Currently 0 + * is used as there is a bug with the gap timer in PLL bypass mode. + ***********************************************************************/ + +static unsigned int calcRxCharGapRegister( void ) +{ + return NS9750_SER_RX_CHAR_TIMER_TRUN; +} + +#endif /* CFG_NS9750_UART */ diff --git a/drivers/serial/s3c4510b_uart.c b/drivers/serial/s3c4510b_uart.c new file mode 100644 index 0000000000..ddcd591f84 --- /dev/null +++ b/drivers/serial/s3c4510b_uart.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune + * + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * (C) Copyright 2002-2004 + * Wolfgang Denk, DENX Software Engineering, + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) + * + * 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 + * + * MODULE: $Id:$ + * Description: UART/Serial interface for Samsung S3C4510B SoC + * Runtime Env: ARM7TDMI + * Change History: + * 03-02-04 Create (Curt Brune) curt@cucy.com + * + */ + +#include + +#ifdef CONFIG_DRIVER_S3C4510_UART + +#include +#include "s3c4510b_uart.h" + +DECLARE_GLOBAL_DATA_PTR; + +static UART *uart; + +/* flush serial input queue. returns 0 on success or negative error + * number otherwise + */ +static int serial_flush_input(void) +{ + volatile u32 tmp; + + /* keep on reading as long as the receiver is not empty */ + while( uart->m_stat.bf.rxReady) { + tmp = uart->m_rx; + } + + return 0; +} + + +/* flush output queue. returns 0 on success or negative error number + * otherwise + */ +static int serial_flush_output(void) +{ + /* wait until the transmitter is no longer busy */ + while( !uart->m_stat.bf.txBufEmpty); + + return 0; +} + + +void serial_setbrg (void) +{ + UART_LINE_CTRL ulctrl; + UART_CTRL uctrl; + UART_BAUD_DIV ubd; + + serial_flush_output(); + serial_flush_input(); + + /* control register */ + uctrl.ui = 0x0; + uctrl.bf.rxMode = 0x1; + uctrl.bf.rxIrq = 0x0; + uctrl.bf.txMode = 0x1; + uctrl.bf.DSR = 0x0; + uctrl.bf.sendBreak = 0x0; + uctrl.bf.loopBack = 0x0; + uart->m_ctrl.ui = uctrl.ui; + + /* line control register */ + ulctrl.ui = 0x0; + ulctrl.bf.wordLen = 0x3; /* 8 bit data */ + ulctrl.bf.nStop = 0x0; /* 1 stop bit */ + ulctrl.bf.parity = 0x0; /* no parity */ + ulctrl.bf.clk = 0x0; /* internal clock */ + ulctrl.bf.infra_red = 0x0; /* no infra_red */ + uart->m_lineCtrl.ui = ulctrl.ui; + + ubd.ui = 0x0; + + /* see table on page 10-15 in SAMSUNG S3C4510B manual */ + /* get correct divisor */ + switch(gd->baudrate) { + case 1200: ubd.bf.cnt0 = 1301; break; + case 2400: ubd.bf.cnt0 = 650; break; + case 4800: ubd.bf.cnt0 = 324; break; + case 9600: ubd.bf.cnt0 = 162; break; + case 19200: ubd.bf.cnt0 = 80; break; + case 38400: ubd.bf.cnt0 = 40; break; + case 57600: ubd.bf.cnt0 = 26; break; + case 115200: ubd.bf.cnt0 = 13; break; + } + + uart->m_baudDiv.ui = ubd.ui; + uart->m_baudCnt = 0x0; + uart->m_baudClk = 0x0; + +} + + +/* + * Initialise the serial port with the given baudrate. The settings + * are always 8 data bits, no parity, 1 stop bit, no start bits. + * + */ +int serial_init (void) +{ + +#if CONFIG_SERIAL1 == 1 + uart = (UART *)UART0_BASE; +#elif CONFIG_SERIAL1 == 2 + uart = (UART *)UART1_BASE; +#else +#error CONFIG_SERIAL1 not equal to 1 or 2 +#endif + + serial_setbrg (); + + return (0); +} + + +/* + * Output a single byte to the serial port. + */ +void serial_putc (const char c) +{ + /* wait for room in the transmit FIFO */ + while( !uart->m_stat.bf.txBufEmpty); + + uart->m_tx = c; + + /* + to be polite with serial console add a line feed + to the carriage return character + */ + if (c=='\n') + serial_putc('\r'); +} + +/* + * Test if an input byte is ready from the serial port. Returns non-zero on + * success, 0 otherwise. + */ +int serial_tstc (void) +{ + return uart->m_stat.bf.rxReady; +} + +/* + * Read a single byte from the serial port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ +int serial_getc (void) +{ + int rv; + + for(;;) { + rv = serial_tstc(); + + if (rv) { + return uart->m_rx & 0xFF; + } + } +} + +void serial_puts (const char *s) +{ + while (*s) { + serial_putc (*s++); + } + + /* busy wait for tx complete */ + while ( !uart->m_stat.bf.txComplete); + + /* clear break */ + uart->m_ctrl.bf.sendBreak = 0; + +} + +#endif diff --git a/drivers/serial/s3c4510b_uart.h b/drivers/serial/s3c4510b_uart.h new file mode 100644 index 0000000000..b06c76d84a --- /dev/null +++ b/drivers/serial/s3c4510b_uart.h @@ -0,0 +1,109 @@ +#ifndef __UART_H +#define __UART_H + +/* + * Copyright (c) 2004 Cucy Systems (http://www.cucy.com) + * Curt Brune + * + * 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 + * + * Description: S3C4510B UART register layout + */ + +/* UART LINE CONTROL register */ +typedef struct __BF_UART_LINE_CTRL { + u32 wordLen: 2; + u32 nStop: 1; + u32 parity: 3; + u32 clk: 1; + u32 infra_red: 1; + u32 unused:24; +} BF_UART_LINE_CTRL; + +typedef union _UART_LINE_CTRL { + u32 ui; + BF_UART_LINE_CTRL bf; +} UART_LINE_CTRL; + +/* UART CONTROL register */ +typedef struct __BF_UART_CTRL { + u32 rxMode: 2; + u32 rxIrq: 1; + u32 txMode: 2; + u32 DSR: 1; + u32 sendBreak: 1; + u32 loopBack: 1; + u32 unused:24; +} BF_UART_CTRL; + +typedef union _UART_CTRL { + u32 ui; + BF_UART_CTRL bf; +} UART_CTRL; + +/* UART STATUS register */ +typedef struct __BF_UART_STAT { + u32 overrun: 1; + u32 parity: 1; + u32 frame: 1; + u32 breakIrq: 1; + u32 DTR: 1; + u32 rxReady: 1; + u32 txBufEmpty: 1; + u32 txComplete: 1; + u32 unused:24; +} BF_UART_STAT; + +typedef union _UART_STAT { + u32 ui; + BF_UART_STAT bf; +} UART_STAT; + +/* UART BAUD_DIV register */ +typedef struct __BF_UART_BAUD_DIV { + u32 cnt1: 4; + u32 cnt0:12; + u32 unused:16; +} BF_UART_BAUD_DIV; + +typedef union _UART_BAUD_DIV { + u32 ui; + BF_UART_BAUD_DIV bf; +} UART_BAUD_DIV; + +/* UART register block */ +typedef struct __UART { + volatile UART_LINE_CTRL m_lineCtrl; + volatile UART_CTRL m_ctrl; + volatile UART_STAT m_stat; + volatile u32 m_tx; + volatile u32 m_rx; + volatile UART_BAUD_DIV m_baudDiv; + volatile u32 m_baudCnt; + volatile u32 m_baudClk; +} UART; + +#define NL 0x0A +#define CR 0x0D +#define BSP 0x08 +#define ESC 0x1B +#define CTRLZ 0x1A +#define RUBOUT 0x7F + +#endif diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c new file mode 100644 index 0000000000..76425d8790 --- /dev/null +++ b/drivers/serial/serial.c @@ -0,0 +1,326 @@ +/* + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. + * + * 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 + +#ifdef CFG_NS16550_SERIAL + +#include +#ifdef CFG_NS87308 +#include +#endif + +#if defined (CONFIG_SERIAL_MULTI) +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +#if !defined(CONFIG_CONS_INDEX) +#if defined (CONFIG_SERIAL_MULTI) +/* with CONFIG_SERIAL_MULTI we might have no console + * on these devices + */ +#else +#error "No console index specified." +#endif /* CONFIG_SERIAL_MULTI */ +#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4) +#error "Invalid console index value." +#endif + +#if CONFIG_CONS_INDEX == 1 && !defined(CFG_NS16550_COM1) +#error "Console port 1 defined but not configured." +#elif CONFIG_CONS_INDEX == 2 && !defined(CFG_NS16550_COM2) +#error "Console port 2 defined but not configured." +#elif CONFIG_CONS_INDEX == 3 && !defined(CFG_NS16550_COM3) +#error "Console port 3 defined but not configured." +#elif CONFIG_CONS_INDEX == 4 && !defined(CFG_NS16550_COM4) +#error "Console port 4 defined but not configured." +#endif + +/* Note: The port number specified in the functions is 1 based. + * the array is 0 based. + */ +static NS16550_t serial_ports[4] = { +#ifdef CFG_NS16550_COM1 + (NS16550_t)CFG_NS16550_COM1, +#else + NULL, +#endif +#ifdef CFG_NS16550_COM2 + (NS16550_t)CFG_NS16550_COM2, +#else + NULL, +#endif +#ifdef CFG_NS16550_COM3 + (NS16550_t)CFG_NS16550_COM3, +#else + NULL, +#endif +#ifdef CFG_NS16550_COM4 + (NS16550_t)CFG_NS16550_COM4 +#else + NULL +#endif +}; + +#define PORT serial_ports[port-1] +#if defined(CONFIG_CONS_INDEX) +#define CONSOLE (serial_ports[CONFIG_CONS_INDEX-1]) +#endif + +#if defined(CONFIG_SERIAL_MULTI) + +/* Multi serial device functions */ +#define DECLARE_ESERIAL_FUNCTIONS(port) \ + int eserial##port##_init (void) {\ + int clock_divisor; \ + clock_divisor = calc_divisor(serial_ports[port-1]); \ + NS16550_init(serial_ports[port-1], clock_divisor); \ + return(0);}\ + void eserial##port##_setbrg (void) {\ + serial_setbrg_dev(port);}\ + int eserial##port##_getc (void) {\ + return serial_getc_dev(port);}\ + int eserial##port##_tstc (void) {\ + return serial_tstc_dev(port);}\ + void eserial##port##_putc (const char c) {\ + serial_putc_dev(port, c);}\ + void eserial##port##_puts (const char *s) {\ + serial_puts_dev(port, s);} + +/* Serial device descriptor */ +#define INIT_ESERIAL_STRUCTURE(port,name,bus) {\ + name,\ + bus,\ + eserial##port##_init,\ + eserial##port##_setbrg,\ + eserial##port##_getc,\ + eserial##port##_tstc,\ + eserial##port##_putc,\ + eserial##port##_puts, } + +#endif /* CONFIG_SERIAL_MULTI */ + +static int calc_divisor (NS16550_t port) +{ +#ifdef CONFIG_OMAP1510 + /* If can't cleanly clock 115200 set div to 1 */ + if ((CFG_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) { + port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */ + return (1); /* return 1 for base divisor */ + } + port->osc_12m_sel = 0; /* clear if previsouly set */ +#endif +#ifdef CONFIG_OMAP1610 + /* If can't cleanly clock 115200 set div to 1 */ + if ((CFG_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) { + return (26); /* return 26 for base divisor */ + } +#endif + +#ifdef CONFIG_APTIX +#define MODE_X_DIV 13 +#else +#define MODE_X_DIV 16 +#endif + return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate); + +} + +#if !defined(CONFIG_SERIAL_MULTI) +int serial_init (void) +{ + int clock_divisor; + +#ifdef CFG_NS87308 + initialise_ns87308(); +#endif + +#ifdef CFG_NS16550_COM1 + clock_divisor = calc_divisor(serial_ports[0]); + NS16550_init(serial_ports[0], clock_divisor); +#endif +#ifdef CFG_NS16550_COM2 + clock_divisor = calc_divisor(serial_ports[1]); + NS16550_init(serial_ports[1], clock_divisor); +#endif +#ifdef CFG_NS16550_COM3 + clock_divisor = calc_divisor(serial_ports[2]); + NS16550_init(serial_ports[2], clock_divisor); +#endif +#ifdef CFG_NS16550_COM4 + clock_divisor = calc_divisor(serial_ports[3]); + NS16550_init(serial_ports[3], clock_divisor); +#endif + + return (0); +} +#endif + +void +_serial_putc(const char c,const int port) +{ + if (c == '\n') + NS16550_putc(PORT, '\r'); + + NS16550_putc(PORT, c); +} + +void +_serial_putc_raw(const char c,const int port) +{ + NS16550_putc(PORT, c); +} + +void +_serial_puts (const char *s,const int port) +{ + while (*s) { + _serial_putc (*s++,port); + } +} + + +int +_serial_getc(const int port) +{ + return NS16550_getc(PORT); +} + +int +_serial_tstc(const int port) +{ + return NS16550_tstc(PORT); +} + +void +_serial_setbrg (const int port) +{ + int clock_divisor; + + clock_divisor = calc_divisor(PORT); + NS16550_reinit(PORT, clock_divisor); +} + +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_putc_dev(unsigned int dev_index,const char c) +{ + _serial_putc(c,dev_index); +} +#else +void +serial_putc(const char c) +{ + _serial_putc(c,CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_putc_raw_dev(unsigned int dev_index,const char c) +{ + _serial_putc_raw(c,dev_index); +} +#else +void +serial_putc_raw(const char c) +{ + _serial_putc_raw(c,CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_puts_dev(unsigned int dev_index,const char *s) +{ + _serial_puts(s,dev_index); +} +#else +void +serial_puts(const char *s) +{ + _serial_puts(s,CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +static inline int +serial_getc_dev(unsigned int dev_index) +{ + return _serial_getc(dev_index); +} +#else +int +serial_getc(void) +{ + return _serial_getc(CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +static inline int +serial_tstc_dev(unsigned int dev_index) +{ + return _serial_tstc(dev_index); +} +#else +int +serial_tstc(void) +{ + return _serial_tstc(CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) +static inline void +serial_setbrg_dev(unsigned int dev_index) +{ + _serial_setbrg(dev_index); +} +#else +void +serial_setbrg(void) +{ + _serial_setbrg(CONFIG_CONS_INDEX); +} +#endif + +#if defined(CONFIG_SERIAL_MULTI) + +DECLARE_ESERIAL_FUNCTIONS(1); +struct serial_device eserial1_device = + INIT_ESERIAL_STRUCTURE(1,"eserial0","EUART1"); +DECLARE_ESERIAL_FUNCTIONS(2); +struct serial_device eserial2_device = + INIT_ESERIAL_STRUCTURE(2,"eserial1","EUART2"); +DECLARE_ESERIAL_FUNCTIONS(3); +struct serial_device eserial3_device = + INIT_ESERIAL_STRUCTURE(3,"eserial2","EUART3"); +DECLARE_ESERIAL_FUNCTIONS(4); +struct serial_device eserial4_device = + INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4"); +#endif /* CONFIG_SERIAL_MULTI */ + +#endif diff --git a/drivers/serial/serial_max3100.c b/drivers/serial/serial_max3100.c new file mode 100644 index 0000000000..35c5596985 --- /dev/null +++ b/drivers/serial/serial_max3100.c @@ -0,0 +1,302 @@ +/* + * (C) Copyright 2003 + * + * Pantelis Antoniou + * Intracom S.A. + * + * 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 +#include + +#ifdef CONFIG_MAX3100_SERIAL + +DECLARE_GLOBAL_DATA_PTR; + +/**************************************************************/ + +/* convienient macros */ +#define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT) + +#define MAX3100_SPI_TXD(x) \ + do { \ + if (x) \ + MAX3100_SPI_TXD_PORT |= MAX3100_SPI_TXD_BIT; \ + else \ + MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \ + } while(0) + +#define MAX3100_SPI_CLK(x) \ + do { \ + if (x) \ + MAX3100_SPI_CLK_PORT |= MAX3100_SPI_CLK_BIT; \ + else \ + MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \ + } while(0) + +#define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT) + +#define MAX3100_CS(x) \ + do { \ + if (x) \ + MAX3100_CS_PORT |= MAX3100_CS_BIT; \ + else \ + MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \ + } while(0) + +/**************************************************************/ + +/* MAX3100 definitions */ + +#define MAX3100_WC (3 << 14) /* write configuration */ +#define MAX3100_RC (1 << 14) /* read configuration */ +#define MAX3100_WD (2 << 14) /* write data */ +#define MAX3100_RD (0 << 14) /* read data */ + +/* configuration register bits */ +#define MAX3100_FEN (1 << 13) /* FIFO enable */ +#define MAX3100_SHDN (1 << 12) /* shutdown bit */ +#define MAX3100_TM (1 << 11) /* T bit irq mask */ +#define MAX3100_RM (1 << 10) /* R bit irq mask */ +#define MAX3100_PM (1 << 9) /* P bit irq mask */ +#define MAX3100_RAM (1 << 8) /* mask for RA/FE bit */ +#define MAX3100_IR (1 << 7) /* IRDA timing mode */ +#define MAX3100_ST (1 << 6) /* transmit stop bit */ +#define MAX3100_PE (1 << 5) /* parity enable bit */ +#define MAX3100_L (1 << 4) /* Length bit */ +#define MAX3100_B_MASK (0x000F) /* baud rate bits mask */ +#define MAX3100_B(x) ((x) & 0x000F) /* baud rate select bits */ + +/* data register bits (write) */ +#define MAX3100_TE (1 << 10) /* transmit enable bit (active low) */ +#define MAX3100_RTS (1 << 9) /* request-to-send bit (inverted ~RTS pin) */ + +/* data register bits (read) */ +#define MAX3100_RA (1 << 10) /* receiver activity when in shutdown mode */ +#define MAX3100_FE (1 << 10) /* framing error when in normal mode */ +#define MAX3100_CTS (1 << 9) /* clear-to-send bit (inverted ~CTS pin) */ + +/* data register bits (both directions) */ +#define MAX3100_R (1 << 15) /* receive bit */ +#define MAX3100_T (1 << 14) /* transmit bit */ +#define MAX3100_P (1 << 8) /* parity bit */ +#define MAX3100_D_MASK 0x00FF /* data bits mask */ +#define MAX3100_D(x) ((x) & 0x00FF) /* data bits */ + +/* these definitions are valid only for fOSC = 3.6864MHz */ +#define MAX3100_B_230400 MAX3100_B(0) +#define MAX3100_B_115200 MAX3100_B(1) +#define MAX3100_B_57600 MAX3100_B(2) +#define MAX3100_B_38400 MAX3100_B(9) +#define MAX3100_B_19200 MAX3100_B(10) +#define MAX3100_B_9600 MAX3100_B(11) +#define MAX3100_B_4800 MAX3100_B(12) +#define MAX3100_B_2400 MAX3100_B(13) +#define MAX3100_B_1200 MAX3100_B(14) +#define MAX3100_B_600 MAX3100_B(15) + +/**************************************************************/ + +static inline unsigned int max3100_transfer(unsigned int val) +{ + unsigned int rx; + int b; + + MAX3100_SPI_CLK(0); + MAX3100_CS(0); + + rx = 0; b = 16; + while (--b >= 0) { + MAX3100_SPI_TXD(val & 0x8000); + val <<= 1; + MAX3100_SPI_CLK_TOGGLE(); + udelay(1); + rx <<= 1; + if (MAX3100_SPI_RXD()) + rx |= 1; + MAX3100_SPI_CLK_TOGGLE(); + udelay(1); + } + + MAX3100_SPI_CLK(1); + MAX3100_CS(1); + + return rx; +} + +/**************************************************************/ + +/* must be power of 2 */ +#define RXFIFO_SZ 16 + +static int rxfifo_cnt; +static int rxfifo_in; +static int rxfifo_out; +static unsigned char rxfifo_buf[16]; + +static void max3100_putc(int c) +{ + unsigned int rx; + + while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0) + WATCHDOG_RESET(); + + rx = max3100_transfer(MAX3100_WD | (c & 0xff)); + if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) { + rxfifo_cnt++; + rxfifo_buf[rxfifo_in++] = rx & 0xff; + rxfifo_in &= RXFIFO_SZ - 1; + } +} + +static int max3100_getc(void) +{ + int c; + unsigned int rx; + + while (rxfifo_cnt == 0) { + rx = max3100_transfer(MAX3100_RD); + if ((rx & MAX3100_R) != 0) { + do { + rxfifo_cnt++; + rxfifo_buf[rxfifo_in++] = rx & 0xff; + rxfifo_in &= RXFIFO_SZ - 1; + + if (rxfifo_cnt >= RXFIFO_SZ) + break; + } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0); + } + WATCHDOG_RESET(); + } + + rxfifo_cnt--; + c = rxfifo_buf[rxfifo_out++]; + rxfifo_out &= RXFIFO_SZ - 1; + return c; +} + +static int max3100_tstc(void) +{ + unsigned int rx; + + if (rxfifo_cnt > 0) + return 1; + + rx = max3100_transfer(MAX3100_RD); + if ((rx & MAX3100_R) == 0) + return 0; + + do { + rxfifo_cnt++; + rxfifo_buf[rxfifo_in++] = rx & 0xff; + rxfifo_in &= RXFIFO_SZ - 1; + + if (rxfifo_cnt >= RXFIFO_SZ) + break; + } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0); + + return 1; +} + +int serial_init(void) +{ + unsigned int wconf, rconf; + int i; + + wconf = 0; + + /* Set baud rate */ + switch (gd->baudrate) { + case 1200: + wconf = MAX3100_B_1200; + break; + case 2400: + wconf = MAX3100_B_2400; + break; + case 4800: + wconf = MAX3100_B_4800; + break; + case 9600: + wconf = MAX3100_B_9600; + break; + case 19200: + wconf = MAX3100_B_19200; + break; + case 38400: + wconf = MAX3100_B_38400; + break; + case 57600: + wconf = MAX3100_B_57600; + break; + default: + case 115200: + wconf = MAX3100_B_115200; + break; + case 230400: + wconf = MAX3100_B_230400; + break; + } + + /* try for 10ms, with a 100us gap */ + for (i = 0; i < 10000; i += 100) { + + max3100_transfer(MAX3100_WC | wconf); + rconf = max3100_transfer(MAX3100_RC) & 0x3fff; + + if (rconf == wconf) + break; + udelay(100); + } + + rxfifo_in = rxfifo_out = rxfifo_cnt = 0; + + return (0); +} + +void serial_putc(const char c) +{ + if (c == '\n') + max3100_putc('\r'); + + max3100_putc(c); +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc (*s++); +} + +int serial_getc(void) +{ + return max3100_getc(); +} + +int serial_tstc(void) +{ + return max3100_tstc(); +} + +/* XXX WTF? */ +void serial_setbrg(void) +{ +} + +#endif diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c new file mode 100644 index 0000000000..d678ab6b76 --- /dev/null +++ b/drivers/serial/serial_xuartlite.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2004 Atmark Techno, Inc. + * + * Yasushi SHOJI + * + * 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 + +#ifdef CONFIG_XILINX_UARTLITE + +#include + +/* FIXME: we should convert these to in32 and out32 */ +#define IO_WORD(offset) (*(volatile unsigned long *)(offset)) +#define IO_SERIAL(offset) IO_WORD(CONFIG_SERIAL_BASE + (offset)) + +#define IO_SERIAL_RX_FIFO IO_SERIAL(XUL_RX_FIFO_OFFSET) +#define IO_SERIAL_TX_FIFO IO_SERIAL(XUL_TX_FIFO_OFFSET) +#define IO_SERIAL_STATUS IO_SERIAL(XUL_STATUS_REG_OFFSET) +#define IO_SERIAL_CONTROL IO_SERIAL(XUL_CONTROL_REG_OFFSET) + +int serial_init(void) +{ + /* FIXME: Nothing for now. We should initialize fifo, etc */ + return 0; +} + +void serial_setbrg(void) +{ + /* FIXME: what's this for? */ +} + +void serial_putc(const char c) +{ + if (c == '\n') serial_putc('\r'); + while (IO_SERIAL_STATUS & XUL_SR_TX_FIFO_FULL); + IO_SERIAL_TX_FIFO = (unsigned char) (c & 0xff); +} + +void serial_puts(const char * s) +{ + while (*s) { + serial_putc(*s++); + } +} + +int serial_getc(void) +{ + while (!(IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA)); + return IO_SERIAL_RX_FIFO & 0xff; +} + +int serial_tstc(void) +{ + return (IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA); +} + +#endif /* CONFIG_MICROBLZE */ diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c new file mode 100644 index 0000000000..a3b50131df --- /dev/null +++ b/drivers/serial/usbtty.c @@ -0,0 +1,1012 @@ +/* + * (C) Copyright 2003 + * Gerry Hamel, geh@ti.com, Texas Instruments + * + * (C) Copyright 2006 + * Bryan O'Donoghue, bodonoghue@codehermit.ie + * + * 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 + +#ifdef CONFIG_USB_TTY + +#include +#include +#include "usbtty.h" +#include "usb_cdc_acm.h" +#include "usbdescriptors.h" +#include /* If defined, override Linux identifiers with + * vendor specific ones */ + +#if 0 +#define TTYDBG(fmt,args...)\ + serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) +#else +#define TTYDBG(fmt,args...) do{}while(0) +#endif + +#if 1 +#define TTYERR(fmt,args...)\ + serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\ + __LINE__,##args) +#else +#define TTYERR(fmt,args...) do{}while(0) +#endif + +/* + * Defines + */ +#define NUM_CONFIGS 1 +#define MAX_INTERFACES 2 +#define NUM_ENDPOINTS 3 +#define ACM_TX_ENDPOINT 3 +#define ACM_RX_ENDPOINT 2 +#define GSERIAL_TX_ENDPOINT 2 +#define GSERIAL_RX_ENDPOINT 1 +#define NUM_ACM_INTERFACES 2 +#define NUM_GSERIAL_INTERFACES 1 +#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface" +#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface" + +/* + * Buffers to hold input and output data + */ +#define USBTTY_BUFFER_SIZE 256 +static circbuf_t usbtty_input; +static circbuf_t usbtty_output; + + +/* + * Instance variables + */ +static device_t usbttydev; +static struct usb_device_instance device_instance[1]; +static struct usb_bus_instance bus_instance[1]; +static struct usb_configuration_instance config_instance[NUM_CONFIGS]; +static struct usb_interface_instance interface_instance[MAX_INTERFACES]; +static struct usb_alternate_instance alternate_instance[MAX_INTERFACES]; +/* one extra for control endpoint */ +static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; + +/* + * Global flag + */ +int usbtty_configured_flag = 0; + +/* + * Serial number + */ +static char serial_number[16]; + + +/* + * Descriptors, Strings, Local variables. + */ + +/* defined and used by usbdcore_ep0.c */ +extern struct usb_string_descriptor **usb_strings; + +/* Indicies, References */ +static unsigned short rx_endpoint = 0; +static unsigned short tx_endpoint = 0; +static unsigned short interface_count = 0; +static struct usb_string_descriptor *usbtty_string_table[STR_COUNT]; + +/* USB Descriptor Strings */ +static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4}; +static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)]; +static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)]; +static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)]; +static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)]; +static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; +static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; + +/* Standard USB Data Structures */ +static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES]; +static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS]; +static struct usb_configuration_descriptor *configuration_descriptor = 0; +static struct usb_device_descriptor device_descriptor = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = cpu_to_le16(USB_BCD_VERSION), + .bDeviceSubClass = 0x00, + .bDeviceProtocol = 0x00, + .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE, + .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID), + .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE), + .iManufacturer = STR_MANUFACTURER, + .iProduct = STR_PRODUCT, + .iSerialNumber = STR_SERIAL, + .bNumConfigurations = NUM_CONFIGS +}; + + +/* + * Static CDC ACM specific descriptors + */ + +struct acm_config_desc { + struct usb_configuration_descriptor configuration_desc; + + /* Master Interface */ + struct usb_interface_descriptor interface_desc; + + struct usb_class_header_function_descriptor usb_class_header; + struct usb_class_call_management_descriptor usb_class_call_mgt; + struct usb_class_abstract_control_descriptor usb_class_acm; + struct usb_class_union_function_descriptor usb_class_union; + struct usb_endpoint_descriptor notification_endpoint; + + /* Slave Interface */ + struct usb_interface_descriptor data_class_interface; + struct usb_endpoint_descriptor + data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed)); +} __attribute__((packed)); + +static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = { + { + .configuration_desc ={ + .bLength = + sizeof(struct usb_configuration_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = + cpu_to_le16(sizeof(struct acm_config_desc)), + .bNumInterfaces = NUM_ACM_INTERFACES, + .bConfigurationValue = 1, + .iConfiguration = STR_CONFIG, + .bmAttributes = + BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, + .bMaxPower = USBTTY_MAXPOWER + }, + /* Interface 1 */ + .interface_desc = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0x01, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_CONTROL, + .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS, + .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL, + .iInterface = STR_CTRL_INTERFACE, + }, + .usb_class_header = { + .bFunctionLength = + sizeof(struct usb_class_header_function_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_HEADER, + .bcdCDC = cpu_to_le16(110), + }, + .usb_class_call_mgt = { + .bFunctionLength = + sizeof(struct usb_class_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_CMF, + .bmCapabilities = 0x00, + .bDataInterface = 0x01, + }, + .usb_class_acm = { + .bFunctionLength = + sizeof(struct usb_class_abstract_control_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_ACMF, + .bmCapabilities = 0x00, + }, + .usb_class_union = { + .bFunctionLength = + sizeof(struct usb_class_union_function_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_UF, + .bMasterInterface = 0x00, + .bSlaveInterface0 = 0x01, + }, + .notification_endpoint = { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize + = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), + .bInterval = 0xFF, + }, + + /* Interface 2 */ + .data_class_interface = { + .bLength = + sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0x01, + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_DATA, + .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE, + .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE, + .iInterface = STR_DATA_INTERFACE, + }, + .data_endpoints = { + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x02 | USB_DIR_OUT, + .bmAttributes = + USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), + .bInterval = 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x03 | USB_DIR_IN, + .bmAttributes = + USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), + .bInterval = 0xFF, + }, + }, + }, +}; + +static struct rs232_emu rs232_desc={ + .dter = 115200, + .stop_bits = 0x00, + .parity = 0x00, + .data_bits = 0x08 +}; + + +/* + * Static Generic Serial specific data + */ + + +struct gserial_config_desc { + + struct usb_configuration_descriptor configuration_desc; + struct usb_interface_descriptor + interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed)); + struct usb_endpoint_descriptor + data_endpoints[NUM_ENDPOINTS] __attribute__((packed)); + +} __attribute__((packed)); + +static struct gserial_config_desc +gserial_configuration_descriptors[NUM_CONFIGS] ={ + { + .configuration_desc ={ + .bLength = sizeof(struct usb_configuration_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = + cpu_to_le16(sizeof(struct gserial_config_desc)), + .bNumInterfaces = NUM_GSERIAL_INTERFACES, + .bConfigurationValue = 1, + .iConfiguration = STR_CONFIG, + .bmAttributes = + BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, + .bMaxPower = USBTTY_MAXPOWER + }, + .interface_desc = { + { + .bLength = + sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = NUM_ENDPOINTS, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_VENDOR, + .bInterfaceSubClass = + COMMUNICATIONS_NO_SUBCLASS, + .bInterfaceProtocol = + COMMUNICATIONS_NO_PROTOCOL, + .iInterface = STR_DATA_INTERFACE + }, + }, + .data_endpoints = { + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE), + .bInterval= 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x02 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE), + .bInterval = 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x03 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), + .bInterval = 0xFF, + }, + }, + }, +}; + +/* + * Static Function Prototypes + */ + +static void usbtty_init_strings (void); +static void usbtty_init_instances (void); +static void usbtty_init_endpoints (void); +static void usbtty_init_terminal_type(short type); +static void usbtty_event_handler (struct usb_device_instance *device, + usb_device_event_t event, int data); +static int usbtty_cdc_setup(struct usb_device_request *request, + struct urb *urb); +static int usbtty_configured (void); +static int write_buffer (circbuf_t * buf); +static int fill_buffer (circbuf_t * buf); + +void usbtty_poll (void); + +/* utility function for converting char* to wide string used by USB */ +static void str2wide (char *str, u16 * wide) +{ + int i; + for (i = 0; i < strlen (str) && str[i]; i++){ + #if defined(__LITTLE_ENDIAN) + wide[i] = (u16) str[i]; + #elif defined(__BIG_ENDIAN) + wide[i] = ((u16)(str[i])<<8); + #else + #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined" + #endif + } +} + +/* + * Test whether a character is in the RX buffer + */ + +int usbtty_tstc (void) +{ + struct usb_endpoint_instance *endpoint = + &endpoint_instance[rx_endpoint]; + + /* If no input data exists, allow more RX to be accepted */ + if(usbtty_input.size <= 0){ + udc_unset_nak(endpoint->endpoint_address&0x03); + } + + usbtty_poll (); + return (usbtty_input.size > 0); +} + +/* + * Read a single byte from the usb client port. Returns 1 on success, 0 + * otherwise. When the function is succesfull, the character read is + * written into its argument c. + */ + +int usbtty_getc (void) +{ + char c; + struct usb_endpoint_instance *endpoint = + &endpoint_instance[rx_endpoint]; + + while (usbtty_input.size <= 0) { + udc_unset_nak(endpoint->endpoint_address&0x03); + usbtty_poll (); + } + + buf_pop (&usbtty_input, &c, 1); + udc_set_nak(endpoint->endpoint_address&0x03); + + return c; +} + +/* + * Output a single byte to the usb client port. + */ +void usbtty_putc (const char c) +{ + buf_push (&usbtty_output, &c, 1); + /* If \n, also do \r */ + if (c == '\n') + buf_push (&usbtty_output, "\r", 1); + + /* Poll at end to handle new data... */ + if ((usbtty_output.size + 2) >= usbtty_output.totalsize) { + usbtty_poll (); + } +} + +/* usbtty_puts() helper function for finding the next '\n' in a string */ +static int next_nl_pos (const char *s) +{ + int i; + + for (i = 0; s[i] != '\0'; i++) { + if (s[i] == '\n') + return i; + } + return i; +} + +/* + * Output a string to the usb client port - implementing flow control + */ + +static void __usbtty_puts (const char *str, int len) +{ + int maxlen = usbtty_output.totalsize; + int space, n; + + /* break str into chunks < buffer size, if needed */ + while (len > 0) { + usbtty_poll (); + + space = maxlen - usbtty_output.size; + /* Empty buffer here, if needed, to ensure space... */ + if (space) { + write_buffer (&usbtty_output); + + n = MIN (space, MIN (len, maxlen)); + buf_push (&usbtty_output, str, n); + + str += n; + len -= n; + } + } +} + +void usbtty_puts (const char *str) +{ + int n; + int len = strlen (str); + + /* add '\r' for each '\n' */ + while (len > 0) { + n = next_nl_pos (str); + + if (str[n] == '\n') { + __usbtty_puts (str, n + 1); + __usbtty_puts ("\r", 1); + str += (n + 1); + len -= (n + 1); + } else { + /* No \n found. All done. */ + __usbtty_puts (str, n); + break; + } + } + + /* Poll at end to handle new data... */ + usbtty_poll (); +} + +/* + * Initialize the usb client port. + * + */ +int drv_usbtty_init (void) +{ + int rc; + char * sn; + char * tt; + int snlen; + + /* Ger seiral number */ + if (!(sn = getenv("serial#"))) { + sn = "000000000000"; + } + snlen = strlen(sn); + if (snlen > sizeof(serial_number) - 1) { + printf ("Warning: serial number %s is too long (%d > %d)\n", + sn, snlen, sizeof(serial_number) - 1); + snlen = sizeof(serial_number) - 1; + } + memcpy (serial_number, sn, snlen); + serial_number[snlen] = '\0'; + + /* Decide on which type of UDC device to be. + */ + + if(!(tt = getenv("usbtty"))) { + tt = "generic"; + } + usbtty_init_terminal_type(strcmp(tt,"cdc_acm")); + + /* prepare buffers... */ + buf_init (&usbtty_input, USBTTY_BUFFER_SIZE); + buf_init (&usbtty_output, USBTTY_BUFFER_SIZE); + + /* Now, set up USB controller and infrastructure */ + udc_init (); /* Basic USB initialization */ + + usbtty_init_strings (); + usbtty_init_instances (); + + udc_startup_events (device_instance);/* Enable dev, init udc pointers */ + udc_connect (); /* Enable pullup for host detection */ + + usbtty_init_endpoints (); + + /* Device initialization */ + memset (&usbttydev, 0, sizeof (usbttydev)); + + strcpy (usbttydev.name, "usbtty"); + usbttydev.ext = 0; /* No extensions */ + usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT; + usbttydev.tstc = usbtty_tstc; /* 'tstc' function */ + usbttydev.getc = usbtty_getc; /* 'getc' function */ + usbttydev.putc = usbtty_putc; /* 'putc' function */ + usbttydev.puts = usbtty_puts; /* 'puts' function */ + + rc = device_register (&usbttydev); + + return (rc == 0) ? 1 : rc; +} + +static void usbtty_init_strings (void) +{ + struct usb_string_descriptor *string; + + usbtty_string_table[STR_LANG] = + (struct usb_string_descriptor*)wstrLang; + + string = (struct usb_string_descriptor *) wstrManufacturer; + string->bLength = sizeof(wstrManufacturer); + string->bDescriptorType = USB_DT_STRING; + str2wide (CONFIG_USBD_MANUFACTURER, string->wData); + usbtty_string_table[STR_MANUFACTURER]=string; + + + string = (struct usb_string_descriptor *) wstrProduct; + string->bLength = sizeof(wstrProduct); + string->bDescriptorType = USB_DT_STRING; + str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData); + usbtty_string_table[STR_PRODUCT]=string; + + + string = (struct usb_string_descriptor *) wstrSerial; + string->bLength = sizeof(serial_number); + string->bDescriptorType = USB_DT_STRING; + str2wide (serial_number, string->wData); + usbtty_string_table[STR_SERIAL]=string; + + + string = (struct usb_string_descriptor *) wstrConfiguration; + string->bLength = sizeof(wstrConfiguration); + string->bDescriptorType = USB_DT_STRING; + str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData); + usbtty_string_table[STR_CONFIG]=string; + + + string = (struct usb_string_descriptor *) wstrDataInterface; + string->bLength = sizeof(wstrDataInterface); + string->bDescriptorType = USB_DT_STRING; + str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData); + usbtty_string_table[STR_DATA_INTERFACE]=string; + + string = (struct usb_string_descriptor *) wstrCtrlInterface; + string->bLength = sizeof(wstrCtrlInterface); + string->bDescriptorType = USB_DT_STRING; + str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData); + usbtty_string_table[STR_CTRL_INTERFACE]=string; + + /* Now, initialize the string table for ep0 handling */ + usb_strings = usbtty_string_table; +} + +static void usbtty_init_instances (void) +{ + int i; + + /* initialize device instance */ + memset (device_instance, 0, sizeof (struct usb_device_instance)); + device_instance->device_state = STATE_INIT; + device_instance->device_descriptor = &device_descriptor; + device_instance->event = usbtty_event_handler; + device_instance->cdc_recv_setup = usbtty_cdc_setup; + device_instance->bus = bus_instance; + device_instance->configurations = NUM_CONFIGS; + device_instance->configuration_instance_array = config_instance; + + /* initialize bus instance */ + memset (bus_instance, 0, sizeof (struct usb_bus_instance)); + bus_instance->device = device_instance; + bus_instance->endpoint_array = endpoint_instance; + bus_instance->max_endpoints = 1; + bus_instance->maxpacketsize = 64; + bus_instance->serial_number_str = serial_number; + + /* configuration instance */ + memset (config_instance, 0, + sizeof (struct usb_configuration_instance)); + config_instance->interfaces = interface_count; + config_instance->configuration_descriptor = configuration_descriptor; + config_instance->interface_instance_array = interface_instance; + + /* interface instance */ + memset (interface_instance, 0, + sizeof (struct usb_interface_instance)); + interface_instance->alternates = 1; + interface_instance->alternates_instance_array = alternate_instance; + + /* alternates instance */ + memset (alternate_instance, 0, + sizeof (struct usb_alternate_instance)); + alternate_instance->interface_descriptor = interface_descriptors; + alternate_instance->endpoints = NUM_ENDPOINTS; + alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs; + + /* endpoint instances */ + memset (&endpoint_instance[0], 0, + sizeof (struct usb_endpoint_instance)); + endpoint_instance[0].endpoint_address = 0; + endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE; + endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL; + endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE; + endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL; + udc_setup_ep (device_instance, 0, &endpoint_instance[0]); + + for (i = 1; i <= NUM_ENDPOINTS; i++) { + memset (&endpoint_instance[i], 0, + sizeof (struct usb_endpoint_instance)); + + endpoint_instance[i].endpoint_address = + ep_descriptor_ptrs[i - 1]->bEndpointAddress; + + endpoint_instance[i].rcv_attributes = + ep_descriptor_ptrs[i - 1]->bmAttributes; + + endpoint_instance[i].rcv_packetSize = + le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); + + endpoint_instance[i].tx_attributes = + ep_descriptor_ptrs[i - 1]->bmAttributes; + + endpoint_instance[i].tx_packetSize = + le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); + + endpoint_instance[i].tx_attributes = + ep_descriptor_ptrs[i - 1]->bmAttributes; + + urb_link_init (&endpoint_instance[i].rcv); + urb_link_init (&endpoint_instance[i].rdy); + urb_link_init (&endpoint_instance[i].tx); + urb_link_init (&endpoint_instance[i].done); + + if (endpoint_instance[i].endpoint_address & USB_DIR_IN) + endpoint_instance[i].tx_urb = + usbd_alloc_urb (device_instance, + &endpoint_instance[i]); + else + endpoint_instance[i].rcv_urb = + usbd_alloc_urb (device_instance, + &endpoint_instance[i]); + } +} + +static void usbtty_init_endpoints (void) +{ + int i; + + bus_instance->max_endpoints = NUM_ENDPOINTS + 1; + for (i = 1; i <= NUM_ENDPOINTS; i++) { + udc_setup_ep (device_instance, i, &endpoint_instance[i]); + } +} + +/* usbtty_init_terminal_type + * + * Do some late binding for our device type. + */ +static void usbtty_init_terminal_type(short type) +{ + switch(type){ + /* CDC ACM */ + case 0: + /* Assign endpoint descriptors */ + ep_descriptor_ptrs[0] = + &acm_configuration_descriptors[0].notification_endpoint; + ep_descriptor_ptrs[1] = + &acm_configuration_descriptors[0].data_endpoints[0]; + ep_descriptor_ptrs[2] = + &acm_configuration_descriptors[0].data_endpoints[1]; + + /* Enumerate Device Descriptor */ + device_descriptor.bDeviceClass = + COMMUNICATIONS_DEVICE_CLASS; + device_descriptor.idProduct = + cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM); + + /* Assign endpoint indices */ + tx_endpoint = ACM_TX_ENDPOINT; + rx_endpoint = ACM_RX_ENDPOINT; + + /* Configuration Descriptor */ + configuration_descriptor = + (struct usb_configuration_descriptor*) + &acm_configuration_descriptors; + + /* Interface count */ + interface_count = NUM_ACM_INTERFACES; + break; + + /* BULK IN/OUT & Default */ + case 1: + default: + /* Assign endpoint descriptors */ + ep_descriptor_ptrs[0] = + &gserial_configuration_descriptors[0].data_endpoints[0]; + ep_descriptor_ptrs[1] = + &gserial_configuration_descriptors[0].data_endpoints[1]; + ep_descriptor_ptrs[2] = + &gserial_configuration_descriptors[0].data_endpoints[2]; + + /* Enumerate Device Descriptor */ + device_descriptor.bDeviceClass = 0xFF; + device_descriptor.idProduct = + cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL); + + /* Assign endpoint indices */ + tx_endpoint = GSERIAL_TX_ENDPOINT; + rx_endpoint = GSERIAL_RX_ENDPOINT; + + /* Configuration Descriptor */ + configuration_descriptor = + (struct usb_configuration_descriptor*) + &gserial_configuration_descriptors; + + /* Interface count */ + interface_count = NUM_GSERIAL_INTERFACES; + break; + } +} + +/******************************************************************************/ + +static struct urb *next_urb (struct usb_device_instance *device, + struct usb_endpoint_instance *endpoint) +{ + struct urb *current_urb = NULL; + int space; + + /* If there's a queue, then we should add to the last urb */ + if (!endpoint->tx_queue) { + current_urb = endpoint->tx_urb; + } else { + /* Last urb from tx chain */ + current_urb = + p2surround (struct urb, link, endpoint->tx.prev); + } + + /* Make sure this one has enough room */ + space = current_urb->buffer_length - current_urb->actual_length; + if (space > 0) { + return current_urb; + } else { /* No space here */ + /* First look at done list */ + current_urb = first_urb_detached (&endpoint->done); + if (!current_urb) { + current_urb = usbd_alloc_urb (device, endpoint); + } + + urb_append (&endpoint->tx, current_urb); + endpoint->tx_queue++; + } + return current_urb; +} + +static int write_buffer (circbuf_t * buf) +{ + if (!usbtty_configured ()) { + return 0; + } + + struct usb_endpoint_instance *endpoint = + &endpoint_instance[tx_endpoint]; + struct urb *current_urb = NULL; + + current_urb = next_urb (device_instance, endpoint); + /* TX data still exists - send it now + */ + if(endpoint->sent < current_urb->actual_length){ + if(udc_endpoint_write (endpoint)){ + /* Write pre-empted by RX */ + return -1; + } + } + + if (buf->size) { + char *dest; + + int space_avail; + int popnum, popped; + int total = 0; + + /* Break buffer into urb sized pieces, + * and link each to the endpoint + */ + while (buf->size > 0) { + + if (!current_urb) { + TTYERR ("current_urb is NULL, buf->size %d\n", + buf->size); + return total; + } + + dest = (char*)current_urb->buffer + + current_urb->actual_length; + + space_avail = + current_urb->buffer_length - + current_urb->actual_length; + popnum = MIN (space_avail, buf->size); + if (popnum == 0) + break; + + popped = buf_pop (buf, dest, popnum); + if (popped == 0) + break; + current_urb->actual_length += popped; + total += popped; + + /* If endpoint->last == 0, then transfers have + * not started on this endpoint + */ + if (endpoint->last == 0) { + if(udc_endpoint_write (endpoint)){ + /* Write pre-empted by RX */ + return -1; + } + } + + }/* end while */ + return total; + } + + return 0; +} + +static int fill_buffer (circbuf_t * buf) +{ + struct usb_endpoint_instance *endpoint = + &endpoint_instance[rx_endpoint]; + + if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) { + unsigned int nb = 0; + char *src = (char *) endpoint->rcv_urb->buffer; + unsigned int rx_avail = buf->totalsize - buf->size; + + if(rx_avail >= endpoint->rcv_urb->actual_length){ + + nb = endpoint->rcv_urb->actual_length; + buf_push (buf, src, nb); + endpoint->rcv_urb->actual_length = 0; + + } + return nb; + } + return 0; +} + +static int usbtty_configured (void) +{ + return usbtty_configured_flag; +} + +/******************************************************************************/ + +static void usbtty_event_handler (struct usb_device_instance *device, + usb_device_event_t event, int data) +{ + switch (event) { + case DEVICE_RESET: + case DEVICE_BUS_INACTIVE: + usbtty_configured_flag = 0; + break; + case DEVICE_CONFIGURED: + usbtty_configured_flag = 1; + break; + + case DEVICE_ADDRESS_ASSIGNED: + usbtty_init_endpoints (); + + default: + break; + } +} + +/******************************************************************************/ + +int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb) +{ + switch (request->bRequest){ + + case ACM_SET_CONTROL_LINE_STATE: /* Implies DTE ready */ + break; + case ACM_SEND_ENCAPSULATED_COMMAND : /* Required */ + break; + case ACM_SET_LINE_ENCODING : /* DTE stop/parity bits + * per character */ + break; + case ACM_GET_ENCAPSULATED_RESPONSE : /* request response */ + break; + case ACM_GET_LINE_ENCODING : /* request DTE rate, + * stop/parity bits */ + memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc)); + urb->actual_length = sizeof(rs232_desc); + + break; + default: + return 1; + } + return 0; +} + +/******************************************************************************/ + +/* + * Since interrupt handling has not yet been implemented, we use this function + * to handle polling. This is called by the tstc,getc,putc,puts routines to + * update the USB state. + */ +void usbtty_poll (void) +{ + /* New interrupts? */ + udc_irq(); + + /* Write any output data to host buffer + * (do this before checking interrupts to avoid missing one) + */ + if (usbtty_configured ()) { + write_buffer (&usbtty_output); + } + + /* New interrupts? */ + udc_irq(); + + /* Check for new data from host.. + * (do this after checking interrupts to get latest data) + */ + if (usbtty_configured ()) { + fill_buffer (&usbtty_input); + } + + /* New interrupts? */ + udc_irq(); + +} + + +#endif diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h new file mode 100644 index 0000000000..8154e3072e --- /dev/null +++ b/drivers/serial/usbtty.h @@ -0,0 +1,70 @@ +/* + * (C) Copyright 2003 + * Gerry Hamel, geh@ti.com, Texas Instruments + * + * (C) Copyright 2006 + * Bryan O'Donoghue, bodonoghue@codehermit.ie, CodeHermit + * + * 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 + * + */ + +#ifndef __USB_TTY_H__ +#define __USB_TTY_H__ + +#include "usbdcore.h" +#if defined(CONFIG_PPC) +#include "usbdcore_mpc8xx.h" +#elif defined(CONFIG_ARM) +#include "usbdcore_omap1510.h" +#endif + +#include + +/* If no VendorID/ProductID is defined in config.h, pretend to be Linux + * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */ + +#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ +#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ +#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ +#define CONFIG_USBD_MANUFACTURER "Das U-Boot" +#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION + + +#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" + +#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT +#define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE +#define CONFIG_USBD_SERIAL_IN_ENDPOINT UDC_IN_ENDPOINT +#define CONFIG_USBD_SERIAL_IN_PKTSIZE UDC_IN_PACKET_SIZE +#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT +#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE +#define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE + +#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS + +#define USBTTY_BCD_DEVICE 0x00 +#define USBTTY_MAXPOWER 0x00 + +#define STR_LANG 0x00 +#define STR_MANUFACTURER 0x01 +#define STR_PRODUCT 0x02 +#define STR_SERIAL 0x03 +#define STR_CONFIG 0x04 +#define STR_DATA_INTERFACE 0x05 +#define STR_CTRL_INTERFACE 0x06 +#define STR_COUNT 0x07 + +#endif diff --git a/drivers/serial_max3100.c b/drivers/serial_max3100.c deleted file mode 100644 index 35c5596985..0000000000 --- a/drivers/serial_max3100.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * (C) Copyright 2003 - * - * Pantelis Antoniou - * Intracom S.A. - * - * 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 -#include - -#ifdef CONFIG_MAX3100_SERIAL - -DECLARE_GLOBAL_DATA_PTR; - -/**************************************************************/ - -/* convienient macros */ -#define MAX3100_SPI_RXD() (MAX3100_SPI_RXD_PORT & MAX3100_SPI_RXD_BIT) - -#define MAX3100_SPI_TXD(x) \ - do { \ - if (x) \ - MAX3100_SPI_TXD_PORT |= MAX3100_SPI_TXD_BIT; \ - else \ - MAX3100_SPI_TXD_PORT &= ~MAX3100_SPI_TXD_BIT; \ - } while(0) - -#define MAX3100_SPI_CLK(x) \ - do { \ - if (x) \ - MAX3100_SPI_CLK_PORT |= MAX3100_SPI_CLK_BIT; \ - else \ - MAX3100_SPI_CLK_PORT &= ~MAX3100_SPI_CLK_BIT; \ - } while(0) - -#define MAX3100_SPI_CLK_TOGGLE() (MAX3100_SPI_CLK_PORT ^= MAX3100_SPI_CLK_BIT) - -#define MAX3100_CS(x) \ - do { \ - if (x) \ - MAX3100_CS_PORT |= MAX3100_CS_BIT; \ - else \ - MAX3100_CS_PORT &= ~MAX3100_CS_BIT; \ - } while(0) - -/**************************************************************/ - -/* MAX3100 definitions */ - -#define MAX3100_WC (3 << 14) /* write configuration */ -#define MAX3100_RC (1 << 14) /* read configuration */ -#define MAX3100_WD (2 << 14) /* write data */ -#define MAX3100_RD (0 << 14) /* read data */ - -/* configuration register bits */ -#define MAX3100_FEN (1 << 13) /* FIFO enable */ -#define MAX3100_SHDN (1 << 12) /* shutdown bit */ -#define MAX3100_TM (1 << 11) /* T bit irq mask */ -#define MAX3100_RM (1 << 10) /* R bit irq mask */ -#define MAX3100_PM (1 << 9) /* P bit irq mask */ -#define MAX3100_RAM (1 << 8) /* mask for RA/FE bit */ -#define MAX3100_IR (1 << 7) /* IRDA timing mode */ -#define MAX3100_ST (1 << 6) /* transmit stop bit */ -#define MAX3100_PE (1 << 5) /* parity enable bit */ -#define MAX3100_L (1 << 4) /* Length bit */ -#define MAX3100_B_MASK (0x000F) /* baud rate bits mask */ -#define MAX3100_B(x) ((x) & 0x000F) /* baud rate select bits */ - -/* data register bits (write) */ -#define MAX3100_TE (1 << 10) /* transmit enable bit (active low) */ -#define MAX3100_RTS (1 << 9) /* request-to-send bit (inverted ~RTS pin) */ - -/* data register bits (read) */ -#define MAX3100_RA (1 << 10) /* receiver activity when in shutdown mode */ -#define MAX3100_FE (1 << 10) /* framing error when in normal mode */ -#define MAX3100_CTS (1 << 9) /* clear-to-send bit (inverted ~CTS pin) */ - -/* data register bits (both directions) */ -#define MAX3100_R (1 << 15) /* receive bit */ -#define MAX3100_T (1 << 14) /* transmit bit */ -#define MAX3100_P (1 << 8) /* parity bit */ -#define MAX3100_D_MASK 0x00FF /* data bits mask */ -#define MAX3100_D(x) ((x) & 0x00FF) /* data bits */ - -/* these definitions are valid only for fOSC = 3.6864MHz */ -#define MAX3100_B_230400 MAX3100_B(0) -#define MAX3100_B_115200 MAX3100_B(1) -#define MAX3100_B_57600 MAX3100_B(2) -#define MAX3100_B_38400 MAX3100_B(9) -#define MAX3100_B_19200 MAX3100_B(10) -#define MAX3100_B_9600 MAX3100_B(11) -#define MAX3100_B_4800 MAX3100_B(12) -#define MAX3100_B_2400 MAX3100_B(13) -#define MAX3100_B_1200 MAX3100_B(14) -#define MAX3100_B_600 MAX3100_B(15) - -/**************************************************************/ - -static inline unsigned int max3100_transfer(unsigned int val) -{ - unsigned int rx; - int b; - - MAX3100_SPI_CLK(0); - MAX3100_CS(0); - - rx = 0; b = 16; - while (--b >= 0) { - MAX3100_SPI_TXD(val & 0x8000); - val <<= 1; - MAX3100_SPI_CLK_TOGGLE(); - udelay(1); - rx <<= 1; - if (MAX3100_SPI_RXD()) - rx |= 1; - MAX3100_SPI_CLK_TOGGLE(); - udelay(1); - } - - MAX3100_SPI_CLK(1); - MAX3100_CS(1); - - return rx; -} - -/**************************************************************/ - -/* must be power of 2 */ -#define RXFIFO_SZ 16 - -static int rxfifo_cnt; -static int rxfifo_in; -static int rxfifo_out; -static unsigned char rxfifo_buf[16]; - -static void max3100_putc(int c) -{ - unsigned int rx; - - while (((rx = max3100_transfer(MAX3100_RC)) & MAX3100_T) == 0) - WATCHDOG_RESET(); - - rx = max3100_transfer(MAX3100_WD | (c & 0xff)); - if ((rx & MAX3100_RD) != 0 && rxfifo_cnt < RXFIFO_SZ) { - rxfifo_cnt++; - rxfifo_buf[rxfifo_in++] = rx & 0xff; - rxfifo_in &= RXFIFO_SZ - 1; - } -} - -static int max3100_getc(void) -{ - int c; - unsigned int rx; - - while (rxfifo_cnt == 0) { - rx = max3100_transfer(MAX3100_RD); - if ((rx & MAX3100_R) != 0) { - do { - rxfifo_cnt++; - rxfifo_buf[rxfifo_in++] = rx & 0xff; - rxfifo_in &= RXFIFO_SZ - 1; - - if (rxfifo_cnt >= RXFIFO_SZ) - break; - } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0); - } - WATCHDOG_RESET(); - } - - rxfifo_cnt--; - c = rxfifo_buf[rxfifo_out++]; - rxfifo_out &= RXFIFO_SZ - 1; - return c; -} - -static int max3100_tstc(void) -{ - unsigned int rx; - - if (rxfifo_cnt > 0) - return 1; - - rx = max3100_transfer(MAX3100_RD); - if ((rx & MAX3100_R) == 0) - return 0; - - do { - rxfifo_cnt++; - rxfifo_buf[rxfifo_in++] = rx & 0xff; - rxfifo_in &= RXFIFO_SZ - 1; - - if (rxfifo_cnt >= RXFIFO_SZ) - break; - } while (((rx = max3100_transfer(MAX3100_RD)) & MAX3100_R) != 0); - - return 1; -} - -int serial_init(void) -{ - unsigned int wconf, rconf; - int i; - - wconf = 0; - - /* Set baud rate */ - switch (gd->baudrate) { - case 1200: - wconf = MAX3100_B_1200; - break; - case 2400: - wconf = MAX3100_B_2400; - break; - case 4800: - wconf = MAX3100_B_4800; - break; - case 9600: - wconf = MAX3100_B_9600; - break; - case 19200: - wconf = MAX3100_B_19200; - break; - case 38400: - wconf = MAX3100_B_38400; - break; - case 57600: - wconf = MAX3100_B_57600; - break; - default: - case 115200: - wconf = MAX3100_B_115200; - break; - case 230400: - wconf = MAX3100_B_230400; - break; - } - - /* try for 10ms, with a 100us gap */ - for (i = 0; i < 10000; i += 100) { - - max3100_transfer(MAX3100_WC | wconf); - rconf = max3100_transfer(MAX3100_RC) & 0x3fff; - - if (rconf == wconf) - break; - udelay(100); - } - - rxfifo_in = rxfifo_out = rxfifo_cnt = 0; - - return (0); -} - -void serial_putc(const char c) -{ - if (c == '\n') - max3100_putc('\r'); - - max3100_putc(c); -} - -void serial_puts(const char *s) -{ - while (*s) - serial_putc (*s++); -} - -int serial_getc(void) -{ - return max3100_getc(); -} - -int serial_tstc(void) -{ - return max3100_tstc(); -} - -/* XXX WTF? */ -void serial_setbrg(void) -{ -} - -#endif diff --git a/drivers/serial_xuartlite.c b/drivers/serial_xuartlite.c deleted file mode 100644 index d678ab6b76..0000000000 --- a/drivers/serial_xuartlite.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Yasushi SHOJI - * - * 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 - -#ifdef CONFIG_XILINX_UARTLITE - -#include - -/* FIXME: we should convert these to in32 and out32 */ -#define IO_WORD(offset) (*(volatile unsigned long *)(offset)) -#define IO_SERIAL(offset) IO_WORD(CONFIG_SERIAL_BASE + (offset)) - -#define IO_SERIAL_RX_FIFO IO_SERIAL(XUL_RX_FIFO_OFFSET) -#define IO_SERIAL_TX_FIFO IO_SERIAL(XUL_TX_FIFO_OFFSET) -#define IO_SERIAL_STATUS IO_SERIAL(XUL_STATUS_REG_OFFSET) -#define IO_SERIAL_CONTROL IO_SERIAL(XUL_CONTROL_REG_OFFSET) - -int serial_init(void) -{ - /* FIXME: Nothing for now. We should initialize fifo, etc */ - return 0; -} - -void serial_setbrg(void) -{ - /* FIXME: what's this for? */ -} - -void serial_putc(const char c) -{ - if (c == '\n') serial_putc('\r'); - while (IO_SERIAL_STATUS & XUL_SR_TX_FIFO_FULL); - IO_SERIAL_TX_FIFO = (unsigned char) (c & 0xff); -} - -void serial_puts(const char * s) -{ - while (*s) { - serial_putc(*s++); - } -} - -int serial_getc(void) -{ - while (!(IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA)); - return IO_SERIAL_RX_FIFO & 0xff; -} - -int serial_tstc(void) -{ - return (IO_SERIAL_STATUS & XUL_SR_RX_FIFO_VALID_DATA); -} - -#endif /* CONFIG_MICROBLZE */ diff --git a/drivers/usbtty.c b/drivers/usbtty.c deleted file mode 100644 index a3b50131df..0000000000 --- a/drivers/usbtty.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* - * (C) Copyright 2003 - * Gerry Hamel, geh@ti.com, Texas Instruments - * - * (C) Copyright 2006 - * Bryan O'Donoghue, bodonoghue@codehermit.ie - * - * 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 - -#ifdef CONFIG_USB_TTY - -#include -#include -#include "usbtty.h" -#include "usb_cdc_acm.h" -#include "usbdescriptors.h" -#include /* If defined, override Linux identifiers with - * vendor specific ones */ - -#if 0 -#define TTYDBG(fmt,args...)\ - serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) -#else -#define TTYDBG(fmt,args...) do{}while(0) -#endif - -#if 1 -#define TTYERR(fmt,args...)\ - serial_printf("ERROR![%s] %s %d: "fmt, __FILE__,__FUNCTION__,\ - __LINE__,##args) -#else -#define TTYERR(fmt,args...) do{}while(0) -#endif - -/* - * Defines - */ -#define NUM_CONFIGS 1 -#define MAX_INTERFACES 2 -#define NUM_ENDPOINTS 3 -#define ACM_TX_ENDPOINT 3 -#define ACM_RX_ENDPOINT 2 -#define GSERIAL_TX_ENDPOINT 2 -#define GSERIAL_RX_ENDPOINT 1 -#define NUM_ACM_INTERFACES 2 -#define NUM_GSERIAL_INTERFACES 1 -#define CONFIG_USBD_DATA_INTERFACE_STR "Bulk Data Interface" -#define CONFIG_USBD_CTRL_INTERFACE_STR "Control Interface" - -/* - * Buffers to hold input and output data - */ -#define USBTTY_BUFFER_SIZE 256 -static circbuf_t usbtty_input; -static circbuf_t usbtty_output; - - -/* - * Instance variables - */ -static device_t usbttydev; -static struct usb_device_instance device_instance[1]; -static struct usb_bus_instance bus_instance[1]; -static struct usb_configuration_instance config_instance[NUM_CONFIGS]; -static struct usb_interface_instance interface_instance[MAX_INTERFACES]; -static struct usb_alternate_instance alternate_instance[MAX_INTERFACES]; -/* one extra for control endpoint */ -static struct usb_endpoint_instance endpoint_instance[NUM_ENDPOINTS+1]; - -/* - * Global flag - */ -int usbtty_configured_flag = 0; - -/* - * Serial number - */ -static char serial_number[16]; - - -/* - * Descriptors, Strings, Local variables. - */ - -/* defined and used by usbdcore_ep0.c */ -extern struct usb_string_descriptor **usb_strings; - -/* Indicies, References */ -static unsigned short rx_endpoint = 0; -static unsigned short tx_endpoint = 0; -static unsigned short interface_count = 0; -static struct usb_string_descriptor *usbtty_string_table[STR_COUNT]; - -/* USB Descriptor Strings */ -static u8 wstrLang[4] = {4,USB_DT_STRING,0x9,0x4}; -static u8 wstrManufacturer[2 + 2*(sizeof(CONFIG_USBD_MANUFACTURER)-1)]; -static u8 wstrProduct[2 + 2*(sizeof(CONFIG_USBD_PRODUCT_NAME)-1)]; -static u8 wstrSerial[2 + 2*(sizeof(serial_number) - 1)]; -static u8 wstrConfiguration[2 + 2*(sizeof(CONFIG_USBD_CONFIGURATION_STR)-1)]; -static u8 wstrDataInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; -static u8 wstrCtrlInterface[2 + 2*(sizeof(CONFIG_USBD_DATA_INTERFACE_STR)-1)]; - -/* Standard USB Data Structures */ -static struct usb_interface_descriptor interface_descriptors[MAX_INTERFACES]; -static struct usb_endpoint_descriptor *ep_descriptor_ptrs[NUM_ENDPOINTS]; -static struct usb_configuration_descriptor *configuration_descriptor = 0; -static struct usb_device_descriptor device_descriptor = { - .bLength = sizeof(struct usb_device_descriptor), - .bDescriptorType = USB_DT_DEVICE, - .bcdUSB = cpu_to_le16(USB_BCD_VERSION), - .bDeviceSubClass = 0x00, - .bDeviceProtocol = 0x00, - .bMaxPacketSize0 = EP0_MAX_PACKET_SIZE, - .idVendor = cpu_to_le16(CONFIG_USBD_VENDORID), - .bcdDevice = cpu_to_le16(USBTTY_BCD_DEVICE), - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIAL, - .bNumConfigurations = NUM_CONFIGS -}; - - -/* - * Static CDC ACM specific descriptors - */ - -struct acm_config_desc { - struct usb_configuration_descriptor configuration_desc; - - /* Master Interface */ - struct usb_interface_descriptor interface_desc; - - struct usb_class_header_function_descriptor usb_class_header; - struct usb_class_call_management_descriptor usb_class_call_mgt; - struct usb_class_abstract_control_descriptor usb_class_acm; - struct usb_class_union_function_descriptor usb_class_union; - struct usb_endpoint_descriptor notification_endpoint; - - /* Slave Interface */ - struct usb_interface_descriptor data_class_interface; - struct usb_endpoint_descriptor - data_endpoints[NUM_ENDPOINTS-1] __attribute__((packed)); -} __attribute__((packed)); - -static struct acm_config_desc acm_configuration_descriptors[NUM_CONFIGS] = { - { - .configuration_desc ={ - .bLength = - sizeof(struct usb_configuration_descriptor), - .bDescriptorType = USB_DT_CONFIG, - .wTotalLength = - cpu_to_le16(sizeof(struct acm_config_desc)), - .bNumInterfaces = NUM_ACM_INTERFACES, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG, - .bmAttributes = - BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, - .bMaxPower = USBTTY_MAXPOWER - }, - /* Interface 1 */ - .interface_desc = { - .bLength = sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = 0x01, - .bInterfaceClass = - COMMUNICATIONS_INTERFACE_CLASS_CONTROL, - .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS, - .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL, - .iInterface = STR_CTRL_INTERFACE, - }, - .usb_class_header = { - .bFunctionLength = - sizeof(struct usb_class_header_function_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_ST_HEADER, - .bcdCDC = cpu_to_le16(110), - }, - .usb_class_call_mgt = { - .bFunctionLength = - sizeof(struct usb_class_call_management_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_ST_CMF, - .bmCapabilities = 0x00, - .bDataInterface = 0x01, - }, - .usb_class_acm = { - .bFunctionLength = - sizeof(struct usb_class_abstract_control_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_ST_ACMF, - .bmCapabilities = 0x00, - }, - .usb_class_union = { - .bFunctionLength = - sizeof(struct usb_class_union_function_descriptor), - .bDescriptorType = CS_INTERFACE, - .bDescriptorSubtype = USB_ST_UF, - .bMasterInterface = 0x00, - .bSlaveInterface0 = 0x01, - }, - .notification_endpoint = { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize - = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), - .bInterval = 0xFF, - }, - - /* Interface 2 */ - .data_class_interface = { - .bLength = - sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0x01, - .bAlternateSetting = 0x00, - .bNumEndpoints = 0x02, - .bInterfaceClass = - COMMUNICATIONS_INTERFACE_CLASS_DATA, - .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE, - .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE, - .iInterface = STR_DATA_INTERFACE, - }, - .data_endpoints = { - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x02 | USB_DIR_OUT, - .bmAttributes = - USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), - .bInterval = 0xFF, - }, - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x03 | USB_DIR_IN, - .bmAttributes = - USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), - .bInterval = 0xFF, - }, - }, - }, -}; - -static struct rs232_emu rs232_desc={ - .dter = 115200, - .stop_bits = 0x00, - .parity = 0x00, - .data_bits = 0x08 -}; - - -/* - * Static Generic Serial specific data - */ - - -struct gserial_config_desc { - - struct usb_configuration_descriptor configuration_desc; - struct usb_interface_descriptor - interface_desc[NUM_GSERIAL_INTERFACES] __attribute__((packed)); - struct usb_endpoint_descriptor - data_endpoints[NUM_ENDPOINTS] __attribute__((packed)); - -} __attribute__((packed)); - -static struct gserial_config_desc -gserial_configuration_descriptors[NUM_CONFIGS] ={ - { - .configuration_desc ={ - .bLength = sizeof(struct usb_configuration_descriptor), - .bDescriptorType = USB_DT_CONFIG, - .wTotalLength = - cpu_to_le16(sizeof(struct gserial_config_desc)), - .bNumInterfaces = NUM_GSERIAL_INTERFACES, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG, - .bmAttributes = - BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, - .bMaxPower = USBTTY_MAXPOWER - }, - .interface_desc = { - { - .bLength = - sizeof(struct usb_interface_descriptor), - .bDescriptorType = USB_DT_INTERFACE, - .bInterfaceNumber = 0, - .bAlternateSetting = 0, - .bNumEndpoints = NUM_ENDPOINTS, - .bInterfaceClass = - COMMUNICATIONS_INTERFACE_CLASS_VENDOR, - .bInterfaceSubClass = - COMMUNICATIONS_NO_SUBCLASS, - .bInterfaceProtocol = - COMMUNICATIONS_NO_PROTOCOL, - .iInterface = STR_DATA_INTERFACE - }, - }, - .data_endpoints = { - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x01 | USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE), - .bInterval= 0xFF, - }, - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x02 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE), - .bInterval = 0xFF, - }, - { - .bLength = - sizeof(struct usb_endpoint_descriptor), - .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = 0x03 | USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = - cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), - .bInterval = 0xFF, - }, - }, - }, -}; - -/* - * Static Function Prototypes - */ - -static void usbtty_init_strings (void); -static void usbtty_init_instances (void); -static void usbtty_init_endpoints (void); -static void usbtty_init_terminal_type(short type); -static void usbtty_event_handler (struct usb_device_instance *device, - usb_device_event_t event, int data); -static int usbtty_cdc_setup(struct usb_device_request *request, - struct urb *urb); -static int usbtty_configured (void); -static int write_buffer (circbuf_t * buf); -static int fill_buffer (circbuf_t * buf); - -void usbtty_poll (void); - -/* utility function for converting char* to wide string used by USB */ -static void str2wide (char *str, u16 * wide) -{ - int i; - for (i = 0; i < strlen (str) && str[i]; i++){ - #if defined(__LITTLE_ENDIAN) - wide[i] = (u16) str[i]; - #elif defined(__BIG_ENDIAN) - wide[i] = ((u16)(str[i])<<8); - #else - #error "__LITTLE_ENDIAN or __BIG_ENDIAN undefined" - #endif - } -} - -/* - * Test whether a character is in the RX buffer - */ - -int usbtty_tstc (void) -{ - struct usb_endpoint_instance *endpoint = - &endpoint_instance[rx_endpoint]; - - /* If no input data exists, allow more RX to be accepted */ - if(usbtty_input.size <= 0){ - udc_unset_nak(endpoint->endpoint_address&0x03); - } - - usbtty_poll (); - return (usbtty_input.size > 0); -} - -/* - * Read a single byte from the usb client port. Returns 1 on success, 0 - * otherwise. When the function is succesfull, the character read is - * written into its argument c. - */ - -int usbtty_getc (void) -{ - char c; - struct usb_endpoint_instance *endpoint = - &endpoint_instance[rx_endpoint]; - - while (usbtty_input.size <= 0) { - udc_unset_nak(endpoint->endpoint_address&0x03); - usbtty_poll (); - } - - buf_pop (&usbtty_input, &c, 1); - udc_set_nak(endpoint->endpoint_address&0x03); - - return c; -} - -/* - * Output a single byte to the usb client port. - */ -void usbtty_putc (const char c) -{ - buf_push (&usbtty_output, &c, 1); - /* If \n, also do \r */ - if (c == '\n') - buf_push (&usbtty_output, "\r", 1); - - /* Poll at end to handle new data... */ - if ((usbtty_output.size + 2) >= usbtty_output.totalsize) { - usbtty_poll (); - } -} - -/* usbtty_puts() helper function for finding the next '\n' in a string */ -static int next_nl_pos (const char *s) -{ - int i; - - for (i = 0; s[i] != '\0'; i++) { - if (s[i] == '\n') - return i; - } - return i; -} - -/* - * Output a string to the usb client port - implementing flow control - */ - -static void __usbtty_puts (const char *str, int len) -{ - int maxlen = usbtty_output.totalsize; - int space, n; - - /* break str into chunks < buffer size, if needed */ - while (len > 0) { - usbtty_poll (); - - space = maxlen - usbtty_output.size; - /* Empty buffer here, if needed, to ensure space... */ - if (space) { - write_buffer (&usbtty_output); - - n = MIN (space, MIN (len, maxlen)); - buf_push (&usbtty_output, str, n); - - str += n; - len -= n; - } - } -} - -void usbtty_puts (const char *str) -{ - int n; - int len = strlen (str); - - /* add '\r' for each '\n' */ - while (len > 0) { - n = next_nl_pos (str); - - if (str[n] == '\n') { - __usbtty_puts (str, n + 1); - __usbtty_puts ("\r", 1); - str += (n + 1); - len -= (n + 1); - } else { - /* No \n found. All done. */ - __usbtty_puts (str, n); - break; - } - } - - /* Poll at end to handle new data... */ - usbtty_poll (); -} - -/* - * Initialize the usb client port. - * - */ -int drv_usbtty_init (void) -{ - int rc; - char * sn; - char * tt; - int snlen; - - /* Ger seiral number */ - if (!(sn = getenv("serial#"))) { - sn = "000000000000"; - } - snlen = strlen(sn); - if (snlen > sizeof(serial_number) - 1) { - printf ("Warning: serial number %s is too long (%d > %d)\n", - sn, snlen, sizeof(serial_number) - 1); - snlen = sizeof(serial_number) - 1; - } - memcpy (serial_number, sn, snlen); - serial_number[snlen] = '\0'; - - /* Decide on which type of UDC device to be. - */ - - if(!(tt = getenv("usbtty"))) { - tt = "generic"; - } - usbtty_init_terminal_type(strcmp(tt,"cdc_acm")); - - /* prepare buffers... */ - buf_init (&usbtty_input, USBTTY_BUFFER_SIZE); - buf_init (&usbtty_output, USBTTY_BUFFER_SIZE); - - /* Now, set up USB controller and infrastructure */ - udc_init (); /* Basic USB initialization */ - - usbtty_init_strings (); - usbtty_init_instances (); - - udc_startup_events (device_instance);/* Enable dev, init udc pointers */ - udc_connect (); /* Enable pullup for host detection */ - - usbtty_init_endpoints (); - - /* Device initialization */ - memset (&usbttydev, 0, sizeof (usbttydev)); - - strcpy (usbttydev.name, "usbtty"); - usbttydev.ext = 0; /* No extensions */ - usbttydev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_OUTPUT; - usbttydev.tstc = usbtty_tstc; /* 'tstc' function */ - usbttydev.getc = usbtty_getc; /* 'getc' function */ - usbttydev.putc = usbtty_putc; /* 'putc' function */ - usbttydev.puts = usbtty_puts; /* 'puts' function */ - - rc = device_register (&usbttydev); - - return (rc == 0) ? 1 : rc; -} - -static void usbtty_init_strings (void) -{ - struct usb_string_descriptor *string; - - usbtty_string_table[STR_LANG] = - (struct usb_string_descriptor*)wstrLang; - - string = (struct usb_string_descriptor *) wstrManufacturer; - string->bLength = sizeof(wstrManufacturer); - string->bDescriptorType = USB_DT_STRING; - str2wide (CONFIG_USBD_MANUFACTURER, string->wData); - usbtty_string_table[STR_MANUFACTURER]=string; - - - string = (struct usb_string_descriptor *) wstrProduct; - string->bLength = sizeof(wstrProduct); - string->bDescriptorType = USB_DT_STRING; - str2wide (CONFIG_USBD_PRODUCT_NAME, string->wData); - usbtty_string_table[STR_PRODUCT]=string; - - - string = (struct usb_string_descriptor *) wstrSerial; - string->bLength = sizeof(serial_number); - string->bDescriptorType = USB_DT_STRING; - str2wide (serial_number, string->wData); - usbtty_string_table[STR_SERIAL]=string; - - - string = (struct usb_string_descriptor *) wstrConfiguration; - string->bLength = sizeof(wstrConfiguration); - string->bDescriptorType = USB_DT_STRING; - str2wide (CONFIG_USBD_CONFIGURATION_STR, string->wData); - usbtty_string_table[STR_CONFIG]=string; - - - string = (struct usb_string_descriptor *) wstrDataInterface; - string->bLength = sizeof(wstrDataInterface); - string->bDescriptorType = USB_DT_STRING; - str2wide (CONFIG_USBD_DATA_INTERFACE_STR, string->wData); - usbtty_string_table[STR_DATA_INTERFACE]=string; - - string = (struct usb_string_descriptor *) wstrCtrlInterface; - string->bLength = sizeof(wstrCtrlInterface); - string->bDescriptorType = USB_DT_STRING; - str2wide (CONFIG_USBD_CTRL_INTERFACE_STR, string->wData); - usbtty_string_table[STR_CTRL_INTERFACE]=string; - - /* Now, initialize the string table for ep0 handling */ - usb_strings = usbtty_string_table; -} - -static void usbtty_init_instances (void) -{ - int i; - - /* initialize device instance */ - memset (device_instance, 0, sizeof (struct usb_device_instance)); - device_instance->device_state = STATE_INIT; - device_instance->device_descriptor = &device_descriptor; - device_instance->event = usbtty_event_handler; - device_instance->cdc_recv_setup = usbtty_cdc_setup; - device_instance->bus = bus_instance; - device_instance->configurations = NUM_CONFIGS; - device_instance->configuration_instance_array = config_instance; - - /* initialize bus instance */ - memset (bus_instance, 0, sizeof (struct usb_bus_instance)); - bus_instance->device = device_instance; - bus_instance->endpoint_array = endpoint_instance; - bus_instance->max_endpoints = 1; - bus_instance->maxpacketsize = 64; - bus_instance->serial_number_str = serial_number; - - /* configuration instance */ - memset (config_instance, 0, - sizeof (struct usb_configuration_instance)); - config_instance->interfaces = interface_count; - config_instance->configuration_descriptor = configuration_descriptor; - config_instance->interface_instance_array = interface_instance; - - /* interface instance */ - memset (interface_instance, 0, - sizeof (struct usb_interface_instance)); - interface_instance->alternates = 1; - interface_instance->alternates_instance_array = alternate_instance; - - /* alternates instance */ - memset (alternate_instance, 0, - sizeof (struct usb_alternate_instance)); - alternate_instance->interface_descriptor = interface_descriptors; - alternate_instance->endpoints = NUM_ENDPOINTS; - alternate_instance->endpoints_descriptor_array = ep_descriptor_ptrs; - - /* endpoint instances */ - memset (&endpoint_instance[0], 0, - sizeof (struct usb_endpoint_instance)); - endpoint_instance[0].endpoint_address = 0; - endpoint_instance[0].rcv_packetSize = EP0_MAX_PACKET_SIZE; - endpoint_instance[0].rcv_attributes = USB_ENDPOINT_XFER_CONTROL; - endpoint_instance[0].tx_packetSize = EP0_MAX_PACKET_SIZE; - endpoint_instance[0].tx_attributes = USB_ENDPOINT_XFER_CONTROL; - udc_setup_ep (device_instance, 0, &endpoint_instance[0]); - - for (i = 1; i <= NUM_ENDPOINTS; i++) { - memset (&endpoint_instance[i], 0, - sizeof (struct usb_endpoint_instance)); - - endpoint_instance[i].endpoint_address = - ep_descriptor_ptrs[i - 1]->bEndpointAddress; - - endpoint_instance[i].rcv_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - endpoint_instance[i].rcv_packetSize = - le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); - - endpoint_instance[i].tx_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - endpoint_instance[i].tx_packetSize = - le16_to_cpu(ep_descriptor_ptrs[i - 1]->wMaxPacketSize); - - endpoint_instance[i].tx_attributes = - ep_descriptor_ptrs[i - 1]->bmAttributes; - - urb_link_init (&endpoint_instance[i].rcv); - urb_link_init (&endpoint_instance[i].rdy); - urb_link_init (&endpoint_instance[i].tx); - urb_link_init (&endpoint_instance[i].done); - - if (endpoint_instance[i].endpoint_address & USB_DIR_IN) - endpoint_instance[i].tx_urb = - usbd_alloc_urb (device_instance, - &endpoint_instance[i]); - else - endpoint_instance[i].rcv_urb = - usbd_alloc_urb (device_instance, - &endpoint_instance[i]); - } -} - -static void usbtty_init_endpoints (void) -{ - int i; - - bus_instance->max_endpoints = NUM_ENDPOINTS + 1; - for (i = 1; i <= NUM_ENDPOINTS; i++) { - udc_setup_ep (device_instance, i, &endpoint_instance[i]); - } -} - -/* usbtty_init_terminal_type - * - * Do some late binding for our device type. - */ -static void usbtty_init_terminal_type(short type) -{ - switch(type){ - /* CDC ACM */ - case 0: - /* Assign endpoint descriptors */ - ep_descriptor_ptrs[0] = - &acm_configuration_descriptors[0].notification_endpoint; - ep_descriptor_ptrs[1] = - &acm_configuration_descriptors[0].data_endpoints[0]; - ep_descriptor_ptrs[2] = - &acm_configuration_descriptors[0].data_endpoints[1]; - - /* Enumerate Device Descriptor */ - device_descriptor.bDeviceClass = - COMMUNICATIONS_DEVICE_CLASS; - device_descriptor.idProduct = - cpu_to_le16(CONFIG_USBD_PRODUCTID_CDCACM); - - /* Assign endpoint indices */ - tx_endpoint = ACM_TX_ENDPOINT; - rx_endpoint = ACM_RX_ENDPOINT; - - /* Configuration Descriptor */ - configuration_descriptor = - (struct usb_configuration_descriptor*) - &acm_configuration_descriptors; - - /* Interface count */ - interface_count = NUM_ACM_INTERFACES; - break; - - /* BULK IN/OUT & Default */ - case 1: - default: - /* Assign endpoint descriptors */ - ep_descriptor_ptrs[0] = - &gserial_configuration_descriptors[0].data_endpoints[0]; - ep_descriptor_ptrs[1] = - &gserial_configuration_descriptors[0].data_endpoints[1]; - ep_descriptor_ptrs[2] = - &gserial_configuration_descriptors[0].data_endpoints[2]; - - /* Enumerate Device Descriptor */ - device_descriptor.bDeviceClass = 0xFF; - device_descriptor.idProduct = - cpu_to_le16(CONFIG_USBD_PRODUCTID_GSERIAL); - - /* Assign endpoint indices */ - tx_endpoint = GSERIAL_TX_ENDPOINT; - rx_endpoint = GSERIAL_RX_ENDPOINT; - - /* Configuration Descriptor */ - configuration_descriptor = - (struct usb_configuration_descriptor*) - &gserial_configuration_descriptors; - - /* Interface count */ - interface_count = NUM_GSERIAL_INTERFACES; - break; - } -} - -/******************************************************************************/ - -static struct urb *next_urb (struct usb_device_instance *device, - struct usb_endpoint_instance *endpoint) -{ - struct urb *current_urb = NULL; - int space; - - /* If there's a queue, then we should add to the last urb */ - if (!endpoint->tx_queue) { - current_urb = endpoint->tx_urb; - } else { - /* Last urb from tx chain */ - current_urb = - p2surround (struct urb, link, endpoint->tx.prev); - } - - /* Make sure this one has enough room */ - space = current_urb->buffer_length - current_urb->actual_length; - if (space > 0) { - return current_urb; - } else { /* No space here */ - /* First look at done list */ - current_urb = first_urb_detached (&endpoint->done); - if (!current_urb) { - current_urb = usbd_alloc_urb (device, endpoint); - } - - urb_append (&endpoint->tx, current_urb); - endpoint->tx_queue++; - } - return current_urb; -} - -static int write_buffer (circbuf_t * buf) -{ - if (!usbtty_configured ()) { - return 0; - } - - struct usb_endpoint_instance *endpoint = - &endpoint_instance[tx_endpoint]; - struct urb *current_urb = NULL; - - current_urb = next_urb (device_instance, endpoint); - /* TX data still exists - send it now - */ - if(endpoint->sent < current_urb->actual_length){ - if(udc_endpoint_write (endpoint)){ - /* Write pre-empted by RX */ - return -1; - } - } - - if (buf->size) { - char *dest; - - int space_avail; - int popnum, popped; - int total = 0; - - /* Break buffer into urb sized pieces, - * and link each to the endpoint - */ - while (buf->size > 0) { - - if (!current_urb) { - TTYERR ("current_urb is NULL, buf->size %d\n", - buf->size); - return total; - } - - dest = (char*)current_urb->buffer + - current_urb->actual_length; - - space_avail = - current_urb->buffer_length - - current_urb->actual_length; - popnum = MIN (space_avail, buf->size); - if (popnum == 0) - break; - - popped = buf_pop (buf, dest, popnum); - if (popped == 0) - break; - current_urb->actual_length += popped; - total += popped; - - /* If endpoint->last == 0, then transfers have - * not started on this endpoint - */ - if (endpoint->last == 0) { - if(udc_endpoint_write (endpoint)){ - /* Write pre-empted by RX */ - return -1; - } - } - - }/* end while */ - return total; - } - - return 0; -} - -static int fill_buffer (circbuf_t * buf) -{ - struct usb_endpoint_instance *endpoint = - &endpoint_instance[rx_endpoint]; - - if (endpoint->rcv_urb && endpoint->rcv_urb->actual_length) { - unsigned int nb = 0; - char *src = (char *) endpoint->rcv_urb->buffer; - unsigned int rx_avail = buf->totalsize - buf->size; - - if(rx_avail >= endpoint->rcv_urb->actual_length){ - - nb = endpoint->rcv_urb->actual_length; - buf_push (buf, src, nb); - endpoint->rcv_urb->actual_length = 0; - - } - return nb; - } - return 0; -} - -static int usbtty_configured (void) -{ - return usbtty_configured_flag; -} - -/******************************************************************************/ - -static void usbtty_event_handler (struct usb_device_instance *device, - usb_device_event_t event, int data) -{ - switch (event) { - case DEVICE_RESET: - case DEVICE_BUS_INACTIVE: - usbtty_configured_flag = 0; - break; - case DEVICE_CONFIGURED: - usbtty_configured_flag = 1; - break; - - case DEVICE_ADDRESS_ASSIGNED: - usbtty_init_endpoints (); - - default: - break; - } -} - -/******************************************************************************/ - -int usbtty_cdc_setup(struct usb_device_request *request, struct urb *urb) -{ - switch (request->bRequest){ - - case ACM_SET_CONTROL_LINE_STATE: /* Implies DTE ready */ - break; - case ACM_SEND_ENCAPSULATED_COMMAND : /* Required */ - break; - case ACM_SET_LINE_ENCODING : /* DTE stop/parity bits - * per character */ - break; - case ACM_GET_ENCAPSULATED_RESPONSE : /* request response */ - break; - case ACM_GET_LINE_ENCODING : /* request DTE rate, - * stop/parity bits */ - memcpy (urb->buffer , &rs232_desc, sizeof(rs232_desc)); - urb->actual_length = sizeof(rs232_desc); - - break; - default: - return 1; - } - return 0; -} - -/******************************************************************************/ - -/* - * Since interrupt handling has not yet been implemented, we use this function - * to handle polling. This is called by the tstc,getc,putc,puts routines to - * update the USB state. - */ -void usbtty_poll (void) -{ - /* New interrupts? */ - udc_irq(); - - /* Write any output data to host buffer - * (do this before checking interrupts to avoid missing one) - */ - if (usbtty_configured ()) { - write_buffer (&usbtty_output); - } - - /* New interrupts? */ - udc_irq(); - - /* Check for new data from host.. - * (do this after checking interrupts to get latest data) - */ - if (usbtty_configured ()) { - fill_buffer (&usbtty_input); - } - - /* New interrupts? */ - udc_irq(); - -} - - -#endif diff --git a/drivers/usbtty.h b/drivers/usbtty.h deleted file mode 100644 index 8154e3072e..0000000000 --- a/drivers/usbtty.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * (C) Copyright 2003 - * Gerry Hamel, geh@ti.com, Texas Instruments - * - * (C) Copyright 2006 - * Bryan O'Donoghue, bodonoghue@codehermit.ie, CodeHermit - * - * 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 - * - */ - -#ifndef __USB_TTY_H__ -#define __USB_TTY_H__ - -#include "usbdcore.h" -#if defined(CONFIG_PPC) -#include "usbdcore_mpc8xx.h" -#elif defined(CONFIG_ARM) -#include "usbdcore_omap1510.h" -#endif - -#include - -/* If no VendorID/ProductID is defined in config.h, pretend to be Linux - * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */ - -#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ -#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ -#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ -#define CONFIG_USBD_MANUFACTURER "Das U-Boot" -#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION - - -#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" - -#define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT -#define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE -#define CONFIG_USBD_SERIAL_IN_ENDPOINT UDC_IN_ENDPOINT -#define CONFIG_USBD_SERIAL_IN_PKTSIZE UDC_IN_PACKET_SIZE -#define CONFIG_USBD_SERIAL_INT_ENDPOINT UDC_INT_ENDPOINT -#define CONFIG_USBD_SERIAL_INT_PKTSIZE UDC_INT_PACKET_SIZE -#define CONFIG_USBD_SERIAL_BULK_PKTSIZE UDC_BULK_PACKET_SIZE - -#define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS - -#define USBTTY_BCD_DEVICE 0x00 -#define USBTTY_MAXPOWER 0x00 - -#define STR_LANG 0x00 -#define STR_MANUFACTURER 0x01 -#define STR_PRODUCT 0x02 -#define STR_SERIAL 0x03 -#define STR_CONFIG 0x04 -#define STR_DATA_INTERFACE 0x05 -#define STR_CTRL_INTERFACE 0x06 -#define STR_COUNT 0x07 - -#endif