blob: 5348eb52114dc727e1fd257ccffce6a99a022408 [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 Vennapusafddeb0f2013-09-26 17:26:13 +053027#define VBUS_REG_CHECK_DELAY (jiffies + 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
Manu Gautamf1fceddf2012-10-12 14:02:50 +053096/**
97 * dwc3_otg_set_host_power - Enable port power control for host operation
98 *
99 * This function enables the OTG Port Power required to operate in Host mode
100 * This function should be called only after XHCI driver has set the port
101 * power in PORTSC register.
102 *
103 * @w: Pointer to the dwc3 otg struct
104 */
105void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
106{
107 u32 osts;
108
109 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
110 if (!(osts & 0x8))
111 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
112
113 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200114}
115
116/**
117 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
118 *
119 * This function sets the OTG registers to work in B-Device peripheral mode.
120 * This function should be called just before entering to B-Device mode.
121 *
122 * @w: Pointer to the dwc3 otg workqueue.
123 */
124static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
125{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530126 u32 reg;
127 struct dwc3 *dwc = dotg->dwc;
128 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200129
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530130 if (ext_xceiv && !ext_xceiv->otg_capability) {
131 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
132 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
133 reg |= DWC3_OTG_OCTL_PERIMODE;
134 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
135 /*
136 * TODO: add more OTG registers writes for PERIPHERAL mode here,
137 * see figure 12-19 B-device flow in dwc3 Synopsis spec
138 */
139 } else {
140 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
141 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
142 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530143 /*
144 * Set this bit so that device attempts three more times at SS,
145 * even if it failed previously to operate in SS mode.
146 */
147 reg |= DWC3_GCTL_U2RSTECN;
148 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
149 reg |= DWC3_GCTL_PWRDNSCALE(2);
150 reg &= ~(DWC3_GCTL_SOFITPSYNC);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530151 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
152 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200153}
154
155/**
156 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
157 *
158 * @otg: Pointer to the otg_transceiver structure.
159 * @on: start / stop the host controller driver.
160 *
161 * Returns 0 on success otherwise negative errno.
162 */
163static int dwc3_otg_start_host(struct usb_otg *otg, int on)
164{
165 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530166 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530167 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200168 int ret = 0;
169
Manu Gautam61721592012-11-06 18:09:39 +0530170 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200171 return -EINVAL;
172
Manu Gautam61721592012-11-06 18:09:39 +0530173 if (!dotg->vbus_otg) {
174 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
175 "vbus_dwc3");
176 if (IS_ERR(dotg->vbus_otg)) {
177 dev_err(dwc->dev, "Failed to get vbus regulator\n");
178 ret = PTR_ERR(dotg->vbus_otg);
179 dotg->vbus_otg = 0;
180 return ret;
181 }
182 }
183
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200184 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530185 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200186
187 /*
188 * This should be revisited for more testing post-silicon.
189 * In worst case we may need to disconnect the root hub
190 * before stopping the controller so that it does not
191 * interfere with runtime pm/system pm.
192 * We can also consider registering and unregistering xhci
193 * platform device. It is almost similar to add_hcd and
194 * remove_hcd, But we may not use standard set_host method
195 * anymore.
196 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530197 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530198 /*
199 * FIXME If micro A cable is disconnected during system suspend,
200 * xhci platform device will be removed before runtime pm is
201 * enabled for xhci device. Due to this, disable_depth becomes
202 * greater than one and runtimepm is not enabled for next microA
203 * connect. Fix this by calling pm_runtime_init for xhci device.
204 */
205 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530206 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200207 if (ret) {
208 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530209 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200210 __func__, ret);
211 return ret;
212 }
213
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530214 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530215 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200216 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530217 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530218 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200219 return ret;
220 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530221
222 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530223 if (ext_xceiv && !ext_xceiv->otg_capability)
224 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200225 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530226 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
227
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530228 ret = regulator_disable(dotg->vbus_otg);
229 if (ret) {
230 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
231 return ret;
232 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530233 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530234
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530235 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530236 /*
237 * Perform USB hardware RESET (both core reset and DBM reset)
238 * when moving from host to peripheral. This is required for
239 * peripheral mode to work.
240 */
241 if (ext_xceiv && ext_xceiv->otg_capability &&
242 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700243 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530244
Manu Gautamab3da1b2013-04-02 14:29:01 +0530245 dwc3_otg_set_peripheral_regs(dotg);
246
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530247 /* re-init core and OTG registers as block reset clears these */
248 dwc3_post_host_reset_core_init(dwc);
249 if (ext_xceiv && !ext_xceiv->otg_capability)
250 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200251 }
252
253 return 0;
254}
255
256/**
257 * dwc3_otg_set_host - bind/unbind the host controller driver.
258 *
259 * @otg: Pointer to the otg_transceiver structure.
260 * @host: Pointer to the usb_bus structure.
261 *
262 * Returns 0 on success otherwise negative errno.
263 */
264static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
265{
266 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
267
268 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530269 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200270 __func__, host->bus_name);
271 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200272 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530273 * Though XHCI power would be set by now, but some delay is
274 * required for XHCI controller before setting OTG Port Power
275 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200276 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530277 msleep(300);
278 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200279 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530280 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200281 }
282
283 return 0;
284}
285
286/**
287 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
288 *
289 * @otg: Pointer to the otg_transceiver structure.
290 * @gadget: pointer to the usb_gadget structure.
291 *
292 * Returns 0 on success otherwise negative errno.
293 */
294static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
295{
296 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530297 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200298
299 if (!otg->gadget)
300 return -EINVAL;
301
302 if (on) {
303 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
304 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530305
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530306 /* Core reset is not required during start peripheral. Only
307 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530308 if (ext_xceiv && ext_xceiv->otg_capability &&
309 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700310 ext_xceiv->ext_block_reset(ext_xceiv, false);
Manu Gautama302f612012-12-18 17:33:06 +0530311
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200312 dwc3_otg_set_peripheral_regs(dotg);
313 usb_gadget_vbus_connect(otg->gadget);
314 } else {
315 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
316 __func__, otg->gadget->name);
317 usb_gadget_vbus_disconnect(otg->gadget);
318 }
319
320 return 0;
321}
322
323/**
324 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
325 *
326 * @otg: Pointer to the otg_transceiver structure.
327 * @gadget: pointer to the usb_gadget structure.
328 *
329 * Returns 0 on success otherwise negative errno.
330 */
331static int dwc3_otg_set_peripheral(struct usb_otg *otg,
332 struct usb_gadget *gadget)
333{
334 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
335
336 if (gadget) {
337 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
338 __func__, gadget->name);
339 otg->gadget = gadget;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530340 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200341 } else {
342 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
343 dwc3_otg_start_peripheral(otg, 0);
344 otg->gadget = NULL;
345 otg->phy->state = OTG_STATE_UNDEFINED;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530346 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200347 } else {
348 otg->gadget = NULL;
349 }
350 }
351
352 return 0;
353}
354
355/**
Manu Gautam8c642812012-06-07 10:35:10 +0530356 * dwc3_ext_chg_det_done - callback to handle charger detection completion
357 * @otg: Pointer to the otg transceiver structure
358 * @charger: Pointer to the external charger structure
359 *
360 * Returns 0 on success
361 */
362static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
363{
364 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
365
366 /*
367 * Ignore chg_detection notification if BSV has gone off by this time.
368 * STOP chg_det as part of !BSV handling would reset the chg_det flags
369 */
370 if (test_bit(B_SESS_VLD, &dotg->inputs))
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530371 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautam8c642812012-06-07 10:35:10 +0530372}
373
374/**
375 * dwc3_set_charger - bind/unbind external charger driver
376 * @otg: Pointer to the otg transceiver structure
377 * @charger: Pointer to the external charger structure
378 *
379 * Returns 0 on success
380 */
381int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
382{
383 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
384
385 dotg->charger = charger;
386 if (charger)
387 charger->notify_detection_complete = dwc3_ext_chg_det_done;
388
389 return 0;
390}
391
Manu Gautamb5067272012-07-02 09:53:41 +0530392/**
393 * dwc3_ext_event_notify - callback to handle events from external transceiver
394 * @otg: Pointer to the otg transceiver structure
395 * @event: Event reported by transceiver
396 *
397 * Returns 0 on success
398 */
399static void dwc3_ext_event_notify(struct usb_otg *otg,
400 enum dwc3_ext_events event)
401{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530402 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530403 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
404 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
405 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530406 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530407
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530408 /* Flush processing any pending events before handling new ones */
409 if (init)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530410 flush_delayed_work(&dotg->sm_work);
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530411
Manu Gautamb5067272012-07-02 09:53:41 +0530412 if (event == DWC3_EVENT_PHY_RESUME) {
413 if (!pm_runtime_status_suspended(phy->dev)) {
414 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
415 } else {
416 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
417 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530418 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530419 if ((phy->state == OTG_STATE_A_HOST) &&
420 dotg->host_bus_suspend)
421 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530422 if (ret == -EACCES) {
423 /* pm_runtime_get may fail during system
424 resume with -EACCES error */
425 pm_runtime_disable(phy->dev);
426 pm_runtime_set_active(phy->dev);
427 pm_runtime_enable(phy->dev);
428 } else if (ret < 0) {
429 dev_warn(phy->dev, "pm_runtime_get failed!\n");
430 }
Manu Gautamb5067272012-07-02 09:53:41 +0530431 }
Manu Gautam377821c2012-09-28 16:53:24 +0530432 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530433 if (pm_runtime_status_suspended(phy->dev)) {
434 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
435 ret = pm_runtime_get(phy->dev);
436 if (ret < 0)
437 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
438 }
Jack Pham0fc12332012-11-19 13:14:22 -0800439 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530440 dev_dbg(phy->dev, "XCVR: ID set\n");
441 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800442 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530443 dev_dbg(phy->dev, "XCVR: ID clear\n");
444 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800445 }
Manu Gautam377821c2012-09-28 16:53:24 +0530446
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530447 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530448 dev_dbg(phy->dev, "XCVR: BSV set\n");
449 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530450 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530451 dev_dbg(phy->dev, "XCVR: BSV clear\n");
452 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530453 }
Manu Gautam377821c2012-09-28 16:53:24 +0530454
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530455 if (!init) {
456 init = true;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530457 if (!work_busy(&dotg->sm_work.work))
458 queue_delayed_work(system_nrt_wq,
459 &dotg->sm_work, 0);
Manu Gautam4ff07242013-03-27 14:31:11 +0530460
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530461 complete(&dotg->dwc3_xcvr_vbus_init);
462 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
463 return;
464 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530465
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530466 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530467 }
Manu Gautamb5067272012-07-02 09:53:41 +0530468}
469
470/**
471 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
472 * @otg: Pointer to the otg transceiver structure
473 * @ext_xceiv: Pointer to the external transceiver struccture
474 *
475 * Returns 0 on success
476 */
477int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
478{
479 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
480
481 dotg->ext_xceiv = ext_xceiv;
482 if (ext_xceiv)
483 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
484
485 return 0;
486}
487
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530488static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
489{
490 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
491
492 if (!dotg->psy) {
493 dev_err(otg->phy->dev, "no usb power supply registered\n");
494 return;
495 }
496
497 if (host_mode)
498 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
499 else
500 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
501}
502
503static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
504{
505 static int power_supply_type;
506 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
507
508
Manu Gautam6c0ff032012-11-02 14:55:35 +0530509 if (!dotg->psy || !dotg->charger) {
510 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530511 return 0;
512 }
513
Manu Gautam6c0ff032012-11-02 14:55:35 +0530514 if (dotg->charger->charging_disabled)
515 return 0;
516
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530517 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
518 power_supply_type = POWER_SUPPLY_TYPE_USB;
519 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
520 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530521 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
522 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530523 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
524 else
525 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
526
527 power_supply_set_supply_type(dotg->psy, power_supply_type);
528
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530529 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530530 mA = DWC3_IDEV_CHG_MAX;
531
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530532 if (dotg->charger->max_power == mA)
533 return 0;
534
535 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
536
537 if (dotg->charger->max_power <= 2 && mA > 2) {
538 /* Enable charging */
539 if (power_supply_set_online(dotg->psy, true))
540 goto psy_error;
541 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
542 goto psy_error;
543 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
544 /* Disable charging */
545 if (power_supply_set_online(dotg->psy, false))
546 goto psy_error;
547 /* Set max current limit */
548 if (power_supply_set_current_limit(dotg->psy, 0))
549 goto psy_error;
550 }
551
552 power_supply_changed(dotg->psy);
553 dotg->charger->max_power = mA;
554 return 0;
555
556psy_error:
557 dev_dbg(phy->dev, "power supply error when setting property\n");
558 return -ENXIO;
559}
560
Manu Gautam8c642812012-06-07 10:35:10 +0530561/* IRQs which OTG driver is interested in handling */
562#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
563 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
564
565/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200566 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
567 * @_dotg: Pointer to out controller context structure
568 *
569 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
570 */
571static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
572{
573 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530574 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200575 int ret = IRQ_NONE;
576 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530577 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200578
579 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
580
Manu Gautam8c642812012-06-07 10:35:10 +0530581 if (!(oevt_reg & DWC3_OEVT_MASK))
582 return IRQ_NONE;
583
584 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
585
586 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
587 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200588 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530589 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200590 * function, switch from A to B or from B to A.
591 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200592
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530593 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
594 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
595 dev_dbg(phy->dev, "ID set\n");
596 set_bit(ID, &dotg->inputs);
597 } else {
598 dev_dbg(phy->dev, "ID clear\n");
599 clear_bit(ID, &dotg->inputs);
600 }
601 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
602 }
Manu Gautam8c642812012-06-07 10:35:10 +0530603
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530604 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
605 if (osts & DWC3_OTG_OSTS_BSESVALID) {
606 dev_dbg(phy->dev, "BSV set\n");
607 set_bit(B_SESS_VLD, &dotg->inputs);
608 } else {
609 dev_dbg(phy->dev, "BSV clear\n");
610 clear_bit(B_SESS_VLD, &dotg->inputs);
611 }
612 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
613 }
Manu Gautam8c642812012-06-07 10:35:10 +0530614
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530615 queue_delayed_work(system_nrt_wq, &dotg->sm_work, 0);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200616
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200617 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530618
619 /* Clear the interrupts we handled */
620 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200621 }
622
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200623 return ret;
624}
625
626/**
Manu Gautam8c642812012-06-07 10:35:10 +0530627 * dwc3_otg_init_sm - initialize OTG statemachine input
628 * @dotg: Pointer to the dwc3_otg structure
629 *
630 */
631void dwc3_otg_init_sm(struct dwc3_otg *dotg)
632{
633 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
634 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530635 struct dwc3_ext_xceiv *ext_xceiv;
636 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530637
638 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
639
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530640 /*
641 * VBUS initial state is reported after PMIC
642 * driver initialization. Wait for it.
643 */
644 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530645 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530646 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530647 /* We can safely assume no cable connected */
648 set_bit(ID, &dotg->inputs);
649 }
Manu Gautam8c642812012-06-07 10:35:10 +0530650
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530651 ext_xceiv = dotg->ext_xceiv;
652 dwc3_otg_reset(dotg);
653 if (ext_xceiv && !ext_xceiv->otg_capability) {
654 if (osts & DWC3_OTG_OSTS_CONIDSTS)
655 set_bit(ID, &dotg->inputs);
656 else
657 clear_bit(ID, &dotg->inputs);
658
659 if (osts & DWC3_OTG_OSTS_BSESVALID)
660 set_bit(B_SESS_VLD, &dotg->inputs);
661 else
662 clear_bit(B_SESS_VLD, &dotg->inputs);
663 }
Manu Gautam8c642812012-06-07 10:35:10 +0530664}
665
666/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200667 * dwc3_otg_sm_work - workqueue function.
668 *
669 * @w: Pointer to the dwc3 otg workqueue
670 *
671 * NOTE: After any change in phy->state,
672 * we must reschdule the state machine.
673 */
674static void dwc3_otg_sm_work(struct work_struct *w)
675{
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530676 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work.work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200677 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530678 struct dwc3_charger *charger = dotg->charger;
679 bool work = 0;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530680 int ret = 0;
681 int delay = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200682
Manu Gautamb5067272012-07-02 09:53:41 +0530683 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200684 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
685
686 /* Check OTG state */
687 switch (phy->state) {
688 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530689 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530690 if (!dotg->psy) {
691 dotg->psy = power_supply_get_by_name("usb");
692
693 if (!dotg->psy)
694 dev_err(phy->dev,
695 "couldn't get usb power supply\n");
696 }
697
Manu Gautam8c642812012-06-07 10:35:10 +0530698 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530699 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530700 dev_dbg(phy->dev, "!id\n");
701 phy->state = OTG_STATE_A_IDLE;
702 work = 1;
703 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
704 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200705 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530706 work = 1;
707 } else {
708 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530709 dev_dbg(phy->dev, "No device, trying to suspend\n");
710 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200711 }
712 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530713
714 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530715 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530716 dev_dbg(phy->dev, "!id\n");
717 phy->state = OTG_STATE_A_IDLE;
718 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530719 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530720 if (charger) {
721 if (charger->chg_type == DWC3_INVALID_CHARGER)
722 charger->start_detection(dotg->charger,
723 false);
724 else
725 charger->chg_type =
726 DWC3_INVALID_CHARGER;
727 }
728 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
729 dev_dbg(phy->dev, "b_sess_vld\n");
730 if (charger) {
731 /* Has charger been detected? If no detect it */
732 switch (charger->chg_type) {
733 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530734 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530735 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530736 dwc3_otg_set_power(phy,
737 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530738 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530739 break;
740 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530741 dwc3_otg_set_power(phy,
742 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530743 dwc3_otg_start_peripheral(&dotg->otg,
744 1);
745 phy->state = OTG_STATE_B_PERIPHERAL;
746 work = 1;
747 break;
748 case DWC3_SDP_CHARGER:
749 dwc3_otg_start_peripheral(&dotg->otg,
750 1);
751 phy->state = OTG_STATE_B_PERIPHERAL;
752 work = 1;
753 break;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530754 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusac4974862013-07-23 17:36:37 +0530755 if (dotg->charger_retry_count <
756 max_chgr_retry_count)
757 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530758 /*
759 * In case of floating charger, if
760 * retry count equal to max retry count
761 * notify PMIC about floating charger
762 * and put Hw in low power mode. Else
763 * perform charger detection again by
764 * calling start_detection() with false
765 * and then with true argument.
766 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530767 if (dotg->charger_retry_count ==
768 max_chgr_retry_count) {
769 dwc3_otg_set_power(phy, 0);
770 pm_runtime_put_sync(phy->dev);
771 break;
772 }
773 charger->start_detection(dotg->charger,
774 false);
775
Manu Gautam8c642812012-06-07 10:35:10 +0530776 default:
777 dev_dbg(phy->dev, "chg_det started\n");
778 charger->start_detection(charger, true);
779 break;
780 }
781 } else {
782 /* no charger registered, start peripheral */
783 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
784 /*
785 * Probably set_peripheral not called
786 * yet. We will re-try as soon as it
787 * will be called
788 */
Manu Gautamb5067272012-07-02 09:53:41 +0530789 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530790 "unable to start B-device\n");
791 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530792 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530793 return;
794 }
795 }
796 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530797 if (charger)
798 charger->start_detection(dotg->charger, false);
799
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530800 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530801 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530802 dev_dbg(phy->dev, "No device, trying to suspend\n");
803 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530804 }
805 break;
806
807 case OTG_STATE_B_PERIPHERAL:
808 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
809 !test_bit(ID, &dotg->inputs)) {
810 dev_dbg(phy->dev, "!id || !bsv\n");
811 dwc3_otg_start_peripheral(&dotg->otg, 0);
812 phy->state = OTG_STATE_B_IDLE;
813 if (charger)
814 charger->chg_type = DWC3_INVALID_CHARGER;
815 work = 1;
816 }
817 break;
818
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200819 case OTG_STATE_A_IDLE:
820 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530821 if (test_bit(ID, &dotg->inputs)) {
822 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200823 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530824 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530825 work = 1;
826 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530827 phy->state = OTG_STATE_A_HOST;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530828 ret = dwc3_otg_start_host(&dotg->otg, 1);
829 if ((ret == -EPROBE_DEFER) &&
830 dotg->vbus_retry_count < 3) {
831 /*
832 * Get regulator failed as regulator driver is
833 * not up yet. Will try to start host after 1sec
834 */
835 phy->state = OTG_STATE_A_IDLE;
836 dev_dbg(phy->dev, "Unable to get vbus regulator. Retrying...\n");
837 delay = VBUS_REG_CHECK_DELAY;
838 work = 1;
839 dotg->vbus_retry_count++;
840 } else if (ret) {
Manu Gautam8c642812012-06-07 10:35:10 +0530841 /*
842 * Probably set_host was not called yet.
843 * We will re-try as soon as it will be called
844 */
Manu Gautamb5067272012-07-02 09:53:41 +0530845 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530846 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530847 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530848 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530849 return;
850 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200851 }
852 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530853
854 case OTG_STATE_A_HOST:
855 if (test_bit(ID, &dotg->inputs)) {
856 dev_dbg(phy->dev, "id\n");
857 dwc3_otg_start_host(&dotg->otg, 0);
858 phy->state = OTG_STATE_B_IDLE;
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530859 dotg->vbus_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530860 work = 1;
861 }
862 break;
863
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200864 default:
865 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
866
867 }
Manu Gautam8c642812012-06-07 10:35:10 +0530868
869 if (work)
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530870 queue_delayed_work(system_nrt_wq, &dotg->sm_work, delay);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200871}
872
873
874/**
875 * dwc3_otg_reset - reset dwc3 otg registers.
876 *
877 * @w: Pointer to the dwc3 otg workqueue
878 */
879static void dwc3_otg_reset(struct dwc3_otg *dotg)
880{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530881 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530882 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
883
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200884 /*
885 * OCFG[2] - OTG-Version = 1
886 * OCFG[1] - HNPCap = 0
887 * OCFG[0] - SRPCap = 0
888 */
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530889 if (ext_xceiv && !ext_xceiv->otg_capability)
890 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200891
892 /*
893 * OCTL[6] - PeriMode = 1
894 * OCTL[5] - PrtPwrCtl = 0
895 * OCTL[4] - HNPReq = 0
896 * OCTL[3] - SesReq = 0
897 * OCTL[2] - TermSelDLPulse = 0
898 * OCTL[1] - DevSetHNPEn = 0
899 * OCTL[0] - HstSetHNPEn = 0
900 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530901 if (!once) {
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530902 if (ext_xceiv && !ext_xceiv->otg_capability)
903 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530904 once++;
905 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200906
907 /* Clear all otg events (interrupts) indications */
908 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
909
Manu Gautam8c642812012-06-07 10:35:10 +0530910 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530911 if (ext_xceiv && !ext_xceiv->otg_capability)
912 dwc3_writel(dotg->regs, DWC3_OEVTEN,
913 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
914 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200915}
916
917/**
918 * dwc3_otg_init - Initializes otg related registers
919 * @dwc: Pointer to out controller context structure
920 *
921 * Returns 0 on success otherwise negative errno.
922 */
923int dwc3_otg_init(struct dwc3 *dwc)
924{
925 u32 reg;
926 int ret = 0;
927 struct dwc3_otg *dotg;
928
929 dev_dbg(dwc->dev, "dwc3_otg_init\n");
930
931 /*
932 * GHWPARAMS6[10] bit is SRPSupport.
933 * This bit also reflects DWC_USB3_EN_OTG
934 */
935 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
936 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
937 /*
938 * No OTG support in the HW core.
939 * We return 0 to indicate no error, since this is acceptable
940 * situation, just continue probe the dwc3 driver without otg.
941 */
942 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
943 return 0;
944 }
945
946 /* Allocate and init otg instance */
947 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
948 if (!dotg) {
949 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
950 return -ENOMEM;
951 }
952
Manu Gautam17206c22012-06-21 10:17:53 +0530953 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
954 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
955 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200956 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530957 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200958 ret = -ENODEV;
959 goto err1;
960 }
961
962 dotg->regs = dwc->regs;
963
964 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
965 dotg->otg.set_host = dwc3_otg_set_host;
966
967 /* This reference is used by dwc3 modules for checking otg existance */
968 dwc->dotg = dotg;
969
970 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
971 if (!dotg->otg.phy) {
972 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
973 ret = -ENOMEM;
974 goto err1;
975 }
976
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530977 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200978 dotg->otg.phy->otg = &dotg->otg;
979 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530980 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530981 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200982
983 ret = usb_set_transceiver(dotg->otg.phy);
984 if (ret) {
985 dev_err(dotg->otg.phy->dev,
986 "%s: failed to set transceiver, already exists\n",
987 __func__);
988 goto err2;
989 }
990
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200991 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
992
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530993 init_completion(&dotg->dwc3_xcvr_vbus_init);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +0530994 INIT_DELAYED_WORK(&dotg->sm_work, dwc3_otg_sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200995
996 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
997 "dwc3_otg", dotg);
998 if (ret) {
999 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
1000 dotg->irq, ret);
1001 goto err3;
1002 }
1003
Manu Gautamb5067272012-07-02 09:53:41 +05301004 pm_runtime_get(dwc->dev);
1005
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001006 return 0;
1007
1008err3:
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301009 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001010 usb_set_transceiver(NULL);
1011err2:
1012 kfree(dotg->otg.phy);
1013err1:
1014 dwc->dotg = NULL;
1015 kfree(dotg);
1016
1017 return ret;
1018}
1019
1020/**
1021 * dwc3_otg_exit
1022 * @dwc: Pointer to out controller context structure
1023 *
1024 * Returns 0 on success otherwise negative errno.
1025 */
1026void dwc3_otg_exit(struct dwc3 *dwc)
1027{
1028 struct dwc3_otg *dotg = dwc->dotg;
1029
1030 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
1031 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +05301032 if (dotg->charger)
1033 dotg->charger->start_detection(dotg->charger, false);
Vijayavardhan Vennapusafddeb0f2013-09-26 17:26:13 +05301034 cancel_delayed_work_sync(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001035 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +05301036 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001037 free_irq(dotg->irq, dotg);
1038 kfree(dotg->otg.phy);
1039 kfree(dotg);
1040 dwc->dotg = NULL;
1041 }
1042}