static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { unsigned int len; int ret = -1; if (priv->wordlen < 4 || priv->wordlen > 32) { printf("omap3_spi: invalid wordlen %d\n", priv->wordlen); return -1; } if (bitlen % priv->wordlen) return -1; len = bitlen / priv->wordlen; if (bitlen == 0) { /* only change CS */ int chconf = readl(&priv->regs->channel[priv->cs].chconf); if (flags & SPI_XFER_BEGIN) { omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); chconf |= OMAP3_MCSPI_CHCONF_FORCE; omap3_spi_write_chconf(priv, chconf); } if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; omap3_spi_write_chconf(priv, chconf); omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); } ret = 0; } else { if (dout != NULL && din != NULL) ret = omap3_spi_txrx(priv, len, dout, din, flags); else if (dout != NULL) ret = omap3_spi_write(priv, len, dout, flags); else if (din != NULL) ret = omap3_spi_read(priv, len, din, flags); } return ret; }
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct omap3_spi_slave *ds = to_omap3_spi(slave); unsigned int len; const u8 *txp = dout; u8 *rxp = din; int ret = -1; if (bitlen % 8) return -1; len = bitlen / 8; if (bitlen == 0) { /* only change CS */ int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); if (flags & SPI_XFER_BEGIN) { writel(OMAP3_MCSPI_CHCTRL_EN, &ds->regs->channel[ds->slave.cs].chctrl); chconf |= OMAP3_MCSPI_CHCONF_FORCE; writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); } 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); } ret = 0; } else { if (dout != NULL) ret = omap3_spi_write(slave, len, txp, flags); if (din != NULL) ret = omap3_spi_read(slave, len, rxp, flags); } return ret; }