OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 531ef5ebea96394ddb7f554d4d88e017dde30a59 Mon Sep 17 00:00:00 2001 |
2 | From: Amelie Delaunay <amelie.delaunay@st.com> |
||
3 | Date: Tue, 13 Feb 2018 09:28:12 +0100 |
||
4 | Subject: [PATCH] usb: dwc2: add support for host mode external vbus supply |
||
5 | |||
6 | This patch adds a way to enable an external vbus supply in host mode, |
||
7 | when dwc2 drvvbus signal is not used. |
||
8 | |||
9 | This patch is very similar to the one done in U-Boot dwc2 driver [1]. It |
||
10 | also adds dynamic vbus supply management depending on the role and state |
||
11 | of the core. |
||
12 | |||
13 | [1] https://lists.denx.de/pipermail/u-boot/2017-March/283434.html |
||
14 | |||
15 | Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com> |
||
16 | Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> |
||
17 | --- |
||
18 | drivers/usb/dwc2/core.h | 2 ++ |
||
19 | drivers/usb/dwc2/hcd.c | 26 ++++++++++++++++++++++++++ |
||
20 | 2 files changed, 28 insertions(+) |
||
21 | |||
22 | --- a/drivers/usb/dwc2/core.h |
||
23 | +++ b/drivers/usb/dwc2/core.h |
||
24 | @@ -777,6 +777,7 @@ struct dwc2_hregs_backup { |
||
25 | * @plat: The platform specific configuration data. This can be |
||
26 | * removed once all SoCs support usb transceiver. |
||
27 | * @supplies: Definition of USB power supplies |
||
28 | + * @vbus_supply: Regulator supplying vbus. |
||
29 | * @phyif: PHY interface width |
||
30 | * @lock: Spinlock that protects all the driver data structures |
||
31 | * @priv: Stores a pointer to the struct usb_hcd |
||
32 | @@ -914,6 +915,7 @@ struct dwc2_hsotg { |
||
33 | struct usb_phy *uphy; |
||
34 | struct dwc2_hsotg_plat *plat; |
||
35 | struct regulator_bulk_data supplies[DWC2_NUM_SUPPLIES]; |
||
36 | + struct regulator *vbus_supply; |
||
37 | u32 phyif; |
||
38 | |||
39 | spinlock_t lock; |
||
40 | --- a/drivers/usb/dwc2/hcd.c |
||
41 | +++ b/drivers/usb/dwc2/hcd.c |
||
42 | @@ -359,6 +359,23 @@ static void dwc2_gusbcfg_init(struct dwc |
||
43 | dwc2_writel(usbcfg, hsotg->regs + GUSBCFG); |
||
44 | } |
||
45 | |||
46 | +static int dwc2_vbus_supply_init(struct dwc2_hsotg *hsotg) |
||
47 | +{ |
||
48 | + hsotg->vbus_supply = devm_regulator_get_optional(hsotg->dev, "vbus"); |
||
49 | + if (IS_ERR(hsotg->vbus_supply)) |
||
50 | + return 0; |
||
51 | + |
||
52 | + return regulator_enable(hsotg->vbus_supply); |
||
53 | +} |
||
54 | + |
||
55 | +static int dwc2_vbus_supply_exit(struct dwc2_hsotg *hsotg) |
||
56 | +{ |
||
57 | + if (hsotg->vbus_supply) |
||
58 | + return regulator_disable(hsotg->vbus_supply); |
||
59 | + |
||
60 | + return 0; |
||
61 | +} |
||
62 | + |
||
63 | /** |
||
64 | * dwc2_enable_host_interrupts() - Enables the Host mode interrupts |
||
65 | * |
||
66 | @@ -3342,6 +3359,7 @@ static void dwc2_conn_id_status_change(s |
||
67 | |||
68 | /* B-Device connector (Device Mode) */ |
||
69 | if (gotgctl & GOTGCTL_CONID_B) { |
||
70 | + dwc2_vbus_supply_exit(hsotg); |
||
71 | /* Wait for switch to device mode */ |
||
72 | dev_dbg(hsotg->dev, "connId B\n"); |
||
73 | if (hsotg->bus_suspended) { |
||
74 | @@ -4448,6 +4466,9 @@ static int _dwc2_hcd_start(struct usb_hc |
||
75 | } |
||
76 | |||
77 | spin_unlock_irqrestore(&hsotg->lock, flags); |
||
78 | + |
||
79 | + dwc2_vbus_supply_init(hsotg); |
||
80 | + |
||
81 | return 0; |
||
82 | } |
||
83 | |||
84 | @@ -4475,6 +4496,8 @@ static void _dwc2_hcd_stop(struct usb_hc |
||
85 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
||
86 | spin_unlock_irqrestore(&hsotg->lock, flags); |
||
87 | |||
88 | + dwc2_vbus_supply_exit(hsotg); |
||
89 | + |
||
90 | usleep_range(1000, 3000); |
||
91 | } |
||
92 | |||
93 | @@ -4511,6 +4534,7 @@ static int _dwc2_hcd_suspend(struct usb_ |
||
94 | hprt0 |= HPRT0_SUSP; |
||
95 | hprt0 &= ~HPRT0_PWR; |
||
96 | dwc2_writel(hprt0, hsotg->regs + HPRT0); |
||
97 | + dwc2_vbus_supply_exit(hsotg); |
||
98 | } |
||
99 | |||
100 | /* Enter hibernation */ |
||
101 | @@ -4591,6 +4615,8 @@ static int _dwc2_hcd_resume(struct usb_h |
||
102 | spin_unlock_irqrestore(&hsotg->lock, flags); |
||
103 | dwc2_port_resume(hsotg); |
||
104 | } else { |
||
105 | + dwc2_vbus_supply_init(hsotg); |
||
106 | + |
||
107 | /* Wait for controller to correctly update D+/D- level */ |
||
108 | usleep_range(3000, 5000); |
||
109 |