⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amba.c

📁 IXP425 平台下嵌入式LINUX的串口的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
static void ambauart_break_ctl(struct uart_port *port, int break_state){	unsigned int lcr_h;	lcr_h = UART_GET_LCRH(port);	if (break_state == -1)		lcr_h |= AMBA_UARTLCR_H_BRK;	else		lcr_h &= ~AMBA_UARTLCR_H_BRK;	UART_PUT_LCRH(port, lcr_h);}static int ambauart_startup(struct uart_port *port, struct uart_info *info){	int retval;	/*	 * Allocate the IRQ	 */	retval = request_irq(port->irq, ambauart_int, 0, "amba", info);	if (retval)		return retval;	/*	 * initialise the old status of the modem signals	 */	info->drv_old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;	/*	 * Finally, enable interrupts	 */	UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |			  AMBA_UARTCR_RTIE);	return 0;}static void ambauart_shutdown(struct uart_port *port, struct uart_info *info){	/*	 * Free the interrupt	 */	free_irq(port->irq, info);	/*	 * disable all interrupts, disable the port	 */	UART_PUT_CR(port, 0);	/* disable break condition and fifos */	UART_PUT_LCRH(port, UART_GET_LCRH(port) &		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));}static void ambauart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot){	u_int lcr_h, old_cr;	unsigned long flags;#if DEBUG	printk("ambauart_set_cflag(0x%x) called\n", cflag);#endif	/* byte size and parity */	switch (cflag & CSIZE) {	case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; break;	case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; break;	case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; break;	default:  lcr_h = AMBA_UARTLCR_H_WLEN_8; break; // CS8	}	if (cflag & CSTOPB)		lcr_h |= AMBA_UARTLCR_H_STP2;	if (cflag & PARENB) {		lcr_h |= AMBA_UARTLCR_H_PEN;		if (!(cflag & PARODD))			lcr_h |= AMBA_UARTLCR_H_EPS;	}	if (port->fifosize > 1)		lcr_h |= AMBA_UARTLCR_H_FEN;	port->read_status_mask = AMBA_UARTRSR_OE;	if (iflag & INPCK)		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;	if (iflag & (BRKINT | PARMRK))		port->read_status_mask |= AMBA_UARTRSR_BE;	/*	 * Characters to ignore	 */	port->ignore_status_mask = 0;	if (iflag & IGNPAR)		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;	if (iflag & IGNBRK) {		port->ignore_status_mask |= AMBA_UARTRSR_BE;		/*		 * If we're ignoring parity and break indicators,		 * ignore overruns too (for real raw support).		 */		if (iflag & IGNPAR)			port->ignore_status_mask |= AMBA_UARTRSR_OE;	}	/*	 * Ignore all characters if CREAD is not set.	 */	if ((cflag & CREAD) == 0)		port->ignore_status_mask |= UART_DUMMY_RSR_RX;	/* first, disable everything */	save_flags(flags); cli();	old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;	if ((port->flags & ASYNC_HARDPPS_CD) ||	    (cflag & CRTSCTS) || !(cflag & CLOCAL))		old_cr |= AMBA_UARTCR_MSIE;	UART_PUT_CR(port, 0);	/* Set baud rate */	quot -= 1;	UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));	UART_PUT_LCRL(port, (quot & 0xff));	/*	 * ----------v----------v----------v----------v-----	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L	 * ----------^----------^----------^----------^-----	 */	UART_PUT_LCRH(port, lcr_h);	UART_PUT_CR(port, old_cr);	restore_flags(flags);}static const char *ambauart_type(struct uart_port *port){	return port->type == PORT_AMBA ? "AMBA" : NULL;}/* * Release the memory region(s) being used by 'port' */static void ambauart_release_port(struct uart_port *port){	release_mem_region(port->mapbase, UART_PORT_SIZE);}/* * Request the memory region(s) being used by 'port' */static int ambauart_request_port(struct uart_port *port){	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")			!= NULL ? 0 : -EBUSY;}/* * Configure/autoconfigure the port. */static void ambauart_config_port(struct uart_port *port, int flags){	if (flags & UART_CONFIG_TYPE) {		port->type = PORT_AMBA;		ambauart_request_port(port);	}}/* * verify the new serial_struct (for TIOCSSERIAL). */static int ambauart_verify_port(struct uart_port *port, struct serial_struct *ser){	int ret = 0;	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)		ret = -EINVAL;	if (ser->irq < 0 || ser->irq >= NR_IRQS)		ret = -EINVAL;	if (ser->baud_base < 9600)		ret = -EINVAL;	return ret;}static struct uart_ops amba_pops = {	tx_empty:	ambauart_tx_empty,	set_mctrl:	ambauart_set_mctrl,	get_mctrl:	ambauart_get_mctrl,	stop_tx:	ambauart_stop_tx,	start_tx:	ambauart_start_tx,	stop_rx:	ambauart_stop_rx,	enable_ms:	ambauart_enable_ms,	break_ctl:	ambauart_break_ctl,	startup:	ambauart_startup,	shutdown:	ambauart_shutdown,	change_speed:	ambauart_change_speed,	type:		ambauart_type,	release_port:	ambauart_release_port,	request_port:	ambauart_request_port,	config_port:	ambauart_config_port,	verify_port:	ambauart_verify_port,};static struct uart_port amba_ports[UART_NR] = {	{		membase:	(void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),		mapbase:	INTEGRATOR_UART0_BASE,		iotype:		SERIAL_IO_MEM,		irq:		IRQ_UARTINT0,		uartclk:	14745600,		fifosize:	16,		unused:		{ 4, 5 }, /*driver_priv:	PORT_CTRLS(5, 4), */		ops:		&amba_pops,		flags:		ASYNC_BOOT_AUTOCONF,	},	{		membase:	(void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),		mapbase:	INTEGRATOR_UART1_BASE,		iotype:		SERIAL_IO_MEM,		irq:		IRQ_UARTINT1,		uartclk:	14745600,		fifosize:	16,		unused:		{ 6, 7 }, /*driver_priv:	PORT_CTRLS(7, 6), */		ops:		&amba_pops,		flags:		ASYNC_BOOT_AUTOCONF,	}};#ifdef CONFIG_SERIAL_AMBA_CONSOLEstatic void ambauart_console_write(struct console *co, const char *s, u_int count){	struct uart_port *port = amba_ports + co->index;	unsigned int status, old_cr;	int i;	/*	 *	First save the CR then disable the interrupts	 */	old_cr = UART_GET_CR(port);	UART_PUT_CR(port, AMBA_UARTCR_UARTEN);	/*	 *	Now, do each character	 */	for (i = 0; i < count; i++) {		do {			status = UART_GET_FR(port);		} while (!UART_TX_READY(status));		UART_PUT_CHAR(port, s[i]);		if (s[i] == '\n') {			do {				status = UART_GET_FR(port);			} while (!UART_TX_READY(status));			UART_PUT_CHAR(port, '\r');		}	}	/*	 *	Finally, wait for transmitter to become empty	 *	and restore the TCR	 */	do {		status = UART_GET_FR(port);	} while (status & AMBA_UARTFR_BUSY);	UART_PUT_CR(port, old_cr);}static kdev_t ambauart_console_device(struct console *co){	return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);}static void __initambauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits){	if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {		u_int lcr_h, quot;		lcr_h = UART_GET_LCRH(port);		*parity = 'n';		if (lcr_h & AMBA_UARTLCR_H_PEN) {			if (lcr_h & AMBA_UARTLCR_H_EPS)				*parity = 'e';			else				*parity = 'o';		}		if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)			*bits = 7;		else			*bits = 8;		quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8;		*baud = port->uartclk / (16 * (quot + 1));	}}static int __init ambauart_console_setup(struct console *co, char *options){	struct uart_port *port;	int baud = 38400;	int bits = 8;	int parity = 'n';	int flow = 'n';	/*	 * Check whether an invalid uart number has been specified, and	 * if so, search for the first available port that does have	 * console support.	 */	port = uart_get_console(amba_ports, UART_NR, co);	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	else		ambauart_console_get_options(port, &baud, &parity, &bits);	return uart_set_options(port, co, baud, parity, bits, flow);}static struct console amba_console = {	name:		"ttyAM",	write:		ambauart_console_write,	device:		ambauart_console_device,	setup:		ambauart_console_setup,	flags:		CON_PRINTBUFFER,	index:		-1,};void __init ambauart_console_init(void){	register_console(&amba_console);}#define AMBA_CONSOLE	&amba_console#else#define AMBA_CONSOLE	NULL#endifstatic struct uart_driver amba_reg = {	owner:			THIS_MODULE,	normal_major:		SERIAL_AMBA_MAJOR,#ifdef CONFIG_DEVFS_FS	normal_name:		"ttyAM%d",	callout_name:		"cuaam%d",#else	normal_name:		"ttyAM",	callout_name:		"cuaam",#endif	normal_driver:		&normal,	callout_major:		CALLOUT_AMBA_MAJOR,	callout_driver:		&callout,	table:			amba_table,	termios:		amba_termios,	termios_locked:		amba_termios_locked,	minor:			SERIAL_AMBA_MINOR,	nr:			UART_NR,	port:			amba_ports,	cons:			AMBA_CONSOLE,};static int __init ambauart_init(void){	return uart_register_driver(&amba_reg);}static void __exit ambauart_exit(void){	uart_unregister_driver(&amba_reg);}module_init(ambauart_init);module_exit(ambauart_exit);EXPORT_NO_SYMBOLS;MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");MODULE_DESCRIPTION("ARM AMBA serial port driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -