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

📄 omap24xx-uart.c

📁 omap3 linux 2.6 用nocc去除了冗余代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			printk(KERN_INFO			       "FIR Mode : Changing UART speed to %d....",			       speed);			mdr1_data &= MODE_SELECT_MASK;			mdr1_data |= UART_FIR_MODE;			outb(mdr1_data, uart_base + REG_MDR1);			printk("Done\n");		} else {			printk(KERN_ERR			       "!!! Requested speed is not supported!!!!!!\n");			goto exit_path1;		}	} else if (uart_mode[uart_no] == UART_MODE) {		if (speed <= UART_16X_SPEED) {			printk(KERN_INFO			       "16X Mode : Changing UART speed to %d....\n",			       speed);			divisor = BASE_CLK / (16 * speed);			outb(divisor & 0xFF, uart_base + REG_DLL);			outb(divisor >> 8, uart_base + REG_DLH);			mdr1_data &= MODE_SELECT_MASK;			mdr1_data |= UART_16X_MODE;			outb(mdr1_data, uart_base + REG_MDR1);			printk("Done\n");		} else if (speed <= UART_13X_SPEED) {			printk(KERN_INFO			       "13X Mode : Changing UART speed to %d....\n",			       speed);			divisor = BASE_CLK / (13 * speed);			outb(divisor & 0xFF, uart_base + REG_DLL);			outb(divisor >> 8, uart_base + REG_DLH);			mdr1_data &= MODE_SELECT_MASK;			mdr1_data |= UART_13X_MODE;			outb(mdr1_data, uart_base + REG_MDR1);			printk("Done\n");		} else {			printk(KERN_ERR			       "!!! Requested speed is not supported!!!!!!\n");			goto exit_path1;		}	} else if (uart_mode[uart_no] == UART_AUTOBAUD_MODE) {		printk(KERN_INFO " UART%d 16X Auto baud Mode\n", uart_no);		mdr1_data &= MODE_SELECT_MASK;		mdr1_data |= UART_16XAUTO_MODE;		outb(mdr1_data, uart_base + REG_MDR1);	} else if (uart_mode[uart_no] == CIR_MODE) {		printk(KERN_INFO " UART%d CIR Mode\n", uart_no);		mdr1_data &= MODE_SELECT_MASK;		mdr1_data |= UART_CIR_MODE;		outb(mdr1_data, uart_base + REG_MDR1);	} else {		printk(KERN_ERR		       "Invalid parameters for UART speed change!!!!!!!\n");		goto exit_path1;	}	/* restore LCR values */	outb(lcr_data, uart_base + REG_LCR);	spin_unlock(&(ui[uart_no].uart_lock));	FN_OUT(0);	return 0;      exit_path1:	/* Restore LCR and MDR1 regisgters to original value */	outb(mdr1_data, uart_base + REG_MDR1);	outb(lcr_data, uart_base + REG_LCR);	spin_unlock(&(ui[uart_no].uart_lock));	FN_OUT(EPERM);	return -EPERM;}EXPORT_SYMBOL(omap24xx_uart_set_speed);/** * brief omap24xx_uart_config *  configures the requested UART * param uart_no * param uartcfg * * return */int omap24xx_uart_config(int uart_no, struct uart_config *uartcfg){	u32 uart_base = UART_MODULE_BASE(uart_no);	u8 reg_data = 0;	struct clk *uarti = NULL, *uartf = NULL;	FN_IN;	if (in_interrupt())		BUG();	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	/* Start clock for requested UART */	if (get_uart_clocks(&uarti, &uartf, uart_no)) {		printk(KERN_ERR "UART clock configuration error\n");		return -ENOENT;	}	clk_enable(uarti);	clk_enable(uartf);	spin_lock(&(ui[uart_no].uart_lock));	uart_mode[uart_no] = uartcfg->mode;	/* Put UART3 in reset mode */	reg_data = UART_DISABLE;	outb(reg_data, uart_base + REG_MDR1);	/* Clear DLL and DLH */	reg_data = LCR_MODE2;	outb(reg_data, uart_base + REG_LCR);	reg_data = BIT_DLL_CLOCK_LSB;	outb(reg_data, uart_base + REG_DLL);	reg_data = BIT_DLH_CLOCK_MSB;	outb(reg_data, uart_base + REG_DLH);	reg_data = 0;	outb(reg_data, uart_base + REG_SCR);	reg_data = LCR_MODE3;	outb(reg_data, uart_base + REG_LCR);	reg_data = (uartcfg->efr);	outb(reg_data, uart_base + REG_EFR);	reg_data = LCR_MODE2;	outb(reg_data, uart_base + REG_LCR);	/* enable TCR and TLR Registers */	reg_data = ENABLE_TCR_TLR;	outb(reg_data, uart_base + REG_MCR);	reg_data = (uartcfg->tlr);	outb(reg_data, uart_base + REG_TLR);	reg_data = (uartcfg->lcr);	outb(reg_data, uart_base + REG_LCR);	reg_data = (uartcfg->fcr);	outb(reg_data, uart_base + REG_FCR);	/* disable access to TCR and TLR registers */	reg_data = DISABLE_TCR_TLR;	outb(reg_data, uart_base + REG_MCR);	reg_data = (uartcfg->scr) |		(BIT_SCR_TX_TRIG_GRANU1_M | BIT_SCR_RX_TRIG_GRANU1_M);	outb(reg_data, uart_base + REG_SCR);	reg_data = (uartcfg->mdr1);	outb(reg_data, uart_base + REG_MDR1);	reg_data = (uartcfg->mdr2);	outb(reg_data, uart_base + REG_MDR2);	reg_data = (uartcfg->acreg);	outb(reg_data, uart_base + REG_ACREG);	reg_data = (uartcfg->ier);	outb(reg_data, uart_base + REG_IER);	if (uart_mode[uart_no] == IRDA_MODE) {		reg_data = (uartcfg->rxfll);		outb(reg_data, uart_base + REG_RXFLL);		reg_data = (uartcfg->rxflh);		outb(reg_data, uart_base + REG_RXFLH);	}	readb(uart_base + REG_RESUME);	spin_unlock(&(ui[uart_no].uart_lock));	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_config);/** * brief omap24xx_uart_stop * stops/resets requested UART. * param uart_no * * return */int omap24xx_uart_stop(int uart_no){	u32 uart_base = UART_MODULE_BASE(uart_no);	u8 reg_data;	struct clk *uarti = NULL, *uartf = NULL;	FN_IN;	if (in_interrupt())		BUG();	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	/* Stop clock for requested UART */	get_uart_clocks(&uarti, &uartf, uart_no);	clk_disable(uarti);	clk_disable(uartf);	spin_lock(&(ui[uart_no].uart_lock));	/* Put UART3 in reset mode */	reg_data = BIT_MDR1_MODE_SELECT_M;	outb(reg_data, uart_base + REG_MDR1);	/* Clear DLL and DLH */	reg_data = LCR_MODE2;	outb(reg_data, uart_base + REG_LCR);	reg_data = BIT_DLL_CLOCK_LSB;	outb(reg_data, uart_base + REG_DLL);	reg_data = BIT_DLH_CLOCK_MSB;	outb(reg_data, uart_base + REG_DLH);	/* Disable requested UART interrupts */	reg_data = 0;	outb(reg_data, uart_base + REG_IER);	/* Stop DMA channels */	omap_stop_dma(ui[uart_no].rx_dma_channel);	omap_stop_dma(ui[uart_no].tx_dma_channel);	/* Move buffer states to free */	ui[uart_no].tx_buf_state = FREE;	ui[uart_no].rx_buf_state = FREE;	spin_unlock(&(ui[uart_no].uart_lock));	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_stop);/** * brief omap24xx_uart_rx *  Copies data from DMA buffer to user *  driver buffer. * param uart_no * param data * param len * * return */int omap24xx_uart_rx(int uart_no, void *data, int *len){	unsigned long flags;	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	spin_lock_irqsave(&(ui[uart_no].uart_lock), flags);	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		*len = omap_get_dma_dst_pos(ui[uart_no].rx_dma_channel);		*len -= ui[uart_no].rx_buf_dma_phys;		memcpy(data, ui[uart_no].rx_buf_dma_virt, *len);		/* DMA data is copied to user driver buffer,		 * now it is safe to move rx_buf_state to free.		 */		ui[uart_no].rx_buf_state = FREE;	} else {	}	spin_unlock_irqrestore(&(ui[uart_no].uart_lock), flags);	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_rx);/** * brief omap24xx_uart_tx *  copies data from client driver buffer *  to DMA buffer. * param uart_no * param data * param size * * return */int omap24xx_uart_tx(int uart_no, void *data, int size){	unsigned long flags;	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	if (unlikely(size < 0 || size > uart_cb[uart_no].tx_buf_size)) {		D3(KERN_INFO "Error...Invalid buffer size!!!!\n");		return -EPERM;	}	spin_lock_irqsave(&(ui[uart_no].uart_lock), flags);	D3("omap24xx_uart_tx : %s\n", data);	D3("omap24xx_uart_tx : %d\n", size);	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		memcpy(ui[uart_no].tx_buf_dma_virt, data, size);	} else {	}	spin_unlock_irqrestore(&(ui[uart_no].uart_lock), flags);	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_tx);/** * brief omap24xx_uart_start_tx *  Starts transferring data from DMA tx channel * param uart_no * param size * * return */int omap24xx_uart_start_tx(int uart_no, int size){	u32 uart_base = UART_BASE(uart_no);	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	if (ui[uart_no].tx_buf_state == USED) {		D3("Error : UART DMA buffer is not free...!!!\n");		return -EAGAIN;	}	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		omap_set_dma_dest_params(ui[uart_no].tx_dma_channel,						0,			// dest_port is only for OMAP1					 OMAP_DMA_AMODE_CONSTANT, uart_base, 0,					 0);		omap_set_dma_src_params(ui[uart_no].tx_dma_channel,						0,			// src_port is only for OMAP1					OMAP_DMA_AMODE_POST_INC,					ui[uart_no].tx_buf_dma_phys, 0, 0);		omap_set_dma_transfer_params(ui[uart_no].tx_dma_channel,					     OMAP_DMA_DATA_TYPE_S8, size, 1,					     OMAP_DMA_SYNC_ELEMENT,					     uart_dma_tx[uart_no], 0);		omap_start_dma(ui[uart_no].tx_dma_channel);		ui[uart_no].tx_buf_state = USED;	}	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_start_tx);/** * brief omap24xx_uart_start_rx *  Starts receiving data from DMA rx channel * param uart_no * param size * * return */int omap24xx_uart_start_rx(int uart_no, int size){	u32 uart_base = UART_BASE(uart_no);	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	if (ui[uart_no].rx_buf_state == USED) {		D3("Error : UART DMA buffer is not free...!!!\n");		return -EAGAIN;	}	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		omap_set_dma_src_params(ui[uart_no].rx_dma_channel,					0,			// src_port is only for OMAP1					OMAP_DMA_AMODE_CONSTANT, uart_base, 0,					0);		omap_set_dma_dest_params(ui[uart_no].rx_dma_channel,					0,			// dest_port is only for OMAP1					 OMAP_DMA_AMODE_POST_INC,					 ui[uart_no].rx_buf_dma_phys, 0, 0);		omap_set_dma_transfer_params(ui[uart_no].rx_dma_channel,					     OMAP_DMA_DATA_TYPE_S8, size, 1,					     OMAP_DMA_SYNC_ELEMENT,					     uart_dma_rx[uart_no], 0);		OMAP_DMA_CDAC_REG(ui[uart_no].rx_dma_channel) =						ui[uart_no].rx_buf_dma_phys;		if (ui[uart_no].timeout !=0) {			/* Start dma */			omap_start_dma(ui[uart_no].rx_dma_channel);			ui[uart_no].rx_buf_state = USED;			/* Start timer */			ui[uart_no].timer_active = 1;			add_timer(&ui[uart_no].timer);		} else {			/* Start dma */			omap_start_dma(ui[uart_no].rx_dma_channel);			ui[uart_no].rx_buf_state = USED;		}	}	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_start_rx);/** * brief omap24xx_uart_stop_rx * * param uart_no * * return */int omap24xx_uart_stop_rx(int uart_no){	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		omap_stop_dma(ui[uart_no].rx_dma_channel);		OMAP_DMA_CDAC_REG(ui[uart_no].rx_dma_channel) =						ui[uart_no].rx_buf_dma_phys;		del_timer(&ui[uart_no].timer);		ui[uart_no].timer_active = 0;	}	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_stop_rx);/** * brief omap24xx_uart_stop_tx * * param uart_no * * return */int omap24xx_uart_stop_tx(int uart_no){	FN_IN;	if (unlikely(uart_no < 0 || uart_no > MAX_UARTS)) {		D3(KERN_INFO "C Bad uart id %d \n", uart_no);		return -EPERM;	}	if (uart_cb[uart_no].mode == UART_DMA_MODE) {		omap_stop_dma(ui[uart_no].tx_dma_channel);	}	FN_OUT(0);	return 0;}EXPORT_SYMBOL(omap24xx_uart_stop_tx);/** * brief omap24xx_uart_interrupt *  used to enable/disable *  UART interrupts. * param uart_no * param enable *

⌨️ 快捷键说明

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