aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/omap2430.c
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 /drivers/usb/musb/omap2430.c
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>
Diffstat (limited to 'drivers/usb/musb/omap2430.c')
-rw-r--r--drivers/usb/musb/omap2430.c53
1 files changed, 48 insertions, 5 deletions
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);