spi_flash: Add spi_flash_probe_fdt() to locate SPI by FDT node
authorSimon Glass <sjg@chromium.org>
Tue, 3 Dec 2013 23:43:24 +0000 (16:43 -0700)
committerSimon Glass <sjg@chromium.org>
Mon, 9 Dec 2013 19:22:12 +0000 (12:22 -0700)
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>
drivers/misc/cros_ec_spi.c
drivers/mtd/spi/sf_probe.c
drivers/spi/exynos_spi.c
drivers/spi/spi.c
include/configs/exynos5250-dt.h
include/spi.h
include/spi_flash.h

index 202acf2..2fc9110 100644 (file)
@@ -135,8 +135,7 @@ int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
  */
 int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)
 {
-       dev->spi = spi_setup_slave_fdt(blob, dev->parent_node,
-                                      dev->cs, dev->max_frequency, 0);
+       dev->spi = spi_setup_slave_fdt(blob, dev->parent_node, dev->node);
        if (!dev->spi) {
                debug("%s: Could not setup SPI slave\n", __func__);
                return -1;
index 5eb8ffe..ca12715 100644 (file)
@@ -285,16 +285,13 @@ int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
 }
 #endif /* CONFIG_OF_CONTROL */
 
-struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int spi_mode)
+static struct spi_flash *spi_flash_probe_slave(struct spi_slave *spi)
 {
-       struct spi_slave *spi;
        struct spi_flash *flash = NULL;
        u8 idcode[5];
        int ret;
 
        /* Setup spi_slave */
-       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
        if (!spi) {
                printf("SF: Failed to set up slave\n");
                return NULL;
@@ -358,6 +355,26 @@ err_claim_bus:
        return NULL;
 }
 
+struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
+               unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       return spi_flash_probe_slave(spi);
+}
+
+#ifdef CONFIG_OF_SPI_FLASH
+struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
+                                     int spi_node)
+{
+       struct spi_slave *spi;
+
+       spi = spi_setup_slave_fdt(blob, slave_node, spi_node);
+       return spi_flash_probe_slave(spi);
+}
+#endif
+
 void spi_flash_free(struct spi_flash *flash)
 {
        spi_free_slave(flash->spi);
index 699c57e..4d5def2 100644 (file)
@@ -529,18 +529,18 @@ static int process_nodes(const void *blob, int node_list[], int count)
  * @param node         SPI peripheral node to use
  * @return 0 if ok, -1 on error
  */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
-               unsigned int cs, unsigned int max_hz, unsigned int mode)
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+                                     int spi_node)
 {
        struct spi_bus *bus;
        unsigned int i;
 
        for (i = 0, bus = spi_bus; i < bus_count; i++, bus++) {
-               if (bus->node == node)
-                       return spi_setup_slave(i, cs, max_hz, mode);
+               if (bus->node == spi_node)
+                       return spi_base_setup_slave_fdt(blob, i, slave_node);
        }
 
-       debug("%s: Failed to find bus node %d\n", __func__, node);
+       debug("%s: Failed to find bus node %d\n", __func__, spi_node);
        return NULL;
 }
 
index b76a26c..7ddea9b 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <common.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <spi.h>
 
@@ -37,3 +38,21 @@ void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
 
        return ptr;
 }
+
+#ifdef CONFIG_OF_SPI
+struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
+                                          int node)
+{
+       int cs, max_hz, mode = 0;
+
+       cs = fdtdec_get_int(blob, node, "reg", -1);
+       max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 100000);
+       if (fdtdec_get_bool(blob, node, "spi-cpol"))
+               mode |= SPI_CPOL;
+       if (fdtdec_get_bool(blob, node, "spi-cpha"))
+               mode |= SPI_CPHA;
+       if (fdtdec_get_bool(blob, node, "spi-cs-high"))
+               mode |= SPI_CS_HIGH;
+       return spi_setup_slave(busnum, cs, max_hz, mode);
+}
+#endif
index bdefee1..74ba2b6 100644 (file)
 #define CONFIG_SF_DEFAULT_MODE         SPI_MODE_0
 #define CONFIG_SF_DEFAULT_SPEED                50000000
 #define EXYNOS5_SPI_NUM_CONTROLLERS    5
+#define CONFIG_OF_SPI
 #endif
 
 #ifdef CONFIG_ENV_IS_IN_SPI_FLASH
index e2563c9..aba7922 100644 (file)
@@ -259,13 +259,24 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte)
  * spi_free_slave() to free it later.
  *
  * @param blob:                Device tree blob
- * @param node:                SPI peripheral node to use
- * @param cs:          Chip select to use
- * @param max_hz:      Maximum SCK rate in Hz (0 for default)
- * @param mode:                Clock polarity, clock phase and other parameters
+ * @param slave_node:  Slave node to use
+ * @param spi_node:    SPI peripheral node to use
  * @return pointer to new spi_slave structure
  */
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
-               unsigned int cs, unsigned int max_hz, unsigned int mode);
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+                                     int spi_node);
+
+/**
+ * spi_base_setup_slave_fdt() - helper function to set up a SPI slace
+ *
+ * This decodes SPI properties from the slave node to determine the
+ * chip select and SPI parameters.
+ *
+ * @blob:      Device tree blob
+ * @busnum:    Bus number to use
+ * @node:      Device tree node for the SPI bus
+ */
+struct spi_slave *spi_base_setup_slave_fdt(const void *blob, int busnum,
+                                          int node);
 
 #endif /* _SPI_H_ */
index 25ca8f1..afc3a58 100644 (file)
@@ -67,6 +67,19 @@ struct spi_flash {
 
 struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
                unsigned int max_hz, unsigned int spi_mode);
+
+/**
+ * Set up a new SPI flash from an fdt node
+ *
+ * @param blob         Device tree blob
+ * @param slave_node   Pointer to this SPI slave node in the device tree
+ * @param spi_node     Cached pointer to the SPI interface this node belongs
+ *                     to
+ * @return 0 if ok, -1 on error
+ */
+struct spi_flash *spi_flash_probe_fdt(const void *blob, int slave_node,
+                                     int spi_node);
+
 void spi_flash_free(struct spi_flash *flash);
 
 static inline int spi_flash_read(struct spi_flash *flash, u32 offset,