Commit 0efc02499f9131bd7e1689ebb8d626ef12387de4
1 parent
7b3efc6699
Exists in
master
and in
50 other branches
spi_flash: Add spi_flash_probe_fdt() to locate SPI by FDT node
This allows us to put the SPI flash chip inside the SPI interface node, with U-Boot finding the correct bus and chip select automatically. Signed-off-by: Simon Glass <sjg@chromium.org>
Showing 7 changed files with 77 additions and 17 deletions Side-by-side Diff
drivers/misc/cros_ec_spi.c
... | ... | @@ -135,8 +135,7 @@ |
135 | 135 | */ |
136 | 136 | int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob) |
137 | 137 | { |
138 | - dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, | |
139 | - dev->cs, dev->max_frequency, 0); | |
138 | + dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, dev->node); | |
140 | 139 | if (!dev->spi) { |
141 | 140 | debug("%s: Could not setup SPI slave\n", __func__); |
142 | 141 | return -1; |
drivers/mtd/spi/sf_probe.c
... | ... | @@ -285,16 +285,13 @@ |
285 | 285 | } |
286 | 286 | #endif /* CONFIG_OF_CONTROL */ |
287 | 287 | |
288 | -struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, | |
289 | - unsigned int max_hz, unsigned int spi_mode) | |
288 | +static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi) | |
290 | 289 | { |
291 | - struct spi_slave *spi; | |
292 | 290 | struct spi_flash *flash = NULL; |
293 | 291 | u8 idcode[5]; |
294 | 292 | int ret; |
295 | 293 | |
296 | 294 | /* Setup spi_slave */ |
297 | - spi = spi_setup_slave(bus, cs, max_hz, spi_mode); | |
298 | 295 | if (!spi) { |
299 | 296 | printf("SF: Failed to set up slave\n"); |
300 | 297 | return NULL; |
... | ... | @@ -357,6 +354,26 @@ |
357 | 354 | spi_free_slave(spi); |
358 | 355 | return NULL; |
359 | 356 | } |
357 | + | |
358 | +struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, | |
359 | + unsigned int max_hz, unsigned int spi_mode) | |
360 | +{ | |
361 | + struct spi_slave *spi; | |
362 | + | |
363 | + spi = spi_setup_slave(bus, cs, max_hz, spi_mode); | |
364 | + return spi_flash_probe_slave(spi); | |
365 | +} | |
366 | + | |
367 | +#ifdef CONFIG_OF_SPI_FLASH | |
368 | +struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node, | |
369 | + int spi_node) | |
370 | +{ | |
371 | + struct spi_slave *spi; | |
372 | + | |
373 | + spi = spi_setup_slave_fdt(blob, slave_node, spi_node); | |
374 | + return spi_flash_probe_slave(spi); | |
375 | +} | |
376 | +#endif | |
360 | 377 | |
361 | 378 | void spi_flash_free(struct spi_flash *flash) |
362 | 379 | { |
drivers/spi/exynos_spi.c
... | ... | @@ -529,18 +529,18 @@ |
529 | 529 | * @param node SPI peripheral node to use |
530 | 530 | * @return 0 if ok, -1 on error |
531 | 531 | */ |
532 | -struct spi_slave *spi_setup_slave_fdt(const void *blob, int node, | |
533 | - unsigned int cs, unsigned int max_hz, unsigned int mode) | |
532 | +struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, | |
533 | + int spi_node) | |
534 | 534 | { |
535 | 535 | struct spi_bus *bus; |
536 | 536 | unsigned int i; |
537 | 537 | |
538 | 538 | for (i = 0, bus = spi_bus; i < bus_count; i++, bus++) { |
539 | - if (bus->node == node) | |
540 | - return spi_setup_slave(i, cs, max_hz, mode); | |
539 | + if (bus->node == spi_node) | |
540 | + return spi_base_setup_slave_fdt(blob, i, slave_node); | |
541 | 541 | } |
542 | 542 | |
543 | - debug("%s: Failed to find bus node %d\n", __func__, node); | |
543 | + debug("%s: Failed to find bus node %d\n", __func__, spi_node); | |
544 | 544 | return NULL; |
545 | 545 | } |
546 | 546 |
drivers/spi/spi.c
... | ... | @@ -5,6 +5,7 @@ |
5 | 5 | */ |
6 | 6 | |
7 | 7 | #include <common.h> |
8 | +#include <fdtdec.h> | |
8 | 9 | #include <malloc.h> |
9 | 10 | #include <spi.h> |
10 | 11 | |
... | ... | @@ -37,4 +38,22 @@ |
37 | 38 | |
38 | 39 | return ptr; |
39 | 40 | } |
41 | + | |
42 | +#ifdef CONFIG_OF_SPI | |
43 | +struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum, | |
44 | + int node) | |
45 | +{ | |
46 | + int cs, max_hz, mode = 0; | |
47 | + | |
48 | + cs = fdtdec_get_int(blob, node, "reg", -1); | |
49 | + max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000); | |
50 | + if (fdtdec_get_bool(blob, node, "spi-cpol")) | |
51 | + mode |= SPI_CPOL; | |
52 | + if (fdtdec_get_bool(blob, node, "spi-cpha")) | |
53 | + mode |= SPI_CPHA; | |
54 | + if (fdtdec_get_bool(blob, node, "spi-cs-high")) | |
55 | + mode |= SPI_CS_HIGH; | |
56 | + return spi_setup_slave(busnum, cs, max_hz, mode); | |
57 | +} | |
58 | +#endif |
include/configs/exynos5250-dt.h
include/spi.h
... | ... | @@ -259,14 +259,25 @@ |
259 | 259 | * spi_free_slave() to free it later. |
260 | 260 | * |
261 | 261 | * @param blob: Device tree blob |
262 | - * @param node: SPI peripheral node to use | |
263 | - * @param cs: Chip select to use | |
264 | - * @param max_hz: Maximum SCK rate in Hz (0 for default) | |
265 | - * @param mode: Clock polarity, clock phase and other parameters | |
262 | + * @param slave_node: Slave node to use | |
263 | + * @param spi_node: SPI peripheral node to use | |
266 | 264 | * @return pointer to new spi_slave structure |
267 | 265 | */ |
268 | -struct spi_slave *spi_setup_slave_fdt(const void *blob, int node, | |
269 | - unsigned int cs, unsigned int max_hz, unsigned int mode); | |
266 | +struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node, | |
267 | + int spi_node); | |
268 | + | |
269 | +/** | |
270 | + * spi_base_setup_slave_fdt() - helper function to set up a SPI slace | |
271 | + * | |
272 | + * This decodes SPI properties from the slave node to determine the | |
273 | + * chip select and SPI parameters. | |
274 | + * | |
275 | + * @blob: Device tree blob | |
276 | + * @busnum: Bus number to use | |
277 | + * @node: Device tree node for the SPI bus | |
278 | + */ | |
279 | +struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum, | |
280 | + int node); | |
270 | 281 | |
271 | 282 | #endif /* _SPI_H_ */ |
include/spi_flash.h
... | ... | @@ -67,6 +67,19 @@ |
67 | 67 | |
68 | 68 | struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, |
69 | 69 | unsigned int max_hz, unsigned int spi_mode); |
70 | + | |
71 | +/** | |
72 | + * Set up a new SPI flash from an fdt node | |
73 | + * | |
74 | + * @param blob Device tree blob | |
75 | + * @param slave_node Pointer to this SPI slave node in the device tree | |
76 | + * @param spi_node Cached pointer to the SPI interface this node belongs | |
77 | + * to | |
78 | + * @return 0 if ok, -1 on error | |
79 | + */ | |
80 | +struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node, | |
81 | + int spi_node); | |
82 | + | |
70 | 83 | void spi_flash_free(struct spi_flash *flash); |
71 | 84 | |
72 | 85 | static inline int spi_flash_read(struct spi_flash *flash, u32 offset, |
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f
-
mentioned in commit c5b88f