blob: 0d4d58091b9f5c7d95eb0d0735c9813ca4ac96ce [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)
Jack Pham4b00e702013-07-03 17:10:36 -0700221 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530222
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)
Jack Pham4b00e702013-07-03 17:10:36 -0700288 ext_xceiv->ext_block_reset(ext_xceiv, 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 Vennapusab11d7fd2013-07-01 16:40:57 +0530729 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530730 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530731 /*
732 * In case of floating charger, if
733 * retry count equal to max retry count
734 * notify PMIC about floating charger
735 * and put Hw in low power mode. Else
736 * perform charger detection again by
737 * calling start_detection() with false
738 * and then with true argument.
739 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530740 if (dotg->charger_retry_count ==
741 max_chgr_retry_count) {
742 dwc3_otg_set_power(phy, 0);
743 pm_runtime_put_sync(phy->dev);
744 break;
745 }
746 charger->start_detection(dotg->charger,
747 false);
748
Manu Gautam8c642812012-06-07 10:35:10 +0530749 default:
750 dev_dbg(phy->dev, "chg_det started\n");
751 charger->start_detection(charger, true);
752 break;
753 }
754 } else {
755 /* no charger registered, start peripheral */
756 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
757 /*
758 * Probably set_peripheral not called
759 * yet. We will re-try as soon as it
760 * will be called
761 */
Manu Gautamb5067272012-07-02 09:53:41 +0530762 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530763 "unable to start B-device\n");
764 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530765 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530766 return;
767 }
768 }
769 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530770 if (charger)
771 charger->start_detection(dotg->charger, false);
772
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530773 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530774 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530775 dev_dbg(phy->dev, "No device, trying to suspend\n");
776 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530777 }
778 break;
779
780 case OTG_STATE_B_PERIPHERAL:
781 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
782 !test_bit(ID, &dotg->inputs)) {
783 dev_dbg(phy->dev, "!id || !bsv\n");
784 dwc3_otg_start_peripheral(&dotg->otg, 0);
785 phy->state = OTG_STATE_B_IDLE;
786 if (charger)
787 charger->chg_type = DWC3_INVALID_CHARGER;
788 work = 1;
789 }
790 break;
791
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200792 case OTG_STATE_A_IDLE:
793 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530794 if (test_bit(ID, &dotg->inputs)) {
795 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200796 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530797 work = 1;
798 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530799 phy->state = OTG_STATE_A_HOST;
800 if (dwc3_otg_start_host(&dotg->otg, 1)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530801 /*
802 * Probably set_host was not called yet.
803 * We will re-try as soon as it will be called
804 */
Manu Gautamb5067272012-07-02 09:53:41 +0530805 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530806 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530807 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530808 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530809 return;
810 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200811 }
812 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530813
814 case OTG_STATE_A_HOST:
815 if (test_bit(ID, &dotg->inputs)) {
816 dev_dbg(phy->dev, "id\n");
817 dwc3_otg_start_host(&dotg->otg, 0);
818 phy->state = OTG_STATE_B_IDLE;
819 work = 1;
820 }
821 break;
822
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200823 default:
824 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
825
826 }
Manu Gautam8c642812012-06-07 10:35:10 +0530827
828 if (work)
829 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200830}
831
832
833/**
834 * dwc3_otg_reset - reset dwc3 otg registers.
835 *
836 * @w: Pointer to the dwc3 otg workqueue
837 */
838static void dwc3_otg_reset(struct dwc3_otg *dotg)
839{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530840 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530841 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
842
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200843 /*
844 * OCFG[2] - OTG-Version = 1
845 * OCFG[1] - HNPCap = 0
846 * OCFG[0] - SRPCap = 0
847 */
848 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
849
850 /*
851 * OCTL[6] - PeriMode = 1
852 * OCTL[5] - PrtPwrCtl = 0
853 * OCTL[4] - HNPReq = 0
854 * OCTL[3] - SesReq = 0
855 * OCTL[2] - TermSelDLPulse = 0
856 * OCTL[1] - DevSetHNPEn = 0
857 * OCTL[0] - HstSetHNPEn = 0
858 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530859 if (!once) {
860 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
861 once++;
862 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200863
864 /* Clear all otg events (interrupts) indications */
865 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
866
Manu Gautam8c642812012-06-07 10:35:10 +0530867 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530868 if (ext_xceiv && !ext_xceiv->otg_capability)
869 dwc3_writel(dotg->regs, DWC3_OEVTEN,
870 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
871 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200872}
873
874/**
875 * dwc3_otg_init - Initializes otg related registers
876 * @dwc: Pointer to out controller context structure
877 *
878 * Returns 0 on success otherwise negative errno.
879 */
880int dwc3_otg_init(struct dwc3 *dwc)
881{
882 u32 reg;
883 int ret = 0;
884 struct dwc3_otg *dotg;
885
886 dev_dbg(dwc->dev, "dwc3_otg_init\n");
887
888 /*
889 * GHWPARAMS6[10] bit is SRPSupport.
890 * This bit also reflects DWC_USB3_EN_OTG
891 */
892 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
893 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
894 /*
895 * No OTG support in the HW core.
896 * We return 0 to indicate no error, since this is acceptable
897 * situation, just continue probe the dwc3 driver without otg.
898 */
899 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
900 return 0;
901 }
902
903 /* Allocate and init otg instance */
904 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
905 if (!dotg) {
906 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
907 return -ENOMEM;
908 }
909
Manu Gautam17206c22012-06-21 10:17:53 +0530910 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
911 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
912 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200913 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530914 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200915 ret = -ENODEV;
916 goto err1;
917 }
918
919 dotg->regs = dwc->regs;
920
921 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
922 dotg->otg.set_host = dwc3_otg_set_host;
923
924 /* This reference is used by dwc3 modules for checking otg existance */
925 dwc->dotg = dotg;
926
927 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
928 if (!dotg->otg.phy) {
929 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
930 ret = -ENOMEM;
931 goto err1;
932 }
933
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530934 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200935 dotg->otg.phy->otg = &dotg->otg;
936 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530937 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530938 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200939
940 ret = usb_set_transceiver(dotg->otg.phy);
941 if (ret) {
942 dev_err(dotg->otg.phy->dev,
943 "%s: failed to set transceiver, already exists\n",
944 __func__);
945 goto err2;
946 }
947
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200948 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
949
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530950 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200951 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
952
953 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
954 "dwc3_otg", dotg);
955 if (ret) {
956 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
957 dotg->irq, ret);
958 goto err3;
959 }
960
Manu Gautamb5067272012-07-02 09:53:41 +0530961 pm_runtime_get(dwc->dev);
962
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200963 return 0;
964
965err3:
966 cancel_work_sync(&dotg->sm_work);
967 usb_set_transceiver(NULL);
968err2:
969 kfree(dotg->otg.phy);
970err1:
971 dwc->dotg = NULL;
972 kfree(dotg);
973
974 return ret;
975}
976
977/**
978 * dwc3_otg_exit
979 * @dwc: Pointer to out controller context structure
980 *
981 * Returns 0 on success otherwise negative errno.
982 */
983void dwc3_otg_exit(struct dwc3 *dwc)
984{
985 struct dwc3_otg *dotg = dwc->dotg;
986
987 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
988 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530989 if (dotg->charger)
990 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200991 cancel_work_sync(&dotg->sm_work);
992 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530993 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200994 free_irq(dotg->irq, dotg);
995 kfree(dotg->otg.phy);
996 kfree(dotg);
997 dwc->dotg = NULL;
998 }
999}