Commit 5261debe authored by David Brownell's avatar David Brownell Committed by Tony Lindgren

musb_hdrc: DaVinci-specific updates and cleanups

 - Add header needed for DaVinci build.
 - Remove some partially obsolete comments.
 - Cleaner and more reproducible host side VBUS handling, including
   waiting for it to fall after powerdown on rmmod.
 - Tighten up various state machine transitions and diagnostics

Plus removing some generic #ifdeffery.  The vbus updates make it work more like
the TUSB code, and the cleanups etc make upstream merging more practical.
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent 652bfff7
...@@ -35,26 +35,26 @@ ...@@ -35,26 +35,26 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/hardware.h> #include <asm/arch/hardware.h>
#include <asm/arch/memory.h> #include <asm/arch/memory.h>
// #include <asm/arch/gpio.h> #include <asm/arch/gpio.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "musbdefs.h" #include "musbdefs.h"
#ifdef CONFIG_ARCH_DAVINCI
#ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_MACH_DAVINCI_EVM
#include <asm/arch/i2c-client.h> #include <asm/arch/i2c-client.h>
#endif #endif
#include "davinci.h" #include "davinci.h"
#endif
#ifdef CONFIG_USB_TI_CPPI_DMA
#include "cppi_dma.h" #include "cppi_dma.h"
#endif
/* REVISIT (PM) we should be able to keep the PHY in low power mode most
* of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0
* and, when in host mode, autosuspending idle root ports... PHYPLLON
* (overriding SUSPENDM?) then likely needs to stay off.
*/
static inline void phy_on(void) static inline void phy_on(void)
{ {
/* start the on-chip PHY and its PLL */ /* start the on-chip PHY and its PLL */
...@@ -68,7 +68,7 @@ static inline void phy_on(void) ...@@ -68,7 +68,7 @@ static inline void phy_on(void)
static inline void phy_off(void) static inline void phy_off(void)
{ {
/* powerdown the on-chip PHY and its oscillator */ /* powerdown the on-chip PHY and its oscillator */
__raw_writel(USBPHY_OSCPDWN | USBPHY_PHYSPDWN, __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN,
IO_ADDRESS(USBPHY_CTL_PADDR)); IO_ADDRESS(USBPHY_CTL_PADDR));
} }
...@@ -138,26 +138,52 @@ static int vbus_state = -1; ...@@ -138,26 +138,52 @@ static int vbus_state = -1;
static void session(struct musb *musb, int is_on) static void session(struct musb *musb, int is_on)
{ {
void *__iomem mregs = musb->pRegs; void *__iomem mregs = musb->pRegs;
if (musb->xceiv.default_a) {
u8 devctl = musb_readb(mregs, MGC_O_HDRC_DEVCTL); u8 devctl = musb_readb(mregs, MGC_O_HDRC_DEVCTL);
/* NOTE: after drvvbus off the state _could_ be A_IDLE; if (is_on)
* but the silicon seems to couple vbus to "ID grounded".
*/
devctl |= MGC_M_DEVCTL_SESSION; devctl |= MGC_M_DEVCTL_SESSION;
else
devctl &= ~MGC_M_DEVCTL_SESSION;
musb_writeb(mregs, MGC_O_HDRC_DEVCTL, devctl);
} else
is_on = 0;
if (is_on) { if (is_on) {
/* NOTE: assumes VBUS already exceeds A-valid */
musb->xceiv.state = OTG_STATE_A_WAIT_BCON; musb->xceiv.state = OTG_STATE_A_WAIT_BCON;
portstate(musb->port1_status |= USB_PORT_STAT_POWER); portstate(musb->port1_status |= USB_PORT_STAT_POWER);
MUSB_HST_MODE(musb);
} else { } else {
switch (musb->xceiv.state) {
case OTG_STATE_UNDEFINED:
case OTG_STATE_B_IDLE:
MUSB_DEV_MODE(musb);
musb->xceiv.state = OTG_STATE_B_IDLE; musb->xceiv.state = OTG_STATE_B_IDLE;
break;
case OTG_STATE_A_IDLE:
break;
default:
musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
break;
}
portstate(musb->port1_status &= ~USB_PORT_STAT_POWER); portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
} }
musb_writeb(mregs, MGC_O_HDRC_DEVCTL, devctl);
DBG(2, "Default-%c, VBUS power %s, %s, devctl %02x, %s\n",
musb->xceiv.default_a ? 'A' : 'B',
is_on ? "on" : "off",
MUSB_MODE(musb),
musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL),
otg_state_string(musb));
} }
/* VBUS SWITCHING IS BOARD-SPECIFIC */ /* VBUS SWITCHING IS BOARD-SPECIFIC */
#ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_MACH_DAVINCI_EVM
#ifndef CONFIG_MACH_DAVINCI_EVM_OTG
/* I2C operations are always synchronous, and require a task context. /* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice * With unloaded systems, using the shared workqueue seems to suffice
...@@ -166,7 +192,7 @@ static void session(struct musb *musb, int is_on) ...@@ -166,7 +192,7 @@ static void session(struct musb *musb, int is_on)
static void evm_deferred_drvvbus(void *_musb) static void evm_deferred_drvvbus(void *_musb)
{ {
struct musb *musb = _musb; struct musb *musb = _musb;
int is_on = (musb->xceiv.state == OTG_STATE_A_WAIT_VRISE); int is_on = (musb->xceiv.state == OTG_STATE_A_IDLE);
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on); davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
vbus_state = is_on; vbus_state = is_on;
...@@ -174,9 +200,10 @@ static void evm_deferred_drvvbus(void *_musb) ...@@ -174,9 +200,10 @@ static void evm_deferred_drvvbus(void *_musb)
} }
DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus, 0); DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus, 0);
#endif #endif /* modified board */
#endif /* EVM */
static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping) static void davinci_vbus_power(struct musb *musb, int is_on, int immediate)
{ {
if (is_on) if (is_on)
is_on = 1; is_on = 1;
...@@ -184,24 +211,6 @@ static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping) ...@@ -184,24 +211,6 @@ static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping)
if (vbus_state == is_on) if (vbus_state == is_on)
return; return;
if (is_on) {
musb->xceiv.state = OTG_STATE_A_WAIT_VRISE;
MUSB_HST_MODE(musb);
} else {
switch (musb->xceiv.state) {
case OTG_STATE_UNDEFINED:
case OTG_STATE_B_IDLE:
MUSB_DEV_MODE(musb);
musb->xceiv.state = OTG_STATE_B_IDLE;
break;
case OTG_STATE_A_IDLE:
break;
default:
musb->xceiv.state = OTG_STATE_A_WAIT_VFALL;
break;
}
}
#ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm()) { if (machine_is_davinci_evm()) {
#ifdef CONFIG_MACH_DAVINCI_EVM_OTG #ifdef CONFIG_MACH_DAVINCI_EVM_OTG
...@@ -212,25 +221,29 @@ static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping) ...@@ -212,25 +221,29 @@ static void davinci_vbus_power(struct musb *musb, int is_on, int sleeping)
gpio_set(GPIO(6)); gpio_set(GPIO(6));
else else
gpio_clear(GPIO(6)); gpio_clear(GPIO(6));
immediate = 1;
#else #else
if (sleeping) if (immediate)
davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on); davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
else else
schedule_work(&evm_vbus_work); schedule_work(&evm_vbus_work);
#endif #endif
} }
#endif #endif
if (sleeping) { if (immediate) {
vbus_state = is_on; vbus_state = is_on;
session(musb, is_on); session(musb, is_on);
} else {
/* REVISIT: if is_on, start in A_WAIT_VRISE, then OTG timer
* should watch for session valid before calling session().
* EVM charges C133 VERY quickly (but discharge is sloooow).
*/
} }
DBG(2, "VBUS power %s, %s\n", is_on ? "on" : "off",
sleeping ? "immediate" : "deferred");
} }
static void davinci_set_vbus(struct musb *musb, int is_on) static void davinci_set_vbus(struct musb *musb, int is_on)
{ {
WARN_ON(is_on && is_peripheral_active(musb));
return davinci_vbus_power(musb, is_on, 0); return davinci_vbus_power(musb, is_on, 0);
} }
...@@ -281,12 +294,23 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r) ...@@ -281,12 +294,23 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci, struct pt_regs *r)
>> DAVINCI_USB_USBINT_SHIFT; >> DAVINCI_USB_USBINT_SHIFT;
musb->int_regs = r; musb->int_regs = r;
/* treat DRVVBUS irq like an ID change IRQ (for now) */
if (tmp & (1 << (8 + DAVINCI_USB_USBINT_SHIFT))) { if (tmp & (1 << (8 + DAVINCI_USB_USBINT_SHIFT))) {
int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG); int drvvbus = musb_readl(tibase, DAVINCI_USB_STAT_REG);
if (drvvbus) {
MUSB_HST_MODE(musb);
musb->xceiv.default_a = 1;
musb->xceiv.state = OTG_STATE_A_IDLE;
} else {
MUSB_DEV_MODE(musb);
musb->xceiv.default_a = 0;
musb->xceiv.state = OTG_STATE_B_IDLE;
}
/* NOTE: this must complete poweron within 100 msec */ /* NOTE: this must complete poweron within 100 msec */
davinci_vbus_power(musb, drvvbus, 0); davinci_vbus_power(musb, drvvbus, 0);
DBG(2, "DRVVBUS %d (state %d)\n", drvvbus, musb->xceiv.state); DBG(2, "DRVVBUS %d (%s)\n", drvvbus, otg_state_string(musb));
retval = IRQ_HANDLED; retval = IRQ_HANDLED;
} }
...@@ -331,16 +355,13 @@ int __devinit musb_platform_init(struct musb *musb) ...@@ -331,16 +355,13 @@ int __devinit musb_platform_init(struct musb *musb)
if (revision == 0) if (revision == 0)
return -ENODEV; return -ENODEV;
/* note that transceiver issues make us want to charge
* VBUS only when the PHY PLL is not active.
*/
#ifdef CONFIG_MACH_DAVINCI_EVM #ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm())
evm_vbus_work.data = musb; evm_vbus_work.data = musb;
#endif #endif
davinci_vbus_power(musb, musb->board_mode == MUSB_HOST, 1);
if (is_host_enabled(musb))
musb->board_set_vbus = davinci_set_vbus; musb->board_set_vbus = davinci_set_vbus;
davinci_vbus_power(musb, 0, 1);
/* reset the controller */ /* reset the controller */
musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
...@@ -362,7 +383,33 @@ int __devinit musb_platform_init(struct musb *musb) ...@@ -362,7 +383,33 @@ int __devinit musb_platform_init(struct musb *musb)
int musb_platform_exit(struct musb *musb) int musb_platform_exit(struct musb *musb)
{ {
phy_off();
davinci_vbus_power(musb, 0 /*off*/, 1); davinci_vbus_power(musb, 0 /*off*/, 1);
/* delay, to avoid problems with module reload */
if (is_host_enabled(musb)) {
int maxdelay = 30;
u8 devctl, warn = 0;
/* if there's no peripheral connected, this can take a
* long time to fall, especially on EVM with huge C133.
*/
do {
devctl = musb_readb(musb->pRegs, MGC_O_HDRC_DEVCTL);
if (!(devctl & MGC_M_DEVCTL_VBUS))
break;
if ((devctl & MGC_M_DEVCTL_VBUS) != warn) {
warn = devctl & MGC_M_DEVCTL_VBUS;
DBG(1, "VBUS %d\n", warn >> MGC_S_DEVCTL_VBUS);
}
msleep(1000);
maxdelay--;
} while (maxdelay > 0);
/* in OTG mode, another host might be connected */
if (devctl & MGC_M_DEVCTL_VBUS)
DBG(1, "VBUS off timeout (devctl %02x)\n", devctl);
}
phy_off();
return 0; return 0;
} }
...@@ -20,9 +20,9 @@ ...@@ -20,9 +20,9 @@
#define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */ #define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */
#define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */ #define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */
#define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */ #define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */
#define USBPHY_CLK01SEL (1 << 3) #define USBPHY_CLKO1SEL (1 << 3)
#define USBPHY_OSCPDWN (1 << 2) #define USBPHY_OSCPDWN (1 << 2)
#define USBPHY_PHYSPDWN (1 << 0) #define USBPHY_PHYPDWN (1 << 0)
/* For now include usb OTG module registers here */ /* For now include usb OTG module registers here */
#define DAVINCI_USB_VERSION_REG 0x00 #define DAVINCI_USB_VERSION_REG 0x00
......
...@@ -214,15 +214,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) ...@@ -214,15 +214,6 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
if (is_in) if (is_in)
return; return;
/* TODO: with CPPI DMA, once DMA is setup and DmaReqEnable in TxCSR
* is set (which is the case) transfer is initiated. For periodic
* transfer support, add another field in pEnd struct which will
* serve as a flag. If CPPI DMA is programmed for the transfer set
* this flag and disable DMAReqEnab while programming TxCSR in
* programEnd() Once we reach the appropriate time, enable DMA Req
* instead of calling musb_h_tx_start() function
*/
/* determine if the time is right for a periodic transfer */ /* determine if the time is right for a periodic transfer */
switch (qh->type) { switch (qh->type) {
case USB_ENDPOINT_XFER_ISOC: case USB_ENDPOINT_XFER_ISOC:
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <asm/uaccess.h> /* FIXME remove procfs writes */ #include <asm/uaccess.h> /* FIXME remove procfs writes */
#include <asm/arch/hardware.h>
#include "musbdefs.h" #include "musbdefs.h"
......
...@@ -78,17 +78,6 @@ ...@@ -78,17 +78,6 @@
* exist tend to be severely undercommitted. You can't yet hook * exist tend to be severely undercommitted. You can't yet hook
* up both a keyboard and a mouse to an external USB hub. * up both a keyboard and a mouse to an external USB hub.
* *
* * Host side doesn't understand that hardware endpoints have two
* directions, so it uses only half the resources available on
* chips like DaVinci or TUSB 6010.
*
* +++ PARTIALLY RESOLVED +++
*
* RESULT: On DaVinci (and TUSB 6010), only one external device may
* use periodic transfers, other than the hub used to connect it.
* (And if it were to understand, there would still be limitations
* because of the lack of periodic endpoint scheduling.)
*
* - Provides its own OTG bits. These are untested, and many of them * - Provides its own OTG bits. These are untested, and many of them
* seem to be superfluous code bloat given what usbcore does. (They * seem to be superfluous code bloat given what usbcore does. (They
* have now been partially removed.) * have now been partially removed.)
...@@ -416,7 +405,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -416,7 +405,7 @@ static irqreturn_t musb_stage0_irq(struct musb * pThis, u8 bIntrUSB,
#ifdef CONFIG_USB_MUSB_HDRC_HCD #ifdef CONFIG_USB_MUSB_HDRC_HCD
/* see manual for the order of the tests */ /* see manual for the order of the tests */
if (bIntrUSB & MGC_M_INTR_SESSREQ) { if (bIntrUSB & MGC_M_INTR_SESSREQ) {
DBG(1, "SESSION_REQUEST (%d)\n", pThis->xceiv.state); DBG(1, "SESSION_REQUEST (%s)\n", otg_state_string(pThis));
/* IRQ arrives from ID pin sense or (later, if VBUS power /* IRQ arrives from ID pin sense or (later, if VBUS power
* is removed) SRP. responses are time critical: * is removed) SRP. responses are time critical:
...@@ -660,11 +649,9 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB, ...@@ -660,11 +649,9 @@ static irqreturn_t musb_stage2_irq(struct musb * pThis, u8 bIntrUSB,
void musb_start(struct musb *musb) void musb_start(struct musb *musb)
{ {
void __iomem *regs = musb->pRegs; void __iomem *regs = musb->pRegs;
u8 devctl; u8 devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL);
DBG(2, "<==\n");
/* TODO: always set ISOUPDATE in POWER (periph mode) and leave it on! */ DBG(2, "<== devctl %02x\n", devctl);
/* Set INT enable registers, enable interrupts */ /* Set INT enable registers, enable interrupts */
musb_writew(regs, MGC_O_HDRC_INTRTXE, musb->wEndMask); musb_writew(regs, MGC_O_HDRC_INTRTXE, musb->wEndMask);
...@@ -675,30 +662,37 @@ void musb_start(struct musb *musb) ...@@ -675,30 +662,37 @@ void musb_start(struct musb *musb)
musb_platform_enable(musb); musb_platform_enable(musb);
/* enable high-speed/low-power and start session */ /* put into basic highspeed mode and start session */
musb_writeb(regs, MGC_O_HDRC_POWER, musb_writeb(regs, MGC_O_HDRC_POWER, MGC_M_POWER_ISOUPDATE
MGC_M_POWER_SOFTCONN | MGC_M_POWER_HSENAB); | MGC_M_POWER_SOFTCONN
| MGC_M_POWER_HSENAB
// | MGC_M_POWER_ENSUSPEND
);
musb->is_active = 0; musb->is_active = 0;
switch (musb->board_mode) { devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL);
case MUSB_HOST: devctl &= ~MGC_M_DEVCTL_SESSION;
musb_set_vbus(musb, 1);
break; if (is_otg_enabled(pThis)) {
case MUSB_OTG:
/* session started after: /* session started after:
* (a) ID-grounded irq, host mode; * (a) ID-grounded irq, host mode;
* (b) vbus present/connect IRQ, peripheral mode; * (b) vbus present/connect IRQ, peripheral mode;
* (c) peripheral initiates, using SRP * (c) peripheral initiates, using SRP
*/ */
break;
case MUSB_PERIPHERAL:
devctl = musb_readb(regs, MGC_O_HDRC_DEVCTL);
if ((devctl & MGC_M_DEVCTL_VBUS) == MGC_M_DEVCTL_VBUS) if ((devctl & MGC_M_DEVCTL_VBUS) == MGC_M_DEVCTL_VBUS)
musb->is_active = 1; musb->is_active = 1;
musb_writeb(regs, MGC_O_HDRC_DEVCTL, else
devctl & ~MGC_M_DEVCTL_SESSION); devctl |= MGC_M_DEVCTL_SESSION;
break;
} else if (is_host_enabled(pThis)) {
/* assume ID pin is hard-wired to ground */
devctl |= MGC_M_DEVCTL_SESSION;
} else /* peripheral is enabled */ {
if ((devctl & MGC_M_DEVCTL_VBUS) == MGC_M_DEVCTL_VBUS)
musb->is_active = 1;
} }
musb_writeb(regs, MGC_O_HDRC_DEVCTL, devctl);
} }
...@@ -1514,7 +1508,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf) ...@@ -1514,7 +1508,7 @@ musb_cable_show(struct device *dev, struct device_attribute *attr, char *buf)
break; break;
case MUSB_OTG: case MUSB_OTG:
v1 = "Mini-"; v1 = "Mini-";
v2 = (vbus & MGC_M_DEVCTL_BDEVICE) ? "A" : "B"; v2 = (vbus & MGC_M_DEVCTL_BDEVICE) ? "B" : "A";
break; break;
} }
} else /* VBUS level below A-Valid */ } else /* VBUS level below A-Valid */
...@@ -1613,7 +1607,11 @@ static void musb_free(struct musb *musb) ...@@ -1613,7 +1607,11 @@ static void musb_free(struct musb *musb)
(void) c->stop(c->pPrivateData); (void) c->stop(c->pPrivateData);
dma_controller_factory.destroy(c); dma_controller_factory.destroy(c);
} }
musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
musb_platform_exit(musb); musb_platform_exit(musb);
musb_writeb(musb->pRegs, MGC_O_HDRC_DEVCTL, 0);
if (musb->clock) { if (musb->clock) {
clk_disable(musb->clock); clk_disable(musb->clock);
clk_put(musb->clock); clk_put(musb->clock);
...@@ -1762,16 +1760,25 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1762,16 +1760,25 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
#endif #endif
/* For the host-only role, we can activate right away. /* For the host-only role, we can activate right away.
* (We expect the ID pin to be forcibly grounded!!)
* Otherwise, wait till the gadget driver hooks up. * Otherwise, wait till the gadget driver hooks up.
*
* REVISIT switch to compile-time is_role_host() etc
* to get rid of #ifdeffery
*/ */
switch (pThis->board_mode) { pThis->xceiv.state = OTG_STATE_B_IDLE;
#ifdef CONFIG_USB_MUSB_HDRC_HCD pThis->xceiv.default_a = 0;
case MUSB_HOST:
if (is_otg_enabled(pThis)) {
MUSB_OTG_MODE(pThis);
status = musb_gadget_setup(pThis);
DBG(1, "%s mode, status %d, dev%02x\n",
"OTG", status,
musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL));
} else if (is_host_enabled(pThis)) {
MUSB_HST_MODE(pThis); MUSB_HST_MODE(pThis);
pThis->xceiv.default_a = 1;
pThis->xceiv.state = OTG_STATE_A_IDLE; pThis->xceiv.state = OTG_STATE_A_IDLE;
status = usb_add_hcd(musb_to_hcd(pThis), -1, 0); status = usb_add_hcd(musb_to_hcd(pThis), -1, 0);
DBG(1, "%s mode, status %d, devctl %02x %c\n", DBG(1, "%s mode, status %d, devctl %02x %c\n",
...@@ -1780,28 +1787,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) ...@@ -1780,28 +1787,15 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
(musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL) (musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL)
& MGC_M_DEVCTL_BDEVICE & MGC_M_DEVCTL_BDEVICE
? 'B' : 'A')); ? 'B' : 'A'));
break;
#endif } else /* peripheral is enabled */ {
#ifdef CONFIG_USB_GADGET_MUSB_HDRC
case MUSB_PERIPHERAL:
MUSB_DEV_MODE(pThis); MUSB_DEV_MODE(pThis);
status = musb_gadget_setup(pThis); status = musb_gadget_setup(pThis);
DBG(1, "%s mode, status %d, dev%02x\n", DBG(1, "%s mode, status %d, dev%02x\n",
"PERIPHERAL", status, "PERIPHERAL", status,
musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL)); musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL));
break;
#endif
#ifdef CONFIG_USB_MUSB_OTG
case MUSB_OTG:
MUSB_OTG_MODE(pThis);
status = musb_gadget_setup(pThis);
DBG(1, "%s mode, status %d, dev%02x\n",
"OTG", status,
musb_readb(pThis->pRegs, MGC_O_HDRC_DEVCTL));
#endif
break;
} }
if (status == 0) if (status == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment