X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fusb%2Fmusb-new%2Fsunxi.c;h=052e0657d03d22261f9951a13c9295cc119c395b;hb=998b8ab3f61ba3a907a5694cedf81f4cf10b0b5a;hp=5a9d39ca12c1af0c5cc9281bc7a1bd7fd0319c99;hpb=7b798658b289aa4466d974320e2b69f4287216f7;p=u-boot diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 5a9d39ca12..052e0657d0 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "linux-compat.h" #include "musb_core.h" @@ -105,16 +105,6 @@ static void USBC_EnableIdPullUp(__iomem void *base) musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_DisableIdPullUp(__iomem void *base) -{ - u32 reg_val; - - reg_val = musb_readl(base, USBC_REG_o_ISCR); - reg_val &= ~(1 << USBC_BP_ISCR_ID_PULLUP_EN); - reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); - musb_writel(base, USBC_REG_o_ISCR, reg_val); -} - static void USBC_EnableDpDmPullUp(__iomem void *base) { u32 reg_val; @@ -125,34 +115,35 @@ static void USBC_EnableDpDmPullUp(__iomem void *base) musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_DisableDpDmPullUp(__iomem void *base) +static void USBC_ForceIdToLow(__iomem void *base) { u32 reg_val; reg_val = musb_readl(base, USBC_REG_o_ISCR); - reg_val &= ~(1 << USBC_BP_ISCR_DPDM_PULLUP_EN); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID); + reg_val |= (0x02 << USBC_BP_ISCR_FORCE_ID); reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_ForceIdToLow(__iomem void *base) +static void USBC_ForceIdToHigh(__iomem void *base) { u32 reg_val; reg_val = musb_readl(base, USBC_REG_o_ISCR); reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID); - reg_val |= (0x02 << USBC_BP_ISCR_FORCE_ID); + reg_val |= (0x03 << USBC_BP_ISCR_FORCE_ID); reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_ForceIdToHigh(__iomem void *base) +static void USBC_ForceVbusValidToLow(__iomem void *base) { u32 reg_val; reg_val = musb_readl(base, USBC_REG_o_ISCR); - reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID); - reg_val |= (0x03 << USBC_BP_ISCR_FORCE_ID); + reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); + reg_val |= (0x02 << USBC_BP_ISCR_FORCE_VBUS_VALID); reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); musb_writel(base, USBC_REG_o_ISCR, reg_val); } @@ -205,42 +196,41 @@ static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci) return retval; } +/* musb_core does not call enable / disable in a balanced manner */ +static bool enabled = false; + static void sunxi_musb_enable(struct musb *musb) { pr_debug("%s():\n", __func__); + if (enabled) + return; + /* select PIO mode */ musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0); - if (is_host_enabled(musb)) { - /* port power on */ - sunxi_usb_phy_power_on(0); - } + if (is_host_enabled(musb)) + sunxi_usb_phy_power_on(0); /* port power on */ + + USBC_ForceVbusValidToHigh(musb->mregs); + + enabled = true; } static void sunxi_musb_disable(struct musb *musb) { - struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - pr_debug("%s():\n", __func__); - /* Put the controller back in a pristane state for "usb reset" */ - if (musb->is_active) { - sunxi_usb_phy_exit(0); -#ifdef CONFIG_SUNXI_GEN_SUN6I - clrbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0); -#endif - clrbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0); + if (!enabled) + return; - mdelay(10); + if (is_host_enabled(musb)) + sunxi_usb_phy_power_off(0); /* port power off */ - setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0); -#ifdef CONFIG_SUNXI_GEN_SUN6I - setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0); -#endif - sunxi_usb_phy_init(0); - musb->is_active = 0; - } + USBC_ForceVbusValidToLow(musb->mregs); + mdelay(200); /* Wait for the current session to timeout */ + + enabled = false; } static int sunxi_musb_init(struct musb *musb) @@ -250,15 +240,10 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); - err = sunxi_usb_phy_probe(0); - if (err) - return err; - if (is_host_enabled(musb)) { err = sunxi_usb_phy_vbus_detect(0); if (err) { eprintf("Error: A charger is plugged into the OTG\n"); - sunxi_usb_phy_remove(0); return -EIO; } } @@ -287,22 +272,8 @@ static int sunxi_musb_init(struct musb *musb) return 0; } -static int sunxi_musb_exit(struct musb *musb) -{ - pr_debug("%s():\n", __func__); - - USBC_DisableDpDmPullUp(musb->mregs); - USBC_DisableIdPullUp(musb->mregs); - sunxi_usb_phy_power_off(0); - sunxi_usb_phy_exit(0); - - return sunxi_usb_phy_remove(0); -} - const struct musb_platform_ops sunxi_musb_ops = { .init = sunxi_musb_init, - .exit = sunxi_musb_exit, - .enable = sunxi_musb_enable, .disable = sunxi_musb_disable, };