Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23853973 authored by Brian Niebuhr's avatar Brian Niebuhr Committed by Sekhar Nori
Browse files

spi: davinci: enable GPIO lines to be used as chip selects



Sometimes, the chip selects provided by SPI module are
muxed with other functionality and cannot be used in
some designs. In such cases, it becomes convenient to use
an available GPIO line as chip select.

This patch enables the DaVinci SPI driver to treat specific
GPIO lines as chip selects based on information provided in
platform data.

Signed-off-by: default avatarBrian Niebuhr <bniebuhr@efjohnson.com>
Tested-By: default avatarMichael Williamson <michael.williamson@criticallink.com>
Signed-off-by: default avatarSekhar Nori <nsekhar@ti.com>
parent cfbc5d1d
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -19,6 +19,8 @@
#ifndef __ARCH_ARM_DAVINCI_SPI_H
#ifndef __ARCH_ARM_DAVINCI_SPI_H
#define __ARCH_ARM_DAVINCI_SPI_H
#define __ARCH_ARM_DAVINCI_SPI_H


#define SPI_INTERN_CS	0xFF

enum {
enum {
	SPI_VERSION_1, /* For DM355/DM365/DM6467 */
	SPI_VERSION_1, /* For DM355/DM365/DM6467 */
	SPI_VERSION_2, /* For DA8xx */
	SPI_VERSION_2, /* For DA8xx */
@@ -38,6 +40,7 @@ struct davinci_spi_platform_data {
	u8	use_dma;
	u8	use_dma;
	u8	c2tdelay;
	u8	c2tdelay;
	u8	t2cdelay;
	u8	t2cdelay;
	u8	*chip_sel;
};
};


#endif	/* __ARCH_ARM_DAVINCI_SPI_H */
#endif	/* __ARCH_ARM_DAVINCI_SPI_H */
+32 −7
Original line number Original line Diff line number Diff line
@@ -238,14 +238,25 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
	struct davinci_spi_platform_data *pdata;
	struct davinci_spi_platform_data *pdata;
	u8 chip_sel = spi->chip_select;
	u8 chip_sel = spi->chip_select;
	u16 spidat1_cfg = CS_DEFAULT;
	u16 spidat1_cfg = CS_DEFAULT;
	bool gpio_chipsel = false;


	davinci_spi = spi_master_get_devdata(spi->master);
	davinci_spi = spi_master_get_devdata(spi->master);
	pdata = davinci_spi->pdata;
	pdata = davinci_spi->pdata;


	if (pdata->chip_sel && chip_sel < pdata->num_chipselect &&
				pdata->chip_sel[chip_sel] != SPI_INTERN_CS)
		gpio_chipsel = true;

	/*
	/*
	 * Board specific chip select logic decides the polarity and cs
	 * Board specific chip select logic decides the polarity and cs
	 * line for the controller
	 * line for the controller
	 */
	 */
	if (gpio_chipsel) {
		if (value == BITBANG_CS_ACTIVE)
			gpio_set_value(pdata->chip_sel[chip_sel], 0);
		else
			gpio_set_value(pdata->chip_sel[chip_sel], 1);
	} else {
		if (value == BITBANG_CS_ACTIVE) {
		if (value == BITBANG_CS_ACTIVE) {
			spidat1_cfg |= SPIDAT1_CSHOLD_MASK;
			spidat1_cfg |= SPIDAT1_CSHOLD_MASK;
			spidat1_cfg &= ~(0x1 << chip_sel);
			spidat1_cfg &= ~(0x1 << chip_sel);
@@ -253,6 +264,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)


		iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2);
		iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2);
	}
	}
}


/**
/**
 * davinci_spi_setup_transfer - This functions will determine transfer method
 * davinci_spi_setup_transfer - This functions will determine transfer method
@@ -546,6 +558,7 @@ static void davinci_spi_cleanup(struct spi_device *spi)
static int davinci_spi_bufs_prep(struct spi_device *spi,
static int davinci_spi_bufs_prep(struct spi_device *spi,
				 struct davinci_spi *davinci_spi)
				 struct davinci_spi *davinci_spi)
{
{
	struct davinci_spi_platform_data *pdata;
	int op_mode = 0;
	int op_mode = 0;


	/*
	/*
@@ -558,8 +571,12 @@ static int davinci_spi_bufs_prep(struct spi_device *spi,
	op_mode = SPIPC0_DIFUN_MASK
	op_mode = SPIPC0_DIFUN_MASK
		| SPIPC0_DOFUN_MASK
		| SPIPC0_DOFUN_MASK
		| SPIPC0_CLKFUN_MASK;
		| SPIPC0_CLKFUN_MASK;
	if (!(spi->mode & SPI_NO_CS))
	if (!(spi->mode & SPI_NO_CS)) {
		pdata = davinci_spi->pdata;
		if (!pdata->chip_sel ||
		     pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS)
			op_mode |= 1 << spi->chip_select;
			op_mode |= 1 << spi->chip_select;
	}
	if (spi->mode & SPI_READY)
	if (spi->mode & SPI_READY)
		op_mode |= SPIPC0_SPIENA_MASK;
		op_mode |= SPIPC0_SPIENA_MASK;


@@ -1101,6 +1118,14 @@ static int davinci_spi_probe(struct platform_device *pdev)
	udelay(100);
	udelay(100);
	iowrite32(1, davinci_spi->base + SPIGCR0);
	iowrite32(1, davinci_spi->base + SPIGCR0);


	/* initialize chip selects */
	if (pdata->chip_sel) {
		for (i = 0; i < pdata->num_chipselect; i++) {
			if (pdata->chip_sel[i] != SPI_INTERN_CS)
				gpio_direction_output(pdata->chip_sel[i], 1);
		}
	}

	/* Clock internal */
	/* Clock internal */
	if (davinci_spi->pdata->clk_internal)
	if (davinci_spi->pdata->clk_internal)
		set_io_bits(davinci_spi->base + SPIGCR1,
		set_io_bits(davinci_spi->base + SPIGCR1,