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

📄 usb_phci.c

📁 linux下的usb开发
💻 C
📖 第 1 页 / 共 5 页
字号:
	restore_flags(flags);	dma_cnfg |= (DMA_ENABLE | DMA_WRITE_SELECT) ;	/* Enable HC DMA */	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);		/* wait for End of transfer */	do {		isp1362_udelay(1);		phci_reg_read16(REG_IRQ, &int_reg);	} while(!(int_reg&EOT_INT));	/* Disable HC dma */	dma_cnfg &= ~(DMA_ENABLE | DMA_WRITE_SELECT) ;	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);	return;}void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {	__u32		direct_addr_len;	__u16		dma_cnfg = 0;	__u32		int_reg;	unsigned int	flags;	__u32		original_length;	detail_debug(("fnvPhciRamRead(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))	if(!length || !byte_data) return;				/* If there is nothing to write , return back */	original_length = length;	if(length & 0x01)	length++;			/* Align length to even number */	/* fill the direct address length register with len+dir+addr */	direct_addr_len = addr & 0x7FFF;	direct_addr_len |= direction;	direct_addr_len |= (length << 16);	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length 	dma_cnfg = (DMA_BUFF_TYPE_DIR_ADDR | DMA_1CYCLE_BURST_LEN | DMA_COUNTER_ENABLE);	/* Disable DMA */	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);	/* Clear EOT bit inthe interrupt register */	phci_reg_write16(REG_IRQ, EOT_INT);	save_flags(flags);	disable_dma(DMA4HC_CHNNL);	clear_dma_ff(DMA4HC_CHNNL);	set_dma_mode(DMA4HC_CHNNL,DMA_MODE_READ);	set_dma_addr(DMA4HC_CHNNL,virt_to_bus(phci->dma_buff));	set_dma_count(DMA4HC_CHNNL, length);	/* Enable PC DMA */	enable_dma(DMA4HC_CHNNL);	restore_flags(flags);	dma_cnfg |= (DMA_ENABLE) ;	/* Enable HC DMA */	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);		/* wait for End of transfer */	do {		isp1362_udelay(1);		phci_reg_read16(REG_IRQ, &int_reg);	} while(!(int_reg&EOT_INT));	/* Disable HC dma */	dma_cnfg &= ~(DMA_ENABLE) ;	phci_reg_write16(REG_DMA_CNFG, dma_cnfg);	memcpy(byte_data, phci->dma_buff, original_length);	return;}#else /* CONFIG_USB_PHCD_DMA *//*--------------------------------------------------------------* * Host Controller ATL/INTL/ISTL buffer Write *--------------------------------------------------------------*/void	fnvPhciRamWrite(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {	__u32		direct_addr_len, cnt;	__u16		lower_dword, higher_dword = 0;	__u32		*dword_buff = (__u32*)byte_data;	__u32		original_length, rem_length;	detail_debug(("fnvPhciRamWrite(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))	if(!length || !byte_data) return;				/* If there is nothing to write , return back */	original_length = length;	rem_length = (length & (RAM_BUFF_ALIGNMENT-1));		/* 0, 1, 2, 3 */	/* Make length to RAM_BUFF_ALIGNMENT byte boundary */	while(length & (RAM_BUFF_ALIGNMENT-1)){		length++;	}	/* fill the direct address length register with len+dir+addr */	direct_addr_len = addr & 0x7FFF;	direct_addr_len |= direction;	direct_addr_len |= (length << 16);	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length    	/* Receive data from direct address register on the data IO */	isp1362_command((REG_DIRECT_ADDR_DATA|0x80), isp1362_device);	length = original_length;	if(direction == HC_DIR_ADDR_INCREMENT) {		length >>= 2;								/* total number of double words = length/4 */		cnt = 0;		while( cnt < length) {			lower_dword = dword_buff[cnt];			/* convert dword to 2 words */			higher_dword = (dword_buff[cnt++] >> 16);			isp1362_write16(lower_dword,isp1362_device);			isp1362_write16(higher_dword,isp1362_device);		}				if(rem_length) {			length <<= 2;			lower_dword = byte_data[length];			if(rem_length > 1) lower_dword |= (byte_data[length+1] << 8);			if(rem_length > 2) higher_dword = byte_data[length+2];			isp1362_write16(lower_dword,isp1362_device);			isp1362_write16(higher_dword,isp1362_device);		}	}	return;} /* End of fnvPhciRamWrite *//*--------------------------------------------------------------* * Host Controller ATL/INTL/ISTL buffer Read *--------------------------------------------------------------*/void	fnvPhciRamRead(phci_t	*phci, __u32	length, __u32	direction, __u32	addr, __u8	*byte_data) {	__u32		direct_addr_len, cnt;	__u16		lower_dword, higher_dword;	__u32		*dword_buff = (__u32*)byte_data;	__u32		original_length, rem_length, dword;	detail_debug(("fnvPhciRamRead(length = %d, direction = %d, addr = 0x%x, byte_data = 0x%p)\n",length, direction, addr, byte_data))	if(!length || !byte_data) return;				/* If there is nothing to read, return back */	original_length = length;	rem_length = (length & (RAM_BUFF_ALIGNMENT-1));		/* 0, 1, 2, 3 */	/* Make length to RAM_BUFF_ALIGNMENT byte boundary */	while(length & (RAM_BUFF_ALIGNMENT-1)){		length++;	}//	ALIGN_RAM_BUFF_LENGTH(length);	/* fill the direct address length register with len+dir+addr */	direct_addr_len = addr & 0x7FFF;	direct_addr_len |= direction;	direct_addr_len |= (length << 16);	phci_reg_write32(REG_DIRECT_ADDR_LEN  ,direct_addr_len);  // writing the direct address length    	/* Receive data from direct address register on the data IO */	isp1362_command(REG_DIRECT_ADDR_DATA, isp1362_device);	length = original_length;	if(direction == HC_DIR_ADDR_INCREMENT) {		length >>= 2;								/* total number of double words = length/4 */		cnt = 0;		while( cnt < length) {			lower_dword = isp1362_read16(isp1362_device);			higher_dword = isp1362_read16(isp1362_device);		    dword_buff[cnt++] = lower_dword | (higher_dword << 16) ;	/* Combine lower and higher 16 bits and fill buffer */		}				if(rem_length) {			lower_dword = isp1362_read16(isp1362_device);			higher_dword = isp1362_read16(isp1362_device);						length <<= 2;				dword = lower_dword | (higher_dword << 16) ;	/* make the 32 bit double word */			byte_data[length] = (dword & 0xFF);		/* Copy the first remaining byte */			cnt = 1;			while(cnt < rem_length) {			/* Based on reming bytes copy the 2nd, 3rd bytes */				dword >>= 8;				byte_data[length+cnt] = (dword & 0xFF);				cnt++;			}		}	}	return;} /* End of fnvPhciRamRead */#endif /* CONFIG_USB_PHCD_DMA *//*--------------------------------------------------------------* * Host Controller Ram buffer parameter initialization *--------------------------------------------------------------*/void	fnvHcRamBufferInit( phci_t	*phci) {	__u8		ram_data[1024];	int		i;	__u32	data = 0;	func_debug(("fnvHcRamBufferInit(phci = 0x%p)\n",phci))	/* Configure ISTL buffer */	phci_reg_write16(REG_ISTL_BUFF_LEN, HC_ISTL_BUFFER_LENGTH);			/* Istl buffer length */	phci_reg_write16(REG_ISTL_TOGGLE_RATE, HC_ISTL_DEF_TOGGLE_RATE);	/* Istl toggle rate */	/* Configure INTL buffer */	phci_reg_write16(REG_INTL_BUFF_LEN, HC_INTL_BUFFER_LENGTH);			/* Intl buffer length */	phci_reg_write16(REG_INTL_BLK_PL_SIZE, HC_INTL_BLK_PL_SIZE);		/* Intl payload block size */	/* Configure ATL buffer */	phci_reg_write16(REG_ATL_BUFF_LEN, HC_ATL_BUFFER_LENGTH);			/* Atl buffer length */	phci_reg_write16(REG_ATL_BLK_PL_SIZE, HC_ATL_BLK_PL_SIZE);			/* Atl payload block size */	data = 0x0001 << (TD_PTD_MAX_ATL_TDS);	phci_reg_write32(REG_ATL_PTD_LAST_PTD,data);						/* Set the last ATL ptd in HC */	data = (0x0001 << (TD_PTD_MAX_INTL_TDS));	phci_reg_write32(REG_INTL_PTD_LAST_PTD,data);						/* Update the last INTL ptd in HC */	phci_reg_write16(REG_ATL_THRESHOLD_TIMEOUT,HC_DEF_ATL_THRESHOLD_TIMEOUT);	/* set the atl threshold ptd timeout HC */	phci_reg_write32(REG_ATL_PTD_SKIP_MAP,0xFFFFFFFF);					/* Set all ptds to skip */	phci_reg_write32(REG_INTL_PTD_SKIP_MAP,0xFFFFFFFF);					/* Set all ptds to skip */			/* Initialize the RAM buffer with zeros */	for(i=0;i<1024;i++) { ram_data[i] = 0; }	for(i=0; i<(HC_RAM_SIZE/1024);i++) {		fnvPhciRamWrite( phci, 1024, HC_DIR_ADDR_INCREMENT, i*1024, ram_data);	}	return;} /* End of fnvHcRamBufferInit *//*--------------------------------------------------------------* * Host Controller Initialization functions  *--------------------------------------------------------------*//*--------------------------------------------------------------* * Host Controller Reset *--------------------------------------------------------------*/__u32 fnvPhciHostReset(phci_t *phci) {	__u32 uData;	__u32 uI;	__u32 uRetVal;	func_debug(("fnuHostReset(phci = 0x%p)\n",phci))	/* Set the HostController Reset bit in command status register */ 	fnvPhciHcorRead(phci,uHcCommandStatus,&uData); 	uData = HC_COMMAND_STATUS_HCR; 	fnvPhciHcorWrite(phci,uHcCommandStatus, uData);	/* wait some time for HC to be reset */ 	for(uI=0;uI<5000;uI++) {  		fnvPhciHcorRead(phci,uHcCommandStatus,&uData);  		if((uData & HC_COMMAND_STATUS_HCR) == 0) break; 	} 	uRetVal = uData & HC_COMMAND_STATUS_HCR; return uRetVal;} /* End of fnvPhciHostReset *//*--------------------------------------------------------------* * Host Controller hardware Interrupt Initialization *--------------------------------------------------------------*/void fnvHcIntEnable(phci_t *phci) {	__u32		uData;	func_debug(("fnvHcIntEnable(phci = 0x%p)\n",phci))	/* Clear all pending int. source */	uData = 0xFFFFFFFF;	phci_reg_write16(REG_IRQ, uData);	/* Enable int. according settings in host_conf.h */	uData = 0;			/* All int. are initially disabled */	uData |= ATL_INT;	/* Enable ATL interrupt *///	uData |= SOF_INT;	/* Enable ATL interrupt */	uData |= INTL_INT;	/* Enable INTL interrupt */	uData |= ISTL_0_INT;	/* Enable ITL interrupt */	uData |= ISTL_1_INT;	/* Enable ITL interrupt */	phci_reg_write16(REG_IRQ_MASK, uData);} /* End of fnvHcIntEnable() *//*--------------------------------------------------------------* * Host Controller Control Register Initialization *--------------------------------------------------------------*/void fnvHcControlInit(phci_t *phci) {	__u32 uData;	__u32 uHostConfigData;	func_debug(("fnvHcControlInit(phci = 0x%p)\n",phci))	uHostConfigData = 0;	/* Fill the control register of HC */	/* (1) Set the sate to operational */	uData = HC_STATE;	uHostConfigData &= (~HC_CONTROL_HCFS);	uHostConfigData |= (uData << 6);	/* (2)  Enable remote wakeup connection if opted */	uData = REMOTE_WAKEUP_CONN;	uHostConfigData &= (~HC_CONTROL_RWC);	if (uData == YES)		uHostConfigData |= HC_CONTROL_RWC;	/* (3)  Enable remote wakeup if opted */	uData = REMOTE_WAKEUP_ENABLE;	uHostConfigData &= (~HC_CONTROL_RWE);	if (uData == YES)		uHostConfigData |= HC_CONTROL_RWE;	fnvPhciHcorWrite(phci,uHcControl, uHostConfigData);	/* Configure the HCD transfer control registers uHcHcdControl and uHcHcdCommandStatus */	uHostConfigData = 0;				uData = PERIODIC_LIST_ENABLE;				/* Periodic list Enable ? */	if (uData == YES)		uHostConfigData |= HC_CONTROL_PLE;	uData = ISO_ENABLE;							/* Isochronous transfer enabled  ? */	if (uData == YES)		uHostConfigData |= HC_CONTROL_IE;	uData = CONTROL_LIST_ENABLE;				/* Control trasnfer enabled ? */

⌨️ 快捷键说明

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