aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHema HK <hemahk@ti.com>2011-02-17 01:36:10 -0500
committerFelipe Balbi <balbi@ti.com>2011-02-18 07:05:53 -0500
commit002eda1348788f623dc42231dcda5f591d753124 (patch)
tree144e7b97998994fb1c3c46cfa48e1996d84417b1
parent647b2d9c61fe9a842dd89eb01b5f01e9d437993c (diff)
usb: musb: OMAP4430: Fix usb device detection if connected during boot
OMAP4430 is embedded with UTMI PHY. This PHY does not support the OTG features like ID pin detection and VBUS detection. This function is exported to an external companion chip TWL6030. Software must retrieve the OTG HNP and SRP status from the TWL6030 and configure the bits inside the control module that drive the related USBOTGHS UTMI interface signals. It must also read back the UTMI signals needed to configure the TWL6030 OTG module. Can find more details in the TRM[1]. [1]:http://focus.ti.com/pdfs/wtbu/OMAP4430_ES2.0_Public_TRM_vJ.pdf In OMAP4430 musb driver VBUS and ID notifications are received from the transceiver driver. If the cable/device is connected during boot, notifications from transceiver driver will be missed till musb driver is loaded. Patch to configure the transceiver in the platform_enable/disable functions and enable the vbus in the gadget driver based on the last_event of the otg_transceiver. Signed-off-by: Hema HK <hemahk@ti.com> Cc: Tony Lindgren <tony@atomide.com> Cc: Paul Walmsley <paul@pwsan.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/musb/musb_gadget.c4
-rw-r--r--drivers/usb/musb/omap2430.c53
2 files changed, 52 insertions, 5 deletions
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 0f59bf935c85..95fbaccb03e1 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1877,6 +1877,10 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
1877 if (retval < 0) { 1877 if (retval < 0) {
1878 DBG(1, "add_hcd failed, %d\n", retval); 1878 DBG(1, "add_hcd failed, %d\n", retval);
1879 goto err2; 1879 goto err2;
1880
1881 if ((musb->xceiv->last_event == USB_EVENT_ID)
1882 && musb->xceiv->set_vbus)
1883 otg_set_vbus(musb->xceiv, 1);
1880 } 1884 }
1881 1885
1882 hcd->self.uses_pio_for_control = 1; 1886 hcd->self.uses_pio_for_control = 1;
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index bb6e6cd330da..64cf2431c05e 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -328,16 +328,56 @@ static int omap2430_musb_init(struct musb *musb)
328 if (status) 328 if (status)
329 DBG(1, "notification register failed\n"); 329 DBG(1, "notification register failed\n");
330 330
331 /* check whether cable is already connected */
332 if (musb->xceiv->state ==OTG_STATE_B_IDLE)
333 musb_otg_notifications(&musb->nb, 1,
334 musb->xceiv->gadget);
335
336 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); 331 setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
337 332
338 return 0; 333 return 0;
339} 334}
340 335
336static void omap2430_musb_enable(struct musb *musb)
337{
338 u8 devctl;
339 unsigned long timeout = jiffies + msecs_to_jiffies(1000);
340 struct device *dev = musb->controller;
341 struct musb_hdrc_platform_data *pdata = dev->platform_data;
342 struct omap_musb_board_data *data = pdata->board_data;
343
344 switch (musb->xceiv->last_event) {
345
346 case USB_EVENT_ID:
347 otg_init(musb->xceiv);
348 if (data->interface_type == MUSB_INTERFACE_UTMI) {
349 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
350 /* start the session */
351 devctl |= MUSB_DEVCTL_SESSION;
352 musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
353 while (musb_readb(musb->mregs, MUSB_DEVCTL) &
354 MUSB_DEVCTL_BDEVICE) {
355 cpu_relax();
356
357 if (time_after(jiffies, timeout)) {
358 dev_err(musb->controller,
359 "configured as A device timeout");
360 break;
361 }
362 }
363 }
364 break;
365
366 case USB_EVENT_VBUS:
367 otg_init(musb->xceiv);
368 break;
369
370 default:
371 break;
372 }
373}
374
375static void omap2430_musb_disable(struct musb *musb)
376{
377 if (musb->xceiv->last_event)
378 otg_shutdown(musb->xceiv);
379}
380
341static int omap2430_musb_exit(struct musb *musb) 381static int omap2430_musb_exit(struct musb *musb)
342{ 382{
343 383
@@ -355,6 +395,9 @@ static const struct musb_platform_ops omap2430_ops = {
355 .try_idle = omap2430_musb_try_idle, 395 .try_idle = omap2430_musb_try_idle,
356 396
357 .set_vbus = omap2430_musb_set_vbus, 397 .set_vbus = omap2430_musb_set_vbus,
398
399 .enable = omap2430_musb_enable,
400 .disable = omap2430_musb_disable,
358}; 401};
359 402
360static u64 omap2430_dmamask = DMA_BIT_MASK(32); 403static u64 omap2430_dmamask = DMA_BIT_MASK(32);