blob: cacd635d06882d7da32c7a17d1d9953bbd68e787 [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))
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +053028#define MAX_INVALID_CHRGR_RETRY 3
29static 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 Vennapusa47786ef2013-11-11 13:03:19 +053096static void dwc3_otg_set_hsphy_auto_suspend(struct dwc3_otg *dotg, bool susp)
97{
98 struct dwc3 *dwc = dotg->dwc;
99 u32 reg;
100
101 reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
102 if (susp)
103 reg |= DWC3_GUSB2PHYCFG_SUSPHY;
104 else
105 reg &= ~(DWC3_GUSB2PHYCFG_SUSPHY);
106 dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
107}
108
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530109/**
110 * dwc3_otg_set_host_power - Enable port power control for host operation
111 *
112 * This function enables the OTG Port Power required to operate in Host mode
113 * This function should be called only after XHCI driver has set the port
114 * power in PORTSC register.
115 *
116 * @w: Pointer to the dwc3 otg struct
117 */
118void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
119{
120 u32 osts;
121
122 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
123 if (!(osts & 0x8))
124 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
125
126 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200127}
128
129/**
130 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
131 *
132 * This function sets the OTG registers to work in B-Device peripheral mode.
133 * This function should be called just before entering to B-Device mode.
134 *
135 * @w: Pointer to the dwc3 otg workqueue.
136 */
137static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
138{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530139 u32 reg;
140 struct dwc3 *dwc = dotg->dwc;
141 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200142
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530143 if (ext_xceiv && !ext_xceiv->otg_capability) {
144 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
145 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
146 reg |= DWC3_OTG_OCTL_PERIMODE;
147 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
148 /*
149 * TODO: add more OTG registers writes for PERIPHERAL mode here,
150 * see figure 12-19 B-device flow in dwc3 Synopsis spec
151 */
152 } else {
153 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
154 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
155 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530156 /*
157 * Set this bit so that device attempts three more times at SS,
158 * even if it failed previously to operate in SS mode.
159 */
160 reg |= DWC3_GCTL_U2RSTECN;
161 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
162 reg |= DWC3_GCTL_PWRDNSCALE(2);
163 reg &= ~(DWC3_GCTL_SOFITPSYNC);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530164 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
165 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200166}
167
168/**
169 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
170 *
171 * @otg: Pointer to the otg_transceiver structure.
172 * @on: start / stop the host controller driver.
173 *
174 * Returns 0 on success otherwise negative errno.
175 */
176static int dwc3_otg_start_host(struct usb_otg *otg, int on)
177{
178 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530179 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530180 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200181 int ret = 0;
182
Manu Gautam61721592012-11-06 18:09:39 +0530183 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200184 return -EINVAL;
185
Manu Gautam61721592012-11-06 18:09:39 +0530186 if (!dotg->vbus_otg) {
187 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
188 "vbus_dwc3");
189 if (IS_ERR(dotg->vbus_otg)) {
190 dev_err(dwc->dev, "Failed to get vbus regulator\n");
191 ret = PTR_ERR(dotg->vbus_otg);
192 dotg->vbus_otg = 0;
193 return ret;
194 }
195 }
196
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200197 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530198 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200199
200 /*
201 * This should be revisited for more testing post-silicon.
202 * In worst case we may need to disconnect the root hub
203 * before stopping the controller so that it does not
204 * interfere with runtime pm/system pm.
205 * We can also consider registering and unregistering xhci
206 * platform device. It is almost similar to add_hcd and
207 * remove_hcd, But we may not use standard set_host method
208 * anymore.
209 */
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530210 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530211 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530212 /*
213 * FIXME If micro A cable is disconnected during system suspend,
214 * xhci platform device will be removed before runtime pm is
215 * enabled for xhci device. Due to this, disable_depth becomes
216 * greater than one and runtimepm is not enabled for next microA
217 * connect. Fix this by calling pm_runtime_init for xhci device.
218 */
219 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530220 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200221 if (ret) {
222 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530223 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200224 __func__, ret);
225 return ret;
226 }
227
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530228 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530229 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200230 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530231 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530232 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200233 return ret;
234 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530235
236 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530237 if (ext_xceiv && !ext_xceiv->otg_capability)
238 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200239 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530240 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
241
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530242 ret = regulator_disable(dotg->vbus_otg);
243 if (ret) {
244 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
245 return ret;
246 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530247 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530248
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530249 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530250 /*
251 * Perform USB hardware RESET (both core reset and DBM reset)
252 * when moving from host to peripheral. This is required for
253 * peripheral mode to work.
254 */
255 if (ext_xceiv && ext_xceiv->otg_capability &&
256 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700257 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530258
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530259 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Manu Gautamab3da1b2013-04-02 14:29:01 +0530260 dwc3_otg_set_peripheral_regs(dotg);
261
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530262 /* re-init core and OTG registers as block reset clears these */
263 dwc3_post_host_reset_core_init(dwc);
264 if (ext_xceiv && !ext_xceiv->otg_capability)
265 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200266 }
267
268 return 0;
269}
270
271/**
272 * dwc3_otg_set_host - bind/unbind the host controller driver.
273 *
274 * @otg: Pointer to the otg_transceiver structure.
275 * @host: Pointer to the usb_bus structure.
276 *
277 * Returns 0 on success otherwise negative errno.
278 */
279static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
280{
281 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
282
283 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530284 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200285 __func__, host->bus_name);
286 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200287 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530288 * Though XHCI power would be set by now, but some delay is
289 * required for XHCI controller before setting OTG Port Power
290 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200291 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530292 msleep(300);
293 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200294 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530295 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200296 }
297
298 return 0;
299}
300
301/**
302 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
303 *
304 * @otg: Pointer to the otg_transceiver structure.
305 * @gadget: pointer to the usb_gadget structure.
306 *
307 * Returns 0 on success otherwise negative errno.
308 */
309static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
310{
311 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530312 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200313
314 if (!otg->gadget)
315 return -EINVAL;
316
317 if (on) {
318 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
319 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530320
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530321 /* Core reset is not required during start peripheral. Only
322 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530323 if (ext_xceiv && ext_xceiv->otg_capability &&
324 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700325 ext_xceiv->ext_block_reset(ext_xceiv, false);
Manu Gautama302f612012-12-18 17:33:06 +0530326
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530327 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200328 dwc3_otg_set_peripheral_regs(dotg);
329 usb_gadget_vbus_connect(otg->gadget);
330 } else {
331 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
332 __func__, otg->gadget->name);
333 usb_gadget_vbus_disconnect(otg->gadget);
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530334 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200335 }
336
337 return 0;
338}
339
340/**
341 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
342 *
343 * @otg: Pointer to the otg_transceiver structure.
344 * @gadget: pointer to the usb_gadget structure.
345 *
346 * Returns 0 on success otherwise negative errno.
347 */
348static int dwc3_otg_set_peripheral(struct usb_otg *otg,
349 struct usb_gadget *gadget)
350{
351 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
352
353 if (gadget) {
354 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
355 __func__, gadget->name);
356 otg->gadget = gadget;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530357 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200358 } else {
359 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
360 dwc3_otg_start_peripheral(otg, 0);
361 otg->gadget = NULL;
362 otg->phy->state = OTG_STATE_UNDEFINED;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530363 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200364 } else {
365 otg->gadget = NULL;
366 }
367 }
368
369 return 0;
370}
371
372/**
Manu Gautam8c642812012-06-07 10:35:10 +0530373 * dwc3_ext_chg_det_done - callback to handle charger detection completion
374 * @otg: Pointer to the otg transceiver structure
375 * @charger: Pointer to the external charger structure
376 *
377 * Returns 0 on success
378 */
379static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
380{
381 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
382
383 /*
384 * Ignore chg_detection notification if BSV has gone off by this time.
385 * STOP chg_det as part of !BSV handling would reset the chg_det flags
386 */
387 if (test_bit(B_SESS_VLD, &dotg->inputs))
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530388 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautam8c642812012-06-07 10:35:10 +0530389}
390
391/**
392 * dwc3_set_charger - bind/unbind external charger driver
393 * @otg: Pointer to the otg transceiver structure
394 * @charger: Pointer to the external charger structure
395 *
396 * Returns 0 on success
397 */
398int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
399{
400 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
401
402 dotg->charger = charger;
403 if (charger)
404 charger->notify_detection_complete = dwc3_ext_chg_det_done;
405
406 return 0;
407}
408
Manu Gautamb5067272012-07-02 09:53:41 +0530409/**
410 * dwc3_ext_event_notify - callback to handle events from external transceiver
411 * @otg: Pointer to the otg transceiver structure
412 * @event: Event reported by transceiver
413 *
414 * Returns 0 on success
415 */
416static void dwc3_ext_event_notify(struct usb_otg *otg,
417 enum dwc3_ext_events event)
418{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530419 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530420 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
421 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
422 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530423 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530424
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530425 /* Flush processing any pending events before handling new ones */
426 if (init)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530427 flush_delayed_work(&dotg->sm_work);
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530428
Manu Gautamb5067272012-07-02 09:53:41 +0530429 if (event == DWC3_EVENT_PHY_RESUME) {
430 if (!pm_runtime_status_suspended(phy->dev)) {
431 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
432 } else {
433 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
434 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530435 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530436 if ((phy->state == OTG_STATE_A_HOST) &&
437 dotg->host_bus_suspend)
438 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530439 if (ret == -EACCES) {
440 /* pm_runtime_get may fail during system
441 resume with -EACCES error */
442 pm_runtime_disable(phy->dev);
443 pm_runtime_set_active(phy->dev);
444 pm_runtime_enable(phy->dev);
445 } else if (ret < 0) {
446 dev_warn(phy->dev, "pm_runtime_get failed!\n");
447 }
Manu Gautamb5067272012-07-02 09:53:41 +0530448 }
Manu Gautam377821c2012-09-28 16:53:24 +0530449 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530450 if (pm_runtime_status_suspended(phy->dev)) {
451 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
452 ret = pm_runtime_get(phy->dev);
453 if (ret < 0)
454 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
455 }
Jack Pham0fc12332012-11-19 13:14:22 -0800456 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530457 dev_dbg(phy->dev, "XCVR: ID set\n");
458 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800459 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530460 dev_dbg(phy->dev, "XCVR: ID clear\n");
461 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800462 }
Manu Gautam377821c2012-09-28 16:53:24 +0530463
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530464 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530465 dev_dbg(phy->dev, "XCVR: BSV set\n");
466 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530467 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530468 dev_dbg(phy->dev, "XCVR: BSV clear\n");
469 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530470 }
Manu Gautam377821c2012-09-28 16:53:24 +0530471
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530472 if (!init) {
473 init = true;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530474 if (!work_busy(&dotg->sm_work.work))
475 queue_delayed_work(system_nrt_wq,
476 &dotg->sm_work, 0);
Manu Gautam4ff07242013-03-27 14:31:11 +0530477
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530478 complete(&dotg->dwc3_xcvr_vbus_init);
479 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
480 return;
481 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530482
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530483 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530484 }
Manu Gautamb5067272012-07-02 09:53:41 +0530485}
486
487/**
488 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
489 * @otg: Pointer to the otg transceiver structure
490 * @ext_xceiv: Pointer to the external transceiver struccture
491 *
492 * Returns 0 on success
493 */
494int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
495{
496 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
497
498 dotg->ext_xceiv = ext_xceiv;
499 if (ext_xceiv)
500 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
501
502 return 0;
503}
504
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530505static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
506{
507 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
508
509 if (!dotg->psy) {
510 dev_err(otg->phy->dev, "no usb power supply registered\n");
511 return;
512 }
513
514 if (host_mode)
515 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
516 else
517 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
518}
519
520static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
521{
522 static int power_supply_type;
523 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
524
525
Manu Gautam6c0ff032012-11-02 14:55:35 +0530526 if (!dotg->psy || !dotg->charger) {
527 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530528 return 0;
529 }
530
Manu Gautam6c0ff032012-11-02 14:55:35 +0530531 if (dotg->charger->charging_disabled)
532 return 0;
533
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530534 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
535 power_supply_type = POWER_SUPPLY_TYPE_USB;
536 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
537 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530538 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
539 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530540 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
541 else
542 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
543
544 power_supply_set_supply_type(dotg->psy, power_supply_type);
545
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530546 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530547 mA = DWC3_IDEV_CHG_MAX;
548
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530549 if (dotg->charger->max_power == mA)
550 return 0;
551
552 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
553
554 if (dotg->charger->max_power <= 2 && mA > 2) {
555 /* Enable charging */
556 if (power_supply_set_online(dotg->psy, true))
557 goto psy_error;
558 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
559 goto psy_error;
560 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
561 /* Disable charging */
562 if (power_supply_set_online(dotg->psy, false))
563 goto psy_error;
564 /* Set max current limit */
565 if (power_supply_set_current_limit(dotg->psy, 0))
566 goto psy_error;
567 }
568
569 power_supply_changed(dotg->psy);
570 dotg->charger->max_power = mA;
571 return 0;
572
573psy_error:
574 dev_dbg(phy->dev, "power supply error when setting property\n");
575 return -ENXIO;
576}
577
Manu Gautam8c642812012-06-07 10:35:10 +0530578/* IRQs which OTG driver is interested in handling */
579#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
580 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
581
582/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200583 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
584 * @_dotg: Pointer to out controller context structure
585 *
586 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
587 */
588static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
589{
590 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530591 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200592 int ret = IRQ_NONE;
593 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530594 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200595
596 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
597
Manu Gautam8c642812012-06-07 10:35:10 +0530598 if (!(oevt_reg & DWC3_OEVT_MASK))
599 return IRQ_NONE;
600
601 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
602
603 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
604 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200605 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530606 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200607 * function, switch from A to B or from B to A.
608 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200609
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530610 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
611 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
612 dev_dbg(phy->dev, "ID set\n");
613 set_bit(ID, &dotg->inputs);
614 } else {
615 dev_dbg(phy->dev, "ID clear\n");
616 clear_bit(ID, &dotg->inputs);
617 }
618 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
619 }
Manu Gautam8c642812012-06-07 10:35:10 +0530620
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530621 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
622 if (osts & DWC3_OTG_OSTS_BSESVALID) {
623 dev_dbg(phy->dev, "BSV set\n");
624 set_bit(B_SESS_VLD, &dotg->inputs);
625 } else {
626 dev_dbg(phy->dev, "BSV clear\n");
627 clear_bit(B_SESS_VLD, &dotg->inputs);
628 }
629 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
630 }
Manu Gautam8c642812012-06-07 10:35:10 +0530631
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530632 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200633
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200634 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530635
636 /* Clear the interrupts we handled */
637 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200638 }
639
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200640 return ret;
641}
642
643/**
Manu Gautam8c642812012-06-07 10:35:10 +0530644 * dwc3_otg_init_sm - initialize OTG statemachine input
645 * @dotg: Pointer to the dwc3_otg structure
646 *
647 */
648void dwc3_otg_init_sm(struct dwc3_otg *dotg)
649{
650 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
651 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530652 struct dwc3_ext_xceiv *ext_xceiv;
653 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530654
655 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
656
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530657 /*
658 * VBUS initial state is reported after PMIC
659 * driver initialization. Wait for it.
660 */
661 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530662 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530663 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530664 /* We can safely assume no cable connected */
665 set_bit(ID, &dotg->inputs);
666 }
Manu Gautam8c642812012-06-07 10:35:10 +0530667
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530668 ext_xceiv = dotg->ext_xceiv;
669 dwc3_otg_reset(dotg);
670 if (ext_xceiv && !ext_xceiv->otg_capability) {
671 if (osts & DWC3_OTG_OSTS_CONIDSTS)
672 set_bit(ID, &dotg->inputs);
673 else
674 clear_bit(ID, &dotg->inputs);
675
676 if (osts & DWC3_OTG_OSTS_BSESVALID)
677 set_bit(B_SESS_VLD, &dotg->inputs);
678 else
679 clear_bit(B_SESS_VLD, &dotg->inputs);
680 }
Manu Gautam8c642812012-06-07 10:35:10 +0530681}
682
683/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200684 * dwc3_otg_sm_work - workqueue function.
685 *
686 * @w: Pointer to the dwc3 otg workqueue
687 *
688 * NOTE: After any change in phy->state,
689 * we must reschdule the state machine.
690 */
691static void dwc3_otg_sm_work(struct work_struct *w)
692{
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530693 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200694 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530695 struct dwc3_charger *charger = dotg->charger;
696 bool work = 0;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530697 int ret = 0;
Vijayavardhan Vennapusa472520b2013-10-03 18:37:09 +0530698 unsigned long delay = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200699
Manu Gautamb5067272012-07-02 09:53:41 +0530700 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200701 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
702
703 /* Check OTG state */
704 switch (phy->state) {
705 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530706 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530707 if (!dotg->psy) {
708 dotg->psy = power_supply_get_by_name("usb");
709
710 if (!dotg->psy)
711 dev_err(phy->dev,
712 "couldn't get usb power supply\n");
713 }
714
Manu Gautam8c642812012-06-07 10:35:10 +0530715 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530716 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530717 dev_dbg(phy->dev, "!id\n");
718 phy->state = OTG_STATE_A_IDLE;
719 work = 1;
720 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
721 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200722 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530723 work = 1;
724 } else {
725 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530726 dev_dbg(phy->dev, "No device, trying to suspend\n");
727 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200728 }
729 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530730
731 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530732 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530733 dev_dbg(phy->dev, "!id\n");
734 phy->state = OTG_STATE_A_IDLE;
735 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530736 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530737 if (charger) {
738 if (charger->chg_type == DWC3_INVALID_CHARGER)
739 charger->start_detection(dotg->charger,
740 false);
741 else
742 charger->chg_type =
743 DWC3_INVALID_CHARGER;
744 }
745 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
746 dev_dbg(phy->dev, "b_sess_vld\n");
747 if (charger) {
748 /* Has charger been detected? If no detect it */
749 switch (charger->chg_type) {
750 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530751 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530752 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530753 dwc3_otg_set_power(phy,
754 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530755 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530756 break;
757 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530758 dwc3_otg_set_power(phy,
759 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530760 dwc3_otg_start_peripheral(&dotg->otg,
761 1);
762 phy->state = OTG_STATE_B_PERIPHERAL;
763 work = 1;
764 break;
765 case DWC3_SDP_CHARGER:
766 dwc3_otg_start_peripheral(&dotg->otg,
767 1);
768 phy->state = OTG_STATE_B_PERIPHERAL;
769 work = 1;
770 break;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530771 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusac4974862013-07-23 17:36:37 +0530772 if (dotg->charger_retry_count <
773 max_chgr_retry_count)
774 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530775 /*
776 * In case of floating charger, if
777 * retry count equal to max retry count
778 * notify PMIC about floating charger
779 * and put Hw in low power mode. Else
780 * perform charger detection again by
781 * calling start_detection() with false
782 * and then with true argument.
783 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530784 if (dotg->charger_retry_count ==
785 max_chgr_retry_count) {
786 dwc3_otg_set_power(phy, 0);
787 pm_runtime_put_sync(phy->dev);
788 break;
789 }
790 charger->start_detection(dotg->charger,
791 false);
792
Manu Gautam8c642812012-06-07 10:35:10 +0530793 default:
794 dev_dbg(phy->dev, "chg_det started\n");
795 charger->start_detection(charger, true);
796 break;
797 }
798 } else {
799 /* no charger registered, start peripheral */
800 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
801 /*
802 * Probably set_peripheral not called
803 * yet. We will re-try as soon as it
804 * will be called
805 */
Manu Gautamb5067272012-07-02 09:53:41 +0530806 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530807 "unable to start B-device\n");
808 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530809 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530810 return;
811 }
812 }
813 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530814 if (charger)
815 charger->start_detection(dotg->charger, false);
816
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530817 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530818 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530819 dev_dbg(phy->dev, "No device, trying to suspend\n");
820 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530821 }
822 break;
823
824 case OTG_STATE_B_PERIPHERAL:
825 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
826 !test_bit(ID, &dotg->inputs)) {
827 dev_dbg(phy->dev, "!id || !bsv\n");
828 dwc3_otg_start_peripheral(&dotg->otg, 0);
829 phy->state = OTG_STATE_B_IDLE;
830 if (charger)
831 charger->chg_type = DWC3_INVALID_CHARGER;
832 work = 1;
833 }
834 break;
835
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200836 case OTG_STATE_A_IDLE:
837 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530838 if (test_bit(ID, &dotg->inputs)) {
839 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200840 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530841 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530842 work = 1;
843 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530844 phy->state = OTG_STATE_A_HOST;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530845 ret = dwc3_otg_start_host(&dotg->otg, 1);
846 if ((ret == -EPROBE_DEFER) &&
847 dotg->vbus_retry_count < 3) {
848 /*
849 * Get regulator failed as regulator driver is
850 * not up yet. Will try to start host after 1sec
851 */
852 phy->state = OTG_STATE_A_IDLE;
853 dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n");
854 delay = VBUS_REG_CHECK_DELAY;
855 work = 1;
856 dotg->vbus_retry_count++;
857 } else if (ret) {
Manu Gautam8c642812012-06-07 10:35:10 +0530858 /*
859 * Probably set_host was not called yet.
860 * We will re-try as soon as it will be called
861 */
Manu Gautamb5067272012-07-02 09:53:41 +0530862 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530863 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530864 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530865 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530866 return;
867 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200868 }
869 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530870
871 case OTG_STATE_A_HOST:
872 if (test_bit(ID, &dotg->inputs)) {
873 dev_dbg(phy->dev, "id\n");
874 dwc3_otg_start_host(&dotg->otg, 0);
875 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530876 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530877 work = 1;
878 }
879 break;
880
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200881 default:
882 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
883
884 }
Manu Gautam8c642812012-06-07 10:35:10 +0530885
886 if (work)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530887 queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200888}
889
890
891/**
892 * dwc3_otg_reset - reset dwc3 otg registers.
893 *
894 * @w: Pointer to the dwc3 otg workqueue
895 */
896static void dwc3_otg_reset(struct dwc3_otg *dotg)
897{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530898 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530899 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
900
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200901 /*
902 * OCFG[2] - OTG-Version = 1
903 * OCFG[1] - HNPCap = 0
904 * OCFG[0] - SRPCap = 0
905 */
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530906 if (ext_xceiv && !ext_xceiv->otg_capability)
907 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200908
909 /*
910 * OCTL[6] - PeriMode = 1
911 * OCTL[5] - PrtPwrCtl = 0
912 * OCTL[4] - HNPReq = 0
913 * OCTL[3] - SesReq = 0
914 * OCTL[2] - TermSelDLPulse = 0
915 * OCTL[1] - DevSetHNPEn = 0
916 * OCTL[0] - HstSetHNPEn = 0
917 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530918 if (!once) {
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530919 if (ext_xceiv && !ext_xceiv->otg_capability)
920 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530921 once++;
922 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200923
924 /* Clear all otg events (interrupts) indications */
925 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
926
Manu Gautam8c642812012-06-07 10:35:10 +0530927 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530928 if (ext_xceiv && !ext_xceiv->otg_capability)
929 dwc3_writel(dotg->regs, DWC3_OEVTEN,
930 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
931 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200932}
933
934/**
935 * dwc3_otg_init - Initializes otg related registers
936 * @dwc: Pointer to out controller context structure
937 *
938 * Returns 0 on success otherwise negative errno.
939 */
940int dwc3_otg_init(struct dwc3 *dwc)
941{
942 u32 reg;
943 int ret = 0;
944 struct dwc3_otg *dotg;
945
946 dev_dbg(dwc->dev, "dwc3_otg_init\n");
947
948 /*
949 * GHWPARAMS6[10] bit is SRPSupport.
950 * This bit also reflects DWC_USB3_EN_OTG
951 */
952 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
953 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
954 /*
955 * No OTG support in the HW core.
956 * We return 0 to indicate no error, since this is acceptable
957 * situation, just continue probe the dwc3 driver without otg.
958 */
959 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
960 return 0;
961 }
962
963 /* Allocate and init otg instance */
964 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
965 if (!dotg) {
966 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
967 return -ENOMEM;
968 }
969
Manu Gautam17206c22012-06-21 10:17:53 +0530970 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
971 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
972 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200973 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530974 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200975 ret = -ENODEV;
976 goto err1;
977 }
978
979 dotg->regs = dwc->regs;
980
981 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
982 dotg->otg.set_host = dwc3_otg_set_host;
983
984 /* This reference is used by dwc3 modules for checking otg existance */
985 dwc->dotg = dotg;
986
987 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
988 if (!dotg->otg.phy) {
989 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
990 ret = -ENOMEM;
991 goto err1;
992 }
993
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530994 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200995 dotg->otg.phy->otg = &dotg->otg;
996 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530997 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530998 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200999
1000 ret = usb_set_transceiver(dotg->otg.phy);
1001 if (ret) {
1002 dev_err(dotg->otg.phy->dev,
1003 "%s: failed to set transceiver, already exists\n",
1004 __func__);
1005 goto err2;
1006 }
1007
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001008 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
1009
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +05301010 init_completion(&dotg->dwc3_xcvr_vbus_init);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301011 INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001012
1013 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
1014 "dwc3_otg", dotg);
1015 if (ret) {
1016 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
1017 dotg->irq, ret);
1018 goto err3;
1019 }
1020
Manu Gautamb5067272012-07-02 09:53:41 +05301021 pm_runtime_get(dwc->dev);
1022
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001023 return 0;
1024
1025err3:
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301026 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001027 usb_set_transceiver(NULL);
1028err2:
1029 kfree(dotg->otg.phy);
1030err1:
1031 dwc->dotg = NULL;
1032 kfree(dotg);
1033
1034 return ret;
1035}
1036
1037/**
1038 * dwc3_otg_exit
1039 * @dwc: Pointer to out controller context structure
1040 *
1041 * Returns 0 on success otherwise negative errno.
1042 */
1043void dwc3_otg_exit(struct dwc3 *dwc)
1044{
1045 struct dwc3_otg *dotg = dwc->dotg;
1046
1047 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
1048 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +05301049 if (dotg->charger)
1050 dotg->charger->start_detection(dotg->charger, false);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301051 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001052 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +05301053 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001054 free_irq(dotg->irq, dotg);
1055 kfree(dotg->otg.phy);
1056 kfree(dotg);
1057 dwc->dotg = NULL;
1058 }
1059}