usb: musb: add ulpi access operations
This adds helper functions for ULPI access, and implements otg_io_access_ops for musb. Signed-off-by: Heikki Krogerus <ext-heikki.krogerus@nokia.com> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
58815fa3bf
Коммит
ffb865b1e4
|
@ -149,6 +149,87 @@ static inline struct musb *dev_to_musb(struct device *dev)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef CONFIG_BLACKFIN
|
||||
static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
|
||||
{
|
||||
void __iomem *addr = otg->io_priv;
|
||||
int i = 0;
|
||||
u8 r;
|
||||
u8 power;
|
||||
|
||||
/* Make sure the transceiver is not in low power mode */
|
||||
power = musb_readb(addr, MUSB_POWER);
|
||||
power &= ~MUSB_POWER_SUSPENDM;
|
||||
musb_writeb(addr, MUSB_POWER, power);
|
||||
|
||||
/* REVISIT: musbhdrc_ulpi_an.pdf recommends setting the
|
||||
* ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
|
||||
*/
|
||||
|
||||
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
|
||||
MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
|
||||
|
||||
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
|
||||
& MUSB_ULPI_REG_CMPLT)) {
|
||||
i++;
|
||||
if (i == 10000) {
|
||||
DBG(3, "ULPI read timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
}
|
||||
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
|
||||
r &= ~MUSB_ULPI_REG_CMPLT;
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
|
||||
|
||||
return musb_readb(addr, MUSB_ULPI_REG_DATA);
|
||||
}
|
||||
|
||||
static int musb_ulpi_write(struct otg_transceiver *otg,
|
||||
u32 offset, u32 data)
|
||||
{
|
||||
void __iomem *addr = otg->io_priv;
|
||||
int i = 0;
|
||||
u8 r = 0;
|
||||
u8 power;
|
||||
|
||||
/* Make sure the transceiver is not in low power mode */
|
||||
power = musb_readb(addr, MUSB_POWER);
|
||||
power &= ~MUSB_POWER_SUSPENDM;
|
||||
musb_writeb(addr, MUSB_POWER, power);
|
||||
|
||||
musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
|
||||
|
||||
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
|
||||
& MUSB_ULPI_REG_CMPLT)) {
|
||||
i++;
|
||||
if (i == 10000) {
|
||||
DBG(3, "ULPI write timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
|
||||
r &= ~MUSB_ULPI_REG_CMPLT;
|
||||
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define musb_ulpi_read(a, b) NULL
|
||||
#define musb_ulpi_write(a, b, c) NULL
|
||||
#endif
|
||||
|
||||
static struct otg_io_access_ops musb_ulpi_access = {
|
||||
.read = musb_ulpi_read,
|
||||
.write = musb_ulpi_write,
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if !defined(CONFIG_USB_TUSB6010) && !defined(CONFIG_BLACKFIN)
|
||||
|
||||
/*
|
||||
|
@ -1954,6 +2035,11 @@ bad_config:
|
|||
goto fail3;
|
||||
}
|
||||
|
||||
if (!musb->xceiv->io_ops) {
|
||||
musb->xceiv->io_priv = musb->mregs;
|
||||
musb->xceiv->io_ops = &musb_ulpi_access;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_MUSB_PIO_ONLY
|
||||
if (use_dma && dev->dma_mask) {
|
||||
struct dma_controller *c;
|
||||
|
|
|
@ -75,6 +75,10 @@
|
|||
/* MUSB ULPI VBUSCONTROL */
|
||||
#define MUSB_ULPI_USE_EXTVBUS 0x01
|
||||
#define MUSB_ULPI_USE_EXTVBUSIND 0x02
|
||||
/* ULPI_REG_CONTROL */
|
||||
#define MUSB_ULPI_REG_REQ (1 << 0)
|
||||
#define MUSB_ULPI_REG_CMPLT (1 << 1)
|
||||
#define MUSB_ULPI_RDN_WR (1 << 2)
|
||||
|
||||
/* TESTMODE */
|
||||
#define MUSB_TEST_FORCE_HOST 0x80
|
||||
|
@ -251,6 +255,12 @@
|
|||
/* REVISIT: vctrl/vstatus: optional vendor utmi+phy register at 0x68 */
|
||||
#define MUSB_HWVERS 0x6C /* 8 bit */
|
||||
#define MUSB_ULPI_BUSCONTROL 0x70 /* 8 bit */
|
||||
#define MUSB_ULPI_INT_MASK 0x72 /* 8 bit */
|
||||
#define MUSB_ULPI_INT_SRC 0x73 /* 8 bit */
|
||||
#define MUSB_ULPI_REG_DATA 0x74 /* 8 bit */
|
||||
#define MUSB_ULPI_REG_ADDR 0x75 /* 8 bit */
|
||||
#define MUSB_ULPI_REG_CONTROL 0x76 /* 8 bit */
|
||||
#define MUSB_ULPI_RAW_DATA 0x77 /* 8 bit */
|
||||
|
||||
#define MUSB_EPINFO 0x78 /* 8 bit */
|
||||
#define MUSB_RAMINFO 0x79 /* 8 bit */
|
||||
|
|
Загрузка…
Ссылка в новой задаче