From patchwork Tue Sep 18 18:21:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 1474141 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id BAA6A3FCFC for ; Tue, 18 Sep 2012 18:27:05 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TE2Th-0007Qr-KT; Tue, 18 Sep 2012 18:24:57 +0000 Received: from mail-vc0-f201.google.com ([209.85.220.201]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TE2TL-0007K3-Oj for linux-arm-kernel@lists.infradead.org; Tue, 18 Sep 2012 18:24:36 +0000 Received: by vchn11 with SMTP id n11so19257vch.0 for ; Tue, 18 Sep 2012 11:24:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=tw2qi7fLbjMvAs5GgjNGEYEZFf0/TUFIUQUKY1WS5K8=; b=YE2TghfyZ+LF/2/jFZ7SdLvhz61Ewq77gqy7u1avvjvvOniq81pCxX4lSxkb5H/S1X DaDPBVA5sZg+mVfvfdzj4utAztclMXABoweND3OY/Joc0Rati54YuIrH1AcMf0xGuesQ sHyDWqaMfLE/0zcVrRv+66qboh6wJpP22uG8xrghcDCa05TDr4H1FdCPN0/cfcBZeali Dbi1anM0Xiufem/5vDmAKJCPREZ1cJ1UXEwIGM58PTgFMzZSho5T1e79d4xi0TS58z9p 3uWJ0+Klqs7xaLnHoz1T0gSd7qARYtpdPxpjf1VS5Nthf92aEwyVYGiBFWdnSRQeIDVW ZXnw== Received: by 10.236.133.242 with SMTP id q78mr483721yhi.11.1347992673760; Tue, 18 Sep 2012 11:24:33 -0700 (PDT) Received: by 10.236.133.242 with SMTP id q78mr483706yhi.11.1347992673685; Tue, 18 Sep 2012 11:24:33 -0700 (PDT) Received: from wpzn3.hot.corp.google.com (216-239-44-65.google.com [216.239.44.65]) by gmr-mx.google.com with ESMTPS id n2si32928anp.3.2012.09.18.11.24.33 (version=TLSv1/SSLv3 cipher=AES128-SHA); Tue, 18 Sep 2012 11:24:33 -0700 (PDT) Received: from kaka.mtv.corp.google.com (kaka.mtv.corp.google.com [172.22.73.79]) by wpzn3.hot.corp.google.com (Postfix) with ESMTP id 71D01100047; Tue, 18 Sep 2012 11:24:33 -0700 (PDT) Received: by kaka.mtv.corp.google.com (Postfix, from userid 121222) id 2043B16214A; Tue, 18 Sep 2012 11:24:33 -0700 (PDT) From: Simon Glass To: LKML , linux-arm-kernel@lists.infradead.org Subject: [PATCH 6/7] spi: s3c64xx: Tidy up SPI chip select handling Date: Tue, 18 Sep 2012 11:21:58 -0700 Message-Id: <1347992519-6904-7-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.7.3 In-Reply-To: <1347992519-6904-1-git-send-email-sjg@chromium.org> References: <1347992519-6904-1-git-send-email-sjg@chromium.org> X-Gm-Message-State: ALoCoQkhSTbnuP3B2f1meYEdCBLk1nRkZt6fwEAbxMZ/T2ARPZv1saCdyJ4VYTELMLBpE//bVpkjuNCQLooREetdNgtcdu/sFFByzZedELJQL6E9y4ah0Prk+zzvtZd8ubQEhdmzCthrmPiwvb0VE2GJ2H8MAZCRqF3hBbhnAcnuSt6Iq1kfWOz/eC/+6D+FkMZS2wRN39hXjQU26xWHh7f7ckB45oHCLw== X-Spam-Note: CRM114 invocation failed X-Spam-Score: -3.1 (---) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-3.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.220.201 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Simon Glass , "kgene.kim" , Ben Dooks , Srinivas KANDAGATLA X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org While it is possible to use a GPIO, it is useful to be able to use the SPI peripheral's built-in chip select feature. This should be supported. The current driver is broken in that it doesn't properly support the cs_change property in the message. To fix this, the chip select should be changed in one place (enable/disable_cs()) instead of using the macro separately in a different place. Also we need to make sure that the FIFOs are cleared even in the event of an empty transaction or error. (This adds a proposed new fdt binding for Samsung SPI) Signed-off-by: Simon Glass --- .../devicetree/bindings/spi/spi-samsung.txt | 7 ++++ arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | 6 ++- drivers/spi/spi-s3c64xx.c | 34 +++++++++++++------ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt index 59bfc4f..74d67e1 100644 --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt +++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt @@ -60,6 +60,13 @@ SPI Controller specific data in SPI slave nodes: - 2: 180 degree phase shift sampling. - 3: 270 degree phase shift sampling. +- The spi slave nodes may provide the following optional properties: + + - samsung,spi-cs: (boolean property). If present, uses the SPI controller's + built-in chip select feature, rather than toggling GPIOs manually. The + correct chip select line must still be specified in cs-gpio, and in this + case should be assigned to the SPI controller. + Aliases: - All the SPI controller nodes should be represented in the aliases node using diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index ceba18d..7103f71 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h @@ -17,7 +17,8 @@ struct platform_device; * struct s3c64xx_spi_csinfo - ChipSelect description * @fb_delay: Slave specific feedback delay. * Refer to FB_CLK_SEL register definition in SPI chapter. - * @line: Custom 'identity' of the CS line. + * @line: Custom 'identity' of the CS line (-1 to use SPI controller) + * @use_spi_cs: Use SPI's chip select toggle instead of GPIO * * This is per SPI-Slave Chipselect information. * Allocate and initialize one in machine init code and make the @@ -25,7 +26,8 @@ struct platform_device; */ struct s3c64xx_spi_csinfo { u8 fb_delay; - unsigned line; + int line; + bool only_spi_cs; }; /** diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index ed12872..c34ef8f 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -414,14 +414,21 @@ static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ /* Deselect the last toggled device */ cs = sdd->tgl_spi->controller_data; - gpio_set_value(cs->line, - spi->mode & SPI_CS_HIGH ? 0 : 1); + writel(S3C64XX_SPI_SLAVE_SIG_INACT, + sdd->regs + S3C64XX_SPI_SLAVE_SEL); + if (!cs->only_spi_cs) { + gpio_set_value(cs->line, + spi->mode & SPI_CS_HIGH ? 0 : 1); + } } sdd->tgl_spi = NULL; } + /* Start the signals */ cs = spi->controller_data; - gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); + if (!cs->only_spi_cs) + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 1 : 0); + writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); } static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, @@ -514,7 +521,10 @@ static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, if (sdd->tgl_spi == spi) sdd->tgl_spi = NULL; - gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); + /* Quiese the signals */ + writel(S3C64XX_SPI_SLAVE_SIG_INACT, sdd->regs + S3C64XX_SPI_SLAVE_SEL); + if (!cs->only_spi_cs) + gpio_set_value(cs->line, spi->mode & SPI_CS_HIGH ? 0 : 1); } static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) @@ -746,17 +756,10 @@ static int s3c64xx_spi_transfer_one_message(struct spi_master *master, /* Slave Select */ enable_cs(sdd, spi); - /* Start the signals */ - writel(0, sdd->regs + S3C64XX_SPI_SLAVE_SEL); - spin_unlock_irqrestore(&sdd->lock, flags); status = wait_for_xfer(sdd, xfer, use_dma); - /* Quiese the signals */ - writel(S3C64XX_SPI_SLAVE_SIG_INACT, - sdd->regs + S3C64XX_SPI_SLAVE_SEL); - if (status) { dev_err(&spi->dev, "I/O Error: " "rx-%d tx-%d res:rx-%c tx-%c len-%d\n", @@ -801,6 +804,9 @@ out: else sdd->tgl_spi = spi; + /* Make sure empty transactions and error clean up the state */ + flush_fifo(sdd); + if (have_dma) s3c64xx_spi_unmap_mssg(sdd, msg); out_nomap: @@ -878,6 +884,12 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( return ERR_PTR(-EINVAL); } + /* + * Rather than manually toggle GPIOs, we can use the SPI chip select + * feature. + */ + cs->only_spi_cs = of_property_read_bool(data_np, "samsung,spi-cs"); + of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay); cs->fb_delay = fb_delay; return cs;