blob: e912e864cb5dc0c65f8490f3c2f371b2510fd4e9 [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);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +053059 /*
60 * Allow ITP generated off of ref clk based counter instead
61 * of UTMI/ULPI clk based counter, when superspeed only is
62 * active so that UTMI/ULPI can be suspened.
63 */
64 reg |= DWC3_GCTL_SOFITPSYNC;
65 /*
66 * Set this bit so that device attempts three more times at SS,
67 * even if it failed previously to operate in SS mode.
68 */
69 reg |= DWC3_GCTL_U2RSTECN;
70 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
71 reg |= DWC3_GCTL_PWRDNSCALE(2);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +053072 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
73 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +053074}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020075
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +053076static int dwc3_otg_set_suspend(struct usb_phy *phy, int suspend)
77{
78 struct usb_otg *otg = phy->otg;
79 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
80
81 if (dotg->host_bus_suspend == suspend)
82 return 0;
83
84 dotg->host_bus_suspend = suspend;
85 if (suspend) {
86 pm_runtime_put_sync(phy->dev);
87 } else {
88 pm_runtime_get_noresume(phy->dev);
89 pm_runtime_resume(phy->dev);
90 }
91
92 return 0;
93}
94
Manu Gautamf1fceddf2012-10-12 14:02:50 +053095/**
96 * dwc3_otg_set_host_power - Enable port power control for host operation
97 *
98 * This function enables the OTG Port Power required to operate in Host mode
99 * This function should be called only after XHCI driver has set the port
100 * power in PORTSC register.
101 *
102 * @w: Pointer to the dwc3 otg struct
103 */
104void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
105{
106 u32 osts;
107
108 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
109 if (!(osts & 0x8))
110 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
111
112 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200113}
114
115/**
116 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
117 *
118 * This function sets the OTG registers to work in B-Device peripheral mode.
119 * This function should be called just before entering to B-Device mode.
120 *
121 * @w: Pointer to the dwc3 otg workqueue.
122 */
123static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
124{
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530125 u32 reg;
126 struct dwc3 *dwc = dotg->dwc;
127 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200128
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530129 if (ext_xceiv && !ext_xceiv->otg_capability) {
130 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
131 reg = dwc3_readl(dotg->regs, DWC3_OCTL);
132 reg |= DWC3_OTG_OCTL_PERIMODE;
133 dwc3_writel(dotg->regs, DWC3_OCTL, reg);
134 /*
135 * TODO: add more OTG registers writes for PERIPHERAL mode here,
136 * see figure 12-19 B-device flow in dwc3 Synopsis spec
137 */
138 } else {
139 reg = dwc3_readl(dwc->regs, DWC3_GCTL);
140 reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG));
141 reg |= DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_DEVICE);
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530142 /*
143 * Set this bit so that device attempts three more times at SS,
144 * even if it failed previously to operate in SS mode.
145 */
146 reg |= DWC3_GCTL_U2RSTECN;
147 reg &= ~(DWC3_GCTL_PWRDNSCALEMASK);
148 reg |= DWC3_GCTL_PWRDNSCALE(2);
149 reg &= ~(DWC3_GCTL_SOFITPSYNC);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530150 dwc3_writel(dwc->regs, DWC3_GCTL, reg);
151 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200152}
153
154/**
155 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
156 *
157 * @otg: Pointer to the otg_transceiver structure.
158 * @on: start / stop the host controller driver.
159 *
160 * Returns 0 on success otherwise negative errno.
161 */
162static int dwc3_otg_start_host(struct usb_otg *otg, int on)
163{
164 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530165 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Manu Gautam61721592012-11-06 18:09:39 +0530166 struct dwc3 *dwc = dotg->dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200167 int ret = 0;
168
Manu Gautam61721592012-11-06 18:09:39 +0530169 if (!dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200170 return -EINVAL;
171
Manu Gautam61721592012-11-06 18:09:39 +0530172 if (!dotg->vbus_otg) {
173 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
174 "vbus_dwc3");
175 if (IS_ERR(dotg->vbus_otg)) {
176 dev_err(dwc->dev, "Failed to get vbus regulator\n");
177 ret = PTR_ERR(dotg->vbus_otg);
178 dotg->vbus_otg = 0;
179 return ret;
180 }
181 }
182
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200183 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530184 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200185
186 /*
187 * This should be revisited for more testing post-silicon.
188 * In worst case we may need to disconnect the root hub
189 * before stopping the controller so that it does not
190 * interfere with runtime pm/system pm.
191 * We can also consider registering and unregistering xhci
192 * platform device. It is almost similar to add_hcd and
193 * remove_hcd, But we may not use standard set_host method
194 * anymore.
195 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530196 dwc3_otg_set_host_regs(dotg);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530197 /*
198 * FIXME If micro A cable is disconnected during system suspend,
199 * xhci platform device will be removed before runtime pm is
200 * enabled for xhci device. Due to this, disable_depth becomes
201 * greater than one and runtimepm is not enabled for next microA
202 * connect. Fix this by calling pm_runtime_init for xhci device.
203 */
204 pm_runtime_init(&dwc->xhci->dev);
Manu Gautam61721592012-11-06 18:09:39 +0530205 ret = platform_device_add(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200206 if (ret) {
207 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530208 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200209 __func__, ret);
210 return ret;
211 }
212
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530213 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530214 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200215 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530216 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
Manu Gautam61721592012-11-06 18:09:39 +0530217 platform_device_del(dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200218 return ret;
219 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530220
221 /* re-init OTG EVTEN register as XHCI reset clears it */
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530222 if (ext_xceiv && !ext_xceiv->otg_capability)
223 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200224 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530225 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
226
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530227 ret = regulator_disable(dotg->vbus_otg);
228 if (ret) {
229 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
230 return ret;
231 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530232 dwc3_otg_notify_host_mode(otg, on);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530233
Vijayavardhan Vennapusaf9937962013-04-17 17:51:30 +0530234 platform_device_del(dwc->xhci);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530235 /*
236 * Perform USB hardware RESET (both core reset and DBM reset)
237 * when moving from host to peripheral. This is required for
238 * peripheral mode to work.
239 */
240 if (ext_xceiv && ext_xceiv->otg_capability &&
241 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700242 ext_xceiv->ext_block_reset(ext_xceiv, true);
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530243
Manu Gautamab3da1b2013-04-02 14:29:01 +0530244 dwc3_otg_set_peripheral_regs(dotg);
245
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530246 /* re-init core and OTG registers as block reset clears these */
247 dwc3_post_host_reset_core_init(dwc);
248 if (ext_xceiv && !ext_xceiv->otg_capability)
249 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200250 }
251
252 return 0;
253}
254
255/**
256 * dwc3_otg_set_host - bind/unbind the host controller driver.
257 *
258 * @otg: Pointer to the otg_transceiver structure.
259 * @host: Pointer to the usb_bus structure.
260 *
261 * Returns 0 on success otherwise negative errno.
262 */
263static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
264{
265 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
266
267 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530268 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200269 __func__, host->bus_name);
270 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200271 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530272 * Though XHCI power would be set by now, but some delay is
273 * required for XHCI controller before setting OTG Port Power
274 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200275 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530276 msleep(300);
277 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200278 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530279 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200280 }
281
282 return 0;
283}
284
285/**
286 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
287 *
288 * @otg: Pointer to the otg_transceiver structure.
289 * @gadget: pointer to the usb_gadget structure.
290 *
291 * Returns 0 on success otherwise negative errno.
292 */
293static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
294{
295 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Manu Gautama302f612012-12-18 17:33:06 +0530296 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200297
298 if (!otg->gadget)
299 return -EINVAL;
300
301 if (on) {
302 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
303 __func__, otg->gadget->name);
Manu Gautama302f612012-12-18 17:33:06 +0530304
Vijayavardhan Vennapusaf7c01a42013-03-15 15:29:11 +0530305 /* Core reset is not required during start peripheral. Only
306 * DBM reset is required, hence perform only DBM reset here */
Manu Gautama302f612012-12-18 17:33:06 +0530307 if (ext_xceiv && ext_xceiv->otg_capability &&
308 ext_xceiv->ext_block_reset)
Jack Pham4b00e702013-07-03 17:10:36 -0700309 ext_xceiv->ext_block_reset(ext_xceiv, false);
Manu Gautama302f612012-12-18 17:33:06 +0530310
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200311 dwc3_otg_set_peripheral_regs(dotg);
312 usb_gadget_vbus_connect(otg->gadget);
313 } else {
314 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
315 __func__, otg->gadget->name);
316 usb_gadget_vbus_disconnect(otg->gadget);
317 }
318
319 return 0;
320}
321
322/**
323 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
324 *
325 * @otg: Pointer to the otg_transceiver structure.
326 * @gadget: pointer to the usb_gadget structure.
327 *
328 * Returns 0 on success otherwise negative errno.
329 */
330static int dwc3_otg_set_peripheral(struct usb_otg *otg,
331 struct usb_gadget *gadget)
332{
333 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
334
335 if (gadget) {
336 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
337 __func__, gadget->name);
338 otg->gadget = gadget;
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530339 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200340 } else {
341 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
342 dwc3_otg_start_peripheral(otg, 0);
343 otg->gadget = NULL;
344 otg->phy->state = OTG_STATE_UNDEFINED;
345 schedule_work(&dotg->sm_work);
346 } else {
347 otg->gadget = NULL;
348 }
349 }
350
351 return 0;
352}
353
354/**
Manu Gautam8c642812012-06-07 10:35:10 +0530355 * dwc3_ext_chg_det_done - callback to handle charger detection completion
356 * @otg: Pointer to the otg transceiver structure
357 * @charger: Pointer to the external charger structure
358 *
359 * Returns 0 on success
360 */
361static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
362{
363 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
364
365 /*
366 * Ignore chg_detection notification if BSV has gone off by this time.
367 * STOP chg_det as part of !BSV handling would reset the chg_det flags
368 */
369 if (test_bit(B_SESS_VLD, &dotg->inputs))
370 schedule_work(&dotg->sm_work);
371}
372
373/**
374 * dwc3_set_charger - bind/unbind external charger driver
375 * @otg: Pointer to the otg transceiver structure
376 * @charger: Pointer to the external charger structure
377 *
378 * Returns 0 on success
379 */
380int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
381{
382 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
383
384 dotg->charger = charger;
385 if (charger)
386 charger->notify_detection_complete = dwc3_ext_chg_det_done;
387
388 return 0;
389}
390
Manu Gautamb5067272012-07-02 09:53:41 +0530391/**
392 * dwc3_ext_event_notify - callback to handle events from external transceiver
393 * @otg: Pointer to the otg transceiver structure
394 * @event: Event reported by transceiver
395 *
396 * Returns 0 on success
397 */
398static void dwc3_ext_event_notify(struct usb_otg *otg,
399 enum dwc3_ext_events event)
400{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530401 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530402 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
403 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
404 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530405 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530406
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530407 /* Flush processing any pending events before handling new ones */
408 if (init)
409 flush_work(&dotg->sm_work);
410
Manu Gautamb5067272012-07-02 09:53:41 +0530411 if (event == DWC3_EVENT_PHY_RESUME) {
412 if (!pm_runtime_status_suspended(phy->dev)) {
413 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
414 } else {
415 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
416 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530417 ret = pm_runtime_get(phy->dev);
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530418 if ((phy->state == OTG_STATE_A_HOST) &&
419 dotg->host_bus_suspend)
420 dotg->host_bus_suspend = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530421 if (ret == -EACCES) {
422 /* pm_runtime_get may fail during system
423 resume with -EACCES error */
424 pm_runtime_disable(phy->dev);
425 pm_runtime_set_active(phy->dev);
426 pm_runtime_enable(phy->dev);
427 } else if (ret < 0) {
428 dev_warn(phy->dev, "pm_runtime_get failed!\n");
429 }
Manu Gautamb5067272012-07-02 09:53:41 +0530430 }
Manu Gautam377821c2012-09-28 16:53:24 +0530431 } else if (event == DWC3_EVENT_XCEIV_STATE) {
Manu Gautamf71d9cb2013-02-07 13:52:12 +0530432 if (pm_runtime_status_suspended(phy->dev)) {
433 dev_warn(phy->dev, "PHY_STATE event in LPM!!!!\n");
434 ret = pm_runtime_get(phy->dev);
435 if (ret < 0)
436 dev_warn(phy->dev, "pm_runtime_get failed!!\n");
437 }
Jack Pham0fc12332012-11-19 13:14:22 -0800438 if (ext_xceiv->id == DWC3_ID_FLOAT) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530439 dev_dbg(phy->dev, "XCVR: ID set\n");
440 set_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800441 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530442 dev_dbg(phy->dev, "XCVR: ID clear\n");
443 clear_bit(ID, &dotg->inputs);
Jack Pham0fc12332012-11-19 13:14:22 -0800444 }
Manu Gautam377821c2012-09-28 16:53:24 +0530445
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530446 if (ext_xceiv->bsv) {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530447 dev_dbg(phy->dev, "XCVR: BSV set\n");
448 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530449 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530450 dev_dbg(phy->dev, "XCVR: BSV clear\n");
451 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530452 }
Manu Gautam377821c2012-09-28 16:53:24 +0530453
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530454 if (!init) {
455 init = true;
Manu Gautam4ff07242013-03-27 14:31:11 +0530456 if (!work_busy(&dotg->sm_work))
457 schedule_work(&dotg->sm_work);
458
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530459 complete(&dotg->dwc3_xcvr_vbus_init);
460 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
461 return;
462 }
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530463
464 schedule_work(&dotg->sm_work);
Manu Gautamb5067272012-07-02 09:53:41 +0530465 }
Manu Gautamb5067272012-07-02 09:53:41 +0530466}
467
468/**
469 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
470 * @otg: Pointer to the otg transceiver structure
471 * @ext_xceiv: Pointer to the external transceiver struccture
472 *
473 * Returns 0 on success
474 */
475int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
476{
477 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
478
479 dotg->ext_xceiv = ext_xceiv;
480 if (ext_xceiv)
481 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
482
483 return 0;
484}
485
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530486static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
487{
488 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
489
490 if (!dotg->psy) {
491 dev_err(otg->phy->dev, "no usb power supply registered\n");
492 return;
493 }
494
495 if (host_mode)
496 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
497 else
498 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
499}
500
501static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
502{
503 static int power_supply_type;
504 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
505
506
Manu Gautam6c0ff032012-11-02 14:55:35 +0530507 if (!dotg->psy || !dotg->charger) {
508 dev_err(phy->dev, "no usb power supply/charger registered\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530509 return 0;
510 }
511
Manu Gautam6c0ff032012-11-02 14:55:35 +0530512 if (dotg->charger->charging_disabled)
513 return 0;
514
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530515 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
516 power_supply_type = POWER_SUPPLY_TYPE_USB;
517 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
518 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
Manu Gautama1e331d2013-02-07 14:55:05 +0530519 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER ||
520 dotg->charger->chg_type == DWC3_PROPRIETARY_CHARGER)
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530521 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
522 else
523 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
524
525 power_supply_set_supply_type(dotg->psy, power_supply_type);
526
Pavankumar Kondeti6a351422013-06-07 10:02:43 +0530527 if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
Vijayavardhan Vennapusa2e0b4182013-03-21 12:49:43 +0530528 mA = DWC3_IDEV_CHG_MAX;
529
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530530 if (dotg->charger->max_power == mA)
531 return 0;
532
533 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
534
535 if (dotg->charger->max_power <= 2 && mA > 2) {
536 /* Enable charging */
537 if (power_supply_set_online(dotg->psy, true))
538 goto psy_error;
539 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
540 goto psy_error;
541 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
542 /* Disable charging */
543 if (power_supply_set_online(dotg->psy, false))
544 goto psy_error;
545 /* Set max current limit */
546 if (power_supply_set_current_limit(dotg->psy, 0))
547 goto psy_error;
548 }
549
550 power_supply_changed(dotg->psy);
551 dotg->charger->max_power = mA;
552 return 0;
553
554psy_error:
555 dev_dbg(phy->dev, "power supply error when setting property\n");
556 return -ENXIO;
557}
558
Manu Gautam8c642812012-06-07 10:35:10 +0530559/* IRQs which OTG driver is interested in handling */
560#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
561 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
562
563/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200564 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
565 * @_dotg: Pointer to out controller context structure
566 *
567 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
568 */
569static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
570{
571 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530572 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200573 int ret = IRQ_NONE;
574 int handled_irqs = 0;
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530575 struct usb_phy *phy = dotg->otg.phy;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200576
577 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
578
Manu Gautam8c642812012-06-07 10:35:10 +0530579 if (!(oevt_reg & DWC3_OEVT_MASK))
580 return IRQ_NONE;
581
582 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
583
584 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
585 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200586 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530587 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200588 * function, switch from A to B or from B to A.
589 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200590
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530591 if (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) {
592 if (osts & DWC3_OTG_OSTS_CONIDSTS) {
593 dev_dbg(phy->dev, "ID set\n");
594 set_bit(ID, &dotg->inputs);
595 } else {
596 dev_dbg(phy->dev, "ID clear\n");
597 clear_bit(ID, &dotg->inputs);
598 }
599 handled_irqs |= DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT;
600 }
Manu Gautam8c642812012-06-07 10:35:10 +0530601
Vijayavardhan Vennapusab7434562012-12-12 16:48:49 +0530602 if (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) {
603 if (osts & DWC3_OTG_OSTS_BSESVALID) {
604 dev_dbg(phy->dev, "BSV set\n");
605 set_bit(B_SESS_VLD, &dotg->inputs);
606 } else {
607 dev_dbg(phy->dev, "BSV clear\n");
608 clear_bit(B_SESS_VLD, &dotg->inputs);
609 }
610 handled_irqs |= DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT;
611 }
Manu Gautam8c642812012-06-07 10:35:10 +0530612
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200613 schedule_work(&dotg->sm_work);
614
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200615 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530616
617 /* Clear the interrupts we handled */
618 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200619 }
620
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200621 return ret;
622}
623
624/**
Manu Gautam8c642812012-06-07 10:35:10 +0530625 * dwc3_otg_init_sm - initialize OTG statemachine input
626 * @dotg: Pointer to the dwc3_otg structure
627 *
628 */
629void dwc3_otg_init_sm(struct dwc3_otg *dotg)
630{
631 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
632 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530633 struct dwc3_ext_xceiv *ext_xceiv;
634 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530635
636 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
637
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530638 /*
639 * VBUS initial state is reported after PMIC
640 * driver initialization. Wait for it.
641 */
642 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
Manu Gautam4ff07242013-03-27 14:31:11 +0530643 if (!ret) {
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530644 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam4ff07242013-03-27 14:31:11 +0530645 /* We can safely assume no cable connected */
646 set_bit(ID, &dotg->inputs);
647 }
Manu Gautam8c642812012-06-07 10:35:10 +0530648
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530649 ext_xceiv = dotg->ext_xceiv;
650 dwc3_otg_reset(dotg);
651 if (ext_xceiv && !ext_xceiv->otg_capability) {
652 if (osts & DWC3_OTG_OSTS_CONIDSTS)
653 set_bit(ID, &dotg->inputs);
654 else
655 clear_bit(ID, &dotg->inputs);
656
657 if (osts & DWC3_OTG_OSTS_BSESVALID)
658 set_bit(B_SESS_VLD, &dotg->inputs);
659 else
660 clear_bit(B_SESS_VLD, &dotg->inputs);
661 }
Manu Gautam8c642812012-06-07 10:35:10 +0530662}
663
664/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200665 * dwc3_otg_sm_work - workqueue function.
666 *
667 * @w: Pointer to the dwc3 otg workqueue
668 *
669 * NOTE: After any change in phy->state,
670 * we must reschdule the state machine.
671 */
672static void dwc3_otg_sm_work(struct work_struct *w)
673{
674 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
675 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530676 struct dwc3_charger *charger = dotg->charger;
677 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200678
Manu Gautamb5067272012-07-02 09:53:41 +0530679 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200680 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
681
682 /* Check OTG state */
683 switch (phy->state) {
684 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530685 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530686 if (!dotg->psy) {
687 dotg->psy = power_supply_get_by_name("usb");
688
689 if (!dotg->psy)
690 dev_err(phy->dev,
691 "couldn't get usb power supply\n");
692 }
693
Manu Gautam8c642812012-06-07 10:35:10 +0530694 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530695 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530696 dev_dbg(phy->dev, "!id\n");
697 phy->state = OTG_STATE_A_IDLE;
698 work = 1;
699 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
700 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200701 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530702 work = 1;
703 } else {
704 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530705 dev_dbg(phy->dev, "No device, trying to suspend\n");
706 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200707 }
708 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530709
710 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530711 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530712 dev_dbg(phy->dev, "!id\n");
713 phy->state = OTG_STATE_A_IDLE;
714 work = 1;
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530715 dotg->charger_retry_count = 0;
Manu Gautam8c642812012-06-07 10:35:10 +0530716 if (charger) {
717 if (charger->chg_type == DWC3_INVALID_CHARGER)
718 charger->start_detection(dotg->charger,
719 false);
720 else
721 charger->chg_type =
722 DWC3_INVALID_CHARGER;
723 }
724 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
725 dev_dbg(phy->dev, "b_sess_vld\n");
726 if (charger) {
727 /* Has charger been detected? If no detect it */
728 switch (charger->chg_type) {
729 case DWC3_DCP_CHARGER:
Manu Gautama1e331d2013-02-07 14:55:05 +0530730 case DWC3_PROPRIETARY_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530731 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530732 dwc3_otg_set_power(phy,
733 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530734 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530735 break;
736 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530737 dwc3_otg_set_power(phy,
738 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530739 dwc3_otg_start_peripheral(&dotg->otg,
740 1);
741 phy->state = OTG_STATE_B_PERIPHERAL;
742 work = 1;
743 break;
744 case DWC3_SDP_CHARGER:
745 dwc3_otg_start_peripheral(&dotg->otg,
746 1);
747 phy->state = OTG_STATE_B_PERIPHERAL;
748 work = 1;
749 break;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530750 case DWC3_FLOATED_CHARGER:
Vijayavardhan Vennapusac4974862013-07-23 17:36:37 +0530751 if (dotg->charger_retry_count <
752 max_chgr_retry_count)
753 dotg->charger_retry_count++;
Vijayavardhan Vennapusab11d7fd2013-07-01 16:40:57 +0530754 /*
755 * In case of floating charger, if
756 * retry count equal to max retry count
757 * notify PMIC about floating charger
758 * and put Hw in low power mode. Else
759 * perform charger detection again by
760 * calling start_detection() with false
761 * and then with true argument.
762 */
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530763 if (dotg->charger_retry_count ==
764 max_chgr_retry_count) {
765 dwc3_otg_set_power(phy, 0);
766 pm_runtime_put_sync(phy->dev);
767 break;
768 }
769 charger->start_detection(dotg->charger,
770 false);
771
Manu Gautam8c642812012-06-07 10:35:10 +0530772 default:
773 dev_dbg(phy->dev, "chg_det started\n");
774 charger->start_detection(charger, true);
775 break;
776 }
777 } else {
778 /* no charger registered, start peripheral */
779 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
780 /*
781 * Probably set_peripheral not called
782 * yet. We will re-try as soon as it
783 * will be called
784 */
Manu Gautamb5067272012-07-02 09:53:41 +0530785 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530786 "unable to start B-device\n");
787 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530788 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530789 return;
790 }
791 }
792 } else {
Manu Gautam98013c22012-11-20 17:42:42 +0530793 if (charger)
794 charger->start_detection(dotg->charger, false);
795
Vijayavardhan Vennapusaa04e0c92013-06-04 12:37:10 +0530796 dotg->charger_retry_count = 0;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530797 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530798 dev_dbg(phy->dev, "No device, trying to suspend\n");
799 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530800 }
801 break;
802
803 case OTG_STATE_B_PERIPHERAL:
804 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
805 !test_bit(ID, &dotg->inputs)) {
806 dev_dbg(phy->dev, "!id || !bsv\n");
807 dwc3_otg_start_peripheral(&dotg->otg, 0);
808 phy->state = OTG_STATE_B_IDLE;
809 if (charger)
810 charger->chg_type = DWC3_INVALID_CHARGER;
811 work = 1;
812 }
813 break;
814
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200815 case OTG_STATE_A_IDLE:
816 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530817 if (test_bit(ID, &dotg->inputs)) {
818 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200819 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530820 work = 1;
821 } else {
Manu Gautama4c3c1f2012-12-18 13:56:43 +0530822 phy->state = OTG_STATE_A_HOST;
823 if (dwc3_otg_start_host(&dotg->otg, 1)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530824 /*
825 * Probably set_host was not called yet.
826 * We will re-try as soon as it will be called
827 */
Manu Gautamb5067272012-07-02 09:53:41 +0530828 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530829 "unable to start A-device\n");
Manu Gautama57dfa32013-07-17 10:58:43 +0530830 phy->state = OTG_STATE_A_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530831 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530832 return;
833 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200834 }
835 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530836
837 case OTG_STATE_A_HOST:
838 if (test_bit(ID, &dotg->inputs)) {
839 dev_dbg(phy->dev, "id\n");
840 dwc3_otg_start_host(&dotg->otg, 0);
841 phy->state = OTG_STATE_B_IDLE;
842 work = 1;
843 }
844 break;
845
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200846 default:
847 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
848
849 }
Manu Gautam8c642812012-06-07 10:35:10 +0530850
851 if (work)
852 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200853}
854
855
856/**
857 * dwc3_otg_reset - reset dwc3 otg registers.
858 *
859 * @w: Pointer to the dwc3 otg workqueue
860 */
861static void dwc3_otg_reset(struct dwc3_otg *dotg)
862{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530863 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530864 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
865
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200866 /*
867 * OCFG[2] - OTG-Version = 1
868 * OCFG[1] - HNPCap = 0
869 * OCFG[0] - SRPCap = 0
870 */
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530871 if (ext_xceiv && !ext_xceiv->otg_capability)
872 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200873
874 /*
875 * OCTL[6] - PeriMode = 1
876 * OCTL[5] - PrtPwrCtl = 0
877 * OCTL[4] - HNPReq = 0
878 * OCTL[3] - SesReq = 0
879 * OCTL[2] - TermSelDLPulse = 0
880 * OCTL[1] - DevSetHNPEn = 0
881 * OCTL[0] - HstSetHNPEn = 0
882 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530883 if (!once) {
Vijayavardhan Vennapusaba79f6b2013-07-30 13:39:52 +0530884 if (ext_xceiv && !ext_xceiv->otg_capability)
885 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530886 once++;
887 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200888
889 /* Clear all otg events (interrupts) indications */
890 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
891
Manu Gautam8c642812012-06-07 10:35:10 +0530892 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530893 if (ext_xceiv && !ext_xceiv->otg_capability)
894 dwc3_writel(dotg->regs, DWC3_OEVTEN,
895 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
896 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200897}
898
899/**
900 * dwc3_otg_init - Initializes otg related registers
901 * @dwc: Pointer to out controller context structure
902 *
903 * Returns 0 on success otherwise negative errno.
904 */
905int dwc3_otg_init(struct dwc3 *dwc)
906{
907 u32 reg;
908 int ret = 0;
909 struct dwc3_otg *dotg;
910
911 dev_dbg(dwc->dev, "dwc3_otg_init\n");
912
913 /*
914 * GHWPARAMS6[10] bit is SRPSupport.
915 * This bit also reflects DWC_USB3_EN_OTG
916 */
917 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
918 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
919 /*
920 * No OTG support in the HW core.
921 * We return 0 to indicate no error, since this is acceptable
922 * situation, just continue probe the dwc3 driver without otg.
923 */
924 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
925 return 0;
926 }
927
928 /* Allocate and init otg instance */
929 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
930 if (!dotg) {
931 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
932 return -ENOMEM;
933 }
934
Manu Gautam17206c22012-06-21 10:17:53 +0530935 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
936 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
937 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200938 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530939 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200940 ret = -ENODEV;
941 goto err1;
942 }
943
944 dotg->regs = dwc->regs;
945
946 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
947 dotg->otg.set_host = dwc3_otg_set_host;
948
949 /* This reference is used by dwc3 modules for checking otg existance */
950 dwc->dotg = dotg;
951
952 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
953 if (!dotg->otg.phy) {
954 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
955 ret = -ENOMEM;
956 goto err1;
957 }
958
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530959 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200960 dotg->otg.phy->otg = &dotg->otg;
961 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530962 dotg->otg.phy->set_power = dwc3_otg_set_power;
Vijayavardhan Vennapusa45145882013-01-03 14:11:58 +0530963 dotg->otg.phy->set_suspend = dwc3_otg_set_suspend;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200964
965 ret = usb_set_transceiver(dotg->otg.phy);
966 if (ret) {
967 dev_err(dotg->otg.phy->dev,
968 "%s: failed to set transceiver, already exists\n",
969 __func__);
970 goto err2;
971 }
972
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200973 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
974
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530975 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200976 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
977
978 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
979 "dwc3_otg", dotg);
980 if (ret) {
981 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
982 dotg->irq, ret);
983 goto err3;
984 }
985
Manu Gautamb5067272012-07-02 09:53:41 +0530986 pm_runtime_get(dwc->dev);
987
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200988 return 0;
989
990err3:
991 cancel_work_sync(&dotg->sm_work);
992 usb_set_transceiver(NULL);
993err2:
994 kfree(dotg->otg.phy);
995err1:
996 dwc->dotg = NULL;
997 kfree(dotg);
998
999 return ret;
1000}
1001
1002/**
1003 * dwc3_otg_exit
1004 * @dwc: Pointer to out controller context structure
1005 *
1006 * Returns 0 on success otherwise negative errno.
1007 */
1008void dwc3_otg_exit(struct dwc3 *dwc)
1009{
1010 struct dwc3_otg *dotg = dwc->dotg;
1011
1012 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
1013 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +05301014 if (dotg->charger)
1015 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001016 cancel_work_sync(&dotg->sm_work);
1017 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +05301018 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001019 free_irq(dotg->irq, dotg);
1020 kfree(dotg->otg.phy);
1021 kfree(dotg);
1022 dwc->dotg = NULL;
1023 }
1024}