dm: sandbox: spi: Move to driver model
authorSimon Glass <sjg@chromium.org>
Tue, 14 Oct 2014 05:41:57 +0000 (23:41 -0600)
committerSimon Glass <sjg@chromium.org>
Wed, 22 Oct 2014 16:36:48 +0000 (10:36 -0600)
Adjust the sandbox SPI driver to support driver model and move sandbox over
to driver model for SPI.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
arch/sandbox/include/asm/state.h
drivers/spi/sandbox_spi.c
include/configs/sandbox.h

index d17a82e..4e0981a 100644 (file)
@@ -43,6 +43,7 @@ enum state_terminal_raw {
 struct sandbox_spi_info {
        const char *spec;
        const struct sandbox_spi_emu_ops *ops;
+       struct udevice *emul;
 };
 
 /* The complete state of the test system */
index 12e9bda..e717424 100644 (file)
@@ -9,26 +9,23 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <malloc.h>
 #include <spi.h>
+#include <spi_flash.h>
 #include <os.h>
 
 #include <asm/errno.h>
 #include <asm/spi.h>
 #include <asm/state.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 #ifndef CONFIG_SPI_IDLE_VAL
 # define CONFIG_SPI_IDLE_VAL 0xFF
 #endif
 
-struct sandbox_spi_slave {
-       struct spi_slave slave;
-       const struct sandbox_spi_emu_ops *ops;
-       void *priv;
-};
-
-#define to_sandbox_spi_slave(s) container_of(s, struct sandbox_spi_slave, slave)
-
 const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
                                   unsigned long *cs)
 {
@@ -45,120 +42,52 @@ const char *sandbox_spi_parse_spec(const char *arg, unsigned long *bus,
        return endp + 1;
 }
 
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
-       return bus < CONFIG_SANDBOX_SPI_MAX_BUS &&
-               cs < CONFIG_SANDBOX_SPI_MAX_CS;
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: activating CS\n");
-       if (sss->ops->cs_activate)
-               sss->ops->cs_activate(sss->priv);
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: deactivating CS\n");
-       if (sss->ops->cs_deactivate)
-               sss->ops->cs_deactivate(sss->priv);
-}
-
-void spi_init(void)
-{
-}
-
-void spi_set_speed(struct spi_slave *slave, uint hz)
+__weak int sandbox_spi_get_emul(struct sandbox_state *state,
+                               struct udevice *bus, struct udevice *slave,
+                               struct udevice **emulp)
 {
+       return -ENOENT;
 }
 
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
-               unsigned int max_hz, unsigned int mode)
+static int sandbox_spi_xfer(struct udevice *slave, unsigned int bitlen,
+                           const void *dout, void *din, unsigned long flags)
 {
-       struct sandbox_spi_slave *sss;
+       struct udevice *bus = slave->parent;
        struct sandbox_state *state = state_get_current();
-       const char *spec;
-
-       if (!spi_cs_is_valid(bus, cs)) {
-               debug("sandbox_spi: Invalid SPI bus/cs\n");
-               return NULL;
-       }
-
-       sss = spi_alloc_slave(struct sandbox_spi_slave, bus, cs);
-       if (!sss) {
-               debug("sandbox_spi: Out of memory\n");
-               return NULL;
-       }
-
-       spec = state->spi[bus][cs].spec;
-       sss->ops = state->spi[bus][cs].ops;
-       if (!spec || !sss->ops || sss->ops->setup(&sss->priv, spec)) {
-               free(sss);
-               printf("sandbox_spi: unable to locate a slave client\n");
-               return NULL;
-       }
-
-       return &sss->slave;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
-
-       debug("sandbox_spi: releasing slave\n");
-
-       if (sss->ops->free)
-               sss->ops->free(sss->priv);
-
-       free(sss);
-}
-
-static int spi_bus_claim_cnt[CONFIG_SANDBOX_SPI_MAX_BUS];
-
-int spi_claim_bus(struct spi_slave *slave)
-{
-       if (spi_bus_claim_cnt[slave->bus]++) {
-               printf("sandbox_spi: error: bus already claimed: %d!\n",
-                      spi_bus_claim_cnt[slave->bus]);
-       }
-
-       return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
-       if (--spi_bus_claim_cnt[slave->bus]) {
-               printf("sandbox_spi: error: bus freed too often: %d!\n",
-                      spi_bus_claim_cnt[slave->bus]);
-       }
-}
-
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
-               void *din, unsigned long flags)
-{
-       struct sandbox_spi_slave *sss = to_sandbox_spi_slave(slave);
+       struct dm_spi_emul_ops *ops;
+       struct udevice *emul;
        uint bytes = bitlen / 8, i;
-       int ret = 0;
+       int ret;
        u8 *tx = (void *)dout, *rx = din;
+       uint busnum, cs;
 
        if (bitlen == 0)
-               goto done;
+               return 0;
 
        /* we can only do 8 bit transfers */
        if (bitlen % 8) {
                printf("sandbox_spi: xfer: invalid bitlen size %u; needs to be 8bit\n",
                       bitlen);
-               flags |= SPI_XFER_END;
-               goto done;
+               return -EINVAL;
        }
 
-       if (flags & SPI_XFER_BEGIN)
-               spi_cs_activate(slave);
+       busnum = bus->seq;
+       cs = spi_chip_select(slave);
+       if (busnum >= CONFIG_SANDBOX_SPI_MAX_BUS ||
+           cs >= CONFIG_SANDBOX_SPI_MAX_CS) {
+               printf("%s: busnum=%u, cs=%u: out of range\n", __func__,
+                      busnum, cs);
+               return -ENOENT;
+       }
+       ret = sandbox_spi_get_emul(state, bus, slave, &emul);
+       if (ret) {
+               printf("%s: busnum=%u, cs=%u: no emulation available (err=%d)\n",
+                      __func__, busnum, cs, ret);
+               return -ENOENT;
+       }
+       ret = device_probe(emul);
+       if (ret)
+               return ret;
 
        /* make sure rx/tx buffers are full so clients can assume */
        if (!tx) {
@@ -178,12 +107,8 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
                }
        }
 
-       debug("sandbox_spi: xfer: bytes = %u\n tx:", bytes);
-       for (i = 0; i < bytes; ++i)
-               debug(" %u:%02x", i, tx[i]);
-       debug("\n");
-
-       ret = sss->ops->xfer(sss->priv, tx, rx, bytes);
+       ops = spi_emul_get_ops(emul);
+       ret = ops->xfer(emul, bitlen, dout, din, flags);
 
        debug("sandbox_spi: xfer: got back %i (that's %s)\n rx:",
              ret, ret ? "bad" : "good");
@@ -196,22 +121,45 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
        if (rx != din)
                free(rx);
 
- done:
-       if (flags & SPI_XFER_END)
-               spi_cs_deactivate(slave);
-
        return ret;
 }
 
-/**
- * Set up a new SPI slave for an fdt node
- *
- * @param blob         Device tree blob
- * @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 slave_node,
-                                     int spi_node)
+static int sandbox_spi_set_speed(struct udevice *bus, uint speed)
+{
+       return 0;
+}
+
+static int sandbox_spi_set_mode(struct udevice *bus, uint mode)
+{
+       return 0;
+}
+
+static int sandbox_cs_info(struct udevice *bus, uint cs,
+                          struct spi_cs_info *info)
 {
-       return NULL;
+       /* Always allow activity on CS 0 */
+       if (cs >= 1)
+               return -ENODEV;
+
+       return 0;
 }
+
+static const struct dm_spi_ops sandbox_spi_ops = {
+       .xfer           = sandbox_spi_xfer,
+       .set_speed      = sandbox_spi_set_speed,
+       .set_mode       = sandbox_spi_set_mode,
+       .cs_info        = sandbox_cs_info,
+};
+
+static const struct udevice_id sandbox_spi_ids[] = {
+       { .compatible = "sandbox,spi" },
+       { }
+};
+
+U_BOOT_DRIVER(spi_sandbox) = {
+       .name   = "spi_sandbox",
+       .id     = UCLASS_SPI,
+       .of_match = sandbox_spi_ids,
+       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+       .ops    = &sandbox_spi_ops,
+};
index 022629f..8b74f49 100644 (file)
@@ -97,8 +97,7 @@
 #define CONFIG_CMD_SF_TEST
 #define CONFIG_CMD_SPI
 #define CONFIG_SPI_FLASH
-#define CONFIG_OF_SPI
-#define CONFIG_OF_SPI_FLASH
+#define CONFIG_DM_SPI
 #define CONFIG_SPI_FLASH_ATMEL
 #define CONFIG_SPI_FLASH_EON
 #define CONFIG_SPI_FLASH_GIGADEVICE