usb: renesas_usbhs: gadget: fix the behavior of pullup
This patch fixes an issue that this driver always enable the D+ pullup after it detected the VBUS connection even though this usb controller can control the D+ pullup timing by software. So, this driver should enable the D+ pullup after a gadget driver called usb_gadget_connect(). Signed-off-by: Takeshi Kihara <takeshi.kihara.df@renesas.com> Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com> Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
11432050f0
commit
04a5def3df
@ -126,13 +126,15 @@ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable)
|
||||
void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable)
|
||||
{
|
||||
u16 mask = DCFM | DRPD | DPRPU | HSE | USBE;
|
||||
u16 val = DPRPU | HSE | USBE;
|
||||
u16 val = HSE | USBE;
|
||||
|
||||
/*
|
||||
* if enable
|
||||
*
|
||||
* - select Function mode
|
||||
* - D+ Line Pull-up
|
||||
* - D+ Line Pull-up is disabled
|
||||
* When D+ Line Pull-up is enabled,
|
||||
* calling usbhs_sys_function_pullup(,1)
|
||||
*/
|
||||
usbhs_bset(priv, SYSCFG, mask, enable ? val : 0);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ struct usbhsg_gpriv {
|
||||
#define USBHSG_STATUS_REGISTERD (1 << 1)
|
||||
#define USBHSG_STATUS_WEDGE (1 << 2)
|
||||
#define USBHSG_STATUS_SELF_POWERED (1 << 3)
|
||||
#define USBHSG_STATUS_SOFT_CONNECT (1 << 4)
|
||||
};
|
||||
|
||||
struct usbhsg_recip_handle {
|
||||
@ -725,6 +726,25 @@ static struct usb_ep_ops usbhsg_ep_ops = {
|
||||
.set_wedge = usbhsg_ep_set_wedge,
|
||||
};
|
||||
|
||||
/*
|
||||
* pullup control
|
||||
*/
|
||||
static int usbhsg_can_pullup(struct usbhs_priv *priv)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
|
||||
|
||||
return gpriv->driver &&
|
||||
usbhsg_status_has(gpriv, USBHSG_STATUS_SOFT_CONNECT);
|
||||
}
|
||||
|
||||
static void usbhsg_update_pullup(struct usbhs_priv *priv)
|
||||
{
|
||||
if (usbhsg_can_pullup(priv))
|
||||
usbhs_sys_function_pullup(priv, 1);
|
||||
else
|
||||
usbhs_sys_function_pullup(priv, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* usb module start/end
|
||||
*/
|
||||
@ -775,6 +795,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status)
|
||||
* - usb module
|
||||
*/
|
||||
usbhs_sys_function_ctrl(priv, 1);
|
||||
usbhsg_update_pullup(priv);
|
||||
|
||||
/*
|
||||
* enable irq callback
|
||||
@ -880,8 +901,15 @@ static int usbhsg_pullup(struct usb_gadget *gadget, int is_on)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget);
|
||||
struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv);
|
||||
unsigned long flags;
|
||||
|
||||
usbhs_sys_function_pullup(priv, is_on);
|
||||
usbhs_lock(priv, flags);
|
||||
if (is_on)
|
||||
usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT);
|
||||
else
|
||||
usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT);
|
||||
usbhsg_update_pullup(priv);
|
||||
usbhs_unlock(priv, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user