writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable);
}
+static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val)
+{
+ writel(val, &ds->regs->channel[ds->slave.cs].chconf);
+ /* Flash post writes to make immediate effect */
+ readl(&ds->regs->channel[ds->slave.cs].chconf);
+}
+
+static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable)
+{
+ writel(enable, &ds->regs->channel[ds->slave.cs].chctrl);
+ /* Flash post writes to make immediate effect */
+ readl(&ds->regs->channel[ds->slave.cs].chctrl);
+}
+
void spi_init()
{
/* do nothing */
/* Transmit & receive mode */
conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
- writel(conf, &ds->regs->channel[ds->slave.cs].chconf);
+ omap3_spi_write_chconf(ds,conf);
return 0;
}
int timeout = SPI_WAIT_TIMEOUT;
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);
+ /* Enable the channel */
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
- writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+ omap3_spi_write_chconf(ds,chconf);
for (i = 0; i < len; i++) {
/* wait till TX register is empty (TXS == 1) */
writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
}
+ /* wait to finish of transfer */
+ while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
+ OMAP3_MCSPI_CHSTAT_EOT));
+
+ /* Disable the channel otherwise the next immediate RX will get affected */
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
+
if (flags & SPI_XFER_END) {
- /* wait to finish of transfer */
- while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
- OMAP3_MCSPI_CHSTAT_EOT));
chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
- writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
-
- writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+ omap3_spi_write_chconf(ds,chconf);
}
return 0;
}
int timeout = SPI_WAIT_TIMEOUT;
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);
+ /* Enable the channel */
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
- writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+ omap3_spi_write_chconf(ds,chconf);
writel(0, &ds->regs->channel[ds->slave.cs].tx);
return -1;
}
}
+
+ /* Disable the channel to prevent furher receiving */
+ if(i == (len - 1))
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
+
/* Read the data */
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
}
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);
+ omap3_spi_write_chconf(ds,chconf);
}
return 0;
int i=0;
/*Enable SPI channel*/
- if (flags & SPI_XFER_BEGIN)
- writel(OMAP3_MCSPI_CHCTRL_EN,
- &ds->regs->channel[ds->slave.cs].chctrl);
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
/*set TRANSMIT-RECEIVE Mode*/
chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
- writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+ omap3_spi_write_chconf(ds,chconf);
/*Shift in and out 1 byte at time*/
for (i=0; i < len; i++){
/* Read the data */
rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
}
+ /* Disable the channel */
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
/*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);
+ omap3_spi_write_chconf(ds,chconf);
}
return 0;
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);
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
chconf |= OMAP3_MCSPI_CHCONF_FORCE;
- writel(chconf,
- &ds->regs->channel[ds->slave.cs].chconf);
+ omap3_spi_write_chconf(ds,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);
+ omap3_spi_write_chconf(ds,chconf);
+ omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
}
ret = 0;
} else {