blob: 8a034d63c4ba0b3f691a1af0e4214fd840c55006 [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
Jack Pham18321fa2014-01-10 20:24:01 -0800200 dwc3_otg_notify_host_mode(otg, on);
201 ret = regulator_enable(dotg->vbus_otg);
202 if (ret) {
203 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
204 dwc3_otg_notify_host_mode(otg, 0);
205 return ret;
206 }
207
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200208 /*
209 * This should be revisited for more testing post-silicon.
210 * In worst case we may need to disconnect the root hub
211 * before stopping the controller so that it does not
212 * interfere with runtime pm/system pm.
213 * We can also consider registering and unregistering xhci
214 * platform device. It is almost similar to add_hcd and
215 * remove_hcd, But we may not use standard set_host method
216 * anymore.
217 */
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530218 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530219 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530220 /*
221 * FIXME If micro A cable is disconnected during system suspend,
222 * xhci platform device will be removed before runtime pm is
223 * enabled for xhci device. Due to this, disable_depth becomes
224 * greater than one and runtimepm is not enabled for next microA
225 * connect. Fix this by calling pm_runtime_init for xhci device.
226 */
227 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530228 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200229 if (ret) {
230 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530231 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200232 __func__, ret);
Jack Pham18321fa2014-01-10 20:24:01 -0800233 regulator_disable(dotg->vbus_otg);
234 dwc3_otg_notify_host_mode(otg, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200235 return ret;
236 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530237
238 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530239 if (ext_xceiv && !ext_xceiv->otg_capability)
240 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200241 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530242 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
243
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530244 ret = regulator_disable(dotg->vbus_otg);
245 if (ret) {
246 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
247 return ret;
248 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530249 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530250
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530251 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530252 /*
253 * Perform USB hardware RESET (both core reset and DBM reset)
254 * when moving from host to peripheral. This is required for
255 * peripheral mode to work.
256 */
257 if (ext_xceiv && ext_xceiv->otg_capability &&
258 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700259 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530260
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530261 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Manu Gautamab3da1b2013-04-02 14:29:01 +0530262 dwc3_otg_set_peripheral_regs(dotg);
263
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530264 /* re-init core and OTG registers as block reset clears these */
265 dwc3_post_host_reset_core_init(dwc);
266 if (ext_xceiv && !ext_xceiv->otg_capability)
267 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200268 }
269
270 return 0;
271}
272
273/**
274 * dwc3_otg_set_host - bind/unbind the host controller driver.
275 *
276 * @otg: Pointer to the otg_transceiver structure.
277 * @host: Pointer to the usb_bus structure.
278 *
279 * Returns 0 on success otherwise negative errno.
280 */
281static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
282{
283 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
284
285 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530286 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200287 __func__, host->bus_name);
288 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200289 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530290 * Though XHCI power would be set by now, but some delay is
291 * required for XHCI controller before setting OTG Port Power
292 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200293 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530294 msleep(300);
295 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200296 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530297 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200298 }
299
300 return 0;
301}
302
303/**
304 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
305 *
306 * @otg: Pointer to the otg_transceiver structure.
307 * @gadget: pointer to the usb_gadget structure.
308 *
309 * Returns 0 on success otherwise negative errno.
310 */
311static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
312{
313 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530314 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200315
316 if (!otg->gadget)
317 return -EINVAL;
318
319 if (on) {
320 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
321 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530322
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530323 /* Core reset is not required during start peripheral. Only
324 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530325 if (ext_xceiv && ext_xceiv->otg_capability &&
326 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700327 ext_xceiv->ext_block_reset(ext_xceiv, false);
Manu Gautama302f612012-12-18 17:33:06 +0530328
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530329 dwc3_otg_set_hsphy_auto_suspend(dotg, true);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200330 dwc3_otg_set_peripheral_regs(dotg);
331 usb_gadget_vbus_connect(otg->gadget);
332 } else {
333 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
334 __func__, otg->gadget->name);
335 usb_gadget_vbus_disconnect(otg->gadget);
Vijayavardhan Vennapusa47786ef2013-11-11 13:03:19 +0530336 dwc3_otg_set_hsphy_auto_suspend(dotg, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200337 }
338
339 return 0;
340}
341
342/**
343 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
344 *
345 * @otg: Pointer to the otg_transceiver structure.
346 * @gadget: pointer to the usb_gadget structure.
347 *
348 * Returns 0 on success otherwise negative errno.
349 */
350static int dwc3_otg_set_peripheral(struct usb_otg *otg,
351 struct usb_gadget *gadget)
352{
353 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
354
355 if (gadget) {
356 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
357 __func__, gadget->name);
358 otg->gadget = gadget;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530359 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200360 } else {
361 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
362 dwc3_otg_start_peripheral(otg, 0);
363 otg->gadget = NULL;
364 otg->phy->state = OTG_STATE_UNDEFINED;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530365 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200366 } else {
367 otg->gadget = NULL;
368 }
369 }
370
371 return 0;
372}
373
374/**
Manu Gautam8c642812012-06-07 10:35:10 +0530375 * dwc3_ext_chg_det_done - callback to handle charger detection completion
376 * @otg: Pointer to the otg transceiver structure
377 * @charger: Pointer to the external charger structure
378 *
379 * Returns 0 on success
380 */
381static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
382{
383 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
384
385 /*
386 * Ignore chg_detection notification if BSV has gone off by this time.
387 * STOP chg_det as part of !BSV handling would reset the chg_det flags
388 */
389 if (test_bit(B_SESS_VLD, &dotg->inputs))
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530390 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautam8c642812012-06-07 10:35:10 +0530391}
392
393/**
394 * dwc3_set_charger - bind/unbind external charger driver
395 * @otg: Pointer to the otg transceiver structure
396 * @charger: Pointer to the external charger structure
397 *
398 * Returns 0 on success
399 */
400int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
401{
402 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
403
404 dotg->charger = charger;
405 if (charger)
406 charger->notify_detection_complete = dwc3_ext_chg_det_done;
407
408 return 0;
409}
410
Manu Gautamb5067272012-07-02 09:53:41 +0530411/**
412 * dwc3_ext_event_notify - callback to handle events from external transceiver
413 * @otg: Pointer to the otg transceiver structure
414 * @event: Event reported by transceiver
415 *
416 * Returns 0 on success
417 */
418static void dwc3_ext_event_notify(struct usb_otg *otg,
419 enum dwc3_ext_events event)
420{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530421 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530422 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
423 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
424 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530425 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530426
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530427 /* Flush processing any pending events before handling new ones */
428 if (init)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530429 flush_delayed_work(&dotg->sm_work);
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530430
Manu Gautamb5067272012-07-02 09:53:41 +0530431 if (event == DWC3_EVENT_PHY_RESUME) {
432 if (!pm_runtime_status_suspended(phy->dev)) {
433 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
434 } else {
435 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
436 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530437 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530438 if ((phy->state == OTG_STATE_A_HOST) &&
439 dotg->host_bus_suspend)
440 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530441 if (ret == -EACCES) {
442 /* pm_runtime_get may fail during system
443 resume with -EACCES error */
444 pm_runtime_disable(phy->dev);
445 pm_runtime_set_active(phy->dev);
446 pm_runtime_enable(phy->dev);
447 } else if (ret < 0) {
448 dev_warn(phy->dev, "pm_runtime_get failed!\n");
449 }
Manu Gautamb5067272012-07-02 09:53:41 +0530450 }
Manu Gautam377821c2012-09-28 16:53:24 +0530451 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530452 if (pm_runtime_status_suspended(phy->dev)) {
453 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
454 ret = pm_runtime_get(phy->dev);
455 if (ret < 0)
456 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
457 }
Jack Pham0fc12332012-11-19 13:14:22 -0800458 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530459 dev_dbg(phy->dev, "XCVR: ID set\n");
460 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800461 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530462 dev_dbg(phy->dev, "XCVR: ID clear\n");
463 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800464 }
Manu Gautam377821c2012-09-28 16:53:24 +0530465
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530466 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530467 dev_dbg(phy->dev, "XCVR: BSV set\n");
468 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530469 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530470 dev_dbg(phy->dev, "XCVR: BSV clear\n");
471 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530472 }
Manu Gautam377821c2012-09-28 16:53:24 +0530473
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530474 if (!init) {
475 init = true;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530476 if (!work_busy(&dotg->sm_work.work))
477 queue_delayed_work(system_nrt_wq,
478 &dotg->sm_work, 0);
Manu Gautam4ff07242013-03-27 14:31:11 +0530479
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530480 complete(&dotg->dwc3_xcvr_vbus_init);
481 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
482 return;
483 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530484
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530485 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530486 }
Manu Gautamb5067272012-07-02 09:53:41 +0530487}
488
489/**
490 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
491 * @otg: Pointer to the otg transceiver structure
492 * @ext_xceiv: Pointer to the external transceiver struccture
493 *
494 * Returns 0 on success
495 */
496int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
497{
498 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
499
500 dotg->ext_xceiv = ext_xceiv;
501 if (ext_xceiv)
502 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
503
504 return 0;
505}
506
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530507static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
508{
509 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
510
511 if (!dotg->psy) {
512 dev_err(otg->phy->dev, "no usb power supply registered\n");
513 return;
514 }
515
516 if (host_mode)
517 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
518 else
519 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
520}
521
522static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
523{
524 static int power_supply_type;
525 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
526
527
Manu Gautam6c0ff032012-11-02 14:55:35 +0530528 if (!dotg->psy || !dotg->charger) {
529 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530530 return 0;
531 }
532
Manu Gautam6c0ff032012-11-02 14:55:35 +0530533 if (dotg->charger->charging_disabled)
534 return 0;
535
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530536 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
537 power_supply_type = POWER_SUPPLY_TYPE_USB;
538 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
539 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530540 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
541 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530542 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
543 else
544 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
545
546 power_supply_set_supply_type(dotg->psy, power_supply_type);
547
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530548 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530549 mA = DWC3_IDEV_CHG_MAX;
550
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530551 if (dotg->charger->max_power == mA)
552 return 0;
553
554 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
555
556 if (dotg->charger->max_power <= 2 && mA > 2) {
557 /* Enable charging */
558 if (power_supply_set_online(dotg->psy, true))
559 goto psy_error;
560 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
561 goto psy_error;
562 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
563 /* Disable charging */
564 if (power_supply_set_online(dotg->psy, false))
565 goto psy_error;
566 /* Set max current limit */
567 if (power_supply_set_current_limit(dotg->psy, 0))
568 goto psy_error;
569 }
570
571 power_supply_changed(dotg->psy);
572 dotg->charger->max_power = mA;
573 return 0;
574
575psy_error:
576 dev_dbg(phy->dev, "power supply error when setting property\n");
577 return -ENXIO;
578}
579
Manu Gautam8c642812012-06-07 10:35:10 +0530580/* IRQs which OTG driver is interested in handling */
581#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
582 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
583
584/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200585 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
586 * @_dotg: Pointer to out controller context structure
587 *
588 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
589 */
590static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
591{
592 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530593 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200594 int ret = IRQ_NONE;
595 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530596 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200597
598 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
599
Manu Gautam8c642812012-06-07 10:35:10 +0530600 if (!(oevt_reg & DWC3_OEVT_MASK))
601 return IRQ_NONE;
602
603 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
604
605 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
606 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200607 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530608 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200609 * function, switch from A to B or from B to A.
610 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200611
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530612 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
613 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
614 dev_dbg(phy->dev, "ID set\n");
615 set_bit(ID, &dotg->inputs);
616 } else {
617 dev_dbg(phy->dev, "ID clear\n");
618 clear_bit(ID, &dotg->inputs);
619 }
620 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
621 }
Manu Gautam8c642812012-06-07 10:35:10 +0530622
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530623 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
624 if (osts & DWC3_OTG_OSTS_BSESVALID) {
625 dev_dbg(phy->dev, "BSV set\n");
626 set_bit(B_SESS_VLD, &dotg->inputs);
627 } else {
628 dev_dbg(phy->dev, "BSV clear\n");
629 clear_bit(B_SESS_VLD, &dotg->inputs);
630 }
631 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
632 }
Manu Gautam8c642812012-06-07 10:35:10 +0530633
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530634 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200635
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200636 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530637
638 /* Clear the interrupts we handled */
639 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200640 }
641
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200642 return ret;
643}
644
645/**
Manu Gautam8c642812012-06-07 10:35:10 +0530646 * dwc3_otg_init_sm - initialize OTG statemachine input
647 * @dotg: Pointer to the dwc3_otg structure
648 *
649 */
650void dwc3_otg_init_sm(struct dwc3_otg *dotg)
651{
652 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
653 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530654 struct dwc3_ext_xceiv *ext_xceiv;
655 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530656
657 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
658
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530659 /*
660 * VBUS initial state is reported after PMIC
661 * driver initialization. Wait for it.
662 */
663 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530664 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530665 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530666 /* We can safely assume no cable connected */
667 set_bit(ID, &dotg->inputs);
668 }
Manu Gautam8c642812012-06-07 10:35:10 +0530669
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530670 ext_xceiv = dotg->ext_xceiv;
671 dwc3_otg_reset(dotg);
672 if (ext_xceiv && !ext_xceiv->otg_capability) {
673 if (osts & DWC3_OTG_OSTS_CONIDSTS)
674 set_bit(ID, &dotg->inputs);
675 else
676 clear_bit(ID, &dotg->inputs);
677
678 if (osts & DWC3_OTG_OSTS_BSESVALID)
679 set_bit(B_SESS_VLD, &dotg->inputs);
680 else
681 clear_bit(B_SESS_VLD, &dotg->inputs);
682 }
Manu Gautam8c642812012-06-07 10:35:10 +0530683}
684
685/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200686 * dwc3_otg_sm_work - workqueue function.
687 *
688 * @w: Pointer to the dwc3 otg workqueue
689 *
690 * NOTE: After any change in phy->state,
691 * we must reschdule the state machine.
692 */
693static void dwc3_otg_sm_work(struct work_struct *w)
694{
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530695 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200696 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530697 struct dwc3_charger *charger = dotg->charger;
698 bool work = 0;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530699 int ret = 0;
Vijayavardhan Vennapusa472520b2013-10-03 18:37:09 +0530700 unsigned long delay = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200701
Manu Gautamb5067272012-07-02 09:53:41 +0530702 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200703 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
704
705 /* Check OTG state */
706 switch (phy->state) {
707 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530708 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530709 if (!dotg->psy) {
710 dotg->psy = power_supply_get_by_name("usb");
711
712 if (!dotg->psy)
713 dev_err(phy->dev,
714 "couldn't get usb power supply\n");
715 }
716
Manu Gautam8c642812012-06-07 10:35:10 +0530717 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530718 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530719 dev_dbg(phy->dev, "!id\n");
720 phy->state = OTG_STATE_A_IDLE;
721 work = 1;
722 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
723 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200724 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530725 work = 1;
726 } else {
727 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530728 dev_dbg(phy->dev, "No device, trying to suspend\n");
729 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200730 }
731 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530732
733 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530734 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530735 dev_dbg(phy->dev, "!id\n");
736 phy->state = OTG_STATE_A_IDLE;
737 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530738 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530739 if (charger) {
740 if (charger->chg_type == DWC3_INVALID_CHARGER)
741 charger->start_detection(dotg->charger,
742 false);
743 else
744 charger->chg_type =
745 DWC3_INVALID_CHARGER;
746 }
747 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
748 dev_dbg(phy->dev, "b_sess_vld\n");
749 if (charger) {
750 /* Has charger been detected? If no detect it */
751 switch (charger->chg_type) {
752 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530753 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530754 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530755 dwc3_otg_set_power(phy,
756 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530757 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530758 break;
759 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530760 dwc3_otg_set_power(phy,
761 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530762 dwc3_otg_start_peripheral(&dotg->otg,
763 1);
764 phy->state = OTG_STATE_B_PERIPHERAL;
765 work = 1;
766 break;
767 case DWC3_SDP_CHARGER:
768 dwc3_otg_start_peripheral(&dotg->otg,
769 1);
770 phy->state = OTG_STATE_B_PERIPHERAL;
771 work = 1;
772 break;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530773 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusac4974862013-07-23 17:36:37 +0530774 if (dotg->charger_retry_count <
775 max_chgr_retry_count)
776 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530777 /*
778 * In case of floating charger, if
779 * retry count equal to max retry count
780 * notify PMIC about floating charger
781 * and put Hw in low power mode. Else
782 * perform charger detection again by
783 * calling start_detection() with false
784 * and then with true argument.
785 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530786 if (dotg->charger_retry_count ==
787 max_chgr_retry_count) {
788 dwc3_otg_set_power(phy, 0);
789 pm_runtime_put_sync(phy->dev);
790 break;
791 }
792 charger->start_detection(dotg->charger,
793 false);
794
Manu Gautam8c642812012-06-07 10:35:10 +0530795 default:
796 dev_dbg(phy->dev, "chg_det started\n");
797 charger->start_detection(charger, true);
798 break;
799 }
800 } else {
801 /* no charger registered, start peripheral */
802 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
803 /*
804 * Probably set_peripheral not called
805 * yet. We will re-try as soon as it
806 * will be called
807 */
Manu Gautamb5067272012-07-02 09:53:41 +0530808 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530809 "unable to start B-device\n");
810 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530811 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530812 return;
813 }
814 }
815 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530816 if (charger)
817 charger->start_detection(dotg->charger, false);
818
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530819 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530820 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530821 dev_dbg(phy->dev, "No device, trying to suspend\n");
822 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530823 }
824 break;
825
826 case OTG_STATE_B_PERIPHERAL:
827 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
828 !test_bit(ID, &dotg->inputs)) {
829 dev_dbg(phy->dev, "!id || !bsv\n");
830 dwc3_otg_start_peripheral(&dotg->otg, 0);
831 phy->state = OTG_STATE_B_IDLE;
832 if (charger)
833 charger->chg_type = DWC3_INVALID_CHARGER;
834 work = 1;
835 }
836 break;
837
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200838 case OTG_STATE_A_IDLE:
839 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530840 if (test_bit(ID, &dotg->inputs)) {
841 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200842 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530843 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530844 work = 1;
845 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530846 phy->state = OTG_STATE_A_HOST;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530847 ret = dwc3_otg_start_host(&dotg->otg, 1);
848 if ((ret == -EPROBE_DEFER) &&
849 dotg->vbus_retry_count < 3) {
850 /*
851 * Get regulator failed as regulator driver is
852 * not up yet. Will try to start host after 1sec
853 */
854 phy->state = OTG_STATE_A_IDLE;
855 dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n");
856 delay = VBUS_REG_CHECK_DELAY;
857 work = 1;
858 dotg->vbus_retry_count++;
859 } else if (ret) {
Manu Gautam8c642812012-06-07 10:35:10 +0530860 /*
861 * Probably set_host was not called yet.
862 * We will re-try as soon as it will be called
863 */
Manu Gautamb5067272012-07-02 09:53:41 +0530864 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530865 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530866 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530867 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530868 return;
869 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200870 }
871 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530872
873 case OTG_STATE_A_HOST:
874 if (test_bit(ID, &dotg->inputs)) {
875 dev_dbg(phy->dev, "id\n");
876 dwc3_otg_start_host(&dotg->otg, 0);
877 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530878 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530879 work = 1;
880 }
881 break;
882
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200883 default:
884 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
885
886 }
Manu Gautam8c642812012-06-07 10:35:10 +0530887
888 if (work)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530889 queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200890}
891
892
893/**
894 * dwc3_otg_reset - reset dwc3 otg registers.
895 *
896 * @w: Pointer to the dwc3 otg workqueue
897 */
898static void dwc3_otg_reset(struct dwc3_otg *dotg)
899{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530900 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530901 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
902
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200903 /*
904 * OCFG[2] - OTG-Version = 1
905 * OCFG[1] - HNPCap = 0
906 * OCFG[0] - SRPCap = 0
907 */
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530908 if (ext_xceiv && !ext_xceiv->otg_capability)
909 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200910
911 /*
912 * OCTL[6] - PeriMode = 1
913 * OCTL[5] - PrtPwrCtl = 0
914 * OCTL[4] - HNPReq = 0
915 * OCTL[3] - SesReq = 0
916 * OCTL[2] - TermSelDLPulse = 0
917 * OCTL[1] - DevSetHNPEn = 0
918 * OCTL[0] - HstSetHNPEn = 0
919 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530920 if (!once) {
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530921 if (ext_xceiv && !ext_xceiv->otg_capability)
922 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530923 once++;
924 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200925
926 /* Clear all otg events (interrupts) indications */
927 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
928
Manu Gautam8c642812012-06-07 10:35:10 +0530929 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530930 if (ext_xceiv && !ext_xceiv->otg_capability)
931 dwc3_writel(dotg->regs, DWC3_OEVTEN,
932 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
933 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200934}
935
936/**
937 * dwc3_otg_init - Initializes otg related registers
938 * @dwc: Pointer to out controller context structure
939 *
940 * Returns 0 on success otherwise negative errno.
941 */
942int dwc3_otg_init(struct dwc3 *dwc)
943{
944 u32 reg;
945 int ret = 0;
946 struct dwc3_otg *dotg;
947
948 dev_dbg(dwc->dev, "dwc3_otg_init\n");
949
950 /*
951 * GHWPARAMS6[10] bit is SRPSupport.
952 * This bit also reflects DWC_USB3_EN_OTG
953 */
954 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
955 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
956 /*
957 * No OTG support in the HW core.
958 * We return 0 to indicate no error, since this is acceptable
959 * situation, just continue probe the dwc3 driver without otg.
960 */
961 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
962 return 0;
963 }
964
965 /* Allocate and init otg instance */
966 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
967 if (!dotg) {
968 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
969 return -ENOMEM;
970 }
971
Manu Gautam17206c22012-06-21 10:17:53 +0530972 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
973 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
974 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200975 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530976 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200977 ret = -ENODEV;
978 goto err1;
979 }
980
981 dotg->regs = dwc->regs;
982
983 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
984 dotg->otg.set_host = dwc3_otg_set_host;
985
986 /* This reference is used by dwc3 modules for checking otg existance */
987 dwc->dotg = dotg;
988
989 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
990 if (!dotg->otg.phy) {
991 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
992 ret = -ENOMEM;
993 goto err1;
994 }
995
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530996 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200997 dotg->otg.phy->otg = &dotg->otg;
998 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530999 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +05301000 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001001
1002 ret = usb_set_transceiver(dotg->otg.phy);
1003 if (ret) {
1004 dev_err(dotg->otg.phy->dev,
1005 "%s: failed to set transceiver, already exists\n",
1006 __func__);
1007 goto err2;
1008 }
1009
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001010 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
1011
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +05301012 init_completion(&dotg->dwc3_xcvr_vbus_init);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301013 INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001014
1015 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
1016 "dwc3_otg", dotg);
1017 if (ret) {
1018 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
1019 dotg->irq, ret);
1020 goto err3;
1021 }
1022
Manu Gautamb5067272012-07-02 09:53:41 +05301023 pm_runtime_get(dwc->dev);
1024
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001025 return 0;
1026
1027err3:
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301028 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001029 usb_set_transceiver(NULL);
1030err2:
1031 kfree(dotg->otg.phy);
1032err1:
1033 dwc->dotg = NULL;
1034 kfree(dotg);
1035
1036 return ret;
1037}
1038
1039/**
1040 * dwc3_otg_exit
1041 * @dwc: Pointer to out controller context structure
1042 *
1043 * Returns 0 on success otherwise negative errno.
1044 */
1045void dwc3_otg_exit(struct dwc3 *dwc)
1046{
1047 struct dwc3_otg *dotg = dwc->dotg;
1048
1049 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
1050 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +05301051 if (dotg->charger)
1052 dotg->charger->start_detection(dotg->charger, false);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301053 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001054 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +05301055 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001056 free_irq(dotg->irq, dotg);
1057 kfree(dotg->otg.phy);
1058 kfree(dotg);
1059 dwc->dotg = NULL;
1060 }
1061}