summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-davinci/include/mach/spi.h3
-rw-r--r--drivers/spi/davinci_spi.c39
2 files changed, 35 insertions, 7 deletions
diff --git a/arch/arm/mach-davinci/include/mach/spi.h b/arch/arm/mach-davinci/include/mach/spi.h
index 2cb326e536b..734d1fb9961 100644
--- a/arch/arm/mach-davinci/include/mach/spi.h
+++ b/arch/arm/mach-davinci/include/mach/spi.h
@@ -19,6 +19,8 @@
#ifndef __ARCH_ARM_DAVINCI_SPI_H
#define __ARCH_ARM_DAVINCI_SPI_H
+#define SPI_INTERN_CS 0xFF
+
enum {
SPI_VERSION_1, /* For DM355/DM365/DM6467 */
SPI_VERSION_2, /* For DA8xx */
@@ -38,6 +40,7 @@ struct davinci_spi_platform_data {
u8 use_dma;
u8 c2tdelay;
u8 t2cdelay;
+ u8 *chip_sel;
};
#endif /* __ARCH_ARM_DAVINCI_SPI_H */
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 82dddf83daf..d5d7014e6ae 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -238,20 +238,32 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
struct davinci_spi_platform_data *pdata;
u8 chip_sel = spi->chip_select;
u16 spidat1_cfg = CS_DEFAULT;
+ bool gpio_chipsel = false;
davinci_spi = spi_master_get_devdata(spi->master);
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
* line for the controller
*/
- if (value == BITBANG_CS_ACTIVE) {
- spidat1_cfg |= SPIDAT1_CSHOLD_MASK;
- spidat1_cfg &= ~(0x1 << chip_sel);
- }
+ 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) {
+ spidat1_cfg |= SPIDAT1_CSHOLD_MASK;
+ spidat1_cfg &= ~(0x1 << chip_sel);
+ }
- iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2);
+ iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2);
+ }
}
/**
@@ -546,6 +558,7 @@ static void davinci_spi_cleanup(struct spi_device *spi)
static int davinci_spi_bufs_prep(struct spi_device *spi,
struct davinci_spi *davinci_spi)
{
+ struct davinci_spi_platform_data *pdata;
int op_mode = 0;
/*
@@ -558,8 +571,12 @@ static int davinci_spi_bufs_prep(struct spi_device *spi,
op_mode = SPIPC0_DIFUN_MASK
| SPIPC0_DOFUN_MASK
| SPIPC0_CLKFUN_MASK;
- if (!(spi->mode & SPI_NO_CS))
- op_mode |= 1 << spi->chip_select;
+ 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;
+ }
if (spi->mode & SPI_READY)
op_mode |= SPIPC0_SPIENA_MASK;
@@ -1101,6 +1118,14 @@ static int davinci_spi_probe(struct platform_device *pdev)
udelay(100);
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 */
if (davinci_spi->pdata->clk_internal)
set_io_bits(davinci_spi->base + SPIGCR1,