300
/*McSPI Transmit Receive Mode*/
301
int omap3_spi_txrx(struct spi_slave *slave,
302
unsigned int len, const u8 *txp, u8 *rxp, unsigned long flags)
304
struct omap3_spi_slave *ds = to_omap3_spi(slave);
305
int timeout = SPI_WAIT_TIMEOUT;
306
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
307
int irqstatus = readl(&ds->regs->irqstatus);
310
/*Enable SPI channel*/
311
if (flags & SPI_XFER_BEGIN)
312
writel(OMAP3_MCSPI_CHCTRL_EN,
313
&ds->regs->channel[ds->slave.cs].chctrl);
315
/*set TRANSMIT-RECEIVE Mode*/
316
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
317
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
318
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
320
/*Shift in and out 1 byte at time*/
321
for (i=0; i < len; i++){
322
/* Write: wait for TX empty (TXS == 1)*/
323
irqstatus |= (1<< (4*(ds->slave.bus)));
324
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
325
OMAP3_MCSPI_CHSTAT_TXS)) {
326
if (--timeout <= 0) {
327
printf("SPI TXS timed out, status=0x%08x\n",
328
readl(&ds->regs->channel[ds->slave.cs].chstat));
333
writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
335
/*Read: wait for RX containing data (RXS == 1)*/
336
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
337
OMAP3_MCSPI_CHSTAT_RXS)) {
338
if (--timeout <= 0) {
339
printf("SPI RXS timed out, status=0x%08x\n",
340
readl(&ds->regs->channel[ds->slave.cs].chstat));
345
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
348
/*if transfer must be terminated disable the channel*/
349
if (flags & SPI_XFER_END) {
350
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
351
writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
353
writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
300
359
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
301
360
const void *dout, void *din, unsigned long flags)
391
if (dout != NULL && din != NULL)
392
ret = omap3_spi_txrx(slave, len, txp, rxp, flags);
393
else if (dout != NULL)
333
394
ret = omap3_spi_write(slave, len, txp, flags);
395
else if (din != NULL)
336
396
ret = omap3_spi_read(slave, len, rxp, flags);