diff options
| author | Grygorii Strashko <grygorii.strashko@ti.com> | 2014-08-01 12:40:33 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@linaro.org> | 2014-08-01 14:20:52 -0400 |
| commit | c060014063d552c95129279b73c9cc77e69981fe (patch) | |
| tree | 7ffdced08fe7ff2e5dab161769131f1f7471bbdd | |
| parent | a88e34ea213e1bdbd9b2dfca1e1e5fa68b9649a0 (diff) | |
spi: davinci: use spi_device.cs_gpio to store gpio cs per spi device
Rework Davinci SPI driver to store GPIO CS number in cs_gpio field
of SPI device structure (spi_device) for both DT and non-DT cases.
This will make Davinci SPI driver code simpler and allows to reuse
more SPI core functionality.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
| -rw-r--r-- | drivers/spi/spi-davinci.c | 54 |
1 files changed, 17 insertions, 37 deletions
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index ac4414e00bb9..276a3884fb3c 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
| @@ -208,9 +208,7 @@ static inline void clear_io_bits(void __iomem *addr, u32 bits) | |||
| 208 | static void davinci_spi_chipselect(struct spi_device *spi, int value) | 208 | static void davinci_spi_chipselect(struct spi_device *spi, int value) |
| 209 | { | 209 | { |
| 210 | struct davinci_spi *dspi; | 210 | struct davinci_spi *dspi; |
| 211 | struct device_node *np = spi->dev.of_node; | ||
| 212 | struct davinci_spi_platform_data *pdata; | 211 | struct davinci_spi_platform_data *pdata; |
| 213 | struct spi_master *master = spi->master; | ||
| 214 | u8 chip_sel = spi->chip_select; | 212 | u8 chip_sel = spi->chip_select; |
| 215 | u16 spidat1 = CS_DEFAULT; | 213 | u16 spidat1 = CS_DEFAULT; |
| 216 | bool gpio_chipsel = false; | 214 | bool gpio_chipsel = false; |
| @@ -219,16 +217,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
| 219 | dspi = spi_master_get_devdata(spi->master); | 217 | dspi = spi_master_get_devdata(spi->master); |
| 220 | pdata = &dspi->pdata; | 218 | pdata = &dspi->pdata; |
| 221 | 219 | ||
| 222 | if (np && master->cs_gpios != NULL && spi->cs_gpio >= 0) { | 220 | if (spi->cs_gpio >= 0) { |
| 223 | /* SPI core parse and update master->cs_gpio */ | 221 | /* SPI core parse and update master->cs_gpio */ |
| 224 | gpio_chipsel = true; | 222 | gpio_chipsel = true; |
| 225 | gpio = spi->cs_gpio; | 223 | gpio = spi->cs_gpio; |
| 226 | } else if (pdata->chip_sel && | ||
| 227 | chip_sel < pdata->num_chipselect && | ||
| 228 | pdata->chip_sel[chip_sel] != SPI_INTERN_CS) { | ||
| 229 | /* platform data defines chip_sel */ | ||
| 230 | gpio_chipsel = true; | ||
| 231 | gpio = pdata->chip_sel[chip_sel]; | ||
| 232 | } | 224 | } |
| 233 | 225 | ||
| 234 | /* | 226 | /* |
| @@ -237,9 +229,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
| 237 | */ | 229 | */ |
| 238 | if (gpio_chipsel) { | 230 | if (gpio_chipsel) { |
| 239 | if (value == BITBANG_CS_ACTIVE) | 231 | if (value == BITBANG_CS_ACTIVE) |
| 240 | gpio_set_value(gpio, 0); | 232 | gpio_set_value(gpio, spi->mode & SPI_CS_HIGH); |
| 241 | else | 233 | else |
| 242 | gpio_set_value(gpio, 1); | 234 | gpio_set_value(gpio, !(spi->mode & SPI_CS_HIGH)); |
| 243 | } else { | 235 | } else { |
| 244 | if (value == BITBANG_CS_ACTIVE) { | 236 | if (value == BITBANG_CS_ACTIVE) { |
| 245 | spidat1 |= SPIDAT1_CSHOLD_MASK; | 237 | spidat1 |= SPIDAT1_CSHOLD_MASK; |
| @@ -405,35 +397,34 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
| 405 | struct spi_master *master = spi->master; | 397 | struct spi_master *master = spi->master; |
| 406 | struct device_node *np = spi->dev.of_node; | 398 | struct device_node *np = spi->dev.of_node; |
| 407 | bool internal_cs = true; | 399 | bool internal_cs = true; |
| 400 | unsigned long flags = GPIOF_DIR_OUT; | ||
| 408 | 401 | ||
| 409 | dspi = spi_master_get_devdata(spi->master); | 402 | dspi = spi_master_get_devdata(spi->master); |
| 410 | pdata = &dspi->pdata; | 403 | pdata = &dspi->pdata; |
| 411 | 404 | ||
| 405 | flags |= (spi->mode & SPI_CS_HIGH) ? GPIOF_INIT_LOW : GPIOF_INIT_HIGH; | ||
| 406 | |||
| 412 | if (!(spi->mode & SPI_NO_CS)) { | 407 | if (!(spi->mode & SPI_NO_CS)) { |
| 413 | if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { | 408 | if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { |
| 414 | unsigned long flags; | ||
| 415 | |||
| 416 | flags = GPIOF_DIR_OUT; | ||
| 417 | if (spi->mode & SPI_CS_HIGH) | ||
| 418 | flags |= GPIOF_INIT_LOW; | ||
| 419 | else | ||
| 420 | flags |= GPIOF_INIT_HIGH; | ||
| 421 | retval = gpio_request_one(spi->cs_gpio, | 409 | retval = gpio_request_one(spi->cs_gpio, |
| 422 | flags, dev_name(&spi->dev)); | 410 | flags, dev_name(&spi->dev)); |
| 423 | if (retval) { | ||
| 424 | dev_err(&spi->dev, | ||
| 425 | "GPIO %d request failed (%d)\n", | ||
| 426 | spi->cs_gpio, retval); | ||
| 427 | return retval; | ||
| 428 | } | ||
| 429 | internal_cs = false; | 411 | internal_cs = false; |
| 430 | } else if (pdata->chip_sel && | 412 | } else if (pdata->chip_sel && |
| 431 | spi->chip_select < pdata->num_chipselect && | 413 | spi->chip_select < pdata->num_chipselect && |
| 432 | pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { | 414 | pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { |
| 415 | spi->cs_gpio = pdata->chip_sel[spi->chip_select]; | ||
| 416 | retval = gpio_request_one(spi->cs_gpio, | ||
| 417 | flags, dev_name(&spi->dev)); | ||
| 433 | internal_cs = false; | 418 | internal_cs = false; |
| 434 | } | 419 | } |
| 435 | } | 420 | } |
| 436 | 421 | ||
| 422 | if (retval) { | ||
| 423 | dev_err(&spi->dev, "GPIO %d setup failed (%d)\n", | ||
| 424 | spi->cs_gpio, retval); | ||
| 425 | return retval; | ||
| 426 | } | ||
| 427 | |||
| 437 | if (internal_cs) | 428 | if (internal_cs) |
| 438 | set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); | 429 | set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); |
| 439 | 430 | ||
| @@ -450,10 +441,7 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
| 450 | 441 | ||
| 451 | static void davinci_spi_cleanup(struct spi_device *spi) | 442 | static void davinci_spi_cleanup(struct spi_device *spi) |
| 452 | { | 443 | { |
| 453 | struct spi_master *master = spi->master; | 444 | if (spi->cs_gpio >= 0) |
| 454 | struct device_node *np = spi->dev.of_node; | ||
| 455 | |||
| 456 | if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) | ||
| 457 | gpio_free(spi->cs_gpio); | 445 | gpio_free(spi->cs_gpio); |
| 458 | } | 446 | } |
| 459 | 447 | ||
| @@ -895,7 +883,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
| 895 | struct resource *r; | 883 | struct resource *r; |
| 896 | resource_size_t dma_rx_chan = SPI_NO_RESOURCE; | 884 | resource_size_t dma_rx_chan = SPI_NO_RESOURCE; |
| 897 | resource_size_t dma_tx_chan = SPI_NO_RESOURCE; | 885 | resource_size_t dma_tx_chan = SPI_NO_RESOURCE; |
| 898 | int i = 0, ret = 0; | 886 | int ret = 0; |
| 899 | u32 spipc0; | 887 | u32 spipc0; |
| 900 | 888 | ||
| 901 | master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi)); | 889 | master = spi_alloc_master(&pdev->dev, sizeof(struct davinci_spi)); |
| @@ -1016,14 +1004,6 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
| 1016 | spipc0 = SPIPC0_DIFUN_MASK | SPIPC0_DOFUN_MASK | SPIPC0_CLKFUN_MASK; | 1004 | spipc0 = SPIPC0_DIFUN_MASK | SPIPC0_DOFUN_MASK | SPIPC0_CLKFUN_MASK; |
| 1017 | iowrite32(spipc0, dspi->base + SPIPC0); | 1005 | iowrite32(spipc0, dspi->base + SPIPC0); |
| 1018 | 1006 | ||
| 1019 | /* initialize chip selects */ | ||
| 1020 | if (pdata->chip_sel) { | ||
| 1021 | for (i = 0; i < pdata->num_chipselect; i++) { | ||
| 1022 | if (pdata->chip_sel[i] != SPI_INTERN_CS) | ||
| 1023 | gpio_direction_output(pdata->chip_sel[i], 1); | ||
| 1024 | } | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | if (pdata->intr_line) | 1007 | if (pdata->intr_line) |
| 1028 | iowrite32(SPI_INTLVL_1, dspi->base + SPILVL); | 1008 | iowrite32(SPI_INTLVL_1, dspi->base + SPILVL); |
| 1029 | else | 1009 | else |
