int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
	     const void *dout, void *din, unsigned long flags)
{
	struct omap3_spi_priv *priv = to_omap3_spi(slave);

	return _spi_xfer(priv, bitlen, dout, din, flags);
}
Example #2
0
void spi_release_bus(struct spi_slave *slave)
{
	struct omap3_spi_slave *ds = to_omap3_spi(slave);

	/* Reset the SPI hardware */
	spi_reset(ds);
}
void spi_release_bus(struct spi_slave *slave)
{
	struct omap3_spi_priv *priv = to_omap3_spi(slave);

	/* Reset the SPI hardware */
	spi_reset(priv->regs);
}
int spi_claim_bus(struct spi_slave *slave)
{
	struct omap3_spi_priv *priv = to_omap3_spi(slave);

	_omap3_spi_claim_bus(priv);
	_omap3_spi_set_wordlen(priv);
	_omap3_spi_set_mode(priv);
	_omap3_spi_set_speed(priv);

	return 0;
}
Example #5
0
int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
		    unsigned long flags)
{
	struct omap3_spi_slave *ds = to_omap3_spi(slave);
	int i;
	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);

	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);

	for (i = 0; i < len; i++) {
		/* wait till TX register is empty (TXS == 1) */
		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);
	}

	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);
	}
	return 0;
}
Example #6
0
int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
		   unsigned long flags)
{
	struct omap3_spi_slave *ds = to_omap3_spi(slave);
	int i;
	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);

	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);

	writel(0, &ds->regs->channel[ds->slave.cs].tx);

	for (i = 0; i < len; i++) {
		/* Wait till RX register contains 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 (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;
}
Example #7
0
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;
}
void spi_free_slave(struct spi_slave *slave)
{
	struct omap3_spi_priv *priv = to_omap3_spi(slave);

	free(priv);
}
Example #9
0
int spi_claim_bus(struct spi_slave *slave)
{
	struct omap3_spi_slave *ds = to_omap3_spi(slave);
	unsigned int conf, div = 0;

	/* McSPI global module configuration */

	/*
	 * setup when switching from (reset default) slave mode
	 * to single-channel master mode
	 */
	spi_reset(ds);
	conf = readl(&ds->regs->modulctrl);
	conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
	conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
	writel(conf, &ds->regs->modulctrl);

	/* McSPI individual channel configuration */

	/* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
	if (ds->freq) {
		while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
					 > ds->freq)
			div++;
	} else
		div = 0xC;

	conf = readl(&ds->regs->channel[ds->slave.cs].chconf);

	/* channel defaults - 1.5 clock TCS and FIFO mode for TX/RX */
	conf |= OMAP3_MCSPI_CHCONF_TCS | OMAP3_MCSPI_CHCONF_FFEW |
			OMAP3_MCSPI_CHCONF_FFER;

	/* standard 4-wire master mode:  SCK, MOSI/out, MISO/in, nCS
	 * REVISIT: this controller could support SPI_3WIRE mode.
	 */
	if (!ds->data_lines_reversed) {
		conf &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
		conf |= OMAP3_MCSPI_CHCONF_DPE0;
	} else {
		conf &= ~OMAP3_MCSPI_CHCONF_DPE0;
		conf |= (OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
	}

	/* wordlength */
	conf &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
	conf |= (WORD_LEN - 1) << 7;

	/* set chipselect polarity; manage with FORCE */
	if (!(ds->mode & SPI_CS_HIGH))
		conf |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
	else
		conf &= ~OMAP3_MCSPI_CHCONF_EPOL;

	/* set clock divisor */
	conf &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
	conf |= div << 2;

	/* set SPI mode 0..3 */
	if (ds->mode & SPI_CPOL)
		conf |= OMAP3_MCSPI_CHCONF_POL;
	else
		conf &= ~OMAP3_MCSPI_CHCONF_POL;
	if (ds->mode & SPI_CPHA)
		conf |= OMAP3_MCSPI_CHCONF_PHA;
	else
		conf &= ~OMAP3_MCSPI_CHCONF_PHA;

	/* Transmit & receive mode */
	conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;

	writel(conf, &ds->regs->channel[ds->slave.cs].chconf);

	return 0;
}
Example #10
0
void spi_free_slave(struct spi_slave *slave)
{
	struct omap3_spi_slave *ds = to_omap3_spi(slave);

	free(ds);
}