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

📄 usb_phci.c

📁 philips公司ISP1362 USB OTG控制芯片的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
} /* 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;
	__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 read, return back */

	original_length = length;

	if(length%2)	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 

	isp1362_buff_read(isp1362_device, REG_DIRECT_ADDR_DATA, byte_data,original_length);

	return;
} /* End of fnvPhciRamRead */


/*--------------------------------------------------------------*
 * 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 */
                                                                                /* set the atl threshold ptd count */
	phci_reg_write16(REG_ATL_THRESHOLD_COUNT,1);


	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 |= OPR_INT;	/* Enable OPRational Reg  interrupt */

//	uData |= SOF_INT;	/* Enable SOF 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 ? */
	if (uData == YES)
		uHostConfigData |= HC_CONTROL_CLE;

	uData = BULK_LIST_ENABLE;					/* Bulk Transfer Enabled ? */
	if (uData == YES)
		uHostConfigData |= HC_CONTROL_BLE;

	/* Note: HC_CONTROL_TIP (Transfer In Progress) is alreday set to 0 */
	phci->hc_control = (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_PLE | OHCI_USB_OPER ;

	fnvPhciHcorWrite(phci,uHcHcdControl, uHostConfigData);

} /* End of fnvHcControlInit() */

/*--------------------------------------------------------------*
 * Host Controller Interrupt Register Initialization
 *--------------------------------------------------------------*/
void fnvHcInterruptInit(phci_t *phci) {

	__u32 uHostConfigData;

	func_debug(("fnvHcInterruptInit(phci = 0x%p)\n",phci))

	/* First of all, disable all interrupts */
	uHostConfigData = HC_INTERRUPT_ALL;
	fnvPhciHcorWrite(phci,uHcInterruptDisable, uHostConfigData);

	uHostConfigData = 0;

	/* Master Interrupt Enable */
	uHostConfigData |= HC_INTERRUPT_MIE;
	uHostConfigData |= HC_INTERRUPT_RHSC;

	/* Write the configuration to uHcInterruptEnable register */
	fnvPhciHcorWrite(phci,uHcInterruptEnable, uHostConfigData);

} /* End of fnvHcInterruptInit() */

/*--------------------------------------------------------------*
 * Host Controller Frame Number interval Initialization
 *--------------------------------------------------------------*/
void fnvHcFmIntervalInit(phci_t *phci) {

	__u32 uHostConfigData;

	func_debug(("fnvHcFmIntervalInit(phci = 0x%p)\n",phci))

	/* Determine the fram interval and the largest data size */
	uHostConfigData = FRAME_INTERVAL | (FS_LARGEST_DATA << 16);

	/* Write the configuration to uHcFmInterval register */
	fnvPhciHcorWrite(phci,uHcFmInterval, uHostConfigData);

} /* End of fnvHcFmIntervalInit() */


/*--------------------------------------------------------------*
 * Host Controller Roothub registers Initialization
 *--------------------------------------------------------------*/
void fnvHcRhPower(phci_t *phci) {

	__u32 uData;
	__u32 uHostConfigData;

	func_debug(("fnvHcRhPower(phci = 0x%p)\n",phci))

	/* Initialize the configuration data */
	uHostConfigData = 0;

	/* Enable or disable power switching */
	uData = PORT_POWER_SWITCHING;

	if (uData == NO)	/* No power switching; ports are always powered on when the HC is powered on */
		uHostConfigData |= HC_RH_DESCRIPTORA_NPS;

	else {

		/********************************************************/
		/* Power switching is enabled                           */
		/* Program root hub in per-port switching mode          */
		/********************************************************/
		uHostConfigData |= HC_RH_DESCRIPTORA_PSM;

	} /* else */


	/* Port over current protection */
	uData = OVER_CURRENT_PROTECTION;
	if (uData == NO)					/* No over current protection */
		uHostConfigData |= HC_RH_DESCRIPTORA_NOCP;

	else
		uData = PER_PORT_OVER_CURRENT_REPORT;
		if (uData == YES)
			uHostConfigData |= HC_RH_DESCRIPTORA_OCPM;

	/* Set the power on to power good time */
	uHostConfigData |= ((POWER_ON_TO_POWER_GOOD_TIME / 2) << 24);			/* Divided by 2, then move it into position */

	fnvPhciHcorWrite(phci,uHcRhDescriptorA, uHostConfigData);

	/* Set the global power to all the ports */
        uHostConfigData = RH_HS_LPSC;
        fnvPhciHcorWrite(phci,uHcRhStatus, uHostConfigData);

	/* Wait till the POWER ON TO POWER GOOD time */
        isp1362_mdelay(POWER_ON_TO_POWER_GOOD_TIME);


	/* Set the HcRhDescriptorB register (13h) */
	uHostConfigData = DEVICE_REMOVABLE;

	if (PORT_POWER_SWITCHING == YES)
		uHostConfigData |= 0xFFFF0000;		/* Set PPCM bits 31..16 to disable gang-mode power switching */

	fnvPhciHcorWrite(phci,uHcRhDescriptorB, uHostConfigData);

} /* End of fnvHcRhPower() */


/*--------------------------------------------------------------*
 * Host Controller Initialization
 *--------------------------------------------------------------*/
int	 fnuPhciHostInit(phci_t	*phci) {

	struct usb_device 	*usb_dev;

	func_debug(("fnuPhciHostInit(phci = 0x%p)\n",phci))

	/* 1. Host Controller Extended Registers Initialization */
	isp1362_set_hw_config(phci->phci_dev);

	fnvHcIntEnable(phci);

	fnvHcRamBufferInit(phci);

	phci_init_map_buffers(phci);

	fnvHcControlInit(phci);			 	/* Initialize HcControl register */
	
	phci->disabled = 0;

	fnvHcInterruptInit(phci);			/* Initialize HcInterruptEnable/Disable registers */

	fnvHcFmIntervalInit(phci);			/* Initialize HcFmInterval Register */

	fnvHcRhPower(phci);					/* Root hub port power switching mode */

	phci->rh.devnum = 0;				/* No root hub yet */

	phci->p_ed_controlhead = NULL;		/* Initialize control & bulk list heads */
	phci->p_ed_bulkhead = NULL;

	/* Allocate data structure for root hub */
	usb_dev = usb_alloc_dev ( NULL, phci->bus) ;
	
	if( !usb_dev ) {
		phci->disabled = 1;

⌨️ 快捷键说明

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