blob: 98c9b4ca12fabb82fafcf5652088a610ed4d01da [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 Vennapusaa04e0c92013-06-04 12:37:10 +053027#define MAX_INVALID_CHRGR_RETRY 3
28static int max_chgr_retry_count = MAX_INVALID_CHRGR_RETRY;
29module_param(max_chgr_retry_count, int, S_IRUGO | S_IWUSR);
30MODULE_PARM_DESC(max_chgr_retry_count, "Max invalid charger retry count");
Manu Gautamf1fceddf2012-10-12 14:02:50 +053031static void dwc3_otg_reset(struct dwc3_otg *dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020032
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +053033static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
34static void dwc3_otg_reset(struct dwc3_otg *dotg);
35
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020036/**
37 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
38 *
39 * This function sets the OTG registers to work in A-Device host mode.
40 * This function should be called just before entering to A-Device mode.
41 *
Manu Gautamf1fceddf2012-10-12 14:02:50 +053042 * @w: Pointer to the dwc3 otg struct
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020043 */
44static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
45{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053046 u32 reg;
47 struct dwc3 *dwc = dotg->dwc;
48 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020049
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053050 if (ext_xceiv && !ext_xceiv->otg_capability) {
51 /* Set OCTL[6](PeriMode) to 0 (host) */
52 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
53 reg &= ~DWC3_OTG_OCTL_PERIMODE;
54 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
55 } else {
56 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
57 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
58 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST);
59 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
60 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +053061}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020062
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +053063static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
64{
65 struct usb_otg *otg = phy->otg;
66 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
67
68 if (dotg->host_bus_suspend == suspend)
69 return 0;
70
71 dotg->host_bus_suspend = suspend;
72 if (suspend) {
73 pm_runtime_put_sync(phy->dev);
74 } else {
75 pm_runtime_get_noresume(phy->dev);
76 pm_runtime_resume(phy->dev);
77 }
78
79 return 0;
80}
81
Manu Gautamf1fceddf2012-10-12 14:02:50 +053082/**
83 * dwc3_otg_set_host_power - Enable port power control for host operation
84 *
85 * This function enables the OTG Port Power required to operate in Host mode
86 * This function should be called only after XHCI driver has set the port
87 * power in PORTSC register.
88 *
89 * @w: Pointer to the dwc3 otg struct
90 */
91void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
92{
93 u32 osts;
94
95 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
96 if (!(osts & 0x8))
97 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
98
99 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200100}
101
102/**
103 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
104 *
105 * This function sets the OTG registers to work in B-Device peripheral mode.
106 * This function should be called just before entering to B-Device mode.
107 *
108 * @w: Pointer to the dwc3 otg workqueue.
109 */
110static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
111{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530112 u32 reg;
113 struct dwc3 *dwc = dotg->dwc;
114 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200115
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530116 if (ext_xceiv && !ext_xceiv->otg_capability) {
117 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
118 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
119 reg |= DWC3_OTG_OCTL_PERIMODE;
120 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
121 /*
122 * TODO: add more OTG registers writes for PERIPHERAL mode here,
123 * see figure 12-19 B-device flow in dwc3 Synopsis spec
124 */
125 } else {
126 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
127 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
128 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
129 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
130 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200131}
132
133/**
134 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
135 *
136 * @otg: Pointer to the otg_transceiver structure.
137 * @on: start / stop the host controller driver.
138 *
139 * Returns 0 on success otherwise negative errno.
140 */
141static int dwc3_otg_start_host(struct usb_otg *otg, int on)
142{
143 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530144 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530145 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200146 int ret = 0;
147
Manu Gautam61721592012-11-06 18:09:39 +0530148 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200149 return -EINVAL;
150
Manu Gautam61721592012-11-06 18:09:39 +0530151 if (!dotg->vbus_otg) {
152 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
153 "vbus_dwc3");
154 if (IS_ERR(dotg->vbus_otg)) {
155 dev_err(dwc->dev, "Failed to get vbus regulator\n");
156 ret = PTR_ERR(dotg->vbus_otg);
157 dotg->vbus_otg = 0;
158 return ret;
159 }
160 }
161
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200162 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530163 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200164
165 /*
166 * This should be revisited for more testing post-silicon.
167 * In worst case we may need to disconnect the root hub
168 * before stopping the controller so that it does not
169 * interfere with runtime pm/system pm.
170 * We can also consider registering and unregistering xhci
171 * platform device. It is almost similar to add_hcd and
172 * remove_hcd, But we may not use standard set_host method
173 * anymore.
174 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530175 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530176 /*
177 * FIXME If micro A cable is disconnected during system suspend,
178 * xhci platform device will be removed before runtime pm is
179 * enabled for xhci device. Due to this, disable_depth becomes
180 * greater than one and runtimepm is not enabled for next microA
181 * connect. Fix this by calling pm_runtime_init for xhci device.
182 */
183 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530184 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200185 if (ret) {
186 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530187 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200188 __func__, ret);
189 return ret;
190 }
191
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530192 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530193 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200194 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530195 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530196 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200197 return ret;
198 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530199
200 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530201 if (ext_xceiv && !ext_xceiv->otg_capability)
202 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200203 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530204 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
205
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530206 ret = regulator_disable(dotg->vbus_otg);
207 if (ret) {
208 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
209 return ret;
210 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530211 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530212
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530213 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530214 /*
215 * Perform USB hardware RESET (both core reset and DBM reset)
216 * when moving from host to peripheral. This is required for
217 * peripheral mode to work.
218 */
219 if (ext_xceiv && ext_xceiv->otg_capability &&
220 ext_xceiv->ext_block_reset)
221 ext_xceiv->ext_block_reset(true);
222
Manu Gautamab3da1b2013-04-02 14:29:01 +0530223 dwc3_otg_set_peripheral_regs(dotg);
224
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530225 /* re-init core and OTG registers as block reset clears these */
226 dwc3_post_host_reset_core_init(dwc);
227 if (ext_xceiv && !ext_xceiv->otg_capability)
228 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200229 }
230
231 return 0;
232}
233
234/**
235 * dwc3_otg_set_host - bind/unbind the host controller driver.
236 *
237 * @otg: Pointer to the otg_transceiver structure.
238 * @host: Pointer to the usb_bus structure.
239 *
240 * Returns 0 on success otherwise negative errno.
241 */
242static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
243{
244 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
245
246 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530247 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200248 __func__, host->bus_name);
249 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200250 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530251 * Though XHCI power would be set by now, but some delay is
252 * required for XHCI controller before setting OTG Port Power
253 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200254 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530255 msleep(300);
256 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200257 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530258 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200259 }
260
261 return 0;
262}
263
264/**
265 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
266 *
267 * @otg: Pointer to the otg_transceiver structure.
268 * @gadget: pointer to the usb_gadget structure.
269 *
270 * Returns 0 on success otherwise negative errno.
271 */
272static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
273{
274 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530275 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200276
277 if (!otg->gadget)
278 return -EINVAL;
279
280 if (on) {
281 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
282 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530283
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530284 /* Core reset is not required during start peripheral. Only
285 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530286 if (ext_xceiv && ext_xceiv->otg_capability &&
287 ext_xceiv->ext_block_reset)
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530288 ext_xceiv->ext_block_reset(false);
Manu Gautama302f612012-12-18 17:33:06 +0530289
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200290 dwc3_otg_set_peripheral_regs(dotg);
291 usb_gadget_vbus_connect(otg->gadget);
292 } else {
293 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
294 __func__, otg->gadget->name);
295 usb_gadget_vbus_disconnect(otg->gadget);
296 }
297
298 return 0;
299}
300
301/**
302 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
303 *
304 * @otg: Pointer to the otg_transceiver structure.
305 * @gadget: pointer to the usb_gadget structure.
306 *
307 * Returns 0 on success otherwise negative errno.
308 */
309static int dwc3_otg_set_peripheral(struct usb_otg *otg,
310 struct usb_gadget *gadget)
311{
312 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
313
314 if (gadget) {
315 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
316 __func__, gadget->name);
317 otg->gadget = gadget;
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530318 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200319 } else {
320 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
321 dwc3_otg_start_peripheral(otg, 0);
322 otg->gadget = NULL;
323 otg->phy->state = OTG_STATE_UNDEFINED;
324 schedule_work(&dotg->sm_work);
325 } else {
326 otg->gadget = NULL;
327 }
328 }
329
330 return 0;
331}
332
333/**
Manu Gautam8c642812012-06-07 10:35:10 +0530334 * dwc3_ext_chg_det_done - callback to handle charger detection completion
335 * @otg: Pointer to the otg transceiver structure
336 * @charger: Pointer to the external charger structure
337 *
338 * Returns 0 on success
339 */
340static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
341{
342 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
343
344 /*
345 * Ignore chg_detection notification if BSV has gone off by this time.
346 * STOP chg_det as part of !BSV handling would reset the chg_det flags
347 */
348 if (test_bit(B_SESS_VLD, &dotg->inputs))
349 schedule_work(&dotg->sm_work);
350}
351
352/**
353 * dwc3_set_charger - bind/unbind external charger driver
354 * @otg: Pointer to the otg transceiver structure
355 * @charger: Pointer to the external charger structure
356 *
357 * Returns 0 on success
358 */
359int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
360{
361 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
362
363 dotg->charger = charger;
364 if (charger)
365 charger->notify_detection_complete = dwc3_ext_chg_det_done;
366
367 return 0;
368}
369
Manu Gautamb5067272012-07-02 09:53:41 +0530370/**
371 * dwc3_ext_event_notify - callback to handle events from external transceiver
372 * @otg: Pointer to the otg transceiver structure
373 * @event: Event reported by transceiver
374 *
375 * Returns 0 on success
376 */
377static void dwc3_ext_event_notify(struct usb_otg *otg,
378 enum dwc3_ext_events event)
379{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530380 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530381 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
382 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
383 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530384 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530385
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530386 /* Flush processing any pending events before handling new ones */
387 if (init)
388 flush_work(&dotg->sm_work);
389
Manu Gautamb5067272012-07-02 09:53:41 +0530390 if (event == DWC3_EVENT_PHY_RESUME) {
391 if (!pm_runtime_status_suspended(phy->dev)) {
392 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
393 } else {
394 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
395 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530396 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530397 if ((phy->state == OTG_STATE_A_HOST) &&
398 dotg->host_bus_suspend)
399 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530400 if (ret == -EACCES) {
401 /* pm_runtime_get may fail during system
402 resume with -EACCES error */
403 pm_runtime_disable(phy->dev);
404 pm_runtime_set_active(phy->dev);
405 pm_runtime_enable(phy->dev);
406 } else if (ret < 0) {
407 dev_warn(phy->dev, "pm_runtime_get failed!\n");
408 }
Manu Gautamb5067272012-07-02 09:53:41 +0530409 }
Manu Gautam377821c2012-09-28 16:53:24 +0530410 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530411 if (pm_runtime_status_suspended(phy->dev)) {
412 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
413 ret = pm_runtime_get(phy->dev);
414 if (ret < 0)
415 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
416 }
Jack Pham0fc12332012-11-19 13:14:22 -0800417 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530418 dev_dbg(phy->dev, "XCVR: ID set\n");
419 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800420 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530421 dev_dbg(phy->dev, "XCVR: ID clear\n");
422 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800423 }
Manu Gautam377821c2012-09-28 16:53:24 +0530424
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530425 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530426 dev_dbg(phy->dev, "XCVR: BSV set\n");
427 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530428 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530429 dev_dbg(phy->dev, "XCVR: BSV clear\n");
430 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530431 }
Manu Gautam377821c2012-09-28 16:53:24 +0530432
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530433 if (!init) {
434 init = true;
Manu Gautam4ff07242013-03-27 14:31:11 +0530435 if (!work_busy(&dotg->sm_work))
436 schedule_work(&dotg->sm_work);
437
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530438 complete(&dotg->dwc3_xcvr_vbus_init);
439 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
440 return;
441 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530442
443 schedule_work(&dotg->sm_work);
Manu Gautamb5067272012-07-02 09:53:41 +0530444 }
Manu Gautamb5067272012-07-02 09:53:41 +0530445}
446
447/**
448 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
449 * @otg: Pointer to the otg transceiver structure
450 * @ext_xceiv: Pointer to the external transceiver struccture
451 *
452 * Returns 0 on success
453 */
454int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
455{
456 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
457
458 dotg->ext_xceiv = ext_xceiv;
459 if (ext_xceiv)
460 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
461
462 return 0;
463}
464
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530465static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
466{
467 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
468
469 if (!dotg->psy) {
470 dev_err(otg->phy->dev, "no usb power supply registered\n");
471 return;
472 }
473
474 if (host_mode)
475 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
476 else
477 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
478}
479
480static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
481{
482 static int power_supply_type;
483 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
484
485
Manu Gautam6c0ff032012-11-02 14:55:35 +0530486 if (!dotg->psy || !dotg->charger) {
487 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530488 return 0;
489 }
490
Manu Gautam6c0ff032012-11-02 14:55:35 +0530491 if (dotg->charger->charging_disabled)
492 return 0;
493
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530494 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
495 power_supply_type = POWER_SUPPLY_TYPE_USB;
496 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
497 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530498 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
499 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530500 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
501 else
502 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
503
504 power_supply_set_supply_type(dotg->psy, power_supply_type);
505
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530506 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530507 mA = DWC3_IDEV_CHG_MAX;
508
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530509 if (dotg->charger->max_power == mA)
510 return 0;
511
512 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
513
514 if (dotg->charger->max_power <= 2 && mA > 2) {
515 /* Enable charging */
516 if (power_supply_set_online(dotg->psy, true))
517 goto psy_error;
518 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
519 goto psy_error;
520 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
521 /* Disable charging */
522 if (power_supply_set_online(dotg->psy, false))
523 goto psy_error;
524 /* Set max current limit */
525 if (power_supply_set_current_limit(dotg->psy, 0))
526 goto psy_error;
527 }
528
529 power_supply_changed(dotg->psy);
530 dotg->charger->max_power = mA;
531 return 0;
532
533psy_error:
534 dev_dbg(phy->dev, "power supply error when setting property\n");
535 return -ENXIO;
536}
537
Manu Gautam8c642812012-06-07 10:35:10 +0530538/* IRQs which OTG driver is interested in handling */
539#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
540 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
541
542/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200543 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
544 * @_dotg: Pointer to out controller context structure
545 *
546 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
547 */
548static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
549{
550 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530551 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200552 int ret = IRQ_NONE;
553 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530554 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200555
556 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
557
Manu Gautam8c642812012-06-07 10:35:10 +0530558 if (!(oevt_reg & DWC3_OEVT_MASK))
559 return IRQ_NONE;
560
561 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
562
563 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
564 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200565 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530566 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200567 * function, switch from A to B or from B to A.
568 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200569
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530570 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
571 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
572 dev_dbg(phy->dev, "ID set\n");
573 set_bit(ID, &dotg->inputs);
574 } else {
575 dev_dbg(phy->dev, "ID clear\n");
576 clear_bit(ID, &dotg->inputs);
577 }
578 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
579 }
Manu Gautam8c642812012-06-07 10:35:10 +0530580
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530581 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
582 if (osts & DWC3_OTG_OSTS_BSESVALID) {
583 dev_dbg(phy->dev, "BSV set\n");
584 set_bit(B_SESS_VLD, &dotg->inputs);
585 } else {
586 dev_dbg(phy->dev, "BSV clear\n");
587 clear_bit(B_SESS_VLD, &dotg->inputs);
588 }
589 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
590 }
Manu Gautam8c642812012-06-07 10:35:10 +0530591
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200592 schedule_work(&dotg->sm_work);
593
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200594 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530595
596 /* Clear the interrupts we handled */
597 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200598 }
599
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200600 return ret;
601}
602
603/**
Manu Gautam8c642812012-06-07 10:35:10 +0530604 * dwc3_otg_init_sm - initialize OTG statemachine input
605 * @dotg: Pointer to the dwc3_otg structure
606 *
607 */
608void dwc3_otg_init_sm(struct dwc3_otg *dotg)
609{
610 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
611 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530612 struct dwc3_ext_xceiv *ext_xceiv;
613 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530614
615 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
616
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530617 /*
618 * VBUS initial state is reported after PMIC
619 * driver initialization. Wait for it.
620 */
621 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530622 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530623 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530624 /* We can safely assume no cable connected */
625 set_bit(ID, &dotg->inputs);
626 }
Manu Gautam8c642812012-06-07 10:35:10 +0530627
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530628 ext_xceiv = dotg->ext_xceiv;
629 dwc3_otg_reset(dotg);
630 if (ext_xceiv && !ext_xceiv->otg_capability) {
631 if (osts & DWC3_OTG_OSTS_CONIDSTS)
632 set_bit(ID, &dotg->inputs);
633 else
634 clear_bit(ID, &dotg->inputs);
635
636 if (osts & DWC3_OTG_OSTS_BSESVALID)
637 set_bit(B_SESS_VLD, &dotg->inputs);
638 else
639 clear_bit(B_SESS_VLD, &dotg->inputs);
640 }
Manu Gautam8c642812012-06-07 10:35:10 +0530641}
642
643/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200644 * dwc3_otg_sm_work - workqueue function.
645 *
646 * @w: Pointer to the dwc3 otg workqueue
647 *
648 * NOTE: After any change in phy->state,
649 * we must reschdule the state machine.
650 */
651static void dwc3_otg_sm_work(struct work_struct *w)
652{
653 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
654 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530655 struct dwc3_charger *charger = dotg->charger;
656 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200657
Manu Gautamb5067272012-07-02 09:53:41 +0530658 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200659 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
660
661 /* Check OTG state */
662 switch (phy->state) {
663 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530664 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530665 if (!dotg->psy) {
666 dotg->psy = power_supply_get_by_name("usb");
667
668 if (!dotg->psy)
669 dev_err(phy->dev,
670 "couldn't get usb power supply\n");
671 }
672
Manu Gautam8c642812012-06-07 10:35:10 +0530673 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530674 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530675 dev_dbg(phy->dev, "!id\n");
676 phy->state = OTG_STATE_A_IDLE;
677 work = 1;
678 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
679 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200680 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530681 work = 1;
682 } else {
683 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530684 dev_dbg(phy->dev, "No device, trying to suspend\n");
685 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200686 }
687 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530688
689 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530690 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530691 dev_dbg(phy->dev, "!id\n");
692 phy->state = OTG_STATE_A_IDLE;
693 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530694 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530695 if (charger) {
696 if (charger->chg_type == DWC3_INVALID_CHARGER)
697 charger->start_detection(dotg->charger,
698 false);
699 else
700 charger->chg_type =
701 DWC3_INVALID_CHARGER;
702 }
703 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
704 dev_dbg(phy->dev, "b_sess_vld\n");
705 if (charger) {
706 /* Has charger been detected? If no detect it */
707 switch (charger->chg_type) {
708 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530709 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530710 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530711 dwc3_otg_set_power(phy,
712 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530713 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530714 break;
715 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530716 dwc3_otg_set_power(phy,
717 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530718 dwc3_otg_start_peripheral(&dotg->otg,
719 1);
720 phy->state = OTG_STATE_B_PERIPHERAL;
721 work = 1;
722 break;
723 case DWC3_SDP_CHARGER:
724 dwc3_otg_start_peripheral(&dotg->otg,
725 1);
726 phy->state = OTG_STATE_B_PERIPHERAL;
727 work = 1;
728 break;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530729 case DWC3_UNSUPPORTED_CHARGER:
730 dotg->charger_retry_count++;
731 if (dotg->charger_retry_count ==
732 max_chgr_retry_count) {
733 dwc3_otg_set_power(phy, 0);
734 pm_runtime_put_sync(phy->dev);
735 break;
736 }
737 charger->start_detection(dotg->charger,
738 false);
739
Manu Gautam8c642812012-06-07 10:35:10 +0530740 default:
741 dev_dbg(phy->dev, "chg_det started\n");
742 charger->start_detection(charger, true);
743 break;
744 }
745 } else {
746 /* no charger registered, start peripheral */
747 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
748 /*
749 * Probably set_peripheral not called
750 * yet. We will re-try as soon as it
751 * will be called
752 */
Manu Gautamb5067272012-07-02 09:53:41 +0530753 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530754 "unable to start B-device\n");
755 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530756 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530757 return;
758 }
759 }
760 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530761 if (charger)
762 charger->start_detection(dotg->charger, false);
763
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530764 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530765 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530766 dev_dbg(phy->dev, "No device, trying to suspend\n");
767 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530768 }
769 break;
770
771 case OTG_STATE_B_PERIPHERAL:
772 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
773 !test_bit(ID, &dotg->inputs)) {
774 dev_dbg(phy->dev, "!id || !bsv\n");
775 dwc3_otg_start_peripheral(&dotg->otg, 0);
776 phy->state = OTG_STATE_B_IDLE;
777 if (charger)
778 charger->chg_type = DWC3_INVALID_CHARGER;
779 work = 1;
780 }
781 break;
782
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200783 case OTG_STATE_A_IDLE:
784 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530785 if (test_bit(ID, &dotg->inputs)) {
786 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200787 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530788 work = 1;
789 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530790 phy->state = OTG_STATE_A_HOST;
791 if (dwc3_otg_start_host(&dotg->otg, 1)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530792 /*
793 * Probably set_host was not called yet.
794 * We will re-try as soon as it will be called
795 */
Manu Gautamb5067272012-07-02 09:53:41 +0530796 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530797 "unable to start A-device\n");
798 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530799 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530800 return;
801 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200802 }
803 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530804
805 case OTG_STATE_A_HOST:
806 if (test_bit(ID, &dotg->inputs)) {
807 dev_dbg(phy->dev, "id\n");
808 dwc3_otg_start_host(&dotg->otg, 0);
809 phy->state = OTG_STATE_B_IDLE;
810 work = 1;
811 }
812 break;
813
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200814 default:
815 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
816
817 }
Manu Gautam8c642812012-06-07 10:35:10 +0530818
819 if (work)
820 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200821}
822
823
824/**
825 * dwc3_otg_reset - reset dwc3 otg registers.
826 *
827 * @w: Pointer to the dwc3 otg workqueue
828 */
829static void dwc3_otg_reset(struct dwc3_otg *dotg)
830{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530831 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530832 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
833
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200834 /*
835 * OCFG[2] - OTG-Version = 1
836 * OCFG[1] - HNPCap = 0
837 * OCFG[0] - SRPCap = 0
838 */
839 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
840
841 /*
842 * OCTL[6] - PeriMode = 1
843 * OCTL[5] - PrtPwrCtl = 0
844 * OCTL[4] - HNPReq = 0
845 * OCTL[3] - SesReq = 0
846 * OCTL[2] - TermSelDLPulse = 0
847 * OCTL[1] - DevSetHNPEn = 0
848 * OCTL[0] - HstSetHNPEn = 0
849 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530850 if (!once) {
851 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
852 once++;
853 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200854
855 /* Clear all otg events (interrupts) indications */
856 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
857
Manu Gautam8c642812012-06-07 10:35:10 +0530858 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530859 if (ext_xceiv && !ext_xceiv->otg_capability)
860 dwc3_writel(dotg->regs, DWC3_OEVTEN,
861 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
862 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200863}
864
865/**
866 * dwc3_otg_init - Initializes otg related registers
867 * @dwc: Pointer to out controller context structure
868 *
869 * Returns 0 on success otherwise negative errno.
870 */
871int dwc3_otg_init(struct dwc3 *dwc)
872{
873 u32 reg;
874 int ret = 0;
875 struct dwc3_otg *dotg;
876
877 dev_dbg(dwc->dev, "dwc3_otg_init\n");
878
879 /*
880 * GHWPARAMS6[10] bit is SRPSupport.
881 * This bit also reflects DWC_USB3_EN_OTG
882 */
883 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
884 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
885 /*
886 * No OTG support in the HW core.
887 * We return 0 to indicate no error, since this is acceptable
888 * situation, just continue probe the dwc3 driver without otg.
889 */
890 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
891 return 0;
892 }
893
894 /* Allocate and init otg instance */
895 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
896 if (!dotg) {
897 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
898 return -ENOMEM;
899 }
900
Manu Gautam17206c22012-06-21 10:17:53 +0530901 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
902 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
903 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200904 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530905 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200906 ret = -ENODEV;
907 goto err1;
908 }
909
910 dotg->regs = dwc->regs;
911
912 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
913 dotg->otg.set_host = dwc3_otg_set_host;
914
915 /* This reference is used by dwc3 modules for checking otg existance */
916 dwc->dotg = dotg;
917
918 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
919 if (!dotg->otg.phy) {
920 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
921 ret = -ENOMEM;
922 goto err1;
923 }
924
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530925 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200926 dotg->otg.phy->otg = &dotg->otg;
927 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530928 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530929 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200930
931 ret = usb_set_transceiver(dotg->otg.phy);
932 if (ret) {
933 dev_err(dotg->otg.phy->dev,
934 "%s: failed to set transceiver, already exists\n",
935 __func__);
936 goto err2;
937 }
938
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200939 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
940
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530941 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200942 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
943
944 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
945 "dwc3_otg", dotg);
946 if (ret) {
947 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
948 dotg->irq, ret);
949 goto err3;
950 }
951
Manu Gautamb5067272012-07-02 09:53:41 +0530952 pm_runtime_get(dwc->dev);
953
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200954 return 0;
955
956err3:
957 cancel_work_sync(&dotg->sm_work);
958 usb_set_transceiver(NULL);
959err2:
960 kfree(dotg->otg.phy);
961err1:
962 dwc->dotg = NULL;
963 kfree(dotg);
964
965 return ret;
966}
967
968/**
969 * dwc3_otg_exit
970 * @dwc: Pointer to out controller context structure
971 *
972 * Returns 0 on success otherwise negative errno.
973 */
974void dwc3_otg_exit(struct dwc3 *dwc)
975{
976 struct dwc3_otg *dotg = dwc->dotg;
977
978 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
979 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530980 if (dotg->charger)
981 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200982 cancel_work_sync(&dotg->sm_work);
983 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530984 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200985 free_irq(dotg->irq, dotg);
986 kfree(dotg->otg.phy);
987 kfree(dotg);
988 dwc->dotg = NULL;
989 }
990}