From patchwork Thu Oct 8 14:16:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mingyu Li X-Patchwork-Id: 527738 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 377E5140D93 for ; Fri, 9 Oct 2015 01:23:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=HOrfh6Zu; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 1764328C746; Thu, 8 Oct 2015 16:17:32 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 3D4BD28C746 for ; Thu, 8 Oct 2015 16:15:27 +0200 (CEST) X-policyd-weight: using cached result; rate: -8.5 Received: from mail-pa0-f51.google.com (mail-pa0-f51.google.com [209.85.220.51]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Thu, 8 Oct 2015 16:14:57 +0200 (CEST) Received: by pacex6 with SMTP id ex6so56479956pac.0 for ; Thu, 08 Oct 2015 07:16:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=B9B4lvXxsITHfjeRsXooIqJa7eKT3xjsCy7M5dEUl8w=; b=HOrfh6ZucEslW6bTuEmrLrfHSlNksN9EZeueZUPLcXL9760T9fk976+Wei/unY+zac xeG+16E68rK8lzkEHPF3KFtHWiZaWqUyqoNLwuxqA+X2ZSNvG31gPAdp3kT6FqrbIXAq wmJy/Y3rHDGw9McFCj3lfGK1CPEUf6eB5jLOpLmGvpukJctPRIn+CpChZi7lj+BXdJcc wwxtLzF0W0/PxPFu+vlipKQR3VY6lxEivD/pD1h/iJ7LcIa8A+fJ0vnwqDTRnjLlGNf0 yu3VLQRYIr52geZRQy2jHxPlKc4qz1BSYSL52NfAyFWtYlYry9bfUp4lpt5yidIT8ThS YyBg== X-Received: by 10.68.191.200 with SMTP id ha8mr8499929pbc.72.1444313783982; Thu, 08 Oct 2015 07:16:23 -0700 (PDT) Received: from localhost.localdomain (f45hc114.RAS.nctu.edu.tw. [140.113.45.114]) by smtp.gmail.com with ESMTPSA id hq8sm46122436pad.35.2015.10.08.07.16.22 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 08 Oct 2015 07:16:23 -0700 (PDT) From: Michael Lee To: blogic@openwrt.org Date: Thu, 8 Oct 2015 22:16:07 +0800 Message-Id: <1444313768-23970-7-git-send-email-igvtee@gmail.com> X-Mailer: git-send-email 2.3.6 In-Reply-To: <1444313768-23970-1-git-send-email-igvtee@gmail.com> References: <1444313768-23970-1-git-send-email-igvtee@gmail.com> Cc: openwrt-devel@lists.openwrt.org Subject: [OpenWrt-Devel] [PATCH 7/8] ramips: use transfer_one instead of transfer_one_message on rt2880 spi X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" * use kernel buildin transfer_one_message. we only need to implement transfer_one and set_cs function * should support use gpio as cs pin * deselected the spi device when setup and add debug info * only reset device when first driver probe Signed-off-by: Michael Lee --- ...0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch | 127 ++++++++++----------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch b/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch index 862e24c..57986d3 100644 --- a/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch +++ b/target/linux/ramips/patches-3.18/0050-SPI-ralink-add-Ralink-SoC-spi-driver.patch @@ -41,7 +41,7 @@ Acked-by: John Crispin spi-s3c24xx-hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi-s3c24xx-fiq.o --- /dev/null +++ b/drivers/spi/spi-rt2880.c -@@ -0,0 +1,533 @@ +@@ -0,0 +1,530 @@ +/* + * spi-rt2880.c -- Ralink RT288x/RT305x SPI controller driver + * @@ -66,10 +66,9 @@ Acked-by: John Crispin +#include +#include +#include ++#include + +#define DRIVER_NAME "spi-rt2880" -+/* only one slave is supported*/ -+#define RALINK_NUM_CHIPSELECTS 1 + +#define RAMIPS_SPI_STAT 0x00 +#define RAMIPS_SPI_CFG 0x10 @@ -169,6 +168,8 @@ Acked-by: John Crispin +#define RT2880_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | \ + SPI_CS_HIGH) + ++static atomic_t hw_reset_count = ATOMIC_INIT(0); ++ +struct rt2880_spi { + struct spi_master *master; + void __iomem *base; @@ -248,12 +249,14 @@ Acked-by: John Crispin + return offset; +} + -+static void rt2880_spi_set_cs(struct rt2880_spi *rs, int enable) ++static void rt2880_spi_set_cs(struct spi_device *spi, bool enable) +{ ++ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); ++ + if (enable) -+ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); -+ else + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); ++ else ++ rt2880_spi_clrbits(rs, RAMIPS_SPI_CTL, SPICTL_SPIENA); +} + +static int rt2880_spi_wait_ready(struct rt2880_spi *rs, int len) @@ -269,22 +272,41 @@ Acked-by: John Crispin + return -ETIMEDOUT; +} + -+static unsigned int -+rt2880_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) ++static void rt2880_dump_reg(struct spi_master *master) +{ -+ struct rt2880_spi *rs = spidev_to_rt2880_spi(spi); -+ unsigned count = 0; -+ u8 *rx = xfer->rx_buf; -+ const u8 *tx = xfer->tx_buf; -+ int err; ++ struct rt2880_spi *rs = spi_master_get_devdata(master); + -+ dev_dbg(&spi->dev, "read (%d): %s %s\n", xfer->len, -+ (tx != NULL) ? "tx" : " ", -+ (rx != NULL) ? "rx" : " "); ++ dev_dbg(&master->dev, "stat: %08x, cfg: %08x, ctl: %08x, " \ ++ "data: %08x, arb: %08x\n", ++ rt2880_spi_read(rs, RAMIPS_SPI_STAT), ++ rt2880_spi_read(rs, RAMIPS_SPI_CFG), ++ rt2880_spi_read(rs, RAMIPS_SPI_CTL), ++ rt2880_spi_read(rs, RAMIPS_SPI_DATA), ++ rt2880_spi_read(rs, get_arbiter_offset(master))); ++} ++ ++static int rt2880_spi_transfer_one(struct spi_master *master, ++ struct spi_device *spi, struct spi_transfer *xfer) ++{ ++ struct rt2880_spi *rs = spi_master_get_devdata(master); ++ unsigned len; ++ const u8 *tx = xfer->tx_buf; ++ u8 *rx = xfer->rx_buf; ++ int err = 0; ++ ++ /* change clock speed */ ++ if (unlikely(rs->speed != xfer->speed_hz)) { ++ u32 reg; ++ reg = rt2880_spi_read(rs, RAMIPS_SPI_CFG); ++ reg &= ~SPICFG_SPICLK_PRESCALE_MASK; ++ reg |= rt2880_spi_baudrate_get(spi, xfer->speed_hz); ++ rt2880_spi_write(rs, RAMIPS_SPI_CFG, reg); ++ } + + if (tx) { -+ for (count = 0; count < xfer->len; count++) { -+ rt2880_spi_write(rs, RAMIPS_SPI_DATA, tx[count]); ++ len = xfer->len; ++ while (len-- > 0) { ++ rt2880_spi_write(rs, RAMIPS_SPI_DATA, *tx++); + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTWR); + err = rt2880_spi_wait_ready(rs, 1); + if (err) { @@ -295,63 +317,32 @@ Acked-by: John Crispin + } + + if (rx) { -+ for (count = 0; count < xfer->len; count++) { ++ len = xfer->len; ++ while (len-- > 0) { + rt2880_spi_setbits(rs, RAMIPS_SPI_CTL, SPICTL_STARTRD); + err = rt2880_spi_wait_ready(rs, 1); + if (err) { + dev_err(&spi->dev, "RX failed, err=%d\n", err); + goto out; + } -+ rx[count] = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA); ++ *rx++ = (u8) rt2880_spi_read(rs, RAMIPS_SPI_DATA); + } + } + +out: -+ return count; ++ return err; +} + -+static int rt2880_spi_transfer_one_message(struct spi_master *master, -+ struct spi_message *m) ++/* copy from spi.c */ ++static void spi_set_cs(struct spi_device *spi, bool enable) +{ -+ struct rt2880_spi *rs = spi_master_get_devdata(master); -+ struct spi_device *spi = m->spi; -+ struct spi_transfer *t = NULL; -+ int status = 0; -+ int cs_active = 0; -+ -+ list_for_each_entry(t, &m->transfers, transfer_list) { -+ if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { -+ dev_err(&spi->dev, -+ "message rejected: invalid transfer data buffers\n"); -+ status = -EIO; -+ goto msg_done; -+ } -+ -+ if (!cs_active) { -+ rt2880_spi_set_cs(rs, 1); -+ cs_active = 1; -+ } -+ -+ if (t->len) -+ m->actual_length += rt2880_spi_write_read(spi, t); -+ -+ if (t->delay_usecs) -+ udelay(t->delay_usecs); -+ -+ if (t->cs_change) { -+ rt2880_spi_set_cs(rs, 0); -+ cs_active = 0; -+ } -+ } -+ -+msg_done: -+ if (cs_active) -+ rt2880_spi_set_cs(rs, 0); -+ -+ m->status = status; -+ spi_finalize_current_message(master); ++ if (spi->mode & SPI_CS_HIGH) ++ enable = !enable; + -+ return 0; ++ if (spi->cs_gpio >= 0) ++ gpio_set_value(spi->cs_gpio, !enable); ++ else if (spi->master->set_cs) ++ spi->master->set_cs(spi, !enable); +} + +static int rt2880_spi_setup(struct spi_device *spi) @@ -410,6 +401,11 @@ Acked-by: John Crispin + if (reg != old_reg) + rt2880_spi_write(rs, arbit_off, reg); + ++ /* deselected the spi device */ ++ spi_set_cs(spi, false); ++ ++ rt2880_dump_reg(master); ++ + return 0; +} + @@ -508,8 +504,8 @@ Acked-by: John Crispin + master->flags = SPI_MASTER_HALF_DUPLEX; + master->setup = rt2880_spi_setup; + master->prepare_message = rt2880_spi_prepare_message; -+ master->transfer_one_message = rt2880_spi_transfer_one_message; -+ master->num_chipselect = RALINK_NUM_CHIPSELECTS; ++ master->set_cs = rt2880_spi_set_cs; ++ master->transfer_one = rt2880_spi_transfer_one, + + dev_set_drvdata(&pdev->dev, master); + @@ -518,8 +514,8 @@ Acked-by: John Crispin + rs->base = base; + rs->clk = clk; + -+ device_reset(&pdev->dev); -+ ++ if (atomic_inc_return(&hw_reset_count) == 1) ++ device_reset(&pdev->dev); + + ret = devm_spi_register_master(&pdev->dev, master); + if (ret < 0) { @@ -547,6 +543,7 @@ Acked-by: John Crispin + rs = spi_master_get_devdata(master); + + clk_disable_unprepare(rs->clk); ++ atomic_dec(&hw_reset_count); + + return 0; +}