Skip to content

Commit

Permalink
usb: renesas_usbhs: gadget: fix the behavior of pullup
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Takeshi Kihara authored and Felipe Balbi committed Nov 5, 2014
1 parent 1143205 commit 04a5def
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
6 changes: 4 additions & 2 deletions drivers/usb/renesas_usbhs/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
30 changes: 29 additions & 1 deletion drivers/usb/renesas_usbhs/mod_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 04a5def

Please sign in to comment.