blob: 4a37f036345b47f23512c0275dba975fc54fee1a [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>
19
20#include "core.h"
21#include "dwc3_otg.h"
22#include "io.h"
23#include "xhci.h"
24
25
26/**
27 * dwc3_otg_set_host_regs - reset dwc3 otg registers to host operation.
28 *
29 * This function sets the OTG registers to work in A-Device host mode.
30 * This function should be called just before entering to A-Device mode.
31 *
32 * @w: Pointer to the dwc3 otg workqueue.
33 */
34static void dwc3_otg_set_host_regs(struct dwc3_otg *dotg)
35{
36 u32 octl;
37
38 /* Set OCTL[6](PeriMode) to 0 (host) */
39 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
40 octl &= ~DWC3_OTG_OCTL_PERIMODE;
41 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
42
43 /*
44 * TODO: add more OTG registers writes for HOST mode here,
45 * see figure 12-10 A-device flow in dwc3 Synopsis spec
46 */
47}
48
49/**
50 * dwc3_otg_set_peripheral_regs - reset dwc3 otg registers to peripheral operation.
51 *
52 * This function sets the OTG registers to work in B-Device peripheral mode.
53 * This function should be called just before entering to B-Device mode.
54 *
55 * @w: Pointer to the dwc3 otg workqueue.
56 */
57static void dwc3_otg_set_peripheral_regs(struct dwc3_otg *dotg)
58{
59 u32 octl;
60
61 /* Set OCTL[6](PeriMode) to 1 (peripheral) */
62 octl = dwc3_readl(dotg->regs, DWC3_OCTL);
63 octl |= DWC3_OTG_OCTL_PERIMODE;
64 dwc3_writel(dotg->regs, DWC3_OCTL, octl);
65
66 /*
67 * TODO: add more OTG registers writes for PERIPHERAL mode here,
68 * see figure 12-19 B-device flow in dwc3 Synopsis spec
69 */
70}
71
72/**
73 * dwc3_otg_start_host - helper function for starting/stoping the host controller driver.
74 *
75 * @otg: Pointer to the otg_transceiver structure.
76 * @on: start / stop the host controller driver.
77 *
78 * Returns 0 on success otherwise negative errno.
79 */
80static int dwc3_otg_start_host(struct usb_otg *otg, int on)
81{
82 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
83 struct usb_hcd *hcd;
84 struct xhci_hcd *xhci;
85 int ret = 0;
86
87 if (!otg->host)
88 return -EINVAL;
89
90 hcd = bus_to_hcd(otg->host);
91 xhci = hcd_to_xhci(hcd);
92 if (on) {
93 dev_dbg(otg->phy->dev, "%s: turn on host %s\n",
94 __func__, otg->host->bus_name);
95 dwc3_otg_set_host_regs(dotg);
96
97 /*
98 * This should be revisited for more testing post-silicon.
99 * In worst case we may need to disconnect the root hub
100 * before stopping the controller so that it does not
101 * interfere with runtime pm/system pm.
102 * We can also consider registering and unregistering xhci
103 * platform device. It is almost similar to add_hcd and
104 * remove_hcd, But we may not use standard set_host method
105 * anymore.
106 */
107 ret = hcd->driver->start(hcd);
108 if (ret) {
109 dev_err(otg->phy->dev,
110 "%s: failed to start primary hcd, ret=%d\n",
111 __func__, ret);
112 return ret;
113 }
114
115 ret = xhci->shared_hcd->driver->start(xhci->shared_hcd);
116 if (ret) {
117 dev_err(otg->phy->dev,
118 "%s: failed to start secondary hcd, ret=%d\n",
119 __func__, ret);
120 return ret;
121 }
122 } else {
123 dev_dbg(otg->phy->dev, "%s: turn off host %s\n",
124 __func__, otg->host->bus_name);
125 hcd->driver->stop(hcd);
126 }
127
128 return 0;
129}
130
131/**
132 * dwc3_otg_set_host - bind/unbind the host controller driver.
133 *
134 * @otg: Pointer to the otg_transceiver structure.
135 * @host: Pointer to the usb_bus structure.
136 *
137 * Returns 0 on success otherwise negative errno.
138 */
139static int dwc3_otg_set_host(struct usb_otg *otg, struct usb_bus *host)
140{
141 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
142
143 if (host) {
144 dev_dbg(otg->phy->dev, "%s: set host %s\n",
145 __func__, host->bus_name);
146 otg->host = host;
147
148 /*
149 * Only after both peripheral and host are set then check
150 * OTG sm. This prevents unnecessary activation of the sm
151 * in case the ID is high.
152 */
153 if (otg->gadget)
154 schedule_work(&dotg->sm_work);
155 } else {
156 if (otg->phy->state == OTG_STATE_A_HOST) {
157 dwc3_otg_start_host(otg, 0);
158 otg->host = NULL;
159 otg->phy->state = OTG_STATE_UNDEFINED;
160 schedule_work(&dotg->sm_work);
161 } else {
162 otg->host = NULL;
163 }
164 }
165
166 return 0;
167}
168
169/**
170 * dwc3_otg_start_peripheral - bind/unbind the peripheral controller.
171 *
172 * @otg: Pointer to the otg_transceiver structure.
173 * @gadget: pointer to the usb_gadget structure.
174 *
175 * Returns 0 on success otherwise negative errno.
176 */
177static int dwc3_otg_start_peripheral(struct usb_otg *otg, int on)
178{
179 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
180
181 if (!otg->gadget)
182 return -EINVAL;
183
184 if (on) {
185 dev_dbg(otg->phy->dev, "%s: turn on gadget %s\n",
186 __func__, otg->gadget->name);
187 dwc3_otg_set_peripheral_regs(dotg);
188 usb_gadget_vbus_connect(otg->gadget);
189 } else {
190 dev_dbg(otg->phy->dev, "%s: turn off gadget %s\n",
191 __func__, otg->gadget->name);
192 usb_gadget_vbus_disconnect(otg->gadget);
193 }
194
195 return 0;
196}
197
198/**
199 * dwc3_otg_set_peripheral - bind/unbind the peripheral controller driver.
200 *
201 * @otg: Pointer to the otg_transceiver structure.
202 * @gadget: pointer to the usb_gadget structure.
203 *
204 * Returns 0 on success otherwise negative errno.
205 */
206static int dwc3_otg_set_peripheral(struct usb_otg *otg,
207 struct usb_gadget *gadget)
208{
209 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
210
211 if (gadget) {
212 dev_dbg(otg->phy->dev, "%s: set gadget %s\n",
213 __func__, gadget->name);
214 otg->gadget = gadget;
215
216 /*
217 * Only after both peripheral and host are set then check
218 * OTG sm. This prevents unnecessary activation of the sm
219 * in case the ID is grounded.
220 */
221 if (otg->host)
222 schedule_work(&dotg->sm_work);
223 } else {
224 if (otg->phy->state == OTG_STATE_B_PERIPHERAL) {
225 dwc3_otg_start_peripheral(otg, 0);
226 otg->gadget = NULL;
227 otg->phy->state = OTG_STATE_UNDEFINED;
228 schedule_work(&dotg->sm_work);
229 } else {
230 otg->gadget = NULL;
231 }
232 }
233
234 return 0;
235}
236
237/**
Manu Gautam8c642812012-06-07 10:35:10 +0530238 * dwc3_ext_chg_det_done - callback to handle charger detection completion
239 * @otg: Pointer to the otg transceiver structure
240 * @charger: Pointer to the external charger structure
241 *
242 * Returns 0 on success
243 */
244static void dwc3_ext_chg_det_done(struct usb_otg *otg, struct dwc3_charger *chg)
245{
246 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
247
248 /*
249 * Ignore chg_detection notification if BSV has gone off by this time.
250 * STOP chg_det as part of !BSV handling would reset the chg_det flags
251 */
252 if (test_bit(B_SESS_VLD, &dotg->inputs))
253 schedule_work(&dotg->sm_work);
254}
255
256/**
257 * dwc3_set_charger - bind/unbind external charger driver
258 * @otg: Pointer to the otg transceiver structure
259 * @charger: Pointer to the external charger structure
260 *
261 * Returns 0 on success
262 */
263int dwc3_set_charger(struct usb_otg *otg, struct dwc3_charger *charger)
264{
265 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
266
267 dotg->charger = charger;
268 if (charger)
269 charger->notify_detection_complete = dwc3_ext_chg_det_done;
270
271 return 0;
272}
273
Manu Gautamb5067272012-07-02 09:53:41 +0530274/**
275 * dwc3_ext_event_notify - callback to handle events from external transceiver
276 * @otg: Pointer to the otg transceiver structure
277 * @event: Event reported by transceiver
278 *
279 * Returns 0 on success
280 */
281static void dwc3_ext_event_notify(struct usb_otg *otg,
282 enum dwc3_ext_events event)
283{
284 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
285 struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
286 struct usb_phy *phy = dotg->otg.phy;
287
288 if (event == DWC3_EVENT_PHY_RESUME) {
289 if (!pm_runtime_status_suspended(phy->dev)) {
290 dev_warn(phy->dev, "PHY_RESUME event out of LPM!!!!\n");
291 } else {
292 dev_dbg(phy->dev, "ext PHY_RESUME event received\n");
293 /* ext_xceiver would have taken h/w out of LPM by now */
294 pm_runtime_get(phy->dev);
295 }
296 }
297
298 if (ext_xceiv->id == DWC3_ID_FLOAT)
299 set_bit(ID, &dotg->inputs);
300 else
301 clear_bit(ID, &dotg->inputs);
302
303 if (ext_xceiv->bsv)
304 set_bit(B_SESS_VLD, &dotg->inputs);
305 else
306 clear_bit(B_SESS_VLD, &dotg->inputs);
307
308 schedule_work(&dotg->sm_work);
309}
310
311/**
312 * dwc3_set_ext_xceiv - bind/unbind external transceiver driver
313 * @otg: Pointer to the otg transceiver structure
314 * @ext_xceiv: Pointer to the external transceiver struccture
315 *
316 * Returns 0 on success
317 */
318int dwc3_set_ext_xceiv(struct usb_otg *otg, struct dwc3_ext_xceiv *ext_xceiv)
319{
320 struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
321
322 dotg->ext_xceiv = ext_xceiv;
323 if (ext_xceiv)
324 ext_xceiv->notify_ext_events = dwc3_ext_event_notify;
325
326 return 0;
327}
328
Manu Gautam8c642812012-06-07 10:35:10 +0530329/* IRQs which OTG driver is interested in handling */
330#define DWC3_OEVT_MASK (DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT | \
331 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)
332
333/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200334 * dwc3_otg_interrupt - interrupt handler for dwc3 otg events.
335 * @_dotg: Pointer to out controller context structure
336 *
337 * Returns IRQ_HANDLED on success otherwise IRQ_NONE.
338 */
339static irqreturn_t dwc3_otg_interrupt(int irq, void *_dotg)
340{
341 struct dwc3_otg *dotg = (struct dwc3_otg *)_dotg;
Manu Gautamb5067272012-07-02 09:53:41 +0530342 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530343 u32 osts, oevt_reg;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200344 int ret = IRQ_NONE;
345 int handled_irqs = 0;
346
Manu Gautamb5067272012-07-02 09:53:41 +0530347 /*
348 * If PHY is in retention mode then this interrupt would not be fired.
349 * ext_xcvr (parent) is responsible for bringing h/w out of LPM.
350 * OTG driver just need to increment power count and can safely
351 * assume that h/w is out of low power state now.
352 * TODO: explicitly disable OEVTEN interrupts if ext_xceiv is present
353 */
354 if (pm_runtime_status_suspended(phy->dev))
355 pm_runtime_get(phy->dev);
356
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200357 oevt_reg = dwc3_readl(dotg->regs, DWC3_OEVT);
358
Manu Gautam8c642812012-06-07 10:35:10 +0530359 if (!(oevt_reg & DWC3_OEVT_MASK))
360 return IRQ_NONE;
361
362 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
363
364 if ((oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ||
365 (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT)) {
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200366 /*
Manu Gautam8c642812012-06-07 10:35:10 +0530367 * ID sts has changed, set inputs later, in the workqueue
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200368 * function, switch from A to B or from B to A.
369 */
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200370
Manu Gautam8c642812012-06-07 10:35:10 +0530371 if (osts & DWC3_OTG_OSTS_CONIDSTS)
372 set_bit(ID, &dotg->inputs);
373 else
374 clear_bit(ID, &dotg->inputs);
375
376 if (osts & DWC3_OTG_OSTS_BSESVALID)
377 set_bit(B_SESS_VLD, &dotg->inputs);
378 else
379 clear_bit(B_SESS_VLD, &dotg->inputs);
380
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200381 schedule_work(&dotg->sm_work);
382
Manu Gautam8c642812012-06-07 10:35:10 +0530383 handled_irqs |= (oevt_reg & DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT) ?
384 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT : 0;
385 handled_irqs |= (oevt_reg & DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT) ?
386 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT : 0;
387
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200388 ret = IRQ_HANDLED;
Manu Gautam8c642812012-06-07 10:35:10 +0530389
390 /* Clear the interrupts we handled */
391 dwc3_writel(dotg->regs, DWC3_OEVT, handled_irqs);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200392 }
393
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200394 return ret;
395}
396
397/**
Manu Gautam8c642812012-06-07 10:35:10 +0530398 * dwc3_otg_init_sm - initialize OTG statemachine input
399 * @dotg: Pointer to the dwc3_otg structure
400 *
401 */
402void dwc3_otg_init_sm(struct dwc3_otg *dotg)
403{
404 u32 osts = dwc3_readl(dotg->regs, DWC3_OSTS);
405 struct usb_phy *phy = dotg->otg.phy;
406
407 /*
408 * TODO: If using external notifications then wait here till initial
409 * state is reported
410 */
411
412 dev_dbg(phy->dev, "Initialize OTG inputs, osts: 0x%x\n", osts);
413
414 if (osts & DWC3_OTG_OSTS_CONIDSTS)
415 set_bit(ID, &dotg->inputs);
416 else
417 clear_bit(ID, &dotg->inputs);
418
419 if (osts & DWC3_OTG_OSTS_BSESVALID)
420 set_bit(B_SESS_VLD, &dotg->inputs);
421 else
422 clear_bit(B_SESS_VLD, &dotg->inputs);
423}
424
425/**
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200426 * dwc3_otg_sm_work - workqueue function.
427 *
428 * @w: Pointer to the dwc3 otg workqueue
429 *
430 * NOTE: After any change in phy->state,
431 * we must reschdule the state machine.
432 */
433static void dwc3_otg_sm_work(struct work_struct *w)
434{
435 struct dwc3_otg *dotg = container_of(w, struct dwc3_otg, sm_work);
436 struct usb_phy *phy = dotg->otg.phy;
Manu Gautam8c642812012-06-07 10:35:10 +0530437 struct dwc3_charger *charger = dotg->charger;
438 bool work = 0;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200439
Manu Gautamb5067272012-07-02 09:53:41 +0530440 pm_runtime_resume(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200441 dev_dbg(phy->dev, "%s state\n", otg_state_string(phy->state));
442
443 /* Check OTG state */
444 switch (phy->state) {
445 case OTG_STATE_UNDEFINED:
Manu Gautam8c642812012-06-07 10:35:10 +0530446 dwc3_otg_init_sm(dotg);
447 /* Switch to A or B-Device according to ID / BSV */
448 if (!test_bit(ID, &dotg->inputs) && phy->otg->host) {
449 dev_dbg(phy->dev, "!id\n");
450 phy->state = OTG_STATE_A_IDLE;
451 work = 1;
452 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
453 dev_dbg(phy->dev, "b_sess_vld\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200454 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530455 work = 1;
456 } else {
457 phy->state = OTG_STATE_B_IDLE;
Manu Gautamb5067272012-07-02 09:53:41 +0530458 dev_dbg(phy->dev, "No device, trying to suspend\n");
459 pm_runtime_put_sync(phy->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200460 }
461 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530462
463 case OTG_STATE_B_IDLE:
464 if (!test_bit(ID, &dotg->inputs) && phy->otg->host) {
465 dev_dbg(phy->dev, "!id\n");
466 phy->state = OTG_STATE_A_IDLE;
467 work = 1;
468 if (charger) {
469 if (charger->chg_type == DWC3_INVALID_CHARGER)
470 charger->start_detection(dotg->charger,
471 false);
472 else
473 charger->chg_type =
474 DWC3_INVALID_CHARGER;
475 }
476 } else if (test_bit(B_SESS_VLD, &dotg->inputs)) {
477 dev_dbg(phy->dev, "b_sess_vld\n");
478 if (charger) {
479 /* Has charger been detected? If no detect it */
480 switch (charger->chg_type) {
481 case DWC3_DCP_CHARGER:
Manu Gautamb5067272012-07-02 09:53:41 +0530482 dev_dbg(phy->dev, "lpm, DCP charger\n");
483 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530484 break;
485 case DWC3_CDP_CHARGER:
486 dwc3_otg_start_peripheral(&dotg->otg,
487 1);
488 phy->state = OTG_STATE_B_PERIPHERAL;
489 work = 1;
490 break;
491 case DWC3_SDP_CHARGER:
492 dwc3_otg_start_peripheral(&dotg->otg,
493 1);
494 phy->state = OTG_STATE_B_PERIPHERAL;
495 work = 1;
496 break;
497 default:
498 dev_dbg(phy->dev, "chg_det started\n");
499 charger->start_detection(charger, true);
500 break;
501 }
502 } else {
503 /* no charger registered, start peripheral */
504 if (dwc3_otg_start_peripheral(&dotg->otg, 1)) {
505 /*
506 * Probably set_peripheral not called
507 * yet. We will re-try as soon as it
508 * will be called
509 */
Manu Gautamb5067272012-07-02 09:53:41 +0530510 dev_err(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530511 "unable to start B-device\n");
512 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530513 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530514 return;
515 }
516 }
517 } else {
518 if (charger) {
519 if (charger->chg_type == DWC3_INVALID_CHARGER)
520 charger->start_detection(dotg->charger,
521 false);
522 else
523 charger->chg_type =
524 DWC3_INVALID_CHARGER;
525 }
Manu Gautamb5067272012-07-02 09:53:41 +0530526 dev_dbg(phy->dev, "No device, trying to suspend\n");
527 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530528 }
529 break;
530
531 case OTG_STATE_B_PERIPHERAL:
532 if (!test_bit(B_SESS_VLD, &dotg->inputs) ||
533 !test_bit(ID, &dotg->inputs)) {
534 dev_dbg(phy->dev, "!id || !bsv\n");
535 dwc3_otg_start_peripheral(&dotg->otg, 0);
536 phy->state = OTG_STATE_B_IDLE;
537 if (charger)
538 charger->chg_type = DWC3_INVALID_CHARGER;
539 work = 1;
540 }
541 break;
542
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200543 case OTG_STATE_A_IDLE:
544 /* Switch to A-Device*/
Manu Gautam8c642812012-06-07 10:35:10 +0530545 if (test_bit(ID, &dotg->inputs)) {
546 dev_dbg(phy->dev, "id\n");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200547 phy->state = OTG_STATE_B_IDLE;
Manu Gautam8c642812012-06-07 10:35:10 +0530548 work = 1;
549 } else {
550 if (dwc3_otg_start_host(&dotg->otg, 1)) {
551 /*
552 * Probably set_host was not called yet.
553 * We will re-try as soon as it will be called
554 */
Manu Gautamb5067272012-07-02 09:53:41 +0530555 dev_dbg(phy->dev, "enter lpm as\n"
Manu Gautam8c642812012-06-07 10:35:10 +0530556 "unable to start A-device\n");
557 phy->state = OTG_STATE_UNDEFINED;
Manu Gautamb5067272012-07-02 09:53:41 +0530558 pm_runtime_put_sync(phy->dev);
Manu Gautam8c642812012-06-07 10:35:10 +0530559 return;
560 }
561 phy->state = OTG_STATE_A_HOST;
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200562 }
563 break;
Manu Gautam8c642812012-06-07 10:35:10 +0530564
565 case OTG_STATE_A_HOST:
566 if (test_bit(ID, &dotg->inputs)) {
567 dev_dbg(phy->dev, "id\n");
568 dwc3_otg_start_host(&dotg->otg, 0);
569 phy->state = OTG_STATE_B_IDLE;
570 work = 1;
571 }
572 break;
573
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200574 default:
575 dev_err(phy->dev, "%s: invalid otg-state\n", __func__);
576
577 }
Manu Gautam8c642812012-06-07 10:35:10 +0530578
579 if (work)
580 schedule_work(&dotg->sm_work);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200581}
582
583
584/**
585 * dwc3_otg_reset - reset dwc3 otg registers.
586 *
587 * @w: Pointer to the dwc3 otg workqueue
588 */
589static void dwc3_otg_reset(struct dwc3_otg *dotg)
590{
591 /*
592 * OCFG[2] - OTG-Version = 1
593 * OCFG[1] - HNPCap = 0
594 * OCFG[0] - SRPCap = 0
595 */
596 dwc3_writel(dotg->regs, DWC3_OCFG, 0x4);
597
598 /*
599 * OCTL[6] - PeriMode = 1
600 * OCTL[5] - PrtPwrCtl = 0
601 * OCTL[4] - HNPReq = 0
602 * OCTL[3] - SesReq = 0
603 * OCTL[2] - TermSelDLPulse = 0
604 * OCTL[1] - DevSetHNPEn = 0
605 * OCTL[0] - HstSetHNPEn = 0
606 */
607 dwc3_writel(dotg->regs, DWC3_OCTL, 0x40);
608
609 /* Clear all otg events (interrupts) indications */
610 dwc3_writel(dotg->regs, DWC3_OEVT, 0xFFFF);
611
Manu Gautam8c642812012-06-07 10:35:10 +0530612 /* Enable ID/BSV StsChngEn event*/
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200613 dwc3_writel(dotg->regs, DWC3_OEVTEN,
Manu Gautam8c642812012-06-07 10:35:10 +0530614 DWC3_OEVTEN_OTGCONIDSTSCHNGEVNT |
615 DWC3_OEVTEN_OTGBDEVVBUSCHNGEVNT);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200616}
617
618/**
619 * dwc3_otg_init - Initializes otg related registers
620 * @dwc: Pointer to out controller context structure
621 *
622 * Returns 0 on success otherwise negative errno.
623 */
624int dwc3_otg_init(struct dwc3 *dwc)
625{
626 u32 reg;
627 int ret = 0;
628 struct dwc3_otg *dotg;
629
630 dev_dbg(dwc->dev, "dwc3_otg_init\n");
631
632 /*
633 * GHWPARAMS6[10] bit is SRPSupport.
634 * This bit also reflects DWC_USB3_EN_OTG
635 */
636 reg = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6);
637 if (!(reg & DWC3_GHWPARAMS6_SRP_SUPPORT)) {
638 /*
639 * No OTG support in the HW core.
640 * We return 0 to indicate no error, since this is acceptable
641 * situation, just continue probe the dwc3 driver without otg.
642 */
643 dev_dbg(dwc->dev, "dwc3_otg address space is not supported\n");
644 return 0;
645 }
646
647 /* Allocate and init otg instance */
648 dotg = kzalloc(sizeof(struct dwc3_otg), GFP_KERNEL);
649 if (!dotg) {
650 dev_err(dwc->dev, "unable to allocate dwc3_otg\n");
651 return -ENOMEM;
652 }
653
Manu Gautam17206c22012-06-21 10:17:53 +0530654 /* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
655 dotg->irq = platform_get_irq_byname(to_platform_device(dwc->dev),
656 "otg_irq");
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200657 if (dotg->irq < 0) {
Manu Gautam17206c22012-06-21 10:17:53 +0530658 dev_err(dwc->dev, "%s: missing OTG IRQ\n", __func__);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200659 ret = -ENODEV;
660 goto err1;
661 }
662
663 dotg->regs = dwc->regs;
664
665 dotg->otg.set_peripheral = dwc3_otg_set_peripheral;
666 dotg->otg.set_host = dwc3_otg_set_host;
667
668 /* This reference is used by dwc3 modules for checking otg existance */
669 dwc->dotg = dotg;
670
671 dotg->otg.phy = kzalloc(sizeof(struct usb_phy), GFP_KERNEL);
672 if (!dotg->otg.phy) {
673 dev_err(dwc->dev, "unable to allocate dwc3_otg.phy\n");
674 ret = -ENOMEM;
675 goto err1;
676 }
677
678 dotg->otg.phy->otg = &dotg->otg;
679 dotg->otg.phy->dev = dwc->dev;
680
681 ret = usb_set_transceiver(dotg->otg.phy);
682 if (ret) {
683 dev_err(dotg->otg.phy->dev,
684 "%s: failed to set transceiver, already exists\n",
685 __func__);
686 goto err2;
687 }
688
689 dwc3_otg_reset(dotg);
690
691 dotg->otg.phy->state = OTG_STATE_UNDEFINED;
692
693 INIT_WORK(&dotg->sm_work, dwc3_otg_sm_work);
694
695 ret = request_irq(dotg->irq, dwc3_otg_interrupt, IRQF_SHARED,
696 "dwc3_otg", dotg);
697 if (ret) {
698 dev_err(dotg->otg.phy->dev, "failed to request irq #%d --> %d\n",
699 dotg->irq, ret);
700 goto err3;
701 }
702
Manu Gautamb5067272012-07-02 09:53:41 +0530703 pm_runtime_get(dwc->dev);
704
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200705 return 0;
706
707err3:
708 cancel_work_sync(&dotg->sm_work);
709 usb_set_transceiver(NULL);
710err2:
711 kfree(dotg->otg.phy);
712err1:
713 dwc->dotg = NULL;
714 kfree(dotg);
715
716 return ret;
717}
718
719/**
720 * dwc3_otg_exit
721 * @dwc: Pointer to out controller context structure
722 *
723 * Returns 0 on success otherwise negative errno.
724 */
725void dwc3_otg_exit(struct dwc3 *dwc)
726{
727 struct dwc3_otg *dotg = dwc->dotg;
728
729 /* dotg is null when GHWPARAMS6[10]=SRPSupport=0, see dwc3_otg_init */
730 if (dotg) {
Manu Gautam8c642812012-06-07 10:35:10 +0530731 if (dotg->charger)
732 dotg->charger->start_detection(dotg->charger, false);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200733 cancel_work_sync(&dotg->sm_work);
734 usb_set_transceiver(NULL);
Manu Gautamb5067272012-07-02 09:53:41 +0530735 pm_runtime_put(dwc->dev);
Ido Shayevitzcdeef4c2012-05-29 13:17:41 +0200736 free_irq(dotg->irq, dotg);
737 kfree(dotg->otg.phy);
738 kfree(dotg);
739 dwc->dotg = NULL;
740 }
741}