From patchwork Tue Jul 14 16:54:22 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Brownell X-Patchwork-Id: 35580 Received: from comal.ext.ti.com (comal.ext.ti.com [198.47.26.152]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n6EGvfOB003543 for ; Tue, 14 Jul 2009 16:57:41 GMT Received: from dlep35.itg.ti.com ([157.170.170.118]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id n6EGsbnr013863; Tue, 14 Jul 2009 11:54:42 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep35.itg.ti.com (8.13.7/8.13.7) with ESMTP id n6EGsaDR011230; Tue, 14 Jul 2009 11:54:37 -0500 (CDT) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 4BDC980627; Tue, 14 Jul 2009 11:54:36 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dflp52.itg.ti.com (dflp52.itg.ti.com [128.247.22.96]) by linux.omap.com (Postfix) with ESMTP id BAF8380626 for ; Tue, 14 Jul 2009 11:54:33 -0500 (CDT) Received: from medina.ext.ti.com (localhost [127.0.0.1]) by dflp52.itg.ti.com (8.13.7/8.13.7) with ESMTP id n6EGsX5O004647 for ; Tue, 14 Jul 2009 11:54:33 -0500 (CDT) Received: from mail25-va3-R.bigfish.com (mail-va3.bigfish.com [216.32.180.111]) by medina.ext.ti.com (8.13.7/8.13.7) with ESMTP id n6EGsSG1007878 for ; Tue, 14 Jul 2009 11:54:33 -0500 Received: from mail25-va3 (localhost.localdomain [127.0.0.1]) by mail25-va3-R.bigfish.com (Postfix) with ESMTP id 0AE09A801D9 for ; Tue, 14 Jul 2009 16:54:28 +0000 (UTC) X-SpamScore: -14 X-BigFish: vps-14(zcb8kz70dU9370K98dN18c1J19c1l19c2kzz1202hzzz2dh5eh6bh61h) X-Spam-TCS-SCL: 0:0 X-MS-Exchange-Organization-Antispam-Report: OrigIP: 69.147.64.90; Service: EHS Received: by mail25-va3 (MessageSwitch) id 1247590464242119_21801; Tue, 14 Jul 2009 16:54:24 +0000 (UCT) Received: from smtp117.sbc.mail.sp1.yahoo.com (smtp117.sbc.mail.sp1.yahoo.com [69.147.64.90]) by mail25-va3.bigfish.com (Postfix) with SMTP id D3574B98056 for ; Tue, 14 Jul 2009 16:54:23 +0000 (UTC) Received: (qmail 92149 invoked from network); 14 Jul 2009 16:54:23 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=pacbell.net; h=Received:X-YMail-OSG:X-Yahoo-Newman-Property:From:To:Subject:Date:User-Agent:Cc:References:In-Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding:Content-Disposition:Message-Id; b=TqXpFmDJz6RftKrWEydBeKbGn+0lxFiVse2SeNCmMbmG6VEzmCm67rPrzWC94VNAB1VSNPakQoZHTqASyqjEvzSnJd95p3gGZEPHrsymKRMEA57LygvGRpiKrasqsoLqbMt/wvu1siipWP/NEQvxWg1I3B4lUgisGZgFiuzP03A= ; Received: from unknown (HELO albert) (david-b@69.226.209.118 with plain) by smtp117.sbc.mail.sp1.yahoo.com with SMTP; 14 Jul 2009 16:54:22 -0000 X-YMail-OSG: 5Lm.gLkVM1mCjSK9CbmDpucYOMKNiqQcB5BeBJJwwW.iXXwxDLysi6X8NjMJyTUIhg.pjr5y0TGojYRTy0EIqoFPyFK629hg_RhfzInprmt75zn9ftextS6GapiH.Jk.mAu5cMcMNxL0WIGrsmxV.GKS7opcytlGn265oGzoeJH93qx4ps9zvz28QsKoGtgMpReDmhzVihtRPu1w3yc0_gH9q3JTV0q5eHsgAs5.kbziHVIMEWnrmjjtZU6wrzqdP54lBWppuk9OevoR0wEZbi7LPcgWIzWLzu6nGmvKV6M9PveF_Fh4QOq4sovaHORNqCk7dg3pHH7ByIw9Cg-- X-Yahoo-Newman-Property: ymail-3 From: David Brownell To: davinci-linux-open-source@linux.davincidsp.com Date: Tue, 14 Jul 2009 09:54:22 -0700 User-Agent: KMail/1.9.10 References: <1247501652-2549-1-git-send-email-s-paulraj@ti.com> In-Reply-To: <1247501652-2549-1-git-send-email-s-paulraj@ti.com> MIME-Version: 1.0 Content-Disposition: inline Message-Id: <200907140954.22401.david-b@pacbell.net> Cc: Subject: Re: [PATCH 6/6] DaVinci: Adding SPI driver for DM3xx/DM6467/DA8xx X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.4 Precedence: list List-Id: davinci-linux-open-source.linux.davincidsp.com List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com On Monday 13 July 2009, s-paulraj@ti.com wrote: > The patch adds support for SPI driver for DaVinci > DM355/DM365/DM6467 and DA8xx Comments-in-the-form-of-a-patch below ... I figured this could expedite things. :) - Dave =============================== Various bits of cleanup for the davinci_spi driver: - Kconfig should never have "default y" - Reorder #includes ... standard stuff should go first - Remove pointless inlines - Remove needless (and sometimes unused) #defines - Declare the special SPI_* modes which are supported! - Whitespace fixes - Update busy-wait loops - Streamline op_mode setup - ... more NOT ADDRESSED: - The printk(KERN_ERR ...) messages that should be dev_dbg(...) - The use of "-1" error codes instead of negative errno - Timing out busy-wait loops - Adding a comment explaining that either built-in chipselects *or* GPIO versions may be used. (If GPIO, can up to 4 slaves be supported?) --- drivers/spi/Kconfig | 1 drivers/spi/davinci_spi.c | 142 ++++++++++++++++---------------------------- drivers/spi/davinci_spi.h | 42 +------------ 3 files changed, 59 insertions(+), 126 deletions(-) --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -81,7 +81,6 @@ config SPI_DAVINCI tristate "SPI controller driver for DaVinci SoC" depends on SPI_MASTER && ARCH_DAVINCI select SPI_BITBANG - default y help SPI master controller for DaVinci SPI modules. --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -17,11 +17,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "davinci_spi.h" +#include +#include #include #include -#include -#include #include #include #include @@ -29,9 +28,17 @@ #include #include #include +#include -static inline void davinci_spi_rx_buf_u8(u32 data, - struct davinci_spi *davinci_spi) +#include +#include + +#include + +#include "davinci_spi.h" + + +static void davinci_spi_rx_buf_u8(u32 data, struct davinci_spi *davinci_spi) { u8 *rx = davinci_spi->rx; @@ -39,8 +46,7 @@ static inline void davinci_spi_rx_buf_u8 davinci_spi->rx = rx; } -static inline void davinci_spi_rx_buf_u16(u32 data, - struct davinci_spi *davinci_spi) +static void davinci_spi_rx_buf_u16(u32 data, struct davinci_spi *davinci_spi) { u16 *rx = davinci_spi->rx; @@ -48,7 +54,7 @@ static inline void davinci_spi_rx_buf_u1 davinci_spi->rx = rx; } -static inline u32 davinci_spi_tx_buf_u8(struct davinci_spi *davinci_spi) +static u32 davinci_spi_tx_buf_u8(struct davinci_spi *davinci_spi) { u32 data; const u8 *tx = davinci_spi->tx; @@ -58,7 +64,7 @@ static inline u32 davinci_spi_tx_buf_u8( return data; } -static inline u32 davinci_spi_tx_buf_u16(struct davinci_spi *davinci_spi) +static u32 davinci_spi_tx_buf_u16(struct davinci_spi *davinci_spi) { u32 data; const u16 *tx = davinci_spi->tx; @@ -71,6 +77,7 @@ static inline u32 davinci_spi_tx_buf_u16 static inline void set_bits(void __iomem *addr, u32 bits) { u32 v = ioread32(addr); + v |= bits; iowrite32(v, addr); } @@ -78,6 +85,7 @@ static inline void set_bits(void __iomem static inline void clear_bits(void __iomem *addr, u32 bits) { u32 v = ioread32(addr); + v &= ~bits; iowrite32(v, addr); } @@ -114,7 +122,7 @@ static void davinci_spi_chipselect(struc if (pdata->chip_sel != NULL) { for (i = 0; i < pdata->num_chipselect; i++) { if (pdata->chip_sel[i] != DAVINCI_SPI_INTERN_CS) - __gpio_set_value(pdata->chip_sel[i], 1); + gpio_set_value(pdata->chip_sel[i], 1); } } @@ -123,10 +131,9 @@ static void davinci_spi_chipselect(struc data1_reg_val |= CS_DEFAULT << DAVINCI_SPIDAT1_CSNR_SHIFT; iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); - while (1) - if (ioread32(davinci_spi->base + SPIBUF) - & DAVINCI_SPIBUF_RXEMPTY_MASK) - break; + while ((ioread32(davinci_spi->base + SPIBUF) + & DAVINCI_SPIBUF_RXEMPTY_MASK) == 0) + cpu_relax(); } } @@ -309,67 +316,21 @@ static int davinci_spi_bufs_prep(struct iowrite32(DAVINCI_SPI_INTLVL_0, davinci_spi->base + SPILVL); /* - * The driver uses new flags SPI_NO_CS and SPI_RAEDY - * These can be found in /include/linux/spi/spi.h - * Standard SPI mode is a 4 pin variant - * 3 pin SPI is actually the 4 pin variant with no CS(SPI_NO_CS) + * Standard SPI mode uses 4 pins, with chipselect + * 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS) + * (distinct from SPI_3WIRE, with just one data wire; + * or similar variants without MOSI or without MISO) * 4 pin with enable is (SPI_READY | SPI_NO_CS) - * 5 pin SPI variant is SPI_READY - * Operation mode(op_mode) depends on these flags - * op_mode 0 = standard 4 pin mode - * op_mode 1 = 3 pin mode - * op_mode 2 = 5 pin mode - * op_mode 3 = 4 pin mode with enable + * 5 pin SPI variant is standard SPI plus SPI_READY */ - op_mode = ((spi->mode & (SPI_NO_CS | SPI_READY)) >> 6); - - switch (op_mode) { - case 0: - op_mode = (DAVINCI_SPIPC0_DIFUN_DI << - DAVINCI_SPIPC0_DIFUN_SHIFT) - | (DAVINCI_SPIPC0_DOFUN_DO << - DAVINCI_SPIPC0_DOFUN_SHIFT) - | (DAVINCI_SPIPC0_CLKFUN_CLK << - DAVINCI_SPIPC0_CLKFUN_SHIFT) - | (1 << spi->chip_select); - break; - - case 1: - op_mode = (DAVINCI_SPIPC0_DIFUN_DI << - DAVINCI_SPIPC0_DIFUN_SHIFT) - | (DAVINCI_SPIPC0_DOFUN_DO << - DAVINCI_SPIPC0_DOFUN_SHIFT) - | (DAVINCI_SPIPC0_CLKFUN_CLK << - DAVINCI_SPIPC0_CLKFUN_SHIFT); - break; - - case 2: - op_mode = (DAVINCI_SPIPC0_DIFUN_DI << - DAVINCI_SPIPC0_DIFUN_SHIFT) - | (DAVINCI_SPIPC0_DOFUN_DO << - DAVINCI_SPIPC0_DOFUN_SHIFT) - | (DAVINCI_SPIPC0_CLKFUN_CLK < - DAVINCI_SPIPC0_CLKFUN_SHIFT) - | (DAVINCI_SPIPC0_SPIENA << - DAVINCI_SPIPC0_SPIENA_SHIFT) - | (1 << spi->chip_select); - break; - - case 3: - op_mode = (DAVINCI_SPIPC0_DIFUN_DI << - DAVINCI_SPIPC0_DIFUN_SHIFT) - | (DAVINCI_SPIPC0_DOFUN_DO << - DAVINCI_SPIPC0_DOFUN_SHIFT) - | (DAVINCI_SPIPC0_CLKFUN_CLK << - DAVINCI_SPIPC0_CLKFUN_SHIFT) - | (DAVINCI_SPIPC0_SPIENA << - DAVINCI_SPIPC0_SPIENA_SHIFT); - break; - - default: - return -1; - } + op_mode = DAVINCI_SPIPC0_DIFUN_MASK + | DAVINCI_SPIPC0_DOFUN_MASK + | DAVINCI_SPIPC0_CLKFUN_MASK; + if (!(spi->mode & SPI_NO_CS)) + op_mode |= 1 << spi->chip_select; + if (spi->mode & SPI_READY) + op_mode |= DAVINCI_SPIPC0_SPIENA_MASK; iowrite32(op_mode, davinci_spi->base + SPIPC0); @@ -475,16 +436,15 @@ static int davinci_spi_bufs_pio(struct s /* checking for GPIO */ if ((pdata->chip_sel != NULL) && (pdata->chip_sel[spi->chip_select] != DAVINCI_SPI_INTERN_CS)) - __gpio_set_value(pdata->chip_sel[spi->chip_select], 0); + gpio_set_value(pdata->chip_sel[spi->chip_select], 0); else clear_bits(davinci_spi->base + SPIDEF, ~tmp); data1_reg_val |= tmp << DAVINCI_SPIDAT1_CSNR_SHIFT; - while (1) - if (ioread32(davinci_spi->base + SPIBUF) - & DAVINCI_SPIBUF_RXEMPTY_MASK) - break; + while ((ioread32(davinci_spi->base + SPIBUF) + & DAVINCI_SPIBUF_RXEMPTY_MASK) == 0) + cpu_relax(); /* Determine the command to execute READ or WRITE */ if (t->tx_buf) { @@ -505,7 +465,8 @@ static int davinci_spi_bufs_pio(struct s } while (ioread32(davinci_spi->base + SPIBUF) & DAVINCI_SPIBUF_RXEMPTY_MASK) - udelay(1); + cpu_relax(); + /* getting the returned byte */ if (t->rx_buf) { buf_val = ioread32(davinci_spi->base + SPIBUF); @@ -519,13 +480,13 @@ static int davinci_spi_bufs_pio(struct s while (1) { /* keeps the serial clock going */ if ((ioread32(davinci_spi->base + SPIBUF) - & DAVINCI_SPIBUF_TXFULL_MASK) == 0) + & DAVINCI_SPIBUF_TXFULL_MASK) == 0) iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); - while ((ioread32(davinci_spi->base + SPIBUF)) & - (DAVINCI_SPIBUF_RXEMPTY_MASK)) - ; + while (ioread32(davinci_spi->base + SPIBUF) & + DAVINCI_SPIBUF_RXEMPTY_MASK) + cpu_relax(); flg_val = ioread32(davinci_spi->base + SPIFLG); buf_val = ioread32(davinci_spi->base + SPIBUF); @@ -549,8 +510,8 @@ static int davinci_spi_bufs_pio(struct s davinci_spi->base + SPIDAT1); while (ioread32(davinci_spi->base + SPIINT) & - (DAVINCI_SPIINT_RX_INTR)) - ; + DAVINCI_SPIINT_RX_INTR) + cpu_relax(); } iowrite32((data1_reg_val & 0x0ffcffff), davinci_spi->base + SPIDAT1); @@ -659,7 +620,7 @@ static int davinci_spi_probe(struct plat davinci_spi->region_size = resource_size(r); davinci_spi->pdata = pdata; - /* initialize gpio used as chip select */ + /* initialize any gpio lines used as chip select */ if (pdata->chip_sel != NULL) { for (i = 0; i < pdata->num_chipselect; i++) { if (pdata->chip_sel[i] != DAVINCI_SPI_INTERN_CS) { @@ -690,7 +651,7 @@ static int davinci_spi_probe(struct plat } ret = request_irq(davinci_spi->irq, davinci_spi_irq, IRQF_DISABLED, - pdev->name, davinci_spi); + dev_name(&pdev->dev), davinci_spi); if (ret != 0) { ret = -EAGAIN; goto unmap_io; @@ -716,8 +677,12 @@ static int davinci_spi_probe(struct plat davinci_spi->bitbang.chipselect = davinci_spi_chipselect; davinci_spi->bitbang.setup_transfer = davinci_spi_setup_transfer; - davinci_spi->bitbang.txrx_bufs = davinci_spi_bufs_pio; + + davinci_spi->bitbang.flags = SPI_LSB_FIRST | SPI_LOOP; + if (davinci_spi->version == DAVINCI_SPI_VERSION_2) + davinci_spi->bitbang.flags |= SPI_NO_CS | SPI_READY; + davinci_spi->version = pdata->version; davinci_spi->get_rx = davinci_spi_rx_buf_u8; davinci_spi->get_tx = davinci_spi_tx_buf_u8; @@ -733,8 +698,7 @@ static int davinci_spi_probe(struct plat if (ret != 0) goto free_clk; - printk(KERN_NOTICE "Davinci SPI Controller driver at " - "0x%p (irq = %d) \n", + dev_info(&pdev->dev,"Controller at 0x%p (irq = %d) \n", davinci_spi->base, davinci_spi->irq); return ret; --- a/drivers/spi/davinci_spi.h +++ b/drivers/spi/davinci_spi.h @@ -19,13 +19,6 @@ #ifndef __DAVINCI_SPI_H #define __DAVINCI_SPI_H -#include -#include -#include -#include -#include -#include - #define DAVINCI_SPI_MAX_CHIPSELECT 2 #define CS_DEFAULT 0xFF @@ -53,33 +46,12 @@ #define DAVINCI_SPIGCR1_SPIENA_MASK 0x01000000u /* SPIPC0 */ -#define DAVINCI_SPIPC0_DIFUN_MASK BIT(11) -#define DAVINCI_SPIPC0_DIFUN_SHIFT 11 - -/* DIFUN */ -#define DAVINCI_SPIPC0_DIFUN_DI BIT(0) - -/* DOFUN */ -#define DAVINCI_SPIPC0_DOFUN_MASK BIT(10) -#define DAVINCI_SPIPC0_DOFUN_SHIFT 10 -#define DAVINCI_SPIPC0_DOFUN_DO BIT(0) - -/* CLKFUN */ -#define DAVINCI_SPIPC0_CLKFUN_MASK BIT(9) -#define DAVINCI_SPIPC0_CLKFUN_SHIFT 9 -#define DAVINCI_SPIPC0_CLKFUN_CLK BIT(0) - -/* EN1FUN */ +#define DAVINCI_SPIPC0_DIFUN_MASK BIT(11) /* MISO */ +#define DAVINCI_SPIPC0_DOFUN_MASK BIT(10) /* MOSI */ +#define DAVINCI_SPIPC0_CLKFUN_MASK BIT(9) /* CLK */ +#define DAVINCI_SPIPC0_SPIENA_MASK BIT(8) /* nREADY */ #define DAVINCI_SPIPC0_EN1FUN_MASK BIT(1) -#define DAVINCI_SPIPC0_EN1FUN_EN1 BIT(0) - -/* EN0FUN Tokens */ #define DAVINCI_SPIPC0_EN0FUN_MASK BIT(0) -#define DAVINCI_SPIPC0_EN0FUN_SHIFT 0 -#define DAVINCI_SPIPC0_EN0FUN_EN0 BIT(0) - -#define DAVINCI_SPIPC0_SPIENA BIT(0) -#define DAVINCI_SPIPC0_SPIENA_SHIFT 8 #define DAVINCI_SPIINT_MASKALL 0x0101035F #define DAVINCI_SPI_INTLVL_1 0x000001FFu @@ -127,8 +99,6 @@ #define DAVINCI_SPIINT_DMA_REQ_EN BIT(16) #define DAVINCI_SPIINT_ENABLE_HIGHZ BIT(24) -#define DAVINCI_BYTELENGTH 8u - #define DAVINCI_SPI_T2CDELAY_SHIFT 16 #define DAVINCI_SPI_C2TDELAY_SHIFT 24 @@ -171,7 +141,7 @@ struct davinci_spi_slave { struct davinci_spi { /* bitbang has to be first */ struct spi_bitbang bitbang; - struct clk *clk; + struct clk *clk; u8 version; resource_size_t pbase; @@ -183,7 +153,7 @@ struct davinci_spi { const void *tx; void *rx; int count; - struct davinci_spi_platform_data *pdata; + struct davinci_spi_platform_data *pdata; void (*get_rx)(u32 rx_data, struct davinci_spi *); u32 (*get_tx)(struct davinci_spi *);