From patchwork Wed Jan 23 18:08:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Brugger X-Patchwork-Id: 2026411 Return-Path: X-Original-To: patchwork-spi-devel-general@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by patchwork2.kernel.org (Postfix) with ESMTP id 7A59FDF23E for ; Wed, 23 Jan 2013 18:09:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=sfs-ml-1.v29.ch3.sourceforge.com) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1Ty4l4-0007zn-9c; Wed, 23 Jan 2013 18:09:10 +0000 Received: from sog-mx-1.v43.ch3.sourceforge.com ([172.29.43.191] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1Ty4l2-0007zg-RR for spi-devel-general@lists.sourceforge.net; Wed, 23 Jan 2013 18:09:08 +0000 Received-SPF: pass (sog-mx-1.v43.ch3.sourceforge.com: domain of gmail.com designates 209.85.212.172 as permitted sender) client-ip=209.85.212.172; envelope-from=matthias.bgg@gmail.com; helo=mail-wi0-f172.google.com; Received: from mail-wi0-f172.google.com ([209.85.212.172]) by sog-mx-1.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1Ty4kz-0007TJ-Pr for spi-devel-general@lists.sourceforge.net; Wed, 23 Jan 2013 18:09:08 +0000 Received: by mail-wi0-f172.google.com with SMTP id o1so977888wic.5 for ; Wed, 23 Jan 2013 10:08:59 -0800 (PST) X-Received: by 10.180.93.133 with SMTP id cu5mr28805935wib.32.1358964539677; Wed, 23 Jan 2013 10:08:59 -0800 (PST) Received: from ubi.home (206.Red-83-33-115.dynamicIP.rima-tde.net. [83.33.115.206]) by mx.google.com with ESMTPS id ew4sm30741202wid.11.2013.01.23.10.08.57 (version=TLSv1 cipher=RC4-SHA bits=128/128); Wed, 23 Jan 2013 10:08:58 -0800 (PST) From: Matthias Brugger To: Grant Likely , Mark Brown , Tony Lindgren , Daniel Mack , Jarkko Nikula , Greg Kroah-Hartman , eballetbo@gmail.com, javier.martinez@collabora.co.uk, ezequiel.garcia@free-electrons.com, spi-devel-general@lists.sourceforge.net, linux-omap@vger.kernel.org Subject: [PATCH 3/3] spi: spi-omap2-mcspi.c: Toggle CS after each word Date: Wed, 23 Jan 2013 19:08:49 +0100 Message-Id: <1358964529-4905-1-git-send-email-matthias.bgg@gmail.com> X-Mailer: git-send-email 1.7.11.7 X-Spam-Score: -1.6 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (matthias.bgg[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1Ty4kz-0007TJ-Pr Cc: Matthias Brugger X-BeenThere: spi-devel-general@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux SPI core/device drivers discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: spi-devel-general-bounces@lists.sourceforge.net This patch allows the board code to define SPI devices which needs to toggle the chip select after every word send. This is needed to get a better resolution reading e.g. an ADC data stream. Apart from that, as in the normal code CS is controlled by software, a transfer is done much faster. Signed-off-by: Matthias Brugger --- drivers/spi/spi-omap2-mcspi.c | 34 ++++++++++++++++++++------- include/linux/platform_data/spi-omap2-mcspi.h | 3 +++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index b610f52..12789fc 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -927,6 +927,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) struct spi_device *spi; struct spi_transfer *t = NULL; + struct spi_master *master; int cs_active = 0; struct omap2_mcspi_cs *cs; struct omap2_mcspi_device_config *cd; @@ -935,6 +936,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) u32 chconf; spi = m->spi; + master = spi->master; cs = spi->controller_state; cd = spi->controller_data; @@ -952,6 +954,14 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) if (!t->speed_hz && !t->bits_per_word) par_override = 0; } + if (cd && cd->cs_per_word) { + chconf = mcspi->ctx.modulctrl; + chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE; + mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); + mcspi->ctx.modulctrl = + mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); + } + if (!cs_active) { omap2_mcspi_force_cs(spi, 1); @@ -1013,6 +1023,14 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) if (cs_active) omap2_mcspi_force_cs(spi, 0); + if (cd && cd->cs_per_word) { + chconf = mcspi->ctx.modulctrl; + chconf |= OMAP2_MCSPI_MODULCTRL_SINGLE; + mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, chconf); + mcspi->ctx.modulctrl = + mcspi_read_cs_reg(spi, OMAP2_MCSPI_MODULCTRL); + } + omap2_mcspi_set_enable(spi, 0); m->status = status; @@ -1020,7 +1038,7 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) } static int omap2_mcspi_transfer_one_message(struct spi_master *master, - struct spi_message *m) + struct spi_message *m) { struct omap2_mcspi *mcspi; struct spi_transfer *t; @@ -1041,7 +1059,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, || (len && !(rx_buf || tx_buf)) || (t->bits_per_word && ( t->bits_per_word < 4 - || t->bits_per_word > 32))) { + || t->bits_per_word > 32))) { dev_dbg(mcspi->dev, "transfer: %d Hz, %d %s%s, %d bpw\n", t->speed_hz, len, @@ -1052,8 +1070,8 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, } if (t->speed_hz && t->speed_hz < (OMAP2_MCSPI_MAX_FREQ >> 15)) { dev_dbg(mcspi->dev, "speed_hz %d below minimum %d Hz\n", - t->speed_hz, - OMAP2_MCSPI_MAX_FREQ >> 15); + t->speed_hz, + OMAP2_MCSPI_MAX_FREQ >> 15); return -EINVAL; } @@ -1099,7 +1117,7 @@ static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) return ret; mcspi_write_reg(master, OMAP2_MCSPI_WAKEUPENABLE, - OMAP2_MCSPI_WAKEUPENABLE_WKEN); + OMAP2_MCSPI_WAKEUPENABLE_WKEN); ctx->wakeupenable = OMAP2_MCSPI_WAKEUPENABLE_WKEN; omap2_mcspi_set_master_mode(master); @@ -1228,7 +1246,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) sprintf(dma_ch_name, "rx%d", i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_ch_name); if (!dma_res) { dev_dbg(&pdev->dev, "cannot get DMA RX channel\n"); status = -ENODEV; @@ -1238,7 +1256,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start; sprintf(dma_ch_name, "tx%d", i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_ch_name); if (!dma_res) { dev_dbg(&pdev->dev, "cannot get DMA TX channel\n"); status = -ENODEV; @@ -1254,7 +1272,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) pinctrl = devm_pinctrl_get_select_default(&pdev->dev); if (IS_ERR(pinctrl)) dev_warn(&pdev->dev, - "pins are not configured from the driver\n"); + "pins are not configured from the driver\n"); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); diff --git a/include/linux/platform_data/spi-omap2-mcspi.h b/include/linux/platform_data/spi-omap2-mcspi.h index a65572d..c100456 100644 --- a/include/linux/platform_data/spi-omap2-mcspi.h +++ b/include/linux/platform_data/spi-omap2-mcspi.h @@ -22,6 +22,9 @@ struct omap2_mcspi_dev_attr { struct omap2_mcspi_device_config { unsigned turbo_mode:1; + + /* toggle chip select after every word */ + unsigned cs_per_word:1; }; #endif