mirror of
https://github.com/Stichting-MINIX-Research-Foundation/u-boot.git
synced 2025-09-10 12:39:22 -04:00
omap3_spi: receive transmit mode
Implementation of receive-transmit mode for omap3 MCSPI. Introduces full duplex communication, needed by some spi devices (such as enc28j60). Signed-off-by: jacopo mondi <mondi@cs.unibo.it> <j.mondi@voltaelectronics.com>
This commit is contained in:
parent
f8d6c50ead
commit
08b5ab073d
@ -297,6 +297,65 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*McSPI Transmit Receive Mode*/
|
||||||
|
int omap3_spi_txrx(struct spi_slave *slave,
|
||||||
|
unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags)
|
||||||
|
{
|
||||||
|
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
||||||
|
int timeout = SPI_WAIT_TIMEOUT;
|
||||||
|
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||||
|
int irqstatus = readl(&ds->regs->irqstatus);
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
/*Enable SPI channel*/
|
||||||
|
if (flags & SPI_XFER_BEGIN)
|
||||||
|
writel(OMAP3_MCSPI_CHCTRL_EN,
|
||||||
|
&ds->regs->channel[ds->slave.cs].chctrl);
|
||||||
|
|
||||||
|
/*set TRANSMIT-RECEIVE Mode*/
|
||||||
|
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
|
||||||
|
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
|
||||||
|
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||||
|
|
||||||
|
/*Shift in and out 1 byte at time*/
|
||||||
|
for (i=0; i < len; i++){
|
||||||
|
/* Write: wait for TX empty (TXS == 1)*/
|
||||||
|
irqstatus |= (1<< (4*(ds->slave.bus)));
|
||||||
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
|
OMAP3_MCSPI_CHSTAT_TXS)) {
|
||||||
|
if (--timeout <= 0) {
|
||||||
|
printf("SPI TXS timed out, status=0x%08x\n",
|
||||||
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Write the data */
|
||||||
|
writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
|
||||||
|
|
||||||
|
/*Read: wait for RX containing data (RXS == 1)*/
|
||||||
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
|
OMAP3_MCSPI_CHSTAT_RXS)) {
|
||||||
|
if (--timeout <= 0) {
|
||||||
|
printf("SPI RXS timed out, status=0x%08x\n",
|
||||||
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Read the data */
|
||||||
|
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if transfer must be terminated disable the channel*/
|
||||||
|
if (flags & SPI_XFER_END) {
|
||||||
|
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
|
||||||
|
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
|
||||||
|
|
||||||
|
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
|
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
|
||||||
const void *dout, void *din, unsigned long flags)
|
const void *dout, void *din, unsigned long flags)
|
||||||
{
|
{
|
||||||
@ -329,10 +388,11 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
|
|||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
} else {
|
} else {
|
||||||
if (dout != NULL)
|
if (dout != NULL && din != NULL)
|
||||||
|
ret = omap3_spi_txrx(slave, len, txp, rxp, flags);
|
||||||
|
else if (dout != NULL)
|
||||||
ret = omap3_spi_write(slave, len, txp, flags);
|
ret = omap3_spi_write(slave, len, txp, flags);
|
||||||
|
else if (din != NULL)
|
||||||
if (din != NULL)
|
|
||||||
ret = omap3_spi_read(slave, len, rxp, flags);
|
ret = omap3_spi_read(slave, len, rxp, flags);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -109,6 +109,8 @@ static inline struct omap3_spi_slave *to_omap3_spi(struct spi_slave *slave)
|
|||||||
return container_of(slave, struct omap3_spi_slave, slave);
|
return container_of(slave, struct omap3_spi_slave, slave);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, const u8 *txp,
|
||||||
|
u8 *rxp, unsigned long flags);
|
||||||
int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
|
int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
|
||||||
unsigned long flags);
|
unsigned long flags);
|
||||||
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
|
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user