void musb_otg_set_session(bool set){
    unsigned char devctl = musb_readb (mtk_musb->mregs, MUSB_DEVCTL);
    if(set)
        devctl |= MUSB_DEVCTL_SESSION;
    else
        devctl &= ~MUSB_DEVCTL_SESSION;
    musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
    return;
}
Exemplo n.º 2
0
void usb_reset_root_port(void)
{
	void *mbase = host->mregs;
	u8 power;

	power = musb_readb(mbase, MUSB_POWER);
	power &= 0xf0;
	musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
	mdelay(50);
	power = musb_readb(mbase, MUSB_POWER);
	musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
	host->isr(0, host);
	host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
			USB_SPEED_HIGH :
			(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
			USB_SPEED_FULL : USB_SPEED_LOW;
	mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
}
Exemplo n.º 3
0
static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
{
	u8	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);

	devctl |= MUSB_DEVCTL_SESSION;
	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);

	return 0;
}
Exemplo n.º 4
0
static void otg_timer(unsigned long _musb)
{
    struct musb		*musb = (void *)_musb;
    void __iomem		*mregs = musb->mregs;
    u8			devctl;
    unsigned long		flags;

    /* We poll because DaVinci's won't expose several OTG-critical
    * status change events (from the transceiver) otherwise.
     */
    devctl = musb_readb(mregs, MUSB_DEVCTL);
    DBG(7, "poll devctl %02x (%s)\n", devctl, otg_state_string(musb));

    spin_lock_irqsave(&musb->lock, flags);
    switch (musb->xceiv.state) {
    case OTG_STATE_A_WAIT_VFALL:
        /* Wait till VBUS falls below SessionEnd (~0.2V); the 1.3 RTL
         * seems to mis-handle session "start" otherwise (or in our
         * case "recover"), in routine "VBUS was valid by the time
         * VBUSERR got reported during enumeration" cases.
         */
        if (devctl & MUSB_DEVCTL_VBUS) {
            mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
            break;
        }
        musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
        musb_writel(musb->ctrl_base, DAVINCI_USB_INT_SET_REG,
                    MUSB_INTR_VBUSERROR << DAVINCI_USB_USBINT_SHIFT);
        break;
    case OTG_STATE_B_IDLE:
        if (!is_peripheral_enabled(musb))
            break;

        /* There's no ID-changed IRQ, so we have no good way to tell
         * when to switch to the A-Default state machine (by setting
         * the DEVCTL.SESSION flag).
         *
         * Workaround:  whenever we're in B_IDLE, try setting the
         * session flag every few seconds.  If it works, ID was
         * grounded and we're now in the A-Default state machine.
         *
         * NOTE setting the session flag is _supposed_ to trigger
         * SRP, but clearly it doesn't.
         */
        musb_writeb(mregs, MUSB_DEVCTL,
                    devctl | MUSB_DEVCTL_SESSION);
        devctl = musb_readb(mregs, MUSB_DEVCTL);
        if (devctl & MUSB_DEVCTL_BDEVICE)
            mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
        else
            musb->xceiv.state = OTG_STATE_A_IDLE;
        break;
    default:
        break;
    }
    spin_unlock_irqrestore(&musb->lock, flags);
}
Exemplo n.º 5
0
/*
 * Tries to start B-device HNP negotiation if enabled via sysfs
 */
static inline void musb_try_b_hnp_enable(struct musb *musb)
{
	void __iomem	*mbase = musb->mregs;
	u8		devctl;

	DBG(1, "HNP: Setting HR\n");
	devctl = musb_readb(mbase, MUSB_DEVCTL);
	musb_writeb(mbase, MUSB_DEVCTL, devctl | MUSB_DEVCTL_HR);
}
int musb_platform_set_mode(struct musb *musb, u8 musb_mode)
{
	u8	devctl = musb_readb(musb->mregs, MUSB_DEVCTL);

	devctl |= MUSB_DEVCTL_SESSION;
	musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);

	return 0;
}
int musb_otg_env_exit(void){
    DBG(0,"stop the USB-IF test in EM!\n");
    musb_writel(mtk_musb->mregs,USB_L1INTM,0);
    musb_writew(mtk_musb->mregs,MUSB_INTRRXE,0);
    musb_writew(mtk_musb->mregs,MUSB_INTRTXE,0);
    musb_writeb(mtk_musb->mregs,MUSB_INTRUSBE,0);
    musb_writew(mtk_musb->mregs,MUSB_INTRRX,0xffff);
    musb_writew(mtk_musb->mregs,MUSB_INTRTX,0xffff);
    musb_writeb(mtk_musb->mregs,MUSB_INTRUSB,0xff);
    musb_writel(mtk_musb->mregs,USB_L1INTM,usb_l1intm_store);
    musb_writew(mtk_musb->mregs,MUSB_INTRRXE,usb_intrrxe_store);
    musb_writew(mtk_musb->mregs,MUSB_INTRTXE,usb_intrtxe_store);
    musb_writeb(mtk_musb->mregs,MUSB_INTRUSBE,usb_intrusbe_store);
    mtk_musb->usb_if = false;
    mtk_musb->is_host = false;
    upmu_interrupt_chrdet_int_en(1);
    return 0;
}
static void musb_port_suspend(struct musb *musb, bool do_suspend)
{
	u8		power;
	void __iomem	*mbase = musb->mregs;

	if (!is_host_active(musb))
		return;

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

		power &= ~MUSB_POWER_RESUME;
		power |= MUSB_POWER_SUSPENDM;
		musb_writeb(mbase, MUSB_POWER, power);

		/* Needed for OPT A tests */
		power = musb_readb(mbase, MUSB_POWER);
		while (power & MUSB_POWER_SUSPENDM) {
			power = musb_readb(mbase, MUSB_POWER);
			if (retries-- < 1)
				break;
		}

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

		musb->port1_status |= USB_PORT_STAT_SUSPEND;
	} else if (power & MUSB_POWER_SUSPENDM) {
		power &= ~MUSB_POWER_SUSPENDM;
		power |= MUSB_POWER_RESUME;
		musb_writeb(mbase, MUSB_POWER, power);

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

		/* later, GetPortStatus will stop RESUME signaling */
		musb->port1_status |= MUSB_PORT_STAT_RESUME;
		musb->rh_timer = jiffies + msecs_to_jiffies(20);
	}
}
Exemplo n.º 9
0
void musb_read_clear_generic_interrupt(struct musb *musb)
{
	musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
	musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
	musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
	mb();
	musb_writew(musb->mregs,MUSB_INTRRX,musb->int_rx);
	musb_writew(musb->mregs,MUSB_INTRTX,musb->int_tx);
	musb_writeb(musb->mregs,MUSB_INTRUSB,musb->int_usb);
}
void musb_d_soft_connect(bool connect){
    unsigned char power;
    power = musb_readb(mtk_musb->mregs, MUSB_POWER);
    if(connect)
        power |= MUSB_POWER_SOFTCONN;
    else
        power &= ~MUSB_POWER_SOFTCONN;
    musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
    return;
}
Exemplo n.º 11
0
/*
 * am35x_musb_disable - disable HDRC and flush interrupts
 */
static void am35x_musb_disable(struct musb *musb)
{
    void __iomem *reg_base = musb->ctrl_base;

    musb_writel(reg_base, CORE_INTR_MASK_CLEAR_REG, AM35X_INTR_USB_MASK);
    musb_writel(reg_base, EP_INTR_MASK_CLEAR_REG,
                AM35X_TX_INTR_MASK | AM35X_RX_INTR_MASK);
    musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
    musb_writel(reg_base, USB_END_OF_INTR_REG, 0);
}
Exemplo n.º 12
0
/**
 * da8xx_musb_disable - disable HDRC and flush interrupts
 */
static void da8xx_musb_disable(struct musb *musb)
{
	void __iomem *reg_base = musb->ctrl_base;

	musb_writel(reg_base, DA8XX_USB_INTR_MASK_CLEAR_REG,
		    DA8XX_INTR_USB_MASK |
		    DA8XX_INTR_TX_MASK | DA8XX_INTR_RX_MASK);
	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
	musb_writel(reg_base, DA8XX_USB_END_OF_INTR_REG, 0);
}
Exemplo n.º 13
0
u8 musb_read_clear_dma_interrupt(struct musb *musb)
{
	u8 int_hsdma = 0;
	int_hsdma = musb_readb(musb->mregs, MUSB_HSDMA_INTR);

	mb();
	musb_writeb(musb->mregs,MUSB_HSDMA_INTR,int_hsdma);

	return int_hsdma;
}
Exemplo n.º 14
0
static void musb_do_idle(unsigned long _musb)
{
	struct musb	*musb = (void *)_musb;
	unsigned long	flags;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	u8	power;
#endif
	u8	devctl;

	spin_lock_irqsave(&musb->lock, flags);

	switch (musb->xceiv->state) {
	case OTG_STATE_A_WAIT_BCON:

		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
		if (devctl & MUSB_DEVCTL_BDEVICE) {
			musb->xceiv->state = OTG_STATE_B_IDLE;
			MUSB_DEV_MODE(musb);
		} else {
			musb->xceiv->state = OTG_STATE_A_IDLE;
			MUSB_HST_MODE(musb);
		}

		break;
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	case OTG_STATE_A_SUSPEND:
		/* finish RESUME signaling? */
		if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
			power = musb_readb(musb->mregs, MUSB_POWER);
			power &= ~MUSB_POWER_RESUME;
			DBG(1, "root port resume stopped, power %02x\n", power);
			musb_writeb(musb->mregs, MUSB_POWER, power);
			musb->is_active = 1;
			musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
						| MUSB_PORT_STAT_RESUME);
			musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
			usb_hcd_poll_rh_status(musb_to_hcd(musb));
			/* NOTE: it might really be A_WAIT_BCON ... */
			musb->xceiv->state = OTG_STATE_A_HOST;
		}
		break;
#endif
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	case OTG_STATE_A_HOST:
		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
		if (devctl &  MUSB_DEVCTL_BDEVICE)
			musb->xceiv->state = OTG_STATE_B_IDLE;
		else
			musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
#endif
	default:
		break;
	}
	spin_unlock_irqrestore(&musb->lock, flags);
}
Exemplo n.º 15
0
/*
* Program the HDRC to start (enable interrupts, dma, etc.).
*/
static void musb_start(struct musb *musb)
{
	void __iomem	*regs = musb->mregs;
	u8		devctl = musb_readb(regs, MUSB_DEVCTL);

	dev_dbg(musb->controller, "<== devctl %02x\n", devctl);

	/*  Set INT enable registers, enable interrupts */
	musb->intrtxe = musb->epmask;
	musb_writew(regs, MUSB_INTRTXE, musb->intrtxe);
	musb->intrrxe = musb->epmask & 0xfffe;
	musb_writew(regs, MUSB_INTRRXE, musb->intrrxe);
	musb_writeb(regs, MUSB_INTRUSBE, 0xf7);

	musb_writeb(regs, MUSB_TESTMODE, 0);

	/* put into basic highspeed mode and start session */
	musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
						| MUSB_POWER_HSENAB
						/* ENSUSPEND wedges tusb */
						/* | MUSB_POWER_ENSUSPEND */
						);

	musb->is_active = 0;
	devctl = musb_readb(regs, MUSB_DEVCTL);
	devctl &= ~MUSB_DEVCTL_SESSION;

	/* session started after:
	 * (a) ID-grounded irq, host mode;
	 * (b) vbus present/connect IRQ, peripheral mode;
	 * (c) peripheral initiates, using SRP
	 */
	if (musb->port_mode != MUSB_PORT_MODE_HOST &&
	    (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) {
		musb->is_active = 1;
	} else {
		devctl |= MUSB_DEVCTL_SESSION;
	}

	musb_platform_enable(musb);
	musb_writeb(regs, MUSB_DEVCTL, devctl);
}
bool musb_h_reset(void){
    unsigned char power;
    power = musb_readb (mtk_musb->mregs,MUSB_POWER);
    power |= MUSB_POWER_RESET|MUSB_POWER_HSENAB;
    musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
    msleep(60);
    power &= ~MUSB_POWER_RESET;
    musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
    power = musb_readb (mtk_musb->mregs,MUSB_POWER);
    if(power & MUSB_POWER_HSMODE){
        DBG(0,"the device is a hs device!\n");
        high_speed = true;
        return true;
        }
    else{
        DBG(0,"the device is a fs device!\n");
        high_speed = false;
        return false;
        }
}
Exemplo n.º 17
0
static int sunxi_musb_enable(struct musb *musb)
{
	pr_debug("%s():\n", __func__);

	musb_ep_select(musb->mregs, 0);
	musb_writeb(musb->mregs, MUSB_FADDR, 0);

	if (enabled)
		return 0;

	/* select PIO mode */
	musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);

	if (is_host_enabled(musb)) {
		int id = sunxi_usb_phy_id_detect(0);

		if (id == 1 && sunxi_usb_phy_power_is_on(0))
			sunxi_usb_phy_power_off(0);

		if (!sunxi_usb_phy_power_is_on(0)) {
			int vbus = sunxi_usb_phy_vbus_detect(0);
			if (vbus == 1) {
				printf("A charger is plugged into the OTG: ");
				return -ENODEV;
			}
		}

		if (id == 1) {
			printf("No host cable detected: ");
			return -ENODEV;
		}

		if (!sunxi_usb_phy_power_is_on(0))
			sunxi_usb_phy_power_on(0);
	}

	USBC_ForceVbusValidToHigh(musb->mregs);

	enabled = true;
	return 0;
}
Exemplo n.º 18
0
static void davinci_musb_disable(struct musb *musb)
{
	musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG,
			  DAVINCI_USB_USBINT_MASK
			| DAVINCI_USB_TXINT_MASK
			| DAVINCI_USB_RXINT_MASK);
	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
	musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0);

	if (is_dma_capable() && !dma_off)
		WARNING("dma still active\n");
}
unsigned int musb_polling_bus_interrupt(unsigned int intr){
    unsigned char intrusb;
    unsigned long timeout;
    if(MUSB_INTR_CONNECT == intr)
        timeout = jiffies + 15 * HZ;
    if((MUSB_INTR_CONNECT|MUSB_INTR_RESUME) == intr)
        timeout = jiffies + 1;
    if(MUSB_INTR_RESET == intr)
        timeout = jiffies + 2*HZ;

    do{
        intrusb = musb_readb(mtk_musb->mregs,MUSB_INTRUSB);
        mb();
        musb_writeb(mtk_musb->mregs,MUSB_INTRUSB, intrusb);//clear the interrupt
        if(intrusb & intr){
            DBG(0,"interrupt happen, intrusb=0x%x, intr=0x%x\n",intrusb,intr);
            break;
            }
        else{
            //DBG(0,"still polling,intrusb=0x%x,power=0x%x,devctl=0x%x\n",intrusb,musb_readb(mtk_musb->mregs,MUSB_POWER),musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
            //check the timeout
            if((MUSB_INTR_CONNECT == intr) && time_after(jiffies, timeout)){
                DBG(0,"time out for MUSB_INTR_CONNECT\n");
                return DEV_NOT_CONNECT;
                }
            if(((MUSB_INTR_CONNECT|MUSB_INTR_RESUME) == intr) && time_after(jiffies, timeout)){
                DBG(0,"time out for MUSB_INTR_CONNECT|MUSB_INTR_RESUME\n");
                return DEV_HNP_TIMEOUT;
                }
            if((MUSB_INTR_RESET == intr) && time_after(jiffies, timeout)){
                DBG(0,"time out for MUSB_INTR_RESET\n");
                return DEV_NOT_RESET;
                }
            //delay for the interrupt
            if(intr != MUSB_INTR_RESET){
                wait_for_completion_timeout (&stop_event,1);
                if(!g_exec) break;
                }
            }
        }
    while(g_exec);
    if(!g_exec){
        DBG(0,"TEST_IS_STOP\n");
        return TEST_IS_STOP;
        }
    if(intrusb&MUSB_INTR_RESUME){//for TD.4.8, remote wakeup
        DBG(0,"MUSB_INTR_RESUME\n");
        return MUSB_INTR_RESUME;
        }
    else{
        return intrusb;
        }
}
Exemplo n.º 20
0
static void sunxi_musb_enable(struct musb *musb)
{
	pr_debug("%s():\n", __func__);

	/* select PIO mode */
	musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);

	if (is_host_enabled(musb)) {
		/* port power on */
		sunxi_usbc_vbus_enable(0);
	}
}
Exemplo n.º 21
0
static ssize_t mt_usb_store_cmode(struct device* dev, struct device_attribute *attr,
				const char *buf, size_t count)
{
	unsigned int cmode;

	if (!dev) {
		DBG(0,"dev is null!!\n");
		return count;
	} else if (1 == sscanf(buf, "%d", &cmode)) {
		DBG(0, "cmode=%d, cable_mode=%d\n", cmode, cable_mode);
		if (cmode >= CABLE_MODE_MAX)
			cmode = CABLE_MODE_NORMAL;

		if (cable_mode != cmode) {
			if(cmode == CABLE_MODE_CHRG_ONLY) {	// IPO shutdown, disable USB
				if(mtk_musb) {
					mtk_musb->in_ipo_off = true;
				}

			} else if(cmode == CABLE_MODE_NORMAL) {	// IPO bootup, enable USB
				if(mtk_musb) {
					mtk_musb->in_ipo_off = false;
				}
			}

			mt_usb_disconnect();
			cable_mode = cmode;
			msleep(10);
			//ALPS00114502
			//check that "if USB cable connected and than call mt_usb_connect"
			//Then, the Bat_Thread won't be always wakeup while no USB/chatger cable and IPO mode
			//mt_usb_connect();
			usb_check_connect();
			//ALPS00114502

#ifdef CONFIG_USB_MTK_OTG
			if(cmode == CABLE_MODE_CHRG_ONLY) {
				if(mtk_musb && mtk_musb->is_host) {	// shut down USB host for IPO
					musb_stop(mtk_musb);
					/* Think about IPO shutdown with A-cable, then switch to B-cable and IPO bootup. We need a point to clear session bit */
					musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (~MUSB_DEVCTL_SESSION) & musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
				} else {
					switch_int_to_host_and_mask();	// mask ID pin interrupt even if A-cable is not plugged in
				}
			} else if(cmode == CABLE_MODE_NORMAL) {
				switch_int_to_host();	// resotre ID pin interrupt
			}
#endif
		}
	}
	return count;
}
Exemplo n.º 22
0
/*
 * Disable the HDRC and flush interrupts
 */
void musb_platform_disable(struct musb *musb)
{
	/* because we don't set CTRLR.UINT, "important" to:
	 *  - not read/write INTRUSB/INTRUSBE
	 *  - (except during initial setup, as workaround)
	 *  - use INTSETR/INTCLRR instead
	 */
	musb_writel(musb->ctrl_base, DAVINCI_USB_INT_MASK_CLR_REG,
		    DAVINCI_USB_USBINT_MASK
		    | DAVINCI_USB_TXINT_MASK | DAVINCI_USB_RXINT_MASK);
	musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
	musb_writel(musb->ctrl_base, DAVINCI_USB_EOI_REG, 0);
}
Exemplo n.º 23
0
static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
{
	void __iomem *addr = phy->io_priv;
	int	i = 0;
	u8	r;
	u8	power;
	int	ret;

	/* Make sure the transceiver is not in low power mode */
	power = musb_readb(addr, MUSB_POWER);
	power &= ~MUSB_POWER_SUSPENDM;
	musb_writeb(addr, MUSB_POWER, power);

	/* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the
	 * ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
	 */

	musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
	musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
			MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);

	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
				& MUSB_ULPI_REG_CMPLT)) {
		i++;
		if (i == 10000) {
			ret = -ETIMEDOUT;
			goto out;
		}

	}
	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
	r &= ~MUSB_ULPI_REG_CMPLT;
	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);

	ret = musb_readb(addr, MUSB_ULPI_REG_DATA);

out:
	return ret;
}
void musb_h_suspend(void){
    unsigned char power;
    //before suspend, should to send SOF for a while (USB-IF plan need)
    //mdelay(100);
    power = musb_readb(mtk_musb->mregs,MUSB_POWER);
    DBG(0,"before suspend,power=0x%x\n",power);
    if(high_speed)
        power = 0x63;
    else
        power = 0x43;
    musb_writeb(mtk_musb->mregs, MUSB_POWER, power);
    return;
}
Exemplo n.º 25
0
bool musb_is_host(void)
{
	u8 devctl = 0;
  DBG(0,"will mask PMIC charger detection\n");
#ifndef CONFIG_MT6589_FPGA
  upmu_interrupt_chrdet_int_en(0);
#endif
	musb_platform_enable(mtk_musb);
	//musb_set_vbus(mtk_musb,FALSE);
	//mt65xx_eint_mask(EINT_CHR_DET_NUM);
	devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
	DBG(0, "devctl = %x before end session\n", devctl);
	devctl &= ~MUSB_DEVCTL_SESSION;	// this will cause A-device change back to B-device after A-cable plug out
	musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, devctl);
	msleep(delay_time);

	devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
	DBG(0,"devctl = %x before set session\n",devctl);

	devctl |= MUSB_DEVCTL_SESSION;
	//musb_set_vbus(mtk_musb,TRUE);
	musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,devctl);
	msleep(delay_time1);
	devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
	DBG(0,"devclt = %x\n",devctl);

	if (devctl & MUSB_DEVCTL_BDEVICE) {
		usb_is_host = FALSE;
        DBG(0,"will unmask PMIC charger detection\n");
#ifndef CONFIG_MT6589_FPGA
        upmu_interrupt_chrdet_int_en(1);
#endif
		return FALSE;
	} else {
		usb_is_host = TRUE;
		return TRUE;
	}
}
Exemplo n.º 26
0
static bool dsps_sw_babble_control(struct musb *musb)
{
	u8 babble_ctl;
	bool session_restart =  false;

	babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL);
	dev_dbg(musb->controller, "babble: MUSB_BABBLE_CTL value %x\n",
		babble_ctl);
	/*
	 * check line monitor flag to check whether babble is
	 * due to noise
	 */
	dev_dbg(musb->controller, "STUCK_J is %s\n",
		babble_ctl & MUSB_BABBLE_STUCK_J ? "set" : "reset");

	if (babble_ctl & MUSB_BABBLE_STUCK_J) {
		int timeout = 10;

		/*
		 * babble is due to noise, then set transmit idle (d7 bit)
		 * to resume normal operation
		 */
		babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL);
		babble_ctl |= MUSB_BABBLE_FORCE_TXIDLE;
		musb_writeb(musb->mregs, MUSB_BABBLE_CTL, babble_ctl);

		/* wait till line monitor flag cleared */
		dev_dbg(musb->controller, "Set TXIDLE, wait J to clear\n");
		do {
			babble_ctl = musb_readb(musb->mregs, MUSB_BABBLE_CTL);
			udelay(1);
		} while ((babble_ctl & MUSB_BABBLE_STUCK_J) && timeout--);

		/* check whether stuck_at_j bit cleared */
		if (babble_ctl & MUSB_BABBLE_STUCK_J) {
			/*
			 * real babble condition has occurred
			 * restart the controller to start the
			 * session again
			 */
			dev_dbg(musb->controller, "J not cleared, misc (%x)\n",
				babble_ctl);
			session_restart = true;
		}
	} else {
		session_restart = true;
	}

	return session_restart;
}
Exemplo n.º 27
0
static void otg_timer(unsigned long _musb)
{
	struct musb		*musb = (void *)_musb;
	void __iomem		*mregs = musb->mregs;
	u8			devctl;
	unsigned long		flags;

	/*
	 * We poll because AM35x's won't expose several OTG-critical
	 * status change events (from the transceiver) otherwise.
	 */
	devctl = musb_readb(mregs, MUSB_DEVCTL);
	dev_dbg(musb->controller, "Poll devctl %02x (%s)\n", devctl,
		otg_state_string(musb->xceiv->state));

	spin_lock_irqsave(&musb->lock, flags);
	switch (musb->xceiv->state) {
	case OTG_STATE_A_WAIT_BCON:
		devctl &= ~MUSB_DEVCTL_SESSION;
		musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);

		devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
		if (devctl & MUSB_DEVCTL_BDEVICE) {
			musb->xceiv->state = OTG_STATE_B_IDLE;
			MUSB_DEV_MODE(musb);
		} else {
			musb->xceiv->state = OTG_STATE_A_IDLE;
			MUSB_HST_MODE(musb);
		}
		break;
	case OTG_STATE_A_WAIT_VFALL:
		musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
		musb_writel(musb->ctrl_base, CORE_INTR_SRC_SET_REG,
			    MUSB_INTR_VBUSERROR << AM35X_INTR_USB_SHIFT);
		break;
	case OTG_STATE_B_IDLE:
		if (!is_peripheral_enabled(musb))
			break;

		devctl = musb_readb(mregs, MUSB_DEVCTL);
		if (devctl & MUSB_DEVCTL_BDEVICE)
			mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
		else
			musb->xceiv->state = OTG_STATE_A_IDLE;
		break;
	default:
		break;
	}
	spin_unlock_irqrestore(&musb->lock, flags);
}
Exemplo n.º 28
0
/**
 * musb_stm_hs_otg_init() - Initialize the USB for paltform specific.
 * @musb: struct musb pointer.
 *
 * This function initialize the USB with the given musb structure information.
 */
int __init musb_stm_hs_otg_init(struct musb *musb)
{
	u8 val;
	if (musb->clock)
		clk_enable(musb->clock);
/**
 * usb link status update is not coming properly, so usb controller is
 * enabled by default now as part of bring up.it will be modified later.
 */
#if defined(CONFIG_UX500_SOC_DB5500)
	musb_writeb(musb->mregs, MUSB_POWER, 0x50);
#endif
	/* enable ULPI interface */
	val = musb_readb(musb->mregs, OTG_TOPCTRL);
	val |= OTG_TOPCTRL_MODE_ULPI;
	musb_writeb(musb->mregs, OTG_TOPCTRL, val);

	/* do soft reset */
	val = musb_readb(musb->mregs, 0x7F);
	val |= 0x2;
	musb_writeb(musb->mregs, 0x7F, val);

	return 0;
}
Exemplo n.º 29
0
/**
 * musb_set_session() - Start the USB session
 *
 * This function is used to start the USB sessios in USB host mode
 * once the A cable is plugged in
 */
void musb_set_session(int is_on)
{
	u8 val;
	void __iomem *regs;
	struct musb *musb;

	if (musb_status == NULL) {
		printk(KERN_ERR "Error: devctl session cannot be set\n");
		return;
	}
	musb = musb_status;
	regs = musb_status->mregs;
	val = musb_readb(regs, MUSB_DEVCTL);

	if (is_on)
		musb_writeb(regs, MUSB_DEVCTL, val | MUSB_DEVCTL_SESSION);
	else {
		val &= ~MUSB_DEVCTL_SESSION;
		musb_writeb(regs, MUSB_DEVCTL, val);
		musb->xceiv->state = OTG_STATE_B_IDLE;
		MUSB_DEV_MODE(musb);
	}

}
Exemplo n.º 30
0
static void musb_id_pin_work(struct work_struct *data)
{
	//bool is_ready = mtk_musb->is_ready;
	//u8 opstate = 0;
	down(&mtk_musb->musb_lock);
	DBG(0, "work start, is_host=%d\n", mtk_musb->is_host);
	if(mtk_musb->in_ipo_off) {
		DBG(0, "do nothing due to in_ipo_off\n");
		goto out;
	}
	//mtk_musb->is_ready = FALSE;
	mtk_musb ->is_host = musb_is_host();
	DBG(0,"musb is as %s\n",mtk_musb->is_host?"host":"device");
	switch_set_state((struct switch_dev *)&otg_state,mtk_musb->is_host);
	if(mtk_musb ->is_host) {
        	//setup fifo for host mode
        ep_config_from_table_for_host(mtk_musb);
    	wake_lock(&mtk_musb->usb_lock);
    	ignore_vbuserr = false;
		musb_set_vbus(mtk_musb,true);
		musb_start(mtk_musb);
		switch_int_to_device();
	} else {
		DBG(0,"devctl is %x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
		dumpTime(funcWriteb, 0);
		musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,0);
		wake_unlock(&mtk_musb->usb_lock);
		musb_set_vbus(mtk_musb,FALSE);
		/*
		opstate = musb_readb(mtk_musb->mregs,MUSB_OPSTATE);
		while(opstate != OTG_IDLE)
		{
			msleep(10);
			DBG(1,"wait OTG enter IDLE,opstate is %d\n",opstate);
			opstate = musb_readb(mtk_musb->mregs,MUSB_OPSTATE);
		}
		*/
        DBG(0,"musb_stop is called\n");
        //switch_int_to_host(); // move to musb_stop
		musb_stop(mtk_musb);

	}
	//mtk_musb->is_ready = is_ready;
out:
	DBG(0, "work end, is_host=%d\n", mtk_musb->is_host);
	up(&mtk_musb->musb_lock);

}