diff options
-rw-r--r-- | arch/arm/mach-davinci/include/mach/spi.h | 3 | ||||
-rw-r--r-- | drivers/spi/davinci_spi.c | 39 |
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 2cb326e536bb..734d1fb99614 100644 --- a/arch/arm/mach-davinci/include/mach/spi.h +++ b/arch/arm/mach-davinci/include/mach/spi.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef __ARCH_ARM_DAVINCI_SPI_H | 19 | #ifndef __ARCH_ARM_DAVINCI_SPI_H |
20 | #define __ARCH_ARM_DAVINCI_SPI_H | 20 | #define __ARCH_ARM_DAVINCI_SPI_H |
21 | 21 | ||
22 | #define SPI_INTERN_CS 0xFF | ||
23 | |||
22 | enum { | 24 | enum { |
23 | SPI_VERSION_1, /* For DM355/DM365/DM6467 */ | 25 | SPI_VERSION_1, /* For DM355/DM365/DM6467 */ |
24 | SPI_VERSION_2, /* For DA8xx */ | 26 | SPI_VERSION_2, /* For DA8xx */ |
@@ -38,6 +40,7 @@ struct davinci_spi_platform_data { | |||
38 | u8 use_dma; | 40 | u8 use_dma; |
39 | u8 c2tdelay; | 41 | u8 c2tdelay; |
40 | u8 t2cdelay; | 42 | u8 t2cdelay; |
43 | u8 *chip_sel; | ||
41 | }; | 44 | }; |
42 | 45 | ||
43 | #endif /* __ARCH_ARM_DAVINCI_SPI_H */ | 46 | #endif /* __ARCH_ARM_DAVINCI_SPI_H */ |
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 82dddf83daf7..d5d7014e6ae2 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) | |||
238 | struct davinci_spi_platform_data *pdata; | 238 | struct davinci_spi_platform_data *pdata; |
239 | u8 chip_sel = spi->chip_select; | 239 | u8 chip_sel = spi->chip_select; |
240 | u16 spidat1_cfg = CS_DEFAULT; | 240 | u16 spidat1_cfg = CS_DEFAULT; |
241 | bool gpio_chipsel = false; | ||
241 | 242 | ||
242 | davinci_spi = spi_master_get_devdata(spi->master); | 243 | davinci_spi = spi_master_get_devdata(spi->master); |
243 | pdata = davinci_spi->pdata; | 244 | pdata = davinci_spi->pdata; |
244 | 245 | ||
246 | if (pdata->chip_sel && chip_sel < pdata->num_chipselect && | ||
247 | pdata->chip_sel[chip_sel] != SPI_INTERN_CS) | ||
248 | gpio_chipsel = true; | ||
249 | |||
245 | /* | 250 | /* |
246 | * Board specific chip select logic decides the polarity and cs | 251 | * Board specific chip select logic decides the polarity and cs |
247 | * line for the controller | 252 | * line for the controller |
248 | */ | 253 | */ |
249 | if (value == BITBANG_CS_ACTIVE) { | 254 | if (gpio_chipsel) { |
250 | spidat1_cfg |= SPIDAT1_CSHOLD_MASK; | 255 | if (value == BITBANG_CS_ACTIVE) |
251 | spidat1_cfg &= ~(0x1 << chip_sel); | 256 | gpio_set_value(pdata->chip_sel[chip_sel], 0); |
252 | } | 257 | else |
258 | gpio_set_value(pdata->chip_sel[chip_sel], 1); | ||
259 | } else { | ||
260 | if (value == BITBANG_CS_ACTIVE) { | ||
261 | spidat1_cfg |= SPIDAT1_CSHOLD_MASK; | ||
262 | spidat1_cfg &= ~(0x1 << chip_sel); | ||
263 | } | ||
253 | 264 | ||
254 | iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2); | 265 | iowrite16(spidat1_cfg, davinci_spi->base + SPIDAT1 + 2); |
266 | } | ||
255 | } | 267 | } |
256 | 268 | ||
257 | /** | 269 | /** |
@@ -546,6 +558,7 @@ static void davinci_spi_cleanup(struct spi_device *spi) | |||
546 | static int davinci_spi_bufs_prep(struct spi_device *spi, | 558 | static int davinci_spi_bufs_prep(struct spi_device *spi, |
547 | struct davinci_spi *davinci_spi) | 559 | struct davinci_spi *davinci_spi) |
548 | { | 560 | { |
561 | struct davinci_spi_platform_data *pdata; | ||
549 | int op_mode = 0; | 562 | int op_mode = 0; |
550 | 563 | ||
551 | /* | 564 | /* |
@@ -558,8 +571,12 @@ static int davinci_spi_bufs_prep(struct spi_device *spi, | |||
558 | op_mode = SPIPC0_DIFUN_MASK | 571 | op_mode = SPIPC0_DIFUN_MASK |
559 | | SPIPC0_DOFUN_MASK | 572 | | SPIPC0_DOFUN_MASK |
560 | | SPIPC0_CLKFUN_MASK; | 573 | | SPIPC0_CLKFUN_MASK; |
561 | if (!(spi->mode & SPI_NO_CS)) | 574 | if (!(spi->mode & SPI_NO_CS)) { |
562 | op_mode |= 1 << spi->chip_select; | 575 | pdata = davinci_spi->pdata; |
576 | if (!pdata->chip_sel || | ||
577 | pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS) | ||
578 | op_mode |= 1 << spi->chip_select; | ||
579 | } | ||
563 | if (spi->mode & SPI_READY) | 580 | if (spi->mode & SPI_READY) |
564 | op_mode |= SPIPC0_SPIENA_MASK; | 581 | op_mode |= SPIPC0_SPIENA_MASK; |
565 | 582 | ||
@@ -1101,6 +1118,14 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
1101 | udelay(100); | 1118 | udelay(100); |
1102 | iowrite32(1, davinci_spi->base + SPIGCR0); | 1119 | iowrite32(1, davinci_spi->base + SPIGCR0); |
1103 | 1120 | ||
1121 | /* initialize chip selects */ | ||
1122 | if (pdata->chip_sel) { | ||
1123 | for (i = 0; i < pdata->num_chipselect; i++) { | ||
1124 | if (pdata->chip_sel[i] != SPI_INTERN_CS) | ||
1125 | gpio_direction_output(pdata->chip_sel[i], 1); | ||
1126 | } | ||
1127 | } | ||
1128 | |||
1104 | /* Clock internal */ | 1129 | /* Clock internal */ |
1105 | if (davinci_spi->pdata->clk_internal) | 1130 | if (davinci_spi->pdata->clk_internal) |
1106 | set_io_bits(davinci_spi->base + SPIGCR1, | 1131 | set_io_bits(davinci_spi->base + SPIGCR1, |