From patchwork Tue Oct 14 05:41:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 399360 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id B948D140085 for ; Tue, 14 Oct 2014 16:51:48 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C01D0A73FA; Tue, 14 Oct 2014 07:51:33 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PaXqei8bxGsN; Tue, 14 Oct 2014 07:51:33 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C524FA7691; Tue, 14 Oct 2014 07:51:21 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8F999A7480 for ; Tue, 14 Oct 2014 07:50:57 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id OFAZF+imPHsl for ; Tue, 14 Oct 2014 07:50:57 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ig0-f202.google.com (mail-ig0-f202.google.com [209.85.213.202]) by theia.denx.de (Postfix) with ESMTPS id 05824A74C3 for ; Tue, 14 Oct 2014 07:50:53 +0200 (CEST) Received: by mail-ig0-f202.google.com with SMTP id r10so2114985igi.5 for ; Mon, 13 Oct 2014 22:50:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=qYrD+1jaSyARNNocP5Qif4rC8X2xbuZ9QzNfS9cR1UQ=; b=m2YWr9k2gg9WbWQ4wfnUizO/cSNVqAJzzUH9E1m4i3zw030CXQAlMAVD0Zq++t0aa3 zX9BVFrXHxH3z61ZZt46HcpmIOxKlU3wxN9cTxGOoglcLYfroQSgU5nDTHnG02L9PjT9 DT2qH08zjAhmY9OAcdt++OZIJWsd7G3ZV44AhD8N44RdGEJnu9q2dmYyPASCA4CM0q3m rwl0dMKmQxj3BEZ4Fy8rTFzMk/w0Pc6u6GY/BByOXOz81KLOEySkfAdml2C70ZKvfzA6 HPiYVRJsKr6XWBBWIl+8iQ/54BA4FK0JrzfzUmWPh86c/sC8hBIi2uw96TaS0YbQmS39 3UGg== X-Gm-Message-State: ALoCoQl5FTArwwC5m8G97rZ/EU/z8iczabCNhL1N8hU1MtLJZqay4dEYVs8ayItcULLrV3lhWMpU X-Received: by 10.182.49.198 with SMTP id w6mr2362442obn.20.1413265852189; Mon, 13 Oct 2014 22:50:52 -0700 (PDT) Received: from corpmail-nozzle1-2.hot.corp.google.com ([100.108.1.103]) by gmr-mx.google.com with ESMTPS id l45si808755yha.2.2014.10.13.22.50.51 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Oct 2014 22:50:52 -0700 (PDT) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-2.hot.corp.google.com with ESMTP id SkQlDIpG.1; Mon, 13 Oct 2014 22:50:52 -0700 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 342C12217A8; Mon, 13 Oct 2014 23:43:12 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 13 Oct 2014 23:41:57 -0600 Message-Id: <1413265336-9571-11-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1413265336-9571-1-git-send-email-sjg@chromium.org> References: <1413265336-9571-1-git-send-email-sjg@chromium.org> Cc: u-boot-review@google.com, Jagannadha Sutradharudu Teki Subject: [U-Boot] [PATCH v4 10/29] dm: sandbox: spi: Move to driver model X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Adjust the sandbox SPI driver to support driver model and move sandbox over to driver model for SPI. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- Changes in v4: None Changes in v3: - Add implementation/comment for the cs_info() method - Remove the child_pre_probe() method which is no longer needed Changes in v2: - Correct sandbox's xfer() method signature - Use 'bus' instead of 'dev' to make the API clearer arch/sandbox/include/asm/state.h | 1 + drivers/spi/sandbox_spi.c | 200 +++++++++++++++------------------------ include/configs/sandbox.h | 3 +- 3 files changed, 76 insertions(+), 128 deletions(-) diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index d17a82e..4e0981a 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -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 */ diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 12e9bda..e717424 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -9,26 +9,23 @@ */ #include +#include #include #include +#include #include #include #include #include +#include + +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, +}; diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 6972643..c80e4f0 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -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