summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/phy/allwinner/phy-sun4i-usb.c6
-rw-r--r--drivers/usb/musb-new/musb_core.h4
-rw-r--r--drivers/usb/musb-new/musb_uboot.c19
-rw-r--r--drivers/usb/musb-new/sunxi.c16
4 files changed, 34 insertions, 11 deletions
diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 4194a15007..2b3cf48025 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -36,6 +36,7 @@
#define PHY_TX_AMPLITUDE_TUNE 0x20
#define PHY_TX_SLEWRATE_TUNE 0x22
#define PHY_DISCON_TH_SEL 0x2a
+#define PHY_SQUELCH_DETECT 0x3c
#define PHYCTL_DATA BIT(7)
#define OTGCTL_ROUTE_MUSB BIT(0)
@@ -383,6 +384,11 @@ int sun4i_usb_phy_id_detect(struct phy *phy)
return gpio_get_value(usb_phy->gpio_id_det);
}
+void sun4i_usb_phy_set_squelch_detect(struct phy *phy, bool enabled)
+{
+ sun4i_usb_phy_write(phy, PHY_SQUELCH_DETECT, enabled ? 0 : 2, 2);
+}
+
static struct phy_ops sun4i_usb_phy_ops = {
.of_xlate = sun4i_usb_phy_xlate,
.init = sun4i_usb_phy_init,
diff --git a/drivers/usb/musb-new/musb_core.h b/drivers/usb/musb-new/musb_core.h
index fa4cf86c79..821d0e06f6 100644
--- a/drivers/usb/musb-new/musb_core.h
+++ b/drivers/usb/musb-new/musb_core.h
@@ -200,6 +200,8 @@ enum musb_g_ep0_state {
* @vbus_status: returns vbus status if possible
* @set_vbus: forces vbus status
* @adjust_channel_params: pre check for standard dma channel_program func
+ * @pre_root_reset_end: called before the root usb port reset flag gets cleared
+ * @post_root_reset_end: called after the root usb port reset flag gets cleared
*/
struct musb_platform_ops {
int (*init)(struct musb *musb);
@@ -221,6 +223,8 @@ struct musb_platform_ops {
int (*adjust_channel_params)(struct dma_channel *channel,
u16 packet_sz, u8 *mode,
dma_addr_t *dma_addr, u32 *len);
+ void (*pre_root_reset_end)(struct musb *musb);
+ void (*post_root_reset_end)(struct musb *musb);
};
/*
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 8662c0ff70..48242c0475 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -193,19 +193,16 @@ static int _musb_reset_root_port(struct musb_host_data *host,
power &= 0xf0;
musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
mdelay(50);
-#ifdef CONFIG_ARCH_SUNXI
- /*
- * sunxi phy has a bug and it will wrongly detect high speed squelch
- * when clearing reset on low-speed devices, temporary disable
- * squelch detection to work around this.
- */
- sunxi_usb_phy_enable_squelch_detect(0, 0);
-#endif
+
+ if (host->host->ops->pre_root_reset_end)
+ host->host->ops->pre_root_reset_end(host->host);
+
power = musb_readb(mbase, MUSB_POWER);
musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
-#ifdef CONFIG_ARCH_SUNXI
- sunxi_usb_phy_enable_squelch_detect(0, 1);
-#endif
+
+ if (host->host->ops->post_root_reset_end)
+ host->host->ops->post_root_reset_end(host->host);
+
host->host->isr(0, host->host);
host->host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
USB_SPEED_HIGH :
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index a33ebe5caf..5728a3f384 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -304,10 +304,26 @@ static int sunxi_musb_init(struct musb *musb)
return 0;
}
+static void sunxi_musb_pre_root_reset_end(struct musb *musb)
+{
+ struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
+
+ sun4i_usb_phy_set_squelch_detect(glue->phy, false);
+}
+
+static void sunxi_musb_post_root_reset_end(struct musb *musb)
+{
+ struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
+
+ sun4i_usb_phy_set_squelch_detect(glue->phy, true);
+}
+
static const struct musb_platform_ops sunxi_musb_ops = {
.init = sunxi_musb_init,
.enable = sunxi_musb_enable,
.disable = sunxi_musb_disable,
+ .pre_root_reset_end = sunxi_musb_pre_root_reset_end,
+ .post_root_reset_end = sunxi_musb_post_root_reset_end,
};
/* Allwinner OTG supports up to 5 endpoints */