blob: baaca9a8e1e16db2e08e2e2c15bad2c0bf479f6e [file] [log] [blame]
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001/**
2 * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
3 *
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +05304 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +053016#include <linux/module.h>
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020017#include <linux/usb.h>
18#include <linux/usb/hcd.h>
19#include <linux/platform_device.h>
Manu Gautamf1fceddf2012-10-12 14:02:50 +053020#include <linux/regulator/consumer.h>
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020021
22#include "core.h"
23#include "dwc3_otg.h"
24#include "io.h"
25#include "xhci.h"
26
Vijayavardhan Vennapusa472520b2013-10-03 18:37:09 +053027#define VBUS_REG_CHECK_DELAY (msecs_to_jiffies(1000))
wangxl1cd3c562016-01-28 16:07:42 +080028#define MAX_INVALID_CHRGR_RETRY 1
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +053029static int max_chgr_retry_count = MAX_INVALID_CHRGR_RETRY;
30module_param(max_chgr_retry_count, int, S_IRUGO | S_IWUSR);
31MODULE_PARM_DESC(max_chgr_retry_count, "Max invalid charger retry count");
Manu Gautamf1fceddf2012-10-12 14:02:50 +053032static void dwc3_otg_reset(struct dwc3_otg *dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020033
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +053034static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
35static void dwc3_otg_reset(struct dwc3_otg *dotg);
36
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020037/**
38 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
39 *
40 * This function sets the OTG registers to work in A-Device host mode.
41 * This function should be called just before entering to A-Device mode.
42 *
Manu Gautamf1fceddf2012-10-12 14:02:50 +053043 * @w: Pointer to the dwc3 otg struct
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020044 */
45static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
46{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053047 u32 reg;
48 struct dwc3 *dwc = dotg->dwc;
49 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020050
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053051 if (ext_xceiv && !ext_xceiv->otg_capability) {
52 /* Set OCTL[6](PeriMode) to 0 (host) */
53 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
54 reg &= ~DWC3_OTG_OCTL_PERIMODE;
55 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
56 } else {
57 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
58 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
59 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +053060 /*
61 * Allow ITP generated off of ref clk based counter instead
62 * of UTMI/ULPI clk based counter, when superspeed only is
63 * active so that UTMI/ULPI can be suspened.
64 */
65 reg |= DWC3_GCTL_SOFITPSYNC;
66 /*
67 * Set this bit so that device attempts three more times at SS,
68 * even if it failed previously to operate in SS mode.
69 */
70 reg |= DWC3_GCTL_U2RSTECN;
71 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
72 reg |= DWC3_GCTL_PWRDNSCALE(2);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053073 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
74 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +053075}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020076
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +053077static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
78{
79 struct usb_otg *otg = phy->otg;
80 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
81
82 if (dotg->host_bus_suspend == suspend)
83 return 0;
84
85 dotg->host_bus_suspend = suspend;
86 if (suspend) {
87 pm_runtime_put_sync(phy->dev);
88 } else {
89 pm_runtime_get_noresume(phy->dev);
90 pm_runtime_resume(phy->dev);
91 }
92
93 return 0;
94}
95
Vijayavardhan Vennapusab760e0a2014-04-15 15:34:33 +053096static void dwc3_otg_set_hsphy_auto_suspend(struct dwc3_otg *dotg, bool susp);
97static int dwc3_otg_set_autosuspend(struct usb_phy *phy, int enable_autosuspend)
98{
99 struct usb_otg *otg = phy->otg;
100 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
101
102 dwc3_otg_set_hsphy_auto_suspend(dotg, enable_autosuspend);
103
104 return 0;
105}
106
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530107static void dwc3_otg_set_hsphy_auto_suspend(struct dwc3_otg *dotg, bool susp)
108{
109 struct dwc3 *dwc = dotg->dwc;
110 u32 reg;
111
112 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
113 if (susp)
114 reg |= DWC3_GUSB2PHYCFG_SUSPHY;
115 else
116 reg &= ~(DWC3_GUSB2PHYCFG_SUSPHY);
117 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
118}
119
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530120/**
121 * dwc3_otg_set_host_power - Enable port power control for host operation
122 *
123 * This function enables the OTG Port Power required to operate in Host mode
124 * This function should be called only after XHCI driver has set the port
125 * power in PORTSC register.
126 *
127 * @w: Pointer to the dwc3 otg struct
128 */
129void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
130{
131 u32 osts;
132
133 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
134 if (!(osts & 0x8))
135 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
136
137 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200138}
139
140/**
141 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
142 *
143 * This function sets the OTG registers to work in B-Device peripheral mode.
144 * This function should be called just before entering to B-Device mode.
145 *
146 * @w: Pointer to the dwc3 otg workqueue.
147 */
148static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
149{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530150 u32 reg;
151 struct dwc3 *dwc = dotg->dwc;
152 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200153
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530154 if (ext_xceiv && !ext_xceiv->otg_capability) {
155 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
156 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
157 reg |= DWC3_OTG_OCTL_PERIMODE;
158 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
159 /*
160 * TODO: add more OTG registers writes for PERIPHERAL mode here,
161 * see figure 12-19 B-device flow in dwc3 Synopsis spec
162 */
163 } else {
164 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
165 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
166 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530167 /*
168 * Set this bit so that device attempts three more times at SS,
169 * even if it failed previously to operate in SS mode.
170 */
171 reg |= DWC3_GCTL_U2RSTECN;
172 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
173 reg |= DWC3_GCTL_PWRDNSCALE(2);
174 reg &= ~(DWC3_GCTL_SOFITPSYNC);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530175 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
176 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200177}
178
179/**
180 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
181 *
182 * @otg: Pointer to the otg_transceiver structure.
183 * @on: start / stop the host controller driver.
184 *
185 * Returns 0 on success otherwise negative errno.
186 */
187static int dwc3_otg_start_host(struct usb_otg *otg, int on)
188{
189 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530190 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530191 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200192 int ret = 0;
193
Manu Gautam61721592012-11-06 18:09:39 +0530194 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200195 return -EINVAL;
196
Manu Gautam61721592012-11-06 18:09:39 +0530197 if (!dotg->vbus_otg) {
198 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
199 "vbus_dwc3");
200 if (IS_ERR(dotg->vbus_otg)) {
201 dev_err(dwc->dev, "Failed to get vbus regulator\n");
202 ret = PTR_ERR(dotg->vbus_otg);
203 dotg->vbus_otg = 0;
204 return ret;
205 }
206 }
207
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200208 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530209 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200210
Jack Pham18321fa2014-01-10 20:24:01 -0800211 dwc3_otg_notify_host_mode(otg, on);
212 ret = regulator_enable(dotg->vbus_otg);
213 if (ret) {
214 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
215 dwc3_otg_notify_host_mode(otg, 0);
216 return ret;
217 }
218
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200219 /*
220 * This should be revisited for more testing post-silicon.
221 * In worst case we may need to disconnect the root hub
222 * before stopping the controller so that it does not
223 * interfere with runtime pm/system pm.
224 * We can also consider registering and unregistering xhci
225 * platform device. It is almost similar to add_hcd and
226 * remove_hcd, But we may not use standard set_host method
227 * anymore.
228 */
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530229 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530230 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530231 /*
232 * FIXME If micro A cable is disconnected during system suspend,
233 * xhci platform device will be removed before runtime pm is
234 * enabled for xhci device. Due to this, disable_depth becomes
235 * greater than one and runtimepm is not enabled for next microA
236 * connect. Fix this by calling pm_runtime_init for xhci device.
237 */
238 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530239 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200240 if (ret) {
241 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530242 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200243 __func__, ret);
Jack Pham18321fa2014-01-10 20:24:01 -0800244 regulator_disable(dotg->vbus_otg);
245 dwc3_otg_notify_host_mode(otg, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200246 return ret;
247 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530248
249 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530250 if (ext_xceiv && !ext_xceiv->otg_capability)
251 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200252 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530253 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
254
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530255 ret = regulator_disable(dotg->vbus_otg);
256 if (ret) {
257 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
258 return ret;
259 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530260 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530261
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530262 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530263 /*
264 * Perform USB hardware RESET (both core reset and DBM reset)
265 * when moving from host to peripheral. This is required for
266 * peripheral mode to work.
267 */
268 if (ext_xceiv && ext_xceiv->otg_capability &&
269 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700270 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530271
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530272 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Manu Gautamab3da1b2013-04-02 14:29:01 +0530273 dwc3_otg_set_peripheral_regs(dotg);
274
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530275 /* re-init core and OTG registers as block reset clears these */
276 dwc3_post_host_reset_core_init(dwc);
277 if (ext_xceiv && !ext_xceiv->otg_capability)
278 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200279 }
280
281 return 0;
282}
283
284/**
285 * dwc3_otg_set_host - bind/unbind the host controller driver.
286 *
287 * @otg: Pointer to the otg_transceiver structure.
288 * @host: Pointer to the usb_bus structure.
289 *
290 * Returns 0 on success otherwise negative errno.
291 */
292static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
293{
294 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
295
296 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530297 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200298 __func__, host->bus_name);
299 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200300 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530301 * Though XHCI power would be set by now, but some delay is
302 * required for XHCI controller before setting OTG Port Power
303 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200304 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530305 msleep(300);
306 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200307 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530308 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200309 }
310
311 return 0;
312}
313
314/**
315 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
316 *
317 * @otg: Pointer to the otg_transceiver structure.
318 * @gadget: pointer to the usb_gadget structure.
319 *
320 * Returns 0 on success otherwise negative errno.
321 */
322static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
323{
324 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530325 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200326
327 if (!otg->gadget)
328 return -EINVAL;
329
330 if (on) {
331 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
332 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530333
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530334 /* Core reset is not required during start peripheral. Only
335 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530336 if (ext_xceiv && ext_xceiv->otg_capability &&
337 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700338 ext_xceiv->ext_block_reset(ext_xceiv, false);
Manu Gautama302f612012-12-18 17:33:06 +0530339
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530340 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200341 dwc3_otg_set_peripheral_regs(dotg);
342 usb_gadget_vbus_connect(otg->gadget);
343 } else {
344 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
345 __func__, otg->gadget->name);
346 usb_gadget_vbus_disconnect(otg->gadget);
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530347 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200348 }
349
350 return 0;
351}
352
353/**
354 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
355 *
356 * @otg: Pointer to the otg_transceiver structure.
357 * @gadget: pointer to the usb_gadget structure.
358 *
359 * Returns 0 on success otherwise negative errno.
360 */
361static int dwc3_otg_set_peripheral(struct usb_otg *otg,
362 struct usb_gadget *gadget)
363{
364 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
365
366 if (gadget) {
367 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
368 __func__, gadget->name);
369 otg->gadget = gadget;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530370 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200371 } else {
372 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
373 dwc3_otg_start_peripheral(otg, 0);
374 otg->gadget = NULL;
375 otg->phy->state = OTG_STATE_UNDEFINED;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530376 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200377 } else {
378 otg->gadget = NULL;
379 }
380 }
381
382 return 0;
383}
384
385/**
Manu Gautam8c642812012-06-07 10:35:10 +0530386 * dwc3_ext_chg_det_done - callback to handle charger detection completion
387 * @otg: Pointer to the otg transceiver structure
388 * @charger: Pointer to the external charger structure
389 *
390 * Returns 0 on success
391 */
392static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
393{
394 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
395
396 /*
397 * Ignore chg_detection notification if BSV has gone off by this time.
398 * STOP chg_det as part of !BSV handling would reset the chg_det flags
399 */
400 if (test_bit(B_SESS_VLD, &dotg->inputs))
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530401 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautam8c642812012-06-07 10:35:10 +0530402}
403
404/**
405 * dwc3_set_charger - bind/unbind external charger driver
406 * @otg: Pointer to the otg transceiver structure
407 * @charger: Pointer to the external charger structure
408 *
409 * Returns 0 on success
410 */
411int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
412{
413 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
414
415 dotg->charger = charger;
416 if (charger)
417 charger->notify_detection_complete = dwc3_ext_chg_det_done;
418
419 return 0;
420}
421
Manu Gautamb5067272012-07-02 09:53:41 +0530422/**
423 * dwc3_ext_event_notify - callback to handle events from external transceiver
424 * @otg: Pointer to the otg transceiver structure
425 * @event: Event reported by transceiver
426 *
427 * Returns 0 on success
428 */
429static void dwc3_ext_event_notify(struct usb_otg *otg,
430 enum dwc3_ext_events event)
431{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530432 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530433 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
434 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
435 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530436 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530437
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530438 /* Flush processing any pending events before handling new ones */
439 if (init)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530440 flush_delayed_work(&dotg->sm_work);
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530441
Manu Gautamb5067272012-07-02 09:53:41 +0530442 if (event == DWC3_EVENT_PHY_RESUME) {
443 if (!pm_runtime_status_suspended(phy->dev)) {
444 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
445 } else {
446 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
447 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530448 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530449 if ((phy->state == OTG_STATE_A_HOST) &&
450 dotg->host_bus_suspend)
451 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530452 if (ret == -EACCES) {
453 /* pm_runtime_get may fail during system
454 resume with -EACCES error */
455 pm_runtime_disable(phy->dev);
456 pm_runtime_set_active(phy->dev);
457 pm_runtime_enable(phy->dev);
458 } else if (ret < 0) {
459 dev_warn(phy->dev, "pm_runtime_get failed!\n");
460 }
Manu Gautamb5067272012-07-02 09:53:41 +0530461 }
Manu Gautam377821c2012-09-28 16:53:24 +0530462 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530463 if (pm_runtime_status_suspended(phy->dev)) {
464 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
465 ret = pm_runtime_get(phy->dev);
466 if (ret < 0)
467 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
468 }
Jack Pham0fc12332012-11-19 13:14:22 -0800469 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530470 dev_dbg(phy->dev, "XCVR: ID set\n");
471 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800472 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530473 dev_dbg(phy->dev, "XCVR: ID clear\n");
474 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800475 }
Manu Gautam377821c2012-09-28 16:53:24 +0530476
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530477 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530478 dev_dbg(phy->dev, "XCVR: BSV set\n");
479 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530480 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530481 dev_dbg(phy->dev, "XCVR: BSV clear\n");
482 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530483 }
Manu Gautam377821c2012-09-28 16:53:24 +0530484
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530485 if (!init) {
486 init = true;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530487 if (!work_busy(&dotg->sm_work.work))
488 queue_delayed_work(system_nrt_wq,
489 &dotg->sm_work, 0);
Manu Gautam4ff07242013-03-27 14:31:11 +0530490
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530491 complete(&dotg->dwc3_xcvr_vbus_init);
492 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
493 return;
494 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530495
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530496 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530497 }
Manu Gautamb5067272012-07-02 09:53:41 +0530498}
499
500/**
501 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
502 * @otg: Pointer to the otg transceiver structure
503 * @ext_xceiv: Pointer to the external transceiver struccture
504 *
505 * Returns 0 on success
506 */
507int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
508{
509 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
510
511 dotg->ext_xceiv = ext_xceiv;
512 if (ext_xceiv)
513 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
514
515 return 0;
516}
517
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530518static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
519{
520 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
521
522 if (!dotg->psy) {
523 dev_err(otg->phy->dev, "no usb power supply registered\n");
524 return;
525 }
526
527 if (host_mode)
528 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
529 else
530 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
531}
532
533static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
534{
535 static int power_supply_type;
536 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
537
538
Manu Gautam6c0ff032012-11-02 14:55:35 +0530539 if (!dotg->psy || !dotg->charger) {
540 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530541 return 0;
542 }
543
Manu Gautam6c0ff032012-11-02 14:55:35 +0530544 if (dotg->charger->charging_disabled)
545 return 0;
546
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530547 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
548 power_supply_type = POWER_SUPPLY_TYPE_USB;
549 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
550 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530551 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
wangxl1cd3c562016-01-28 16:07:42 +0800552 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER || dotg->charger->chg_type == DWC3_FLOATED_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530553 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
554 else
Manu Gautamc01ee592014-06-12 10:31:09 +0530555 power_supply_type = POWER_SUPPLY_TYPE_UNKNOWN;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530556
557 power_supply_set_supply_type(dotg->psy, power_supply_type);
558
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530559 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530560 mA = DWC3_IDEV_CHG_MAX;
561
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530562 if (dotg->charger->max_power == mA)
563 return 0;
564
565 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
566
567 if (dotg->charger->max_power <= 2 && mA > 2) {
568 /* Enable charging */
569 if (power_supply_set_online(dotg->psy, true))
570 goto psy_error;
571 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
572 goto psy_error;
573 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
574 /* Disable charging */
575 if (power_supply_set_online(dotg->psy, false))
576 goto psy_error;
577 /* Set max current limit */
578 if (power_supply_set_current_limit(dotg->psy, 0))
579 goto psy_error;
580 }
581
582 power_supply_changed(dotg->psy);
583 dotg->charger->max_power = mA;
584 return 0;
585
586psy_error:
587 dev_dbg(phy->dev, "power supply error when setting property\n");
588 return -ENXIO;
589}
590
Manu Gautam8c642812012-06-07 10:35:10 +0530591/* IRQs which OTG driver is interested in handling */
592#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
593 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
594
595/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200596 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
597 * @_dotg: Pointer to out controller context structure
598 *
599 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
600 */
601static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
602{
603 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530604 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200605 int ret = IRQ_NONE;
606 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530607 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200608
609 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
610
Manu Gautam8c642812012-06-07 10:35:10 +0530611 if (!(oevt_reg & DWC3_OEVT_MASK))
612 return IRQ_NONE;
613
614 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
615
616 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
617 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200618 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530619 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200620 * function, switch from A to B or from B to A.
621 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200622
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530623 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
624 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
625 dev_dbg(phy->dev, "ID set\n");
626 set_bit(ID, &dotg->inputs);
627 } else {
628 dev_dbg(phy->dev, "ID clear\n");
629 clear_bit(ID, &dotg->inputs);
630 }
631 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
632 }
Manu Gautam8c642812012-06-07 10:35:10 +0530633
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530634 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
635 if (osts & DWC3_OTG_OSTS_BSESVALID) {
636 dev_dbg(phy->dev, "BSV set\n");
637 set_bit(B_SESS_VLD, &dotg->inputs);
638 } else {
639 dev_dbg(phy->dev, "BSV clear\n");
640 clear_bit(B_SESS_VLD, &dotg->inputs);
641 }
642 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
643 }
Manu Gautam8c642812012-06-07 10:35:10 +0530644
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530645 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200646
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200647 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530648
649 /* Clear the interrupts we handled */
650 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200651 }
652
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200653 return ret;
654}
655
656/**
Manu Gautam8c642812012-06-07 10:35:10 +0530657 * dwc3_otg_init_sm - initialize OTG statemachine input
658 * @dotg: Pointer to the dwc3_otg structure
659 *
660 */
661void dwc3_otg_init_sm(struct dwc3_otg *dotg)
662{
663 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
664 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530665 struct dwc3_ext_xceiv *ext_xceiv;
666 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530667
668 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
669
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530670 /*
671 * VBUS initial state is reported after PMIC
672 * driver initialization. Wait for it.
673 */
674 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530675 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530676 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530677 /* We can safely assume no cable connected */
678 set_bit(ID, &dotg->inputs);
679 }
Manu Gautam8c642812012-06-07 10:35:10 +0530680
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530681 ext_xceiv = dotg->ext_xceiv;
682 dwc3_otg_reset(dotg);
683 if (ext_xceiv && !ext_xceiv->otg_capability) {
684 if (osts & DWC3_OTG_OSTS_CONIDSTS)
685 set_bit(ID, &dotg->inputs);
686 else
687 clear_bit(ID, &dotg->inputs);
688
689 if (osts & DWC3_OTG_OSTS_BSESVALID)
690 set_bit(B_SESS_VLD, &dotg->inputs);
691 else
692 clear_bit(B_SESS_VLD, &dotg->inputs);
693 }
Manu Gautam8c642812012-06-07 10:35:10 +0530694}
695
696/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200697 * dwc3_otg_sm_work - workqueue function.
698 *
699 * @w: Pointer to the dwc3 otg workqueue
700 *
701 * NOTE: After any change in phy->state,
702 * we must reschdule the state machine.
703 */
704static void dwc3_otg_sm_work(struct work_struct *w)
705{
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530706 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200707 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530708 struct dwc3_charger *charger = dotg->charger;
709 bool work = 0;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530710 int ret = 0;
Vijayavardhan Vennapusa472520b2013-10-03 18:37:09 +0530711 unsigned long delay = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200712
Manu Gautamb5067272012-07-02 09:53:41 +0530713 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200714 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
715
716 /* Check OTG state */
717 switch (phy->state) {
718 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530719 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530720 if (!dotg->psy) {
721 dotg->psy = power_supply_get_by_name("usb");
722
723 if (!dotg->psy)
724 dev_err(phy->dev,
725 "couldn't get usb power supply\n");
726 }
727
Manu Gautam8c642812012-06-07 10:35:10 +0530728 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530729 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530730 dev_dbg(phy->dev, "!id\n");
731 phy->state = OTG_STATE_A_IDLE;
732 work = 1;
733 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
734 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200735 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530736 work = 1;
737 } else {
738 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530739 dev_dbg(phy->dev, "No device, trying to suspend\n");
740 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200741 }
742 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530743
744 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530745 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530746 dev_dbg(phy->dev, "!id\n");
747 phy->state = OTG_STATE_A_IDLE;
748 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530749 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530750 if (charger) {
751 if (charger->chg_type == DWC3_INVALID_CHARGER)
752 charger->start_detection(dotg->charger,
753 false);
754 else
755 charger->chg_type =
756 DWC3_INVALID_CHARGER;
757 }
758 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
759 dev_dbg(phy->dev, "b_sess_vld\n");
760 if (charger) {
761 /* Has charger been detected? If no detect it */
762 switch (charger->chg_type) {
763 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530764 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530765 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530766 dwc3_otg_set_power(phy,
767 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530768 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530769 break;
770 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530771 dwc3_otg_set_power(phy,
772 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530773 dwc3_otg_start_peripheral(&dotg->otg,
774 1);
775 phy->state = OTG_STATE_B_PERIPHERAL;
776 work = 1;
777 break;
778 case DWC3_SDP_CHARGER:
779 dwc3_otg_start_peripheral(&dotg->otg,
780 1);
781 phy->state = OTG_STATE_B_PERIPHERAL;
782 work = 1;
783 break;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530784 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusac4974862013-07-23 17:36:37 +0530785 if (dotg->charger_retry_count <
786 max_chgr_retry_count)
787 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530788 /*
789 * In case of floating charger, if
790 * retry count equal to max retry count
791 * notify PMIC about floating charger
792 * and put Hw in low power mode. Else
793 * perform charger detection again by
794 * calling start_detection() with false
795 * and then with true argument.
796 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530797 if (dotg->charger_retry_count ==
798 max_chgr_retry_count) {
wangxl1cd3c562016-01-28 16:07:42 +0800799 dwc3_otg_set_power(phy, DWC3_IDEV_CHG_MAX);
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530800 pm_runtime_put_sync(phy->dev);
801 break;
802 }
803 charger->start_detection(dotg->charger,
804 false);
805
Manu Gautam8c642812012-06-07 10:35:10 +0530806 default:
807 dev_dbg(phy->dev, "chg_det started\n");
808 charger->start_detection(charger, true);
809 break;
810 }
811 } else {
812 /* no charger registered, start peripheral */
813 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
814 /*
815 * Probably set_peripheral not called
816 * yet. We will re-try as soon as it
817 * will be called
818 */
Manu Gautamb5067272012-07-02 09:53:41 +0530819 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530820 "unable to start B-device\n");
821 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530822 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530823 return;
824 }
825 }
826 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530827 if (charger)
828 charger->start_detection(dotg->charger, false);
829
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530830 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530831 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530832 dev_dbg(phy->dev, "No device, trying to suspend\n");
833 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530834 }
835 break;
836
837 case OTG_STATE_B_PERIPHERAL:
838 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
839 !test_bit(ID, &dotg->inputs)) {
840 dev_dbg(phy->dev, "!id || !bsv\n");
841 dwc3_otg_start_peripheral(&dotg->otg, 0);
842 phy->state = OTG_STATE_B_IDLE;
843 if (charger)
844 charger->chg_type = DWC3_INVALID_CHARGER;
845 work = 1;
846 }
847 break;
848
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200849 case OTG_STATE_A_IDLE:
850 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530851 if (test_bit(ID, &dotg->inputs)) {
852 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200853 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530854 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530855 work = 1;
856 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530857 phy->state = OTG_STATE_A_HOST;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530858 ret = dwc3_otg_start_host(&dotg->otg, 1);
859 if ((ret == -EPROBE_DEFER) &&
860 dotg->vbus_retry_count < 3) {
861 /*
862 * Get regulator failed as regulator driver is
863 * not up yet. Will try to start host after 1sec
864 */
865 phy->state = OTG_STATE_A_IDLE;
866 dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n");
867 delay = VBUS_REG_CHECK_DELAY;
868 work = 1;
869 dotg->vbus_retry_count++;
870 } else if (ret) {
Manu Gautam8c642812012-06-07 10:35:10 +0530871 /*
872 * Probably set_host was not called yet.
873 * We will re-try as soon as it will be called
874 */
Manu Gautamb5067272012-07-02 09:53:41 +0530875 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530876 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530877 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530878 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530879 return;
880 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200881 }
882 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530883
884 case OTG_STATE_A_HOST:
885 if (test_bit(ID, &dotg->inputs)) {
886 dev_dbg(phy->dev, "id\n");
887 dwc3_otg_start_host(&dotg->otg, 0);
888 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530889 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530890 work = 1;
891 }
892 break;
893
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200894 default:
895 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
896
897 }
Manu Gautam8c642812012-06-07 10:35:10 +0530898
899 if (work)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530900 queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200901}
902
903
904/**
905 * dwc3_otg_reset - reset dwc3 otg registers.
906 *
907 * @w: Pointer to the dwc3 otg workqueue
908 */
909static void dwc3_otg_reset(struct dwc3_otg *dotg)
910{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530911 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530912 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
913
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200914 /*
915 * OCFG[2] - OTG-Version = 1
916 * OCFG[1] - HNPCap = 0
917 * OCFG[0] - SRPCap = 0
918 */
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530919 if (ext_xceiv && !ext_xceiv->otg_capability)
920 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200921
922 /*
923 * OCTL[6] - PeriMode = 1
924 * OCTL[5] - PrtPwrCtl = 0
925 * OCTL[4] - HNPReq = 0
926 * OCTL[3] - SesReq = 0
927 * OCTL[2] - TermSelDLPulse = 0
928 * OCTL[1] - DevSetHNPEn = 0
929 * OCTL[0] - HstSetHNPEn = 0
930 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530931 if (!once) {
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530932 if (ext_xceiv && !ext_xceiv->otg_capability)
933 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530934 once++;
935 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200936
937 /* Clear all otg events (interrupts) indications */
938 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
939
Manu Gautam8c642812012-06-07 10:35:10 +0530940 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530941 if (ext_xceiv && !ext_xceiv->otg_capability)
942 dwc3_writel(dotg->regs, DWC3_OEVTEN,
943 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
944 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200945}
946
947/**
948 * dwc3_otg_init - Initializes otg related registers
949 * @dwc: Pointer to out controller context structure
950 *
951 * Returns 0 on success otherwise negative errno.
952 */
953int dwc3_otg_init(struct dwc3 *dwc)
954{
955 u32 reg;
956 int ret = 0;
957 struct dwc3_otg *dotg;
958
959 dev_dbg(dwc->dev, "dwc3_otg_init\n");
960
961 /*
962 * GHWPARAMS6[10] bit is SRPSupport.
963 * This bit also reflects DWC_USB3_EN_OTG
964 */
965 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
966 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
967 /*
968 * No OTG support in the HW core.
969 * We return 0 to indicate no error, since this is acceptable
970 * situation, just continue probe the dwc3 driver without otg.
971 */
972 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
973 return 0;
974 }
975
976 /* Allocate and init otg instance */
977 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
978 if (!dotg) {
979 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
980 return -ENOMEM;
981 }
982
Manu Gautam17206c22012-06-21 10:17:53 +0530983 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
984 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
985 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200986 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530987 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200988 ret = -ENODEV;
989 goto err1;
990 }
991
992 dotg->regs = dwc->regs;
993
994 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
995 dotg->otg.set_host = dwc3_otg_set_host;
996
997 /* This reference is used by dwc3 modules for checking otg existance */
998 dwc->dotg = dotg;
999
1000 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
1001 if (!dotg->otg.phy) {
1002 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
1003 ret = -ENOMEM;
1004 goto err1;
1005 }
1006
Manu Gautamf1fceddf2012-10-12 14:02:50 +05301007 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001008 dotg->otg.phy->otg = &dotg->otg;
1009 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +05301010 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +05301011 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Vijayavardhan Vennapusab760e0a2014-04-15 15:34:33 +05301012 dotg->otg.phy->set_phy_autosuspend = dwc3_otg_set_autosuspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001013
1014 ret = usb_set_transceiver(dotg->otg.phy);
1015 if (ret) {
1016 dev_err(dotg->otg.phy->dev,
1017 "%s: failed to set transceiver, already exists\n",
1018 __func__);
1019 goto err2;
1020 }
1021
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001022 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
1023
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +05301024 init_completion(&dotg->dwc3_xcvr_vbus_init);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301025 INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001026
1027 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
1028 "dwc3_otg", dotg);
1029 if (ret) {
1030 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
1031 dotg->irq, ret);
1032 goto err3;
1033 }
1034
Manu Gautamb5067272012-07-02 09:53:41 +05301035 pm_runtime_get(dwc->dev);
1036
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001037 return 0;
1038
1039err3:
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301040 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001041 usb_set_transceiver(NULL);
1042err2:
1043 kfree(dotg->otg.phy);
1044err1:
1045 dwc->dotg = NULL;
1046 kfree(dotg);
1047
1048 return ret;
1049}
1050
1051/**
1052 * dwc3_otg_exit
1053 * @dwc: Pointer to out controller context structure
1054 *
1055 * Returns 0 on success otherwise negative errno.
1056 */
1057void dwc3_otg_exit(struct dwc3 *dwc)
1058{
1059 struct dwc3_otg *dotg = dwc->dotg;
1060
1061 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
1062 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +05301063 if (dotg->charger)
1064 dotg->charger->start_detection(dotg->charger, false);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301065 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001066 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +05301067 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001068 free_irq(dotg->irq, dotg);
1069 kfree(dotg->otg.phy);
1070 kfree(dotg);
1071 dwc->dotg = NULL;
1072 }
1073}