blob: 1aa85193b7ac7c32fe132e16cf8cc1f1f3574242 [file] [log] [blame]
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +02001/**
2 * dwc3_otg.c - DesignWare USB3 DRD Controller OTG
3 *
4 * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/usb.h>
17#include <linux/usb/hcd.h>
18#include <linux/platform_device.h>
Manu Gautamf1fceddf2012-10-12 14:02:50 +053019#include <linux/regulator/consumer.h>
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020020
21#include "core.h"
22#include "dwc3_otg.h"
23#include "io.h"
24#include "xhci.h"
25
Manu Gautamf1fceddf2012-10-12 14:02:50 +053026static void dwc3_otg_reset(struct dwc3_otg *dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020027
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +053028static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode);
29static void dwc3_otg_reset(struct dwc3_otg *dotg);
30
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020031/**
32 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
33 *
34 * This function sets the OTG registers to work in A-Device host mode.
35 * This function should be called just before entering to A-Device mode.
36 *
Manu Gautamf1fceddf2012-10-12 14:02:50 +053037 * @w: Pointer to the dwc3 otg struct
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020038 */
39static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
40{
41 u32 octl;
42
43 /* Set OCTL[6](PeriMode) to 0 (host) */
44 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
45 octl &= ~DWC3_OTG_OCTL_PERIMODE;
46 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
Manu Gautamf1fceddf2012-10-12 14:02:50 +053047}
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020048
Manu Gautamf1fceddf2012-10-12 14:02:50 +053049/**
50 * dwc3_otg_set_host_power - Enable port power control for host operation
51 *
52 * This function enables the OTG Port Power required to operate in Host mode
53 * This function should be called only after XHCI driver has set the port
54 * power in PORTSC register.
55 *
56 * @w: Pointer to the dwc3 otg struct
57 */
58void dwc3_otg_set_host_power(struct dwc3_otg *dotg)
59{
60 u32 osts;
61
62 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
63 if (!(osts & 0x8))
64 dev_err(dotg->dwc->dev, "%s: xHCIPrtPower not set\n", __func__);
65
66 dwc3_writel(dotg->regs, DWC3_OCTL, DWC3_OTG_OCTL_PRTPWRCTL);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +020067}
68
69/**
70 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
71 *
72 * This function sets the OTG registers to work in B-Device peripheral mode.
73 * This function should be called just before entering to B-Device mode.
74 *
75 * @w: Pointer to the dwc3 otg workqueue.
76 */
77static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
78{
79 u32 octl;
80
81 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
82 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
83 octl |= DWC3_OTG_OCTL_PERIMODE;
84 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
85
86 /*
87 * TODO: add more OTG registers writes for PERIPHERAL mode here,
88 * see figure 12-19 B-device flow in dwc3 Synopsis spec
89 */
90}
91
92/**
93 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
94 *
95 * @otg: Pointer to the otg_transceiver structure.
96 * @on: start / stop the host controller driver.
97 *
98 * Returns 0 on success otherwise negative errno.
99 */
100static int dwc3_otg_start_host(struct usb_otg *otg, int on)
101{
102 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200103 int ret = 0;
104
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530105 if (!dotg->dwc->xhci)
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200106 return -EINVAL;
107
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200108 if (on) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530109 dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200110
111 /*
112 * This should be revisited for more testing post-silicon.
113 * In worst case we may need to disconnect the root hub
114 * before stopping the controller so that it does not
115 * interfere with runtime pm/system pm.
116 * We can also consider registering and unregistering xhci
117 * platform device. It is almost similar to add_hcd and
118 * remove_hcd, But we may not use standard set_host method
119 * anymore.
120 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530121 dwc3_otg_set_host_regs(dotg);
122 ret = platform_device_add(dotg->dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200123 if (ret) {
124 dev_err(otg->phy->dev,
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530125 "%s: failed to add XHCI pdev ret=%d\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200126 __func__, ret);
127 return ret;
128 }
129
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530130 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530131 ret = regulator_enable(dotg->vbus_otg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200132 if (ret) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530133 dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
134 platform_device_del(dotg->dwc->xhci);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200135 return ret;
136 }
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530137
138 /* re-init OTG EVTEN register as XHCI reset clears it */
139 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200140 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530141 dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);
142
143 platform_device_del(dotg->dwc->xhci);
144
145 ret = regulator_disable(dotg->vbus_otg);
146 if (ret) {
147 dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
148 return ret;
149 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530150 dwc3_otg_notify_host_mode(otg, on);
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530151
152 /* re-init core and OTG register as XHCI reset clears it */
153 dwc3_post_host_reset_core_init(dotg->dwc);
154 dwc3_otg_reset(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200155 }
156
157 return 0;
158}
159
160/**
161 * dwc3_otg_set_host - bind/unbind the host controller driver.
162 *
163 * @otg: Pointer to the otg_transceiver structure.
164 * @host: Pointer to the usb_bus structure.
165 *
166 * Returns 0 on success otherwise negative errno.
167 */
168static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
169{
170 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
171
172 if (host) {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530173 dev_dbg(otg->phy->dev, "%s: set host %s, portpower\n",
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200174 __func__, host->bus_name);
175 otg->host = host;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200176 /*
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530177 * Though XHCI power would be set by now, but some delay is
178 * required for XHCI controller before setting OTG Port Power
179 * TODO: Tune this delay
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200180 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530181 msleep(300);
182 dwc3_otg_set_host_power(dotg);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200183 } else {
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530184 otg->host = NULL;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200185 }
186
187 return 0;
188}
189
190/**
191 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
192 *
193 * @otg: Pointer to the otg_transceiver structure.
194 * @gadget: pointer to the usb_gadget structure.
195 *
196 * Returns 0 on success otherwise negative errno.
197 */
198static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
199{
200 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
201
202 if (!otg->gadget)
203 return -EINVAL;
204
205 if (on) {
206 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
207 __func__, otg->gadget->name);
208 dwc3_otg_set_peripheral_regs(dotg);
209 usb_gadget_vbus_connect(otg->gadget);
210 } else {
211 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
212 __func__, otg->gadget->name);
213 usb_gadget_vbus_disconnect(otg->gadget);
214 }
215
216 return 0;
217}
218
219/**
220 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
221 *
222 * @otg: Pointer to the otg_transceiver structure.
223 * @gadget: pointer to the usb_gadget structure.
224 *
225 * Returns 0 on success otherwise negative errno.
226 */
227static int dwc3_otg_set_peripheral(struct usb_otg *otg,
228 struct usb_gadget *gadget)
229{
230 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
231
232 if (gadget) {
233 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
234 __func__, gadget->name);
235 otg->gadget = gadget;
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530236 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200237 } else {
238 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
239 dwc3_otg_start_peripheral(otg, 0);
240 otg->gadget = NULL;
241 otg->phy->state = OTG_STATE_UNDEFINED;
242 schedule_work(&dotg->sm_work);
243 } else {
244 otg->gadget = NULL;
245 }
246 }
247
248 return 0;
249}
250
251/**
Manu Gautam8c642812012-06-07 10:35:10 +0530252 * dwc3_ext_chg_det_done - callback to handle charger detection completion
253 * @otg: Pointer to the otg transceiver structure
254 * @charger: Pointer to the external charger structure
255 *
256 * Returns 0 on success
257 */
258static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
259{
260 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
261
262 /*
263 * Ignore chg_detection notification if BSV has gone off by this time.
264 * STOP chg_det as part of !BSV handling would reset the chg_det flags
265 */
266 if (test_bit(B_SESS_VLD, &dotg->inputs))
267 schedule_work(&dotg->sm_work);
268}
269
270/**
271 * dwc3_set_charger - bind/unbind external charger driver
272 * @otg: Pointer to the otg transceiver structure
273 * @charger: Pointer to the external charger structure
274 *
275 * Returns 0 on success
276 */
277int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
278{
279 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
280
281 dotg->charger = charger;
282 if (charger)
283 charger->notify_detection_complete = dwc3_ext_chg_det_done;
284
285 return 0;
286}
287
Manu Gautamb5067272012-07-02 09:53:41 +0530288/**
289 * dwc3_ext_event_notify - callback to handle events from external transceiver
290 * @otg: Pointer to the otg transceiver structure
291 * @event: Event reported by transceiver
292 *
293 * Returns 0 on success
294 */
295static void dwc3_ext_event_notify(struct usb_otg *otg,
296 enum dwc3_ext_events event)
297{
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530298 static bool init;
Manu Gautamb5067272012-07-02 09:53:41 +0530299 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
300 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
301 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530302 int ret = 0;
Manu Gautamb5067272012-07-02 09:53:41 +0530303
304 if (event == DWC3_EVENT_PHY_RESUME) {
305 if (!pm_runtime_status_suspended(phy->dev)) {
306 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
307 } else {
308 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
309 /* ext_xceiver would have taken h/w out of LPM by now */
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530310 ret = pm_runtime_get(phy->dev);
311 if (ret == -EACCES) {
312 /* pm_runtime_get may fail during system
313 resume with -EACCES error */
314 pm_runtime_disable(phy->dev);
315 pm_runtime_set_active(phy->dev);
316 pm_runtime_enable(phy->dev);
317 } else if (ret < 0) {
318 dev_warn(phy->dev, "pm_runtime_get failed!\n");
319 }
Manu Gautamb5067272012-07-02 09:53:41 +0530320 }
Manu Gautam377821c2012-09-28 16:53:24 +0530321 } else if (event == DWC3_EVENT_XCEIV_STATE) {
322 if (ext_xceiv->id == DWC3_ID_FLOAT)
323 set_bit(ID, &dotg->inputs);
324 else
325 clear_bit(ID, &dotg->inputs);
326
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530327 if (ext_xceiv->bsv) {
328 dev_dbg(phy->dev, "XCVR: BSV set\n");
Manu Gautam377821c2012-09-28 16:53:24 +0530329 set_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530330 } else {
331 dev_dbg(phy->dev, "XCVR: BSV clear\n");
Manu Gautam377821c2012-09-28 16:53:24 +0530332 clear_bit(B_SESS_VLD, &dotg->inputs);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530333 }
Manu Gautam377821c2012-09-28 16:53:24 +0530334
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530335 if (!init) {
336 init = true;
337 complete(&dotg->dwc3_xcvr_vbus_init);
338 dev_dbg(phy->dev, "XCVR: BSV init complete\n");
339 return;
340 }
Manu Gautam377821c2012-09-28 16:53:24 +0530341 schedule_work(&dotg->sm_work);
Manu Gautamb5067272012-07-02 09:53:41 +0530342 }
Manu Gautamb5067272012-07-02 09:53:41 +0530343}
344
345/**
346 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
347 * @otg: Pointer to the otg transceiver structure
348 * @ext_xceiv: Pointer to the external transceiver struccture
349 *
350 * Returns 0 on success
351 */
352int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
353{
354 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
355
356 dotg->ext_xceiv = ext_xceiv;
357 if (ext_xceiv)
358 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
359
360 return 0;
361}
362
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530363static void dwc3_otg_notify_host_mode(struct usb_otg *otg, int host_mode)
364{
365 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
366
367 if (!dotg->psy) {
368 dev_err(otg->phy->dev, "no usb power supply registered\n");
369 return;
370 }
371
372 if (host_mode)
373 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_SYSTEM);
374 else
375 power_supply_set_scope(dotg->psy, POWER_SUPPLY_SCOPE_DEVICE);
376}
377
378static int dwc3_otg_set_power(struct usb_phy *phy, unsigned mA)
379{
380 static int power_supply_type;
381 struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
382
383
384 if (!dotg->psy) {
385 dev_err(phy->dev, "no usb power supply registered\n");
386 return 0;
387 }
388
389 if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
390 power_supply_type = POWER_SUPPLY_TYPE_USB;
391 else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
392 power_supply_type = POWER_SUPPLY_TYPE_USB_CDP;
393 else if (dotg->charger->chg_type == DWC3_DCP_CHARGER)
394 power_supply_type = POWER_SUPPLY_TYPE_USB_DCP;
395 else
396 power_supply_type = POWER_SUPPLY_TYPE_BATTERY;
397
398 power_supply_set_supply_type(dotg->psy, power_supply_type);
399
400 if (dotg->charger->max_power == mA)
401 return 0;
402
403 dev_info(phy->dev, "Avail curr from USB = %u\n", mA);
404
405 if (dotg->charger->max_power <= 2 && mA > 2) {
406 /* Enable charging */
407 if (power_supply_set_online(dotg->psy, true))
408 goto psy_error;
409 if (power_supply_set_current_limit(dotg->psy, 1000*mA))
410 goto psy_error;
411 } else if (dotg->charger->max_power > 0 && (mA == 0 || mA == 2)) {
412 /* Disable charging */
413 if (power_supply_set_online(dotg->psy, false))
414 goto psy_error;
415 /* Set max current limit */
416 if (power_supply_set_current_limit(dotg->psy, 0))
417 goto psy_error;
418 }
419
420 power_supply_changed(dotg->psy);
421 dotg->charger->max_power = mA;
422 return 0;
423
424psy_error:
425 dev_dbg(phy->dev, "power supply error when setting property\n");
426 return -ENXIO;
427}
428
Manu Gautam8c642812012-06-07 10:35:10 +0530429/* IRQs which OTG driver is interested in handling */
430#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
431 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
432
433/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200434 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
435 * @_dotg: Pointer to out controller context structure
436 *
437 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
438 */
439static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
440{
441 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautam8c642812012-06-07 10:35:10 +0530442 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200443 int ret = IRQ_NONE;
444 int handled_irqs = 0;
445
446 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
447
Manu Gautam8c642812012-06-07 10:35:10 +0530448 if (!(oevt_reg & DWC3_OEVT_MASK))
449 return IRQ_NONE;
450
451 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
452
453 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
454 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200455 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530456 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200457 * function, switch from A to B or from B to A.
458 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200459
Manu Gautam8c642812012-06-07 10:35:10 +0530460 if (osts & DWC3_OTG_OSTS_CONIDSTS)
461 set_bit(ID, &dotg->inputs);
462 else
463 clear_bit(ID, &dotg->inputs);
464
465 if (osts & DWC3_OTG_OSTS_BSESVALID)
466 set_bit(B_SESS_VLD, &dotg->inputs);
467 else
468 clear_bit(B_SESS_VLD, &dotg->inputs);
469
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200470 schedule_work(&dotg->sm_work);
471
Manu Gautam8c642812012-06-07 10:35:10 +0530472 handled_irqs |= (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ?
473 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT : 0;
474 handled_irqs |= (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) ?
475 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT : 0;
476
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200477 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530478
479 /* Clear the interrupts we handled */
480 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200481 }
482
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200483 return ret;
484}
485
486/**
Manu Gautam8c642812012-06-07 10:35:10 +0530487 * dwc3_otg_init_sm - initialize OTG statemachine input
488 * @dotg: Pointer to the dwc3_otg structure
489 *
490 */
491void dwc3_otg_init_sm(struct dwc3_otg *dotg)
492{
493 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
494 struct usb_phy *phy = dotg->otg.phy;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530495 struct dwc3_ext_xceiv *ext_xceiv;
496 int ret;
Manu Gautam8c642812012-06-07 10:35:10 +0530497
498 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
499
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530500 /*
501 * VBUS initial state is reported after PMIC
502 * driver initialization. Wait for it.
503 */
504 ret = wait_for_completion_timeout(&dotg->dwc3_xcvr_vbus_init, HZ * 5);
505 if (!ret)
506 dev_err(phy->dev, "%s: completion timeout\n", __func__);
Manu Gautam8c642812012-06-07 10:35:10 +0530507
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530508 ext_xceiv = dotg->ext_xceiv;
509 dwc3_otg_reset(dotg);
510 if (ext_xceiv && !ext_xceiv->otg_capability) {
511 if (osts & DWC3_OTG_OSTS_CONIDSTS)
512 set_bit(ID, &dotg->inputs);
513 else
514 clear_bit(ID, &dotg->inputs);
515
516 if (osts & DWC3_OTG_OSTS_BSESVALID)
517 set_bit(B_SESS_VLD, &dotg->inputs);
518 else
519 clear_bit(B_SESS_VLD, &dotg->inputs);
520 }
Manu Gautam8c642812012-06-07 10:35:10 +0530521}
522
523/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200524 * dwc3_otg_sm_work - workqueue function.
525 *
526 * @w: Pointer to the dwc3 otg workqueue
527 *
528 * NOTE: After any change in phy->state,
529 * we must reschdule the state machine.
530 */
531static void dwc3_otg_sm_work(struct work_struct *w)
532{
533 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
534 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530535 struct dwc3_charger *charger = dotg->charger;
536 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200537
Manu Gautamb5067272012-07-02 09:53:41 +0530538 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200539 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
540
541 /* Check OTG state */
542 switch (phy->state) {
543 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530544 dwc3_otg_init_sm(dotg);
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530545 if (!dotg->psy) {
546 dotg->psy = power_supply_get_by_name("usb");
547
548 if (!dotg->psy)
549 dev_err(phy->dev,
550 "couldn't get usb power supply\n");
551 }
552
Manu Gautam8c642812012-06-07 10:35:10 +0530553 /* Switch to A or B-Device according to ID / BSV */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530554 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530555 dev_dbg(phy->dev, "!id\n");
556 phy->state = OTG_STATE_A_IDLE;
557 work = 1;
558 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
559 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200560 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530561 work = 1;
562 } else {
563 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530564 dev_dbg(phy->dev, "No device, trying to suspend\n");
565 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200566 }
567 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530568
569 case OTG_STATE_B_IDLE:
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530570 if (!test_bit(ID, &dotg->inputs)) {
Manu Gautam8c642812012-06-07 10:35:10 +0530571 dev_dbg(phy->dev, "!id\n");
572 phy->state = OTG_STATE_A_IDLE;
573 work = 1;
574 if (charger) {
575 if (charger->chg_type == DWC3_INVALID_CHARGER)
576 charger->start_detection(dotg->charger,
577 false);
578 else
579 charger->chg_type =
580 DWC3_INVALID_CHARGER;
581 }
582 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
583 dev_dbg(phy->dev, "b_sess_vld\n");
584 if (charger) {
585 /* Has charger been detected? If no detect it */
586 switch (charger->chg_type) {
587 case DWC3_DCP_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530588 dev_dbg(phy->dev, "lpm, DCP charger\n");
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530589 dwc3_otg_set_power(phy,
590 DWC3_IDEV_CHG_MAX);
Manu Gautamb5067272012-07-02 09:53:41 +0530591 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530592 break;
593 case DWC3_CDP_CHARGER:
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530594 dwc3_otg_set_power(phy,
595 DWC3_IDEV_CHG_MAX);
Manu Gautam8c642812012-06-07 10:35:10 +0530596 dwc3_otg_start_peripheral(&dotg->otg,
597 1);
598 phy->state = OTG_STATE_B_PERIPHERAL;
599 work = 1;
600 break;
601 case DWC3_SDP_CHARGER:
602 dwc3_otg_start_peripheral(&dotg->otg,
603 1);
604 phy->state = OTG_STATE_B_PERIPHERAL;
605 work = 1;
606 break;
607 default:
608 dev_dbg(phy->dev, "chg_det started\n");
609 charger->start_detection(charger, true);
610 break;
611 }
612 } else {
613 /* no charger registered, start peripheral */
614 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
615 /*
616 * Probably set_peripheral not called
617 * yet. We will re-try as soon as it
618 * will be called
619 */
Manu Gautamb5067272012-07-02 09:53:41 +0530620 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530621 "unable to start B-device\n");
622 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530623 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530624 return;
625 }
626 }
627 } else {
628 if (charger) {
629 if (charger->chg_type == DWC3_INVALID_CHARGER)
630 charger->start_detection(dotg->charger,
631 false);
632 else
633 charger->chg_type =
634 DWC3_INVALID_CHARGER;
635 }
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530636 dwc3_otg_set_power(phy, 0);
Manu Gautamb5067272012-07-02 09:53:41 +0530637 dev_dbg(phy->dev, "No device, trying to suspend\n");
638 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530639 }
640 break;
641
642 case OTG_STATE_B_PERIPHERAL:
643 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
644 !test_bit(ID, &dotg->inputs)) {
645 dev_dbg(phy->dev, "!id || !bsv\n");
646 dwc3_otg_start_peripheral(&dotg->otg, 0);
647 phy->state = OTG_STATE_B_IDLE;
648 if (charger)
649 charger->chg_type = DWC3_INVALID_CHARGER;
650 work = 1;
651 }
652 break;
653
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200654 case OTG_STATE_A_IDLE:
655 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530656 if (test_bit(ID, &dotg->inputs)) {
657 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200658 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530659 work = 1;
660 } else {
661 if (dwc3_otg_start_host(&dotg->otg, 1)) {
662 /*
663 * Probably set_host was not called yet.
664 * We will re-try as soon as it will be called
665 */
Manu Gautamb5067272012-07-02 09:53:41 +0530666 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530667 "unable to start A-device\n");
668 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530669 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530670 return;
671 }
672 phy->state = OTG_STATE_A_HOST;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200673 }
674 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530675
676 case OTG_STATE_A_HOST:
677 if (test_bit(ID, &dotg->inputs)) {
678 dev_dbg(phy->dev, "id\n");
679 dwc3_otg_start_host(&dotg->otg, 0);
680 phy->state = OTG_STATE_B_IDLE;
681 work = 1;
682 }
683 break;
684
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200685 default:
686 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
687
688 }
Manu Gautam8c642812012-06-07 10:35:10 +0530689
690 if (work)
691 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200692}
693
694
695/**
696 * dwc3_otg_reset - reset dwc3 otg registers.
697 *
698 * @w: Pointer to the dwc3 otg workqueue
699 */
700static void dwc3_otg_reset(struct dwc3_otg *dotg)
701{
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530702 static int once;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530703 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
704
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200705 /*
706 * OCFG[2] - OTG-Version = 1
707 * OCFG[1] - HNPCap = 0
708 * OCFG[0] - SRPCap = 0
709 */
710 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
711
712 /*
713 * OCTL[6] - PeriMode = 1
714 * OCTL[5] - PrtPwrCtl = 0
715 * OCTL[4] - HNPReq = 0
716 * OCTL[3] - SesReq = 0
717 * OCTL[2] - TermSelDLPulse = 0
718 * OCTL[1] - DevSetHNPEn = 0
719 * OCTL[0] - HstSetHNPEn = 0
720 */
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530721 if (!once) {
722 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
723 once++;
724 }
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200725
726 /* Clear all otg events (interrupts) indications */
727 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
728
Manu Gautam8c642812012-06-07 10:35:10 +0530729 /* Enable ID/BSV StsChngEn event*/
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530730 if (ext_xceiv && !ext_xceiv->otg_capability)
731 dwc3_writel(dotg->regs, DWC3_OEVTEN,
732 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
733 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200734}
735
736/**
737 * dwc3_otg_init - Initializes otg related registers
738 * @dwc: Pointer to out controller context structure
739 *
740 * Returns 0 on success otherwise negative errno.
741 */
742int dwc3_otg_init(struct dwc3 *dwc)
743{
744 u32 reg;
745 int ret = 0;
746 struct dwc3_otg *dotg;
747
748 dev_dbg(dwc->dev, "dwc3_otg_init\n");
749
750 /*
751 * GHWPARAMS6[10] bit is SRPSupport.
752 * This bit also reflects DWC_USB3_EN_OTG
753 */
754 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
755 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
756 /*
757 * No OTG support in the HW core.
758 * We return 0 to indicate no error, since this is acceptable
759 * situation, just continue probe the dwc3 driver without otg.
760 */
761 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
762 return 0;
763 }
764
765 /* Allocate and init otg instance */
766 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
767 if (!dotg) {
768 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
769 return -ENOMEM;
770 }
771
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530772 dotg->vbus_otg = devm_regulator_get(dwc->dev->parent, "vbus_dwc3");
773 if (IS_ERR(dotg->vbus_otg)) {
774 dev_err(dwc->dev, "Unable to get vbus_dwc3 regulator\n");
775 ret = PTR_ERR(dotg->vbus_otg);
776 goto err1;
777 }
778
Manu Gautam17206c22012-06-21 10:17:53 +0530779 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
780 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
781 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200782 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530783 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200784 ret = -ENODEV;
785 goto err1;
786 }
787
788 dotg->regs = dwc->regs;
789
790 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
791 dotg->otg.set_host = dwc3_otg_set_host;
792
793 /* This reference is used by dwc3 modules for checking otg existance */
794 dwc->dotg = dotg;
795
796 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
797 if (!dotg->otg.phy) {
798 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
799 ret = -ENOMEM;
800 goto err1;
801 }
802
Manu Gautamf1fceddf2012-10-12 14:02:50 +0530803 dotg->dwc = dwc;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200804 dotg->otg.phy->otg = &dotg->otg;
805 dotg->otg.phy->dev = dwc->dev;
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530806 dotg->otg.phy->set_power = dwc3_otg_set_power;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200807
808 ret = usb_set_transceiver(dotg->otg.phy);
809 if (ret) {
810 dev_err(dotg->otg.phy->dev,
811 "%s: failed to set transceiver, already exists\n",
812 __func__);
813 goto err2;
814 }
815
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200816 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
817
Vijayavardhan Vennapusa42eeea32012-10-22 17:56:11 +0530818 init_completion(&dotg->dwc3_xcvr_vbus_init);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200819 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
820
821 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
822 "dwc3_otg", dotg);
823 if (ret) {
824 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
825 dotg->irq, ret);
826 goto err3;
827 }
828
Manu Gautamb5067272012-07-02 09:53:41 +0530829 pm_runtime_get(dwc->dev);
830
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200831 return 0;
832
833err3:
834 cancel_work_sync(&dotg->sm_work);
835 usb_set_transceiver(NULL);
836err2:
837 kfree(dotg->otg.phy);
838err1:
839 dwc->dotg = NULL;
840 kfree(dotg);
841
842 return ret;
843}
844
845/**
846 * dwc3_otg_exit
847 * @dwc: Pointer to out controller context structure
848 *
849 * Returns 0 on success otherwise negative errno.
850 */
851void dwc3_otg_exit(struct dwc3 *dwc)
852{
853 struct dwc3_otg *dotg = dwc->dotg;
854
855 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
856 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530857 if (dotg->charger)
858 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200859 cancel_work_sync(&dotg->sm_work);
860 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530861 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200862 free_irq(dotg->irq, dotg);
863 kfree(dotg->otg.phy);
864 kfree(dotg);
865 dwc->dotg = NULL;
866 }
867}