diff options
author | Felipe Balbi <balbi@ti.com> | 2013-10-29 13:17:16 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-11-26 11:35:14 -0500 |
commit | 943c13971c08ddeb06f4cb9dea1addb76f6b4423 (patch) | |
tree | 0712df52363977e91d0f4d875c51e7e7e885358d /drivers/usb/musb/musb_dsps.c | |
parent | 989c78dd56307c85f710533130a2a464f6f3c5ae (diff) |
usb: musb: dsps: implement ->set_mode()
this will let us support broken designs such
as AM335x EVM SK where ID pin isn't routed
anywhere on a host port.
With this we can toggle internal IDDIG signal
and make sure MUSB goes into host mode as
necessary.
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/musb/musb_dsps.c')
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 1901f6fe5807..ce7ec014a125 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -106,6 +106,7 @@ struct dsps_musb_wrapper { | |||
106 | 106 | ||
107 | /* bit positions for mode */ | 107 | /* bit positions for mode */ |
108 | unsigned iddig:5; | 108 | unsigned iddig:5; |
109 | unsigned iddig_mux:5; | ||
109 | /* miscellaneous stuff */ | 110 | /* miscellaneous stuff */ |
110 | u8 poll_seconds; | 111 | u8 poll_seconds; |
111 | }; | 112 | }; |
@@ -406,6 +407,54 @@ static int dsps_musb_exit(struct musb *musb) | |||
406 | return 0; | 407 | return 0; |
407 | } | 408 | } |
408 | 409 | ||
410 | static int dsps_musb_set_mode(struct musb *musb, u8 mode) | ||
411 | { | ||
412 | struct device *dev = musb->controller; | ||
413 | struct dsps_glue *glue = dev_get_drvdata(dev->parent); | ||
414 | const struct dsps_musb_wrapper *wrp = glue->wrp; | ||
415 | void __iomem *ctrl_base = musb->ctrl_base; | ||
416 | void __iomem *base = musb->mregs; | ||
417 | u32 reg; | ||
418 | |||
419 | reg = dsps_readl(base, wrp->mode); | ||
420 | |||
421 | switch (mode) { | ||
422 | case MUSB_HOST: | ||
423 | reg &= ~(1 << wrp->iddig); | ||
424 | |||
425 | /* | ||
426 | * if we're setting mode to host-only or device-only, we're | ||
427 | * going to ignore whatever the PHY sends us and just force | ||
428 | * ID pin status by SW | ||
429 | */ | ||
430 | reg |= (1 << wrp->iddig_mux); | ||
431 | |||
432 | dsps_writel(base, wrp->mode, reg); | ||
433 | dsps_writel(ctrl_base, wrp->phy_utmi, 0x02); | ||
434 | break; | ||
435 | case MUSB_PERIPHERAL: | ||
436 | reg |= (1 << wrp->iddig); | ||
437 | |||
438 | /* | ||
439 | * if we're setting mode to host-only or device-only, we're | ||
440 | * going to ignore whatever the PHY sends us and just force | ||
441 | * ID pin status by SW | ||
442 | */ | ||
443 | reg |= (1 << wrp->iddig_mux); | ||
444 | |||
445 | dsps_writel(base, wrp->mode, reg); | ||
446 | break; | ||
447 | case MUSB_OTG: | ||
448 | dsps_writel(base, wrp->phy_utmi, 0x02); | ||
449 | break; | ||
450 | default: | ||
451 | dev_err(glue->dev, "unsupported mode %d\n", mode); | ||
452 | return -EINVAL; | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
409 | static struct musb_platform_ops dsps_ops = { | 458 | static struct musb_platform_ops dsps_ops = { |
410 | .init = dsps_musb_init, | 459 | .init = dsps_musb_init, |
411 | .exit = dsps_musb_exit, | 460 | .exit = dsps_musb_exit, |
@@ -414,6 +463,7 @@ static struct musb_platform_ops dsps_ops = { | |||
414 | .disable = dsps_musb_disable, | 463 | .disable = dsps_musb_disable, |
415 | 464 | ||
416 | .try_idle = dsps_musb_try_idle, | 465 | .try_idle = dsps_musb_try_idle, |
466 | .set_mode = dsps_musb_set_mode, | ||
417 | }; | 467 | }; |
418 | 468 | ||
419 | static u64 musb_dmamask = DMA_BIT_MASK(32); | 469 | static u64 musb_dmamask = DMA_BIT_MASK(32); |
@@ -608,6 +658,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = { | |||
608 | .reset = 0, | 658 | .reset = 0, |
609 | .otg_disable = 21, | 659 | .otg_disable = 21, |
610 | .iddig = 8, | 660 | .iddig = 8, |
661 | .iddig_mux = 7, | ||
611 | .usb_shift = 0, | 662 | .usb_shift = 0, |
612 | .usb_mask = 0x1ff, | 663 | .usb_mask = 0x1ff, |
613 | .usb_bitmap = (0x1ff << 0), | 664 | .usb_bitmap = (0x1ff << 0), |