aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/davinci_spi.c
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2010-08-13 01:27:44 -0400
committerSekhar Nori <nsekhar@ti.com>2010-11-18 08:08:25 -0500
commit23853973d9b76eb8b3cf46157689bc6187e141d9 (patch)
tree3eb97d400cb04c54ed0853b71f4d98415846b7cd /drivers/spi/davinci_spi.c
parentcfbc5d1d8fda9d337e912a03502cf77d29870a8e (diff)
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: Brian Niebuhr <bniebuhr@efjohnson.com> Tested-By: Michael Williamson <michael.williamson@criticallink.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers/spi/davinci_spi.c')
-rw-r--r--drivers/spi/davinci_spi.c39
1 files changed, 32 insertions, 7 deletions
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)
546static int davinci_spi_bufs_prep(struct spi_device *spi, 558static 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,