blob: be9a4b52e9dc83c673f40282bc799a4e89f5a49e [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
16#include <linux/usb.h>
17#include <linux/usb/hcd.h>
18#include <linux/platform_device.h>
Manu Gautamf1fceddf2012-10-12 14:02:50 +053019#include <linux/regulator/consumer.h>
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020020
21#include "core.h"
22#include "dwc3_otg.h"
23#include "io.h"
24#include "xhci.h"
25
Manu Gautamf1fceddf2012-10-12 14:02:50 +053026static void dwc3_otg_reset(struct dwc3_otg *dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020027
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +053028static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
29static void dwc3_otg_reset(struct dwc3_otg *dotg);
30
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020031/**
32 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
33 *
34 * This function sets the OTG registers to work in A-Device host mode.
35 * This function should be called just before entering to A-Device mode.
36 *
Manu Gautamf1fceddf2012-10-12 14:02:50 +053037 * @w: Pointer to the dwc3 otg struct
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020038 */
39static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
40{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053041 u32 reg;
42 struct dwc3 *dwc = dotg->dwc;
43 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020044
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053045 if (ext_xceiv && !ext_xceiv->otg_capability) {
46 /* Set OCTL[6](PeriMode) to 0 (host) */
47 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
48 reg &= ~DWC3_OTG_OCTL_PERIMODE;
49 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
50 } else {
51 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
52 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
53 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST);
54 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
55 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +053056}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020057
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +053058static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
59{
60 struct usb_otg *otg = phy->otg;
61 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
62
63 if (dotg->host_bus_suspend == suspend)
64 return 0;
65
66 dotg->host_bus_suspend = suspend;
67 if (suspend) {
68 pm_runtime_put_sync(phy->dev);
69 } else {
70 pm_runtime_get_noresume(phy->dev);
71 pm_runtime_resume(phy->dev);
72 }
73
74 return 0;
75}
76
Manu Gautamf1fceddf2012-10-12 14:02:50 +053077/**
78 * dwc3_otg_set_host_power - Enable port power control for host operation
79 *
80 * This function enables the OTG Port Power required to operate in Host mode
81 * This function should be called only after XHCI driver has set the port
82 * power in PORTSC register.
83 *
84 * @w: Pointer to the dwc3 otg struct
85 */
86void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
87{
88 u32 osts;
89
90 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
91 if (!(osts & 0x8))
92 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
93
94 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020095}
96
97/**
98 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
99 *
100 * This function sets the OTG registers to work in B-Device peripheral mode.
101 * This function should be called just before entering to B-Device mode.
102 *
103 * @w: Pointer to the dwc3 otg workqueue.
104 */
105static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
106{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530107 u32 reg;
108 struct dwc3 *dwc = dotg->dwc;
109 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200110
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530111 if (ext_xceiv && !ext_xceiv->otg_capability) {
112 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
113 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
114 reg |= DWC3_OTG_OCTL_PERIMODE;
115 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
116 /*
117 * TODO: add more OTG registers writes for PERIPHERAL mode here,
118 * see figure 12-19 B-device flow in dwc3 Synopsis spec
119 */
120 } else {
121 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
122 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
123 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
124 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
125 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200126}
127
128/**
129 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
130 *
131 * @otg: Pointer to the otg_transceiver structure.
132 * @on: start / stop the host controller driver.
133 *
134 * Returns 0 on success otherwise negative errno.
135 */
136static int dwc3_otg_start_host(struct usb_otg *otg, int on)
137{
138 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530139 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530140 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200141 int ret = 0;
142
Manu Gautam61721592012-11-06 18:09:39 +0530143 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200144 return -EINVAL;
145
Manu Gautam61721592012-11-06 18:09:39 +0530146 if (!dotg->vbus_otg) {
147 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
148 "vbus_dwc3");
149 if (IS_ERR(dotg->vbus_otg)) {
150 dev_err(dwc->dev, "Failed to get vbus regulator\n");
151 ret = PTR_ERR(dotg->vbus_otg);
152 dotg->vbus_otg = 0;
153 return ret;
154 }
155 }
156
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200157 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530158 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200159
160 /*
161 * This should be revisited for more testing post-silicon.
162 * In worst case we may need to disconnect the root hub
163 * before stopping the controller so that it does not
164 * interfere with runtime pm/system pm.
165 * We can also consider registering and unregistering xhci
166 * platform device. It is almost similar to add_hcd and
167 * remove_hcd, But we may not use standard set_host method
168 * anymore.
169 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530170 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530171 /*
172 * FIXME If micro A cable is disconnected during system suspend,
173 * xhci platform device will be removed before runtime pm is
174 * enabled for xhci device. Due to this, disable_depth becomes
175 * greater than one and runtimepm is not enabled for next microA
176 * connect. Fix this by calling pm_runtime_init for xhci device.
177 */
178 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530179 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200180 if (ret) {
181 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530182 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200183 __func__, ret);
184 return ret;
185 }
186
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530187 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530188 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200189 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530190 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530191 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200192 return ret;
193 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530194
195 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530196 if (ext_xceiv && !ext_xceiv->otg_capability)
197 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200198 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530199 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
200
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530201 ret = regulator_disable(dotg->vbus_otg);
202 if (ret) {
203 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
204 return ret;
205 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530206 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530207
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530208 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530209 /*
210 * Perform USB hardware RESET (both core reset and DBM reset)
211 * when moving from host to peripheral. This is required for
212 * peripheral mode to work.
213 */
214 if (ext_xceiv && ext_xceiv->otg_capability &&
215 ext_xceiv->ext_block_reset)
216 ext_xceiv->ext_block_reset(true);
217
Manu Gautamab3da1b2013-04-02 14:29:01 +0530218 dwc3_otg_set_peripheral_regs(dotg);
219
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530220 /* re-init core and OTG registers as block reset clears these */
221 dwc3_post_host_reset_core_init(dwc);
222 if (ext_xceiv && !ext_xceiv->otg_capability)
223 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200224 }
225
226 return 0;
227}
228
229/**
230 * dwc3_otg_set_host - bind/unbind the host controller driver.
231 *
232 * @otg: Pointer to the otg_transceiver structure.
233 * @host: Pointer to the usb_bus structure.
234 *
235 * Returns 0 on success otherwise negative errno.
236 */
237static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
238{
239 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
240
241 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530242 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200243 __func__, host->bus_name);
244 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200245 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530246 * Though XHCI power would be set by now, but some delay is
247 * required for XHCI controller before setting OTG Port Power
248 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200249 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530250 msleep(300);
251 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200252 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530253 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200254 }
255
256 return 0;
257}
258
259/**
260 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
261 *
262 * @otg: Pointer to the otg_transceiver structure.
263 * @gadget: pointer to the usb_gadget structure.
264 *
265 * Returns 0 on success otherwise negative errno.
266 */
267static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
268{
269 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530270 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200271
272 if (!otg->gadget)
273 return -EINVAL;
274
275 if (on) {
276 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
277 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530278
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530279 /* Core reset is not required during start peripheral. Only
280 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530281 if (ext_xceiv && ext_xceiv->otg_capability &&
282 ext_xceiv->ext_block_reset)
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530283 ext_xceiv->ext_block_reset(false);
Manu Gautama302f612012-12-18 17:33:06 +0530284
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200285 dwc3_otg_set_peripheral_regs(dotg);
286 usb_gadget_vbus_connect(otg->gadget);
287 } else {
288 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
289 __func__, otg->gadget->name);
290 usb_gadget_vbus_disconnect(otg->gadget);
291 }
292
293 return 0;
294}
295
296/**
297 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
298 *
299 * @otg: Pointer to the otg_transceiver structure.
300 * @gadget: pointer to the usb_gadget structure.
301 *
302 * Returns 0 on success otherwise negative errno.
303 */
304static int dwc3_otg_set_peripheral(struct usb_otg *otg,
305 struct usb_gadget *gadget)
306{
307 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
308
309 if (gadget) {
310 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
311 __func__, gadget->name);
312 otg->gadget = gadget;
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530313 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200314 } else {
315 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
316 dwc3_otg_start_peripheral(otg, 0);
317 otg->gadget = NULL;
318 otg->phy->state = OTG_STATE_UNDEFINED;
319 schedule_work(&dotg->sm_work);
320 } else {
321 otg->gadget = NULL;
322 }
323 }
324
325 return 0;
326}
327
328/**
Manu Gautam8c642812012-06-07 10:35:10 +0530329 * dwc3_ext_chg_det_done - callback to handle charger detection completion
330 * @otg: Pointer to the otg transceiver structure
331 * @charger: Pointer to the external charger structure
332 *
333 * Returns 0 on success
334 */
335static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
336{
337 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
338
339 /*
340 * Ignore chg_detection notification if BSV has gone off by this time.
341 * STOP chg_det as part of !BSV handling would reset the chg_det flags
342 */
343 if (test_bit(B_SESS_VLD, &dotg->inputs))
344 schedule_work(&dotg->sm_work);
345}
346
347/**
348 * dwc3_set_charger - bind/unbind external charger driver
349 * @otg: Pointer to the otg transceiver structure
350 * @charger: Pointer to the external charger structure
351 *
352 * Returns 0 on success
353 */
354int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
355{
356 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
357
358 dotg->charger = charger;
359 if (charger)
360 charger->notify_detection_complete = dwc3_ext_chg_det_done;
361
362 return 0;
363}
364
Manu Gautamb5067272012-07-02 09:53:41 +0530365/**
366 * dwc3_ext_event_notify - callback to handle events from external transceiver
367 * @otg: Pointer to the otg transceiver structure
368 * @event: Event reported by transceiver
369 *
370 * Returns 0 on success
371 */
372static void dwc3_ext_event_notify(struct usb_otg *otg,
373 enum dwc3_ext_events event)
374{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530375 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530376 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
377 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
378 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530379 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530380
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530381 /* Flush processing any pending events before handling new ones */
382 if (init)
383 flush_work(&dotg->sm_work);
384
Manu Gautamb5067272012-07-02 09:53:41 +0530385 if (event == DWC3_EVENT_PHY_RESUME) {
386 if (!pm_runtime_status_suspended(phy->dev)) {
387 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
388 } else {
389 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
390 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530391 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530392 if ((phy->state == OTG_STATE_A_HOST) &&
393 dotg->host_bus_suspend)
394 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530395 if (ret == -EACCES) {
396 /* pm_runtime_get may fail during system
397 resume with -EACCES error */
398 pm_runtime_disable(phy->dev);
399 pm_runtime_set_active(phy->dev);
400 pm_runtime_enable(phy->dev);
401 } else if (ret < 0) {
402 dev_warn(phy->dev, "pm_runtime_get failed!\n");
403 }
Manu Gautamb5067272012-07-02 09:53:41 +0530404 }
Manu Gautam377821c2012-09-28 16:53:24 +0530405 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530406 if (pm_runtime_status_suspended(phy->dev)) {
407 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
408 ret = pm_runtime_get(phy->dev);
409 if (ret < 0)
410 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
411 }
Jack Pham0fc12332012-11-19 13:14:22 -0800412 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530413 dev_dbg(phy->dev, "XCVR: ID set\n");
414 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800415 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530416 dev_dbg(phy->dev, "XCVR: ID clear\n");
417 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800418 }
Manu Gautam377821c2012-09-28 16:53:24 +0530419
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530420 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530421 dev_dbg(phy->dev, "XCVR: BSV set\n");
422 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530423 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530424 dev_dbg(phy->dev, "XCVR: BSV clear\n");
425 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530426 }
Manu Gautam377821c2012-09-28 16:53:24 +0530427
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530428 if (!init) {
429 init = true;
Manu Gautam4ff07242013-03-27 14:31:11 +0530430 if (!work_busy(&dotg->sm_work))
431 schedule_work(&dotg->sm_work);
432
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530433 complete(&dotg->dwc3_xcvr_vbus_init);
434 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
435 return;
436 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530437
438 schedule_work(&dotg->sm_work);
Manu Gautamb5067272012-07-02 09:53:41 +0530439 }
Manu Gautamb5067272012-07-02 09:53:41 +0530440}
441
442/**
443 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
444 * @otg: Pointer to the otg transceiver structure
445 * @ext_xceiv: Pointer to the external transceiver struccture
446 *
447 * Returns 0 on success
448 */
449int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
450{
451 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
452
453 dotg->ext_xceiv = ext_xceiv;
454 if (ext_xceiv)
455 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
456
457 return 0;
458}
459
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530460static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
461{
462 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
463
464 if (!dotg->psy) {
465 dev_err(otg->phy->dev, "no usb power supply registered\n");
466 return;
467 }
468
469 if (host_mode)
470 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
471 else
472 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
473}
474
475static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
476{
477 static int power_supply_type;
478 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
479
480
Manu Gautam6c0ff032012-11-02 14:55:35 +0530481 if (!dotg->psy || !dotg->charger) {
482 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530483 return 0;
484 }
485
Manu Gautam6c0ff032012-11-02 14:55:35 +0530486 if (dotg->charger->charging_disabled)
487 return 0;
488
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530489 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
490 power_supply_type = POWER_SUPPLY_TYPE_USB;
491 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
492 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530493 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
494 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530495 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
496 else
497 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
498
499 power_supply_set_supply_type(dotg->psy, power_supply_type);
500
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530501 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530502 mA = DWC3_IDEV_CHG_MAX;
503
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530504 if (dotg->charger->max_power == mA)
505 return 0;
506
507 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
508
509 if (dotg->charger->max_power <= 2 && mA > 2) {
510 /* Enable charging */
511 if (power_supply_set_online(dotg->psy, true))
512 goto psy_error;
513 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
514 goto psy_error;
515 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
516 /* Disable charging */
517 if (power_supply_set_online(dotg->psy, false))
518 goto psy_error;
519 /* Set max current limit */
520 if (power_supply_set_current_limit(dotg->psy, 0))
521 goto psy_error;
522 }
523
524 power_supply_changed(dotg->psy);
525 dotg->charger->max_power = mA;
526 return 0;
527
528psy_error:
529 dev_dbg(phy->dev, "power supply error when setting property\n");
530 return -ENXIO;
531}
532
Manu Gautam8c642812012-06-07 10:35:10 +0530533/* IRQs which OTG driver is interested in handling */
534#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
535 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
536
537/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200538 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
539 * @_dotg: Pointer to out controller context structure
540 *
541 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
542 */
543static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
544{
545 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530546 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200547 int ret = IRQ_NONE;
548 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530549 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200550
551 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
552
Manu Gautam8c642812012-06-07 10:35:10 +0530553 if (!(oevt_reg & DWC3_OEVT_MASK))
554 return IRQ_NONE;
555
556 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
557
558 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
559 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200560 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530561 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200562 * function, switch from A to B or from B to A.
563 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200564
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530565 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
566 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
567 dev_dbg(phy->dev, "ID set\n");
568 set_bit(ID, &dotg->inputs);
569 } else {
570 dev_dbg(phy->dev, "ID clear\n");
571 clear_bit(ID, &dotg->inputs);
572 }
573 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
574 }
Manu Gautam8c642812012-06-07 10:35:10 +0530575
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530576 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
577 if (osts & DWC3_OTG_OSTS_BSESVALID) {
578 dev_dbg(phy->dev, "BSV set\n");
579 set_bit(B_SESS_VLD, &dotg->inputs);
580 } else {
581 dev_dbg(phy->dev, "BSV clear\n");
582 clear_bit(B_SESS_VLD, &dotg->inputs);
583 }
584 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
585 }
Manu Gautam8c642812012-06-07 10:35:10 +0530586
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200587 schedule_work(&dotg->sm_work);
588
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200589 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530590
591 /* Clear the interrupts we handled */
592 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200593 }
594
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200595 return ret;
596}
597
598/**
Manu Gautam8c642812012-06-07 10:35:10 +0530599 * dwc3_otg_init_sm - initialize OTG statemachine input
600 * @dotg: Pointer to the dwc3_otg structure
601 *
602 */
603void dwc3_otg_init_sm(struct dwc3_otg *dotg)
604{
605 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
606 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530607 struct dwc3_ext_xceiv *ext_xceiv;
608 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530609
610 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
611
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530612 /*
613 * VBUS initial state is reported after PMIC
614 * driver initialization. Wait for it.
615 */
616 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530617 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530618 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530619 /* We can safely assume no cable connected */
620 set_bit(ID, &dotg->inputs);
621 }
Manu Gautam8c642812012-06-07 10:35:10 +0530622
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530623 ext_xceiv = dotg->ext_xceiv;
624 dwc3_otg_reset(dotg);
625 if (ext_xceiv && !ext_xceiv->otg_capability) {
626 if (osts & DWC3_OTG_OSTS_CONIDSTS)
627 set_bit(ID, &dotg->inputs);
628 else
629 clear_bit(ID, &dotg->inputs);
630
631 if (osts & DWC3_OTG_OSTS_BSESVALID)
632 set_bit(B_SESS_VLD, &dotg->inputs);
633 else
634 clear_bit(B_SESS_VLD, &dotg->inputs);
635 }
Manu Gautam8c642812012-06-07 10:35:10 +0530636}
637
638/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200639 * dwc3_otg_sm_work - workqueue function.
640 *
641 * @w: Pointer to the dwc3 otg workqueue
642 *
643 * NOTE: After any change in phy->state,
644 * we must reschdule the state machine.
645 */
646static void dwc3_otg_sm_work(struct work_struct *w)
647{
648 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
649 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530650 struct dwc3_charger *charger = dotg->charger;
651 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200652
Manu Gautamb5067272012-07-02 09:53:41 +0530653 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200654 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
655
656 /* Check OTG state */
657 switch (phy->state) {
658 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530659 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530660 if (!dotg->psy) {
661 dotg->psy = power_supply_get_by_name("usb");
662
663 if (!dotg->psy)
664 dev_err(phy->dev,
665 "couldn't get usb power supply\n");
666 }
667
Manu Gautam8c642812012-06-07 10:35:10 +0530668 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530669 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530670 dev_dbg(phy->dev, "!id\n");
671 phy->state = OTG_STATE_A_IDLE;
672 work = 1;
673 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
674 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200675 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530676 work = 1;
677 } else {
678 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530679 dev_dbg(phy->dev, "No device, trying to suspend\n");
680 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200681 }
682 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530683
684 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530685 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530686 dev_dbg(phy->dev, "!id\n");
687 phy->state = OTG_STATE_A_IDLE;
688 work = 1;
689 if (charger) {
690 if (charger->chg_type == DWC3_INVALID_CHARGER)
691 charger->start_detection(dotg->charger,
692 false);
693 else
694 charger->chg_type =
695 DWC3_INVALID_CHARGER;
696 }
697 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
698 dev_dbg(phy->dev, "b_sess_vld\n");
699 if (charger) {
700 /* Has charger been detected? If no detect it */
701 switch (charger->chg_type) {
702 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530703 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530704 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530705 dwc3_otg_set_power(phy,
706 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530707 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530708 break;
709 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530710 dwc3_otg_set_power(phy,
711 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530712 dwc3_otg_start_peripheral(&dotg->otg,
713 1);
714 phy->state = OTG_STATE_B_PERIPHERAL;
715 work = 1;
716 break;
717 case DWC3_SDP_CHARGER:
718 dwc3_otg_start_peripheral(&dotg->otg,
719 1);
720 phy->state = OTG_STATE_B_PERIPHERAL;
721 work = 1;
722 break;
723 default:
724 dev_dbg(phy->dev, "chg_det started\n");
725 charger->start_detection(charger, true);
726 break;
727 }
728 } else {
729 /* no charger registered, start peripheral */
730 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
731 /*
732 * Probably set_peripheral not called
733 * yet. We will re-try as soon as it
734 * will be called
735 */
Manu Gautamb5067272012-07-02 09:53:41 +0530736 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530737 "unable to start B-device\n");
738 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530739 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530740 return;
741 }
742 }
743 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530744 if (charger)
745 charger->start_detection(dotg->charger, false);
746
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530747 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530748 dev_dbg(phy->dev, "No device, trying to suspend\n");
749 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530750 }
751 break;
752
753 case OTG_STATE_B_PERIPHERAL:
754 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
755 !test_bit(ID, &dotg->inputs)) {
756 dev_dbg(phy->dev, "!id || !bsv\n");
757 dwc3_otg_start_peripheral(&dotg->otg, 0);
758 phy->state = OTG_STATE_B_IDLE;
759 if (charger)
760 charger->chg_type = DWC3_INVALID_CHARGER;
761 work = 1;
762 }
763 break;
764
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200765 case OTG_STATE_A_IDLE:
766 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530767 if (test_bit(ID, &dotg->inputs)) {
768 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200769 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530770 work = 1;
771 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530772 phy->state = OTG_STATE_A_HOST;
773 if (dwc3_otg_start_host(&dotg->otg, 1)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530774 /*
775 * Probably set_host was not called yet.
776 * We will re-try as soon as it will be called
777 */
Manu Gautamb5067272012-07-02 09:53:41 +0530778 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530779 "unable to start A-device\n");
780 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530781 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530782 return;
783 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200784 }
785 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530786
787 case OTG_STATE_A_HOST:
788 if (test_bit(ID, &dotg->inputs)) {
789 dev_dbg(phy->dev, "id\n");
790 dwc3_otg_start_host(&dotg->otg, 0);
791 phy->state = OTG_STATE_B_IDLE;
792 work = 1;
793 }
794 break;
795
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200796 default:
797 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
798
799 }
Manu Gautam8c642812012-06-07 10:35:10 +0530800
801 if (work)
802 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200803}
804
805
806/**
807 * dwc3_otg_reset - reset dwc3 otg registers.
808 *
809 * @w: Pointer to the dwc3 otg workqueue
810 */
811static void dwc3_otg_reset(struct dwc3_otg *dotg)
812{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530813 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530814 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
815
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200816 /*
817 * OCFG[2] - OTG-Version = 1
818 * OCFG[1] - HNPCap = 0
819 * OCFG[0] - SRPCap = 0
820 */
821 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
822
823 /*
824 * OCTL[6] - PeriMode = 1
825 * OCTL[5] - PrtPwrCtl = 0
826 * OCTL[4] - HNPReq = 0
827 * OCTL[3] - SesReq = 0
828 * OCTL[2] - TermSelDLPulse = 0
829 * OCTL[1] - DevSetHNPEn = 0
830 * OCTL[0] - HstSetHNPEn = 0
831 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530832 if (!once) {
833 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
834 once++;
835 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200836
837 /* Clear all otg events (interrupts) indications */
838 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
839
Manu Gautam8c642812012-06-07 10:35:10 +0530840 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530841 if (ext_xceiv && !ext_xceiv->otg_capability)
842 dwc3_writel(dotg->regs, DWC3_OEVTEN,
843 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
844 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200845}
846
847/**
848 * dwc3_otg_init - Initializes otg related registers
849 * @dwc: Pointer to out controller context structure
850 *
851 * Returns 0 on success otherwise negative errno.
852 */
853int dwc3_otg_init(struct dwc3 *dwc)
854{
855 u32 reg;
856 int ret = 0;
857 struct dwc3_otg *dotg;
858
859 dev_dbg(dwc->dev, "dwc3_otg_init\n");
860
861 /*
862 * GHWPARAMS6[10] bit is SRPSupport.
863 * This bit also reflects DWC_USB3_EN_OTG
864 */
865 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
866 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
867 /*
868 * No OTG support in the HW core.
869 * We return 0 to indicate no error, since this is acceptable
870 * situation, just continue probe the dwc3 driver without otg.
871 */
872 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
873 return 0;
874 }
875
876 /* Allocate and init otg instance */
877 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
878 if (!dotg) {
879 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
880 return -ENOMEM;
881 }
882
Manu Gautam17206c22012-06-21 10:17:53 +0530883 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
884 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
885 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200886 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530887 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200888 ret = -ENODEV;
889 goto err1;
890 }
891
892 dotg->regs = dwc->regs;
893
894 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
895 dotg->otg.set_host = dwc3_otg_set_host;
896
897 /* This reference is used by dwc3 modules for checking otg existance */
898 dwc->dotg = dotg;
899
900 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
901 if (!dotg->otg.phy) {
902 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
903 ret = -ENOMEM;
904 goto err1;
905 }
906
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530907 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200908 dotg->otg.phy->otg = &dotg->otg;
909 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530910 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530911 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200912
913 ret = usb_set_transceiver(dotg->otg.phy);
914 if (ret) {
915 dev_err(dotg->otg.phy->dev,
916 "%s: failed to set transceiver, already exists\n",
917 __func__);
918 goto err2;
919 }
920
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200921 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
922
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530923 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200924 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
925
926 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
927 "dwc3_otg", dotg);
928 if (ret) {
929 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
930 dotg->irq, ret);
931 goto err3;
932 }
933
Manu Gautamb5067272012-07-02 09:53:41 +0530934 pm_runtime_get(dwc->dev);
935
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200936 return 0;
937
938err3:
939 cancel_work_sync(&dotg->sm_work);
940 usb_set_transceiver(NULL);
941err2:
942 kfree(dotg->otg.phy);
943err1:
944 dwc->dotg = NULL;
945 kfree(dotg);
946
947 return ret;
948}
949
950/**
951 * dwc3_otg_exit
952 * @dwc: Pointer to out controller context structure
953 *
954 * Returns 0 on success otherwise negative errno.
955 */
956void dwc3_otg_exit(struct dwc3 *dwc)
957{
958 struct dwc3_otg *dotg = dwc->dotg;
959
960 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
961 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530962 if (dotg->charger)
963 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200964 cancel_work_sync(&dotg->sm_work);
965 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530966 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200967 free_irq(dotg->irq, dotg);
968 kfree(dotg->otg.phy);
969 kfree(dotg);
970 dwc->dotg = NULL;
971 }
972}