diff options
author | Takeshi Kihara <takeshi.kihara.df@renesas.com> | 2014-11-03 20:05:43 -0500 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-11-05 14:22:09 -0500 |
commit | 04a5def3df1cea758662615e075f64677690c75f (patch) | |
tree | 17807399c602c95dd51344bda14656dcc09401dc | |
parent | 11432050f070810ba139d0226344eef120c3a559 (diff) |
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>
-rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 6 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 30 |
2 files changed, 33 insertions, 3 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 169307ba08b7..371478704899 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -126,13 +126,15 @@ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) | |||
126 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | 126 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) |
127 | { | 127 | { |
128 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; | 128 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; |
129 | u16 val = DPRPU | HSE | USBE; | 129 | u16 val = HSE | USBE; |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * if enable | 132 | * if enable |
133 | * | 133 | * |
134 | * - select Function mode | 134 | * - select Function mode |
135 | * - D+ Line Pull-up | 135 | * - D+ Line Pull-up is disabled |
136 | * When D+ Line Pull-up is enabled, | ||
137 | * calling usbhs_sys_function_pullup(,1) | ||
136 | */ | 138 | */ |
137 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); | 139 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); |
138 | } | 140 | } |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index ac51b594590d..cb2d529e3a33 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -56,6 +56,7 @@ struct usbhsg_gpriv { | |||
56 | #define USBHSG_STATUS_REGISTERD (1 << 1) | 56 | #define USBHSG_STATUS_REGISTERD (1 << 1) |
57 | #define USBHSG_STATUS_WEDGE (1 << 2) | 57 | #define USBHSG_STATUS_WEDGE (1 << 2) |
58 | #define USBHSG_STATUS_SELF_POWERED (1 << 3) | 58 | #define USBHSG_STATUS_SELF_POWERED (1 << 3) |
59 | #define USBHSG_STATUS_SOFT_CONNECT (1 << 4) | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | struct usbhsg_recip_handle { | 62 | struct usbhsg_recip_handle { |
@@ -726,6 +727,25 @@ static struct usb_ep_ops usbhsg_ep_ops = { | |||
726 | }; | 727 | }; |
727 | 728 | ||
728 | /* | 729 | /* |
730 | * pullup control | ||
731 | */ | ||
732 | static int usbhsg_can_pullup(struct usbhs_priv *priv) | ||
733 | { | ||
734 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
735 | |||
736 | return gpriv->driver && | ||
737 | usbhsg_status_has(gpriv, USBHSG_STATUS_SOFT_CONNECT); | ||
738 | } | ||
739 | |||
740 | static void usbhsg_update_pullup(struct usbhs_priv *priv) | ||
741 | { | ||
742 | if (usbhsg_can_pullup(priv)) | ||
743 | usbhs_sys_function_pullup(priv, 1); | ||
744 | else | ||
745 | usbhs_sys_function_pullup(priv, 0); | ||
746 | } | ||
747 | |||
748 | /* | ||
729 | * usb module start/end | 749 | * usb module start/end |
730 | */ | 750 | */ |
731 | static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | 751 | static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) |
@@ -775,6 +795,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
775 | * - usb module | 795 | * - usb module |
776 | */ | 796 | */ |
777 | usbhs_sys_function_ctrl(priv, 1); | 797 | usbhs_sys_function_ctrl(priv, 1); |
798 | usbhsg_update_pullup(priv); | ||
778 | 799 | ||
779 | /* | 800 | /* |
780 | * enable irq callback | 801 | * enable irq callback |
@@ -880,8 +901,15 @@ static int usbhsg_pullup(struct usb_gadget *gadget, int is_on) | |||
880 | { | 901 | { |
881 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | 902 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
882 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | 903 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
904 | unsigned long flags; | ||
883 | 905 | ||
884 | usbhs_sys_function_pullup(priv, is_on); | 906 | usbhs_lock(priv, flags); |
907 | if (is_on) | ||
908 | usbhsg_status_set(gpriv, USBHSG_STATUS_SOFT_CONNECT); | ||
909 | else | ||
910 | usbhsg_status_clr(gpriv, USBHSG_STATUS_SOFT_CONNECT); | ||
911 | usbhsg_update_pullup(priv); | ||
912 | usbhs_unlock(priv, flags); | ||
885 | 913 | ||
886 | return 0; | 914 | return 0; |
887 | } | 915 | } |