Ejemplo n.º 1
0
static __u32 USBC_Phy_TpWrite(__u32 usbc_no, __u32 addr, __u32 data, __u32 len)
{
	__u32 temp = 0, dtmp = 0;
	__u32 j=0;

	dtmp = data;
	for(j = 0; j < len; j++)
	{
		/* set  the bit address to be write */
		temp = USBC_Readl(USBC_Phy_GetCsr(usbc_no));
		temp &= ~(0xff << 8);
		temp |= ((addr + j) << 8);
		USBC_Writel(temp, USBC_Phy_GetCsr(usbc_no));

		temp = USBC_Readb(USBC_Phy_GetCsr(usbc_no));
		temp &= ~(0x1 << 7);
		temp |= (dtmp & 0x1) << 7;
		temp &= ~(0x1 << (usbc_no << 1));
		USBC_Writeb(temp, USBC_Phy_GetCsr(usbc_no));

		temp = USBC_Readb(USBC_Phy_GetCsr(usbc_no));
		temp |= (0x1 << (usbc_no << 1));
		USBC_Writeb( temp, USBC_Phy_GetCsr(usbc_no));

		temp = USBC_Readb(USBC_Phy_GetCsr(usbc_no));
		temp &= ~(0x1 << (usbc_no <<1 ));
		USBC_Writeb(temp, USBC_Phy_GetCsr(usbc_no));
		dtmp >>= 1;
	}

	return data;
}
/*
*******************************************************************************
*                     sw_hcd_port_suspend
*
* Description:
*    suspend USB port
*
* Parameters:
*    sw_hcd        :  input.  USB¿ØÖÆÆ÷
*    do_suspend  :  input.  flag. is suspend USB port or not?
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void sw_hcd_port_suspend(struct sw_hcd *sw_hcd, bool do_suspend)
{
    u8 power = 0;
	void __iomem *usbc_base = sw_hcd->mregs;

	if (!is_host_active(sw_hcd)){
	    DMSG_PANIC("ERR: usb host is not active\n");
	    return;
	}

	/* NOTE:  this doesn't necessarily put PHY into low power mode,
	 * turning off its clock; that's a function of PHY integration and
	 * sw_hcd_POWER_ENSUSPEND.  PHY may need a clock (sigh) to detect
	 * SE0 changing to connect (J) or wakeup (K) states.
	 */
    power = USBC_Readb(USBC_REG_PCTL(usbc_base));
	if (do_suspend) {
		int retries = 10000;

		DMSG_INFO("[sw_hcd]: suspend port.\n");

        power &= ~(1 << USBC_BP_POWER_H_RESUME);
		power |= (1 << USBC_BP_POWER_H_SUSPEND);
		USBC_Writeb(power, USBC_REG_PCTL(usbc_base));

		/* Needed for OPT A tests */
		power = USBC_Readb(USBC_REG_PCTL(usbc_base));
		while (power & (1 << USBC_BP_POWER_H_SUSPEND)) {
			power = USBC_Readb(USBC_REG_PCTL(usbc_base));
			if (retries-- < 1)
				break;
		}

	    DMSG_DBG_HCD("DBG: Root port suspended, power %02x\n", power);

		sw_hcd->port1_status |= USB_PORT_STAT_SUSPEND;
    }else if (power & (1 << USBC_BP_POWER_H_SUSPEND)){
		DMSG_INFO("[sw_hcd]: suspend portend, resume port.\n");

        power &= ~(1 << USBC_BP_POWER_H_SUSPEND);
		power |= (1 << USBC_BP_POWER_H_RESUME);
		USBC_Writeb(power, USBC_REG_PCTL(usbc_base));

		DMSG_DBG_HCD("DBG: Root port resuming, power %02x\n", power);

		/* later, GetPortStatus will stop RESUME signaling */
		sw_hcd->port1_status |= SW_HCD_PORT_STAT_RESUME;
		sw_hcd->rh_timer = jiffies + msecs_to_jiffies(20);
    }else{
        DMSG_PANIC("WRN: sw_hcd_port_suspend nothing to do\n");
    }

    return ;
}
Ejemplo n.º 3
0
static void __USBC_Host_ep0_ConfigEp_Default(__u32 usbc_base_addr)
{
    //--<1>--config ep0 csr
    USBC_Writew(1<<USBC_BP_CSR0_H_FlushFIFO, USBC_REG_CSR0(usbc_base_addr));

	//--<2>--config polling interval
	USBC_Writeb(0x00, USBC_REG_TXINTERVAL(usbc_base_addr));

    /* config ep transfer type */
	USBC_Writeb(0x00, USBC_REG_EP0TYPE(usbc_base_addr));
}
Ejemplo n.º 4
0
static void __USBC_Host_Tx_ClearEpDma(__u32 usbc_base_addr)
{
    __u16 ep_csr = 0;

	//auto_set, dma_tx_en, mode1
	ep_csr = USBC_Readb(USBC_REG_TXCSR(usbc_base_addr) + 1);
	ep_csr &= ~((1 << USBC_BP_TXCSR_H_AUTOSET) >> 8);
	ep_csr &= ~((1 << USBC_BP_TXCSR_H_DMA_REQ_EN) >> 8);
	USBC_Writeb(ep_csr, (USBC_REG_TXCSR(usbc_base_addr) + 1));

	//DMA_REQ_EN和DMA_REQ_MODE不能在同一个cycle中清除
	ep_csr = USBC_Readb(USBC_REG_TXCSR(usbc_base_addr) + 1);
	ep_csr &= ~((1 << USBC_BP_TXCSR_H_DMA_REQ_MODE) >> 8);
	USBC_Writeb(ep_csr, (USBC_REG_TXCSR(usbc_base_addr) + 1));
}
Ejemplo n.º 5
0
static void __USBC_Host_Rx_ConfigEp(__u32 usbc_base_addr, __u32 ep_index, __u32 ts_mode, __u32 ts_type, __u32 is_double_fifo, __u32 ep_MaxPkt, __u32 interval)
{
    __u16 reg_val = 0;
	__u16 temp = 0;

	//--<1>--config rx_csr
    USBC_Writew((1 << USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_H_FLUSH_FIFO),
                USBC_REG_RXCSR(usbc_base_addr));

	if(is_double_fifo){
		USBC_Writew((1 << USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_H_FLUSH_FIFO),
                    USBC_REG_RXCSR(usbc_base_addr));
	}

	//--<2>--config tx ep max packet
	reg_val = USBC_Readw(USBC_REG_RXMAXP(usbc_base_addr));
	temp    = ep_MaxPkt & ((1 << USBC_BP_RXMAXP_PACKET_COUNT) - 1);
	reg_val |= temp;
	USBC_Writew(reg_val, USBC_REG_RXMAXP(usbc_base_addr));

	//--<3>--config ep transfer type
	__USBC_Host_Rx_EpType(usbc_base_addr, ep_index, ts_mode, ts_type);

	//--<4>--config polling interval
	USBC_Writeb(interval, USBC_REG_RXINTERVAL(usbc_base_addr));
}
Ejemplo n.º 6
0
static void __USBC_Host_Tx_ConfigEp_Default(__u32 usbc_base_addr)
{
	//--<1>--config tx_csr, flush fifo, clear all to 0
	USBC_Writew((1 << USBC_BP_TXCSR_H_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_TXCSR_H_FLUSH_FIFO),
	USBC_REG_TXCSR(usbc_base_addr));

	USBC_Writew(0x00, USBC_REG_TXCSR(usbc_base_addr));

	//--<2>--config tx ep max packet
	USBC_Writew(0x00, USBC_REG_TXMAXP(usbc_base_addr));

	//--<3>--config ep transfer type
	USBC_Writeb(0x00, USBC_REG_TXTYPE(usbc_base_addr));

	//--<4>--config polling interval
	USBC_Writeb(0x00, USBC_REG_TXINTERVAL(usbc_base_addr));
}
Ejemplo n.º 7
0
static __u32 usb_phy0_write(__u32 addr, __u32 data, __u32 dmask, __u32 usbc_base_addr)
{
	__u32 i=0;

	data = data & 0x0f;
	addr = addr & 0x0f;
	dmask = dmask & 0x0f;

	USBC_Writeb((dmask<<4)|data, usbc_base_addr + 0x404 + 2);
	USBC_Writeb(addr|0x10, usbc_base_addr + 0x404);
	for(i=0;i<5;i++);
	USBC_Writeb(addr|0x30, usbc_base_addr + 0x404);
	for(i=0;i<5;i++);
	USBC_Writeb(addr|0x10, usbc_base_addr + 0x404);
	for(i=0;i<5;i++);
	return (USBC_Readb(usbc_base_addr + 0x404 + 3) & 0x0f);
}
Ejemplo n.º 8
0
static void __USBC_Host_Rx_ConfigEp_Default(__u32 usbc_base_addr)
{
	//--<1>--config rx_csr, 先刷fifo, 有全部清零
    USBC_Writew((1 << USBC_BP_RXCSR_H_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_H_FLUSH_FIFO),
                USBC_REG_RXCSR(usbc_base_addr));

	USBC_Writew(0x00, USBC_REG_RXCSR(usbc_base_addr));

	//--<2>--config rx ep max packet
	USBC_Writew(0x00, USBC_REG_RXMAXP(usbc_base_addr));

	//--<3>--config ep transfer type
	USBC_Writeb(0x00, USBC_REG_RXTYPE(usbc_base_addr));

	//--<4>--config polling interval
	USBC_Writeb(0x00, USBC_REG_RXINTERVAL(usbc_base_addr));
}
Ejemplo n.º 9
0
/*
***********************************************************************************
*                     USBC_Dev_SetAddress_default
*
* Description:
*    清除host给device分配的地址
*
* Arguments:
*    hUSB       :  input.  USBC_open_otg获得的句柄, 记录了USBC所需要的一些关键数据
*
* Returns:
*
*
* note:
*    无
*
***********************************************************************************
*/
void USBC_Dev_SetAddress_default(__hdle hUSB)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;

	if(usbc_otg == NULL){
		return;
	}

    USBC_Writeb(0x00, USBC_REG_FADDR(usbc_otg->base_addr));
}
Ejemplo n.º 10
0
/*
***********************************************************************************
*                     USBC_Dev_SetAddress
*
* Description:
*    设置地址
*
* Arguments:
*    hUSB       :  input.  USBC_open_otg获得的句柄, 记录了USBC所需要的一些关键数据
*    address    :  input.  host分配的地址
*
* Returns:
*
*
* note:
*    无
*
***********************************************************************************
*/
void USBC_Dev_SetAddress(__hdle hUSB, __u8 address)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;

	if(usbc_otg == NULL){
		return;
	}

    USBC_Writeb(address, USBC_REG_FADDR(usbc_otg->base_addr));
}
Ejemplo n.º 11
0
static void __USBC_Host_ep0_ConfigEp(__u32 usbc_base_addr, __u32 ts_mode, __u32 interval)
{
    //--<1>--config ep0 csr
    USBC_Writew(1<<USBC_BP_CSR0_H_FlushFIFO, USBC_REG_CSR0(usbc_base_addr));

	//--<2>--config polling interval
	USBC_Writeb(interval, USBC_REG_NAKLIMIT0(usbc_base_addr));

    /* config ep0 transfer type */
	__USBC_Host_ep0_EpType(usbc_base_addr, ts_mode);
}
Ejemplo n.º 12
0
static void __USBC_Dev_Rx_ClearEpDma(ulong usbc_base_addr)
{
    __u16 ep_csr = 0;

    //auto_clear, dma_rx_en, mode0
	ep_csr = USBC_Readb(USBC_REG_RXCSR(usbc_base_addr) + 1);
	ep_csr &= ~((1 << USBC_BP_RXCSR_D_AUTO_CLEAR) >> 8);
	ep_csr &= ~((1 << USBC_BP_RXCSR_D_DMA_REQ_MODE) >> 8);
	ep_csr &= ~((1 << USBC_BP_RXCSR_D_DMA_REQ_EN) >> 8);
	USBC_Writeb(ep_csr, (USBC_REG_RXCSR(usbc_base_addr) + 1));
}
Ejemplo n.º 13
0
void USBC_Host_SetHPortAddress(__hdle hUSB, __u32 ep_type, __u32 ep_index, __u8 address)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;

	if(usbc_otg == NULL){
		return;
	}

	switch(ep_type){
		case USBC_EP_TYPE_TX:
			USBC_Writeb(address, USBC_REG_TXHPORTx(usbc_otg->base_addr, ep_index));
		break;

		case USBC_EP_TYPE_RX:
			USBC_Writeb(address, USBC_REG_RXHPORTx(usbc_otg->base_addr, ep_index));
		break;

		default:
		break;
	}
}
Ejemplo n.º 14
0
void USBC_Host_SetHubAddress(__hdle hUSB, __u32 ep_type, __u32 ep_index, __u32 is_mutli_tt, __u8 address)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;

	if(usbc_otg == NULL){
		return;
	}

	switch(ep_type){
		case USBC_EP_TYPE_TX:
			USBC_Writeb(((is_mutli_tt << USBC_BP_HADDR_MULTI_TT) | address), USBC_REG_TXHADDRx(usbc_otg->base_addr, ep_index));
		break;

		case USBC_EP_TYPE_RX:
			USBC_Writeb(((is_mutli_tt << USBC_BP_HADDR_MULTI_TT) | address), USBC_REG_RXHADDRx(usbc_otg->base_addr, ep_index));
		break;

		default:
		break;
	}
}
Ejemplo n.º 15
0
void USBC_Host_SetHubAddress_Deafult(__hdle hUSB, __u32 ep_type, __u32 ep_index)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;

	if(usbc_otg == NULL){
		return;
	}

	switch(ep_type){
		case USBC_EP_TYPE_TX:
			USBC_Writeb(0x00, USBC_REG_TXHADDRx(usbc_otg->base_addr, ep_index));
		break;

		case USBC_EP_TYPE_RX:
			USBC_Writeb(0x00, USBC_REG_RXHADDRx(usbc_otg->base_addr, ep_index));
		break;

		default:
		break;
	}
}
Ejemplo n.º 16
0
static void __USBC_Host_Tx_ConfigEpDma(__u32 usbc_base_addr)
{
    __u16 ep_csr = 0;

	//auto_set, tx_mode, dma_tx_en, mode1
	ep_csr = USBC_Readb(USBC_REG_TXCSR(usbc_base_addr) + 1);
	ep_csr |= (1 << USBC_BP_TXCSR_H_AUTOSET) >> 8;
	ep_csr |= (1 << USBC_BP_TXCSR_H_MODE) >> 8;
	ep_csr |= (1 << USBC_BP_TXCSR_H_DMA_REQ_EN) >> 8;
	ep_csr |= (1 << USBC_BP_TXCSR_H_DMA_REQ_MODE) >> 8;
	USBC_Writeb(ep_csr, (USBC_REG_TXCSR(usbc_base_addr) + 1));
}
Ejemplo n.º 17
0
static void __USBC_Host_Rx_ConfigEpDma(__u32 usbc_base_addr)
{
    __u16 ep_csr = 0;

    //配置dma, auto_clear, dma_rx_en, mode1,
	ep_csr = USBC_Readb(USBC_REG_RXCSR(usbc_base_addr) + 1);
	ep_csr |= (1 << USBC_BP_RXCSR_H_AUTO_CLEAR) >> 8;
	ep_csr |= (1 << USBC_BP_RXCSR_H_AUTO_REQ) >> 8;
//	ep_csr &= ~((1 << USBC_BP_RXCSR_H_DMA_REQ_MODE) >> 8);
	ep_csr |= ((1 << USBC_BP_RXCSR_H_DMA_REQ_MODE) >> 8);
	ep_csr |= (1 << USBC_BP_RXCSR_H_DMA_REQ_EN) >> 8;
	USBC_Writeb(ep_csr, (USBC_REG_RXCSR(usbc_base_addr) + 1));
}
Ejemplo n.º 18
0
/*
 ***************************************************************************
 *
 * read out one bit of USB PHY register
 *
 ***************************************************************************
 */
static __u32 __USBC_PHY_REG_READ(__u32 usbc_base_addr, __u32 usbc_phy_reg_addr)
{
  	__u32 reg_val = 0;
  	__u32 i = 0;

  	USBC_Writeb(usbc_phy_reg_addr, USBC_REG_PHYCTL(USBC0_REGS_BASE) + 1);
  	for(i=0; i<0x4; i++);
  	reg_val = USBC_Readb(USBC_REG_PHYCTL(USBC0_REGS_BASE) + 2);
  	if(usbc_base_addr == USBC0_REGS_BASE)
  		return (reg_val & 0x1);
  	else
  		return ((reg_val >> 1) & 0x1);
}
Ejemplo n.º 19
0
static void __USBC_Host_Rx_EpType(__u32 usbc_base_addr, __u32 ep_index, __u32 ts_mode, __u32 ts_type)
{
    __u32 reg_val = 0;

	/* config transfer speed */
	switch(ts_mode){
		case USBC_TS_MODE_HS:
			reg_val |= 0x01 << USBC_BP_RXTYPE_SPEED;
		break;

		case USBC_TS_MODE_FS:
			reg_val |= 0x02 << USBC_BP_RXTYPE_SPEED;
		break;

		case USBC_TS_MODE_LS:
			reg_val |= 0x03 << USBC_BP_RXTYPE_SPEED;
		break;

		default:
			reg_val = 0;
	}

    //--<1>--config protocol
    switch(ts_type){
		case USBC_TS_TYPE_ISO:
		    reg_val |= 0x1 << USBC_BP_RXTYPE_PROROCOL;
	    break;

		case USBC_TS_TYPE_BULK:
		    reg_val |= 0x2 << USBC_BP_RXTYPE_PROROCOL;
		break;

		case USBC_TS_TYPE_INT:
		    reg_val |= 0x3 << USBC_BP_RXTYPE_PROROCOL;
		break;

		default:
		break;
	}

	//--<2>--config target ep number
	reg_val |= ep_index;

	USBC_Writeb(reg_val, USBC_REG_RXTYPE(usbc_base_addr));
}
Ejemplo n.º 20
0
static void __USBC_Host_ep0_EpType(__u32 usbc_base_addr, __u32 ts_mode)
{
    __u32 reg_val = 0;

	/* config transfer speed */
	switch(ts_mode){
		case USBC_TS_MODE_HS:
			reg_val |= 0x01 << USBC_BP_RXTYPE_SPEED;
		break;

		case USBC_TS_MODE_FS:
			reg_val |= 0x02 << USBC_BP_RXTYPE_SPEED;
		break;

		case USBC_TS_MODE_LS:
			reg_val |= 0x03 << USBC_BP_RXTYPE_SPEED;
		break;

		default:
			reg_val = 0;
	}

	USBC_Writeb(reg_val, USBC_REG_EP0TYPE(usbc_base_addr));
}
Ejemplo n.º 21
0
/*
 ***************************************************************************
 *
 * Write one bit of USB PHY register
 *
 ***************************************************************************
 */
static void __USBC_PHY_REG_WRITE(__u32 usbc_base_addr, __u32 usbc_phy_reg_addr, __u32 usbc_phy_reg_data)
{
  	__u32 reg_val = 0;

  	USBC_Writeb(usbc_phy_reg_addr, USBC_REG_PHYCTL(USBC0_REGS_BASE) + 1);
  	reg_val = USBC_Readb(USBC_REG_PHYCTL(USBC0_REGS_BASE));
  	reg_val &= ~(0x1 << 7);
  	reg_val |= (usbc_phy_reg_data & 0x1) << 7;
  	if(usbc_base_addr == USBC0_REGS_BASE){
  		reg_val &= ~0x1;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  		reg_val |= 0x1;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  		reg_val &= ~0x1;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  	}else{
  		reg_val &= ~0x2;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  		reg_val |= 0x2;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  		reg_val &= ~0x2;
  		USBC_Writeb(reg_val, USBC_REG_PHYCTL(USBC0_REGS_BASE));
  	}
}
Ejemplo n.º 22
0
void USBC_Host_SetFunctionAddress(__hdle hUSB,
								  __u32 EpType,
								  __u32 EpIndex,
								  __u32 FunctionAdress,
								  __u32 MultiTT,
								  __u32 HubAddress,
								  __u32 HubPortNumber)
{
    __usbc_otg_t *usbc_otg = (__usbc_otg_t *)hUSB;
	__u8 temp_8 = 0;

	if(usbc_otg == NULL){
		return;
	}

	if(MultiTT){
		temp_8 = 1 << USBC_BP_HADDR_MULTI_TT;
	}

	temp_8 |= HubAddress;

	switch(EpType){
		case USBC_EP_TYPE_TX:
			USBC_Writeb(FunctionAdress, USBC_REG_TXFADDRx(usbc_otg->base_addr, EpIndex));
			USBC_Writeb(temp_8, USBC_REG_TXHADDRx(usbc_otg->base_addr, EpIndex));
			USBC_Writeb(HubPortNumber, USBC_REG_TXHPORTx(usbc_otg->base_addr, EpIndex));
		break;

		case USBC_EP_TYPE_RX:
			USBC_Writeb(FunctionAdress, USBC_REG_RXFADDRx(usbc_otg->base_addr, EpIndex));
			USBC_Writeb(temp_8, USBC_REG_RXHADDRx(usbc_otg->base_addr, EpIndex));
			USBC_Writeb(HubPortNumber, USBC_REG_RXHPORTx(usbc_otg->base_addr, EpIndex));
		break;

		default:
		break;
	}
}
/*
*******************************************************************************
*                     sw_hcd_port_reset
*
* Description:
*    reset USB port
*
* Parameters:
*    sw_hcd       :  input.  USB¿ØÖÆÆ÷
*    do_reset   :  input.  flag. is reset USB port or not?
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void sw_hcd_port_reset(struct sw_hcd *sw_hcd, bool do_reset)
{
    u8 power = 0;
	void __iomem *usbc_base = sw_hcd->mregs;

	if (!is_host_active(sw_hcd)){
	    DMSG_PANIC("ERR: usb host is not active\n");
	    return;
	}

	/* NOTE:  caller guarantees it will turn off the reset when
	 * the appropriate amount of time has passed
	 */
	power = USBC_Readb(USBC_REG_PCTL(usbc_base));
	if (do_reset) {
        DMSG_INFO("[sw_hcd]: reset port. \n");

		/*
		 * If RESUME is set, we must make sure it stays minimum 20 ms.
		 * Then we must clear RESUME and wait a bit to let sw_hcd start
		 * generating SOFs. If we don't do this, OPT HS A 6.8 tests
		 * fail with "Error! Did not receive an SOF before suspend
		 * detected".
		 */
		if (power & (1 << USBC_BP_POWER_H_RESUME)) {
			while (time_before(jiffies, sw_hcd->rh_timer)){
			    msleep(1);
			}

            power &= ~(1 << USBC_BP_POWER_H_RESUME);
			USBC_Writeb(power, USBC_REG_PCTL(usbc_base));
			msleep(1);
		}

		sw_hcd->ignore_disconnect = true;
		power &= 0xf0;
		power |= (1 << USBC_BP_POWER_H_RESET);
        USBC_Writeb(power, USBC_REG_PCTL(usbc_base));

        sw_hcd->port1_status |= USB_PORT_STAT_RESET;
		sw_hcd->port1_status &= ~USB_PORT_STAT_ENABLE;
		sw_hcd->rh_timer = jiffies + msecs_to_jiffies(50);

		USBC_Host_SetFunctionAddress_Deafult(sw_hcd->sw_hcd_io->usb_bsp_hdle, USBC_EP_TYPE_TX, 0);

		//set address ep0
		{
		    __u32 i = 1;
			__u8 old_ep_index = 0;

			old_ep_index = USBC_GetActiveEp(sw_hcd->sw_hcd_io->usb_bsp_hdle);

			USBC_SelectActiveEp(sw_hcd->sw_hcd_io->usb_bsp_hdle, 0);
			USBC_Host_SetFunctionAddress_Deafult(sw_hcd->sw_hcd_io->usb_bsp_hdle, USBC_EP_TYPE_TX, 0);

			for( i = 1 ; i <= 5; i++){
				USBC_SelectActiveEp(sw_hcd->sw_hcd_io->usb_bsp_hdle, i);
				USBC_Host_SetFunctionAddress_Deafult(sw_hcd->sw_hcd_io->usb_bsp_hdle, USBC_EP_TYPE_TX, i);
				USBC_Host_SetFunctionAddress_Deafult(sw_hcd->sw_hcd_io->usb_bsp_hdle, USBC_EP_TYPE_RX, i);
			}

			USBC_SelectActiveEp(sw_hcd->sw_hcd_io->usb_bsp_hdle, old_ep_index);
		}
    }else{
        DMSG_INFO("[sw_hcd]: reset port stopped.\n");

        UsbPhyEndReset(0);

        power &= ~(1 << USBC_BP_POWER_H_RESET);
        USBC_Writeb(power, USBC_REG_PCTL(usbc_base));

        sw_hcd->ignore_disconnect = false;

        power = USBC_Readb(USBC_REG_PCTL(usbc_base));
        if(power & (1 << USBC_BP_POWER_H_HIGH_SPEED_FLAG)){
            DMSG_DBG_HCD("high-speed device connected\n");
			sw_hcd->port1_status |= USB_PORT_STAT_HIGH_SPEED;
        }

        sw_hcd->port1_status &= ~USB_PORT_STAT_RESET;
		sw_hcd->port1_status |= USB_PORT_STAT_ENABLE
					| (USB_PORT_STAT_C_RESET << 16)
					| (USB_PORT_STAT_C_ENABLE << 16);
		usb_hcd_poll_rh_status(sw_hcd_to_hcd(sw_hcd));

		sw_hcd->vbuserr_retry = VBUSERR_RETRY_COUNT;
    }

    return ;
}
/*
*******************************************************************************
*                     sw_hcd_hub_control
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
int sw_hcd_hub_control(struct usb_hcd	*hcd,
                     u16 typeReq,
                     u16 wValue,
                     u16 wIndex,
                     char *buf,
                     u16 wLength)
{
	struct sw_hcd	*sw_hcd = hcd_to_sw_hcd(hcd);
	u32 temp = 0;
	int retval = 0;
	unsigned long flags = 0;
	void __iomem *usbc_base = sw_hcd->mregs;

    if(hcd == NULL){
        DMSG_PANIC("ERR: invalid argment\n");

        return -ESHUTDOWN;
    }

	spin_lock_irqsave(&sw_hcd->lock, flags);

    if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) {
		spin_unlock_irqrestore(&sw_hcd->lock, flags);
		return -ESHUTDOWN;
	}

    DMSG_DBG_HCD("sw_hcd_hub_control: typeReq = %x, wValue = 0x%x, wIndex = 0x%x\n",
		       typeReq, wValue, wIndex);

	/* hub features:  always zero, setting is a NOP
	 * port features: reported, sometimes updated when host is active
	 * no indicators
	 */
	switch (typeReq) {
        case ClearHubFeature:
    	case SetHubFeature:
    		switch (wValue) {
        		case C_HUB_OVER_CURRENT:
        		case C_HUB_LOCAL_POWER:
        			break;

        		default:
        			goto error;
    		}
        break;

    	case ClearPortFeature:
    		if ((wIndex & 0xff) != 1){
    		    goto error;
    		}

    		switch (wValue) {
        		case USB_PORT_FEAT_ENABLE:
        	    break;

    		    case USB_PORT_FEAT_SUSPEND:
    			    sw_hcd_port_suspend(sw_hcd, false);
    			break;

    		    case USB_PORT_FEAT_POWER:
					/* fixme */
				    sw_hcd_set_vbus(sw_hcd, 0);
    			break;

        		case USB_PORT_FEAT_C_CONNECTION:
        		case USB_PORT_FEAT_C_ENABLE:
        		case USB_PORT_FEAT_C_OVER_CURRENT:
        		case USB_PORT_FEAT_C_RESET:
        		case USB_PORT_FEAT_C_SUSPEND:
    			break;

        		default:
        			goto error;
    		}

    		DMSG_DBG_HCD("DBG: clear feature %d\n", wValue);
    		sw_hcd->port1_status &= ~(1 << wValue);
        break;

    	case GetHubDescriptor:
        {
    		struct usb_hub_descriptor *desc = (void *)buf;

    		desc->bDescLength = 9;
    		desc->bDescriptorType = 0x29;
    		desc->bNbrPorts = 1;
    		desc->wHubCharacteristics = cpu_to_le16(
    				  0x0001	/* per-port power switching */
    				| 0x0010	/* no overcurrent reporting */
    				);
    		desc->bPwrOn2PwrGood = 5;	/* msec/2 */
    		desc->bHubContrCurrent = 0;

    		/* workaround bogus struct definition */
    		desc->u.hs.DeviceRemovable[0] = 0x02;	/* port 1 */
    		desc->u.hs.DeviceRemovable[1] = 0xff;
        }
		break;

	    case GetHubStatus:
		    temp = 0;
		    *(__le32 *) buf = cpu_to_le32(temp);
		break;

	    case GetPortStatus:
	    {
    		if (wIndex != 1){
    		    DMSG_PANIC("ERR: GetPortStatus parameter wIndex is not 1.\n");
    		    goto error;
    		}

    		/* finish RESET signaling? */
    		if ((sw_hcd->port1_status & USB_PORT_STAT_RESET)
    				&& time_after_eq(jiffies, sw_hcd->rh_timer)){
    			sw_hcd_port_reset(sw_hcd, false);
    		}

    		/* finish RESUME signaling? */
    		if ((sw_hcd->port1_status & SW_HCD_PORT_STAT_RESUME)
    				&& time_after_eq(jiffies, sw_hcd->rh_timer)) {
    			u8 power = 0;

    			power = USBC_Readb(USBC_REG_PCTL(usbc_base));
				power &= ~(1 << USBC_BP_POWER_H_RESUME);
    			USBC_Writeb(power, USBC_REG_PCTL(usbc_base));

    			DMSG_DBG_HCD("DBG: root port resume stopped, power %02x\n", power);

    			/* ISSUE:  DaVinci (RTL 1.300) disconnects after
    			 * resume of high speed peripherals (but not full
    			 * speed ones).
    			 */

    			sw_hcd->is_active = 1;
    			sw_hcd->port1_status &= ~(USB_PORT_STAT_SUSPEND
    					| SW_HCD_PORT_STAT_RESUME);
    			sw_hcd->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;

    			usb_hcd_poll_rh_status(sw_hcd_to_hcd(sw_hcd));
    		}

    		put_unaligned(cpu_to_le32(sw_hcd->port1_status
    					& ~SW_HCD_PORT_STAT_RESUME),
    				(__le32 *) buf);

    		/* port change status is more interesting */
    		DMSG_DBG_HCD("DBG: port status %08x\n", sw_hcd->port1_status);
    	}
		break;

	    case SetPortFeature:
	    {
    		if ((wIndex & 0xff) != 1){
    		    goto error;
    		}

    		switch (wValue) {
    		    case USB_PORT_FEAT_POWER:
        			/* NOTE: this controller has a strange state machine
        			 * that involves "requesting sessions" according to
        			 * magic side effects from incompletely-described
        			 * rules about startup...
        			 *
        			 * This call is what really starts the host mode; be
        			 * very careful about side effects if you reorder any
        			 * initialization logic, e.g. for OTG, or change any
        			 * logic relating to VBUS power-up.
        			 */

        			sw_hcd_start(sw_hcd);

    			break;

    		    case USB_PORT_FEAT_RESET:
    			    sw_hcd_port_reset(sw_hcd, true);
    			break;

    		    case USB_PORT_FEAT_SUSPEND:
    			    sw_hcd_port_suspend(sw_hcd, true);
    			break;

    		    case USB_PORT_FEAT_TEST:
    		    {
    			    if (unlikely(is_host_active(sw_hcd))){
    			        DMSG_PANIC("ERR: usb host is not active\n");
    				    goto error;
    				}

    			    wIndex >>= 8;
        			switch (wIndex) {
            			case 1:
            				DMSG_DBG_HCD("TEST_J\n");
            				temp =  1 << USBC_BP_TMCTL_TEST_J;
        				break;

            			case 2:
            				DMSG_DBG_HCD("TEST_K\n");
            				temp = 1 << USBC_BP_TMCTL_TEST_K;
        				break;

            			case 3:
            				DMSG_DBG_HCD("TEST_SE0_NAK\n");
            				temp = 1 << USBC_BP_TMCTL_TEST_SE0_NAK;
        				break;

            			case 4:
            				DMSG_DBG_HCD("TEST_PACKET\n");
            				temp = 1 << USBC_BP_TMCTL_TEST_PACKET;
            				sw_hcd_load_testpacket(sw_hcd);
        				break;

            			case 5:
            				DMSG_DBG_HCD("TEST_FORCE_ENABLE\n");
            				temp = (1 << USBC_BP_TMCTL_FORCE_HOST)
            					| (1 << USBC_BP_TMCTL_FORCE_HS);

            			    USBC_REG_set_bit_b(USBC_BP_DEVCTL_SESSION, USBC_REG_DEVCTL(usbc_base));
        				break;

            			case 6:
            				DMSG_DBG_HCD("TEST_FIFO_ACCESS\n");
            				temp = 1 << USBC_BP_TMCTL_FIFO_ACCESS;
        				break;

        			    default:
        				    DMSG_PANIC("ERR: unkown SetPortFeature USB_PORT_FEAT_TEST wIndex(%d)\n", wIndex);
    			            goto error;
        			}

    			    USBC_Writeb(temp, USBC_REG_TMCTL(usbc_base));
    			}
    			break;

    		    default:{
    		        DMSG_PANIC("ERR: unkown SetPortFeature wValue(%d)\n", wValue);
    			    goto error;
    			}
    		}

    		DMSG_DBG_HCD("DBG: set feature %d\n", wValue);
    		sw_hcd->port1_status |= 1 << wValue;
	    }
		break;

	default:
error:
		DMSG_PANIC("ERR: protocol stall on error\n");

		/* "protocol stall" on error */
		retval = -EPIPE;
	}

	spin_unlock_irqrestore(&sw_hcd->lock, flags);

    return retval;
}
Ejemplo n.º 25
0
void clear_usb_reg(__u32 usb_base)
{
	__u32 reg_val = 0;
	__u32 i = 0;

	/* global control and status */
	reg_val = USBC_Readl(USBC_REG_EX_USB_GCS(usb_base));
	reg_val = 0x20;
	USBC_Writel(reg_val, USBC_REG_EX_USB_GCS(usb_base));

	/* endpoint interrupt flag */
	reg_val = USBC_Readl(USBC_REG_EX_USB_EPINTF(usb_base));
	reg_val = 0x44;
	USBC_Writel(reg_val, USBC_REG_EX_USB_EPINTF(usb_base));

	/* endpoint interrupt enable */
	reg_val = USBC_Readl(USBC_REG_EX_USB_EPINTE(usb_base));
	reg_val = 0x48;
	USBC_Writel(reg_val, USBC_REG_EX_USB_EPINTE(usb_base));

	/* bus interrupt flag */
	reg_val = USBC_Readl(USBC_REG_EX_USB_BUSINTF(usb_base));
	reg_val = 0x4c;
	USBC_Writel(reg_val, USBC_REG_EX_USB_BUSINTF(usb_base));

	/* bus interrupt enable */
	reg_val = USBC_Readl(USBC_REG_EX_USB_BUSINTE(usb_base));
	reg_val = 0x50;
	USBC_Writel(reg_val, USBC_REG_EX_USB_BUSINTE(usb_base));

	/* endpoint control status */
	for(i = 0; i < USBC_MAX_EP_NUM; i++) {
		USBC_Writeb(i, USBC_REG_EPIND(usb_base));

		/* endpoint control status */
		if (i == 0) {
			reg_val = USBC_Readl(USBC_REG_EX_USB_CSR0(usb_base));
			reg_val = 0x00;
			USBC_Writel(reg_val, USBC_REG_EX_USB_CSR0(usb_base));
		} else {
			/* TX endpoint control status */
			reg_val = USBC_Readl(USBC_REG_EX_USB_TXCSR(usb_base));
			reg_val = 0x00;
			USBC_Writel(reg_val, USBC_REG_EX_USB_TXCSR(usb_base));

			/* RX endpoint control status */
			reg_val = USBC_Readl(USBC_REG_EX_USB_RXCSR(usb_base));
			reg_val = 0x00;
			USBC_Writel(reg_val, USBC_REG_EX_USB_RXCSR(usb_base));
		}

		/* TX fifo seting */
		reg_val = USBC_Readl(USBC_REG_EX_USB_TXFIFO(usb_base));
		reg_val = 0x90;
		USBC_Writel(reg_val, USBC_REG_EX_USB_TXFIFO(usb_base));

		/* RX fifo seting */
		reg_val = USBC_Readl(USBC_REG_EX_USB_RXFIFO(usb_base));
		reg_val = 0x94;
		USBC_Writel(reg_val, USBC_REG_EX_USB_RXFIFO(usb_base));

		/* function address */
		reg_val = USBC_Readl(USBC_REG_EX_USB_FADDR(usb_base));
		reg_val = 0x00;
		USBC_Writel(reg_val, USBC_REG_EX_USB_FADDR(usb_base));
	}

	USBC_Writeb(0x00, USBC_REG_EPIND(usb_base));
	return;
}