diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-davinci.txt | 30 | ||||
-rw-r--r-- | drivers/spi/spi-davinci.c | 55 |
2 files changed, 78 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt index f80887bca0d6..12ecfe9e3599 100644 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt | |||
@@ -1,5 +1,10 @@ | |||
1 | Davinci SPI controller device bindings | 1 | Davinci SPI controller device bindings |
2 | 2 | ||
3 | Links on DM: | ||
4 | Keystone 2 - http://www.ti.com/lit/ug/sprugp2a/sprugp2a.pdf | ||
5 | dm644x - http://www.ti.com/lit/ug/sprue32a/sprue32a.pdf | ||
6 | OMAP-L138/da830 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf | ||
7 | |||
3 | Required properties: | 8 | Required properties: |
4 | - #address-cells: number of cells required to define a chip select | 9 | - #address-cells: number of cells required to define a chip select |
5 | address on the SPI bus. Should be set to 1. | 10 | address on the SPI bus. Should be set to 1. |
@@ -24,6 +29,30 @@ Optional: | |||
24 | cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; | 29 | cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; |
25 | where first three are internal CS and last two are GPIO CS. | 30 | where first three are internal CS and last two are GPIO CS. |
26 | 31 | ||
32 | Optional properties for slave devices: | ||
33 | SPI slave nodes can contain the following properties. | ||
34 | Not all SPI Peripherals from Texas Instruments support this. | ||
35 | Please check SPI peripheral documentation for a device before using these. | ||
36 | |||
37 | - ti,spi-wdelay : delay between transmission of words | ||
38 | (SPIFMTn.WDELAY, SPIDAT1.WDEL) must be specified in number of SPI module | ||
39 | clock periods. | ||
40 | |||
41 | delay = WDELAY * SPI_module_clock_period + 2 * SPI_module_clock_period | ||
42 | |||
43 | Below is timing diagram which shows functional meaning of | ||
44 | "ti,spi-wdelay" parameter. | ||
45 | |||
46 | +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ | ||
47 | SPI_CLK | | | | | | | | | | | | | | | | | ||
48 | +----------+ +-+ +-+ +-+ +-+ +---------------------------+ +-+ +-+ +- | ||
49 | |||
50 | SPI_SOMI/SIMO+-----------------+ +----------- | ||
51 | +----------+ word1 +---------------------------+word2 | ||
52 | +-----------------+ +----------- | ||
53 | WDELAY | ||
54 | <--------------------------> | ||
55 | |||
27 | Example of a NOR flash slave device (n25q032) connected to DaVinci | 56 | Example of a NOR flash slave device (n25q032) connected to DaVinci |
28 | SPI controller device over the SPI bus. | 57 | SPI controller device over the SPI bus. |
29 | 58 | ||
@@ -43,6 +72,7 @@ spi0:spi@20BF0000 { | |||
43 | compatible = "st,m25p32"; | 72 | compatible = "st,m25p32"; |
44 | spi-max-frequency = <25000000>; | 73 | spi-max-frequency = <25000000>; |
45 | reg = <0>; | 74 | reg = <0>; |
75 | ti,spi-wdelay = <8>; | ||
46 | 76 | ||
47 | partition@0 { | 77 | partition@0 { |
48 | label = "u-boot-spl"; | 78 | label = "u-boot-spl"; |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 84a9fb1ab984..25886d8a84ba 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -65,6 +65,7 @@ | |||
65 | 65 | ||
66 | /* SPIDAT1 (upper 16 bit defines) */ | 66 | /* SPIDAT1 (upper 16 bit defines) */ |
67 | #define SPIDAT1_CSHOLD_MASK BIT(12) | 67 | #define SPIDAT1_CSHOLD_MASK BIT(12) |
68 | #define SPIDAT1_WDEL BIT(10) | ||
68 | 69 | ||
69 | /* SPIGCR1 */ | 70 | /* SPIGCR1 */ |
70 | #define SPIGCR1_CLKMOD_MASK BIT(1) | 71 | #define SPIGCR1_CLKMOD_MASK BIT(1) |
@@ -209,6 +210,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
209 | { | 210 | { |
210 | struct davinci_spi *dspi; | 211 | struct davinci_spi *dspi; |
211 | struct davinci_spi_platform_data *pdata; | 212 | struct davinci_spi_platform_data *pdata; |
213 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
212 | u8 chip_sel = spi->chip_select; | 214 | u8 chip_sel = spi->chip_select; |
213 | u16 spidat1 = CS_DEFAULT; | 215 | u16 spidat1 = CS_DEFAULT; |
214 | bool gpio_chipsel = false; | 216 | bool gpio_chipsel = false; |
@@ -223,6 +225,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
223 | gpio = spi->cs_gpio; | 225 | gpio = spi->cs_gpio; |
224 | } | 226 | } |
225 | 227 | ||
228 | /* program delay transfers if tx_delay is non zero */ | ||
229 | if (spicfg->wdelay) | ||
230 | spidat1 |= SPIDAT1_WDEL; | ||
231 | |||
226 | /* | 232 | /* |
227 | * Board specific chip select logic decides the polarity and cs | 233 | * Board specific chip select logic decides the polarity and cs |
228 | * line for the controller | 234 | * line for the controller |
@@ -237,9 +243,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) | |||
237 | spidat1 |= SPIDAT1_CSHOLD_MASK; | 243 | spidat1 |= SPIDAT1_CSHOLD_MASK; |
238 | spidat1 &= ~(0x1 << chip_sel); | 244 | spidat1 &= ~(0x1 << chip_sel); |
239 | } | 245 | } |
240 | |||
241 | iowrite16(spidat1, dspi->base + SPIDAT1 + 2); | ||
242 | } | 246 | } |
247 | |||
248 | iowrite16(spidat1, dspi->base + SPIDAT1 + 2); | ||
243 | } | 249 | } |
244 | 250 | ||
245 | /** | 251 | /** |
@@ -285,7 +291,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
285 | int prescale; | 291 | int prescale; |
286 | 292 | ||
287 | dspi = spi_master_get_devdata(spi->master); | 293 | dspi = spi_master_get_devdata(spi->master); |
288 | spicfg = (struct davinci_spi_config *)spi->controller_data; | 294 | spicfg = spi->controller_data; |
289 | if (!spicfg) | 295 | if (!spicfg) |
290 | spicfg = &davinci_spi_default_cfg; | 296 | spicfg = &davinci_spi_default_cfg; |
291 | 297 | ||
@@ -333,6 +339,14 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
333 | spifmt |= SPIFMT_PHASE_MASK; | 339 | spifmt |= SPIFMT_PHASE_MASK; |
334 | 340 | ||
335 | /* | 341 | /* |
342 | * Assume wdelay is used only on SPI peripherals that has this field | ||
343 | * in SPIFMTn register and when it's configured from board file or DT. | ||
344 | */ | ||
345 | if (spicfg->wdelay) | ||
346 | spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT) | ||
347 | & SPIFMT_WDELAY_MASK); | ||
348 | |||
349 | /* | ||
336 | * Version 1 hardware supports two basic SPI modes: | 350 | * Version 1 hardware supports two basic SPI modes: |
337 | * - Standard SPI mode uses 4 pins, with chipselect | 351 | * - Standard SPI mode uses 4 pins, with chipselect |
338 | * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) | 352 | * - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) |
@@ -349,9 +363,6 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
349 | 363 | ||
350 | u32 delay = 0; | 364 | u32 delay = 0; |
351 | 365 | ||
352 | spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT) | ||
353 | & SPIFMT_WDELAY_MASK); | ||
354 | |||
355 | if (spicfg->odd_parity) | 366 | if (spicfg->odd_parity) |
356 | spifmt |= SPIFMT_ODD_PARITY_MASK; | 367 | spifmt |= SPIFMT_ODD_PARITY_MASK; |
357 | 368 | ||
@@ -383,6 +394,26 @@ static int davinci_spi_setup_transfer(struct spi_device *spi, | |||
383 | return 0; | 394 | return 0; |
384 | } | 395 | } |
385 | 396 | ||
397 | static int davinci_spi_of_setup(struct spi_device *spi) | ||
398 | { | ||
399 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
400 | struct device_node *np = spi->dev.of_node; | ||
401 | u32 prop; | ||
402 | |||
403 | if (spicfg == NULL && np) { | ||
404 | spicfg = kzalloc(sizeof(*spicfg), GFP_KERNEL); | ||
405 | if (!spicfg) | ||
406 | return -ENOMEM; | ||
407 | *spicfg = davinci_spi_default_cfg; | ||
408 | /* override with dt configured values */ | ||
409 | if (!of_property_read_u32(np, "ti,spi-wdelay", &prop)) | ||
410 | spicfg->wdelay = (u8)prop; | ||
411 | spi->controller_data = spicfg; | ||
412 | } | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
386 | /** | 417 | /** |
387 | * davinci_spi_setup - This functions will set default transfer method | 418 | * davinci_spi_setup - This functions will set default transfer method |
388 | * @spi: spi device on which data transfer to be done | 419 | * @spi: spi device on which data transfer to be done |
@@ -433,7 +464,16 @@ static int davinci_spi_setup(struct spi_device *spi) | |||
433 | else | 464 | else |
434 | clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK); | 465 | clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK); |
435 | 466 | ||
436 | return retval; | 467 | return davinci_spi_of_setup(spi); |
468 | } | ||
469 | |||
470 | static void davinci_spi_cleanup(struct spi_device *spi) | ||
471 | { | ||
472 | struct davinci_spi_config *spicfg = spi->controller_data; | ||
473 | |||
474 | spi->controller_data = NULL; | ||
475 | if (spi->dev.of_node) | ||
476 | kfree(spicfg); | ||
437 | } | 477 | } |
438 | 478 | ||
439 | static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) | 479 | static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) |
@@ -947,6 +987,7 @@ static int davinci_spi_probe(struct platform_device *pdev) | |||
947 | master->num_chipselect = pdata->num_chipselect; | 987 | master->num_chipselect = pdata->num_chipselect; |
948 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); | 988 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); |
949 | master->setup = davinci_spi_setup; | 989 | master->setup = davinci_spi_setup; |
990 | master->cleanup = davinci_spi_cleanup; | ||
950 | 991 | ||
951 | dspi->bitbang.chipselect = davinci_spi_chipselect; | 992 | dspi->bitbang.chipselect = davinci_spi_chipselect; |
952 | dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; | 993 | dspi->bitbang.setup_transfer = davinci_spi_setup_transfer; |