From patchwork Tue Feb 9 18:10:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Olbrich X-Patchwork-Id: 8264681 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AAAC2BEEE5 for ; Tue, 9 Feb 2016 18:13:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C0ABB20220 for ; Tue, 9 Feb 2016 18:13:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BC16020218 for ; Tue, 9 Feb 2016 18:12:58 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aTCl8-0003J6-GV; Tue, 09 Feb 2016 18:11:30 +0000 Received: from mout.gmx.net ([212.227.15.18]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aTCkn-0002t2-2I; Tue, 09 Feb 2016 18:11:11 +0000 Received: from chaos-desktop.fritz.box ([92.217.39.22]) by mail.gmx.com (mrgmx001) with ESMTPSA (Nemesis) id 0M09BU-1aAhvY3VxU-00uKhe; Tue, 09 Feb 2016 19:10:41 +0100 From: stephanolbrich@gmx.de To: Mark Brown , Stephen Warren , Lee Jones , Eric Anholt , linux-spi@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 3/4] spi: bcm2835aux: set up spi-mode before asserting cs-gpio Date: Tue, 9 Feb 2016 19:10:34 +0100 Message-Id: <1455041435-8015-4-git-send-email-stephanolbrich@gmx.de> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1455041435-8015-1-git-send-email-stephanolbrich@gmx.de> References: <1455041435-8015-1-git-send-email-stephanolbrich@gmx.de> X-Provags-ID: V03:K0:a4cxfBCiloUlqmRncnkPkNxzddiFT4dj8e0cNZLSuk2IQuneSV1 dVq1KB7TMS/cFp0lGLlEMSUQ/TtdiWV9KQMAvm7dDSDoA93juGmxn/gLoWhDL9DxKnu6Qqn Bf52ewlV322oCN8xoFZ3tElAvxdevozkV1s3X1sgfBmbKz6BoykVJylIKv0VsvkwAdLu48l x4Hli/rTQn2kmzQk48vhQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:PMh+zzb/zaI=:Hixytz7yIlEtikHYOZbdaG rwOpeCEhq6Tb2emCZ+xkWAnqne2p2OIKnutBnQ+qYPSAvmB55FG4PtNUDNIQ0eu/A/ZnbZELi TNthRVG02fp1qvaQrhjSsFlPE3HK3KSjmh2+lwUNkwTS4ad2YebSQOmTteHL114p4hogr3R14 XgNukcj00hrER0tH8xPiqAwfphbDbi2RvEOj33r3qqMmNn8lRJbHlKg3L1G9twf9HM8JvpfCl WCbNMrcNcg++GHs6MoHrcbMQeyNzKSdQQGvXbPsMISAfKZea7ccYdFl82DusDv8QgvG735m8H aqVR7+7D8pNJqoIadmpB+bMDs/0DpHNOjP0fNWhkmld6eHUj+QmGURtD/ndg3pY7i3h62dP5S M3RUGk+ulGXLn950PdIf3Jop9T3K68bVd7VlG3zxCejVOY8VtUa6fQlCmQhWHgBGBIE/IyWDI dgC+S48rc/iacOu6pRw830mG1s+I3hVp6ylcdvy6VkxTe+GiohwEHGhBjHrRNwD19E6AYFZ6f tQfx7e5SPHf6DdmeqcB0hCJy0bSJjq0bEkogBhLIYwR1LDLpmvvEVxQrOKbUhvPA5MEAMk/N3 A+45z0bmMs+3KP5+VcCz174wKu+b6hye5+jo9+vWrnvubj2QWvxJdrlySeDaDLPIVyQDgM3QS vX/RLESwyhaoXtXCsrSXRpaU+xUNj1Uz+gqBXutW11a0GxUykDgXqEQpLzFz0TLBGrwmQ73L8 CPN2bk/DVuEkhx97idNBQGsiqZsiy7s0FPJn2q8eWt3hPGzp8N4LW3rtsDw= X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160209_101109_643696_3916E130 X-CRM114-Status: GOOD ( 12.12 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephan Olbrich MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Stephan Olbrich When using reverse polarity for clock (spi-cpol) on a device the clock line gets altered after chip-select has been asserted resulting in an additional clock beat, which confuses hardware. To avoid this situation this patch moves the setup of polarity (spi-cpol and spi-cpha) outside of the chip-select into prepare_message, which is run prior to asserting chip-select. Signed-off-by: Stephan Olbrich Reviewed-by: Martin Sperl Tested-by: Martin Sperl --- drivers/spi/spi-bcm2835aux.c | 54 +++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index d2f0067..b90aa34 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -218,9 +218,9 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) BCM2835_AUX_SPI_CNTL1_IDLE); } - /* and if rx_len is 0 then wake up completion and disable spi */ + /* and if rx_len is 0 then disable interrupts and wake up completion */ if (!bs->rx_len) { - bcm2835aux_spi_reset_hw(bs); + bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); complete(&master->xfer_completion); } @@ -313,9 +313,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, } } - /* Transfer complete - reset SPI HW */ - bcm2835aux_spi_reset_hw(bs); - /* and return without waiting for completion */ return 0; } @@ -336,10 +333,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, * resulting (potentially) in more interrupts when transferring * more than 12 bytes */ - bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE | - BCM2835_AUX_SPI_CNTL0_VAR_WIDTH | - BCM2835_AUX_SPI_CNTL0_MSBF_OUT; - bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; /* set clock */ spi_hz = tfr->speed_hz; @@ -358,13 +351,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, spi_used_hz = clk_hz / (2 * (speed + 1)); - /* handle all the modes */ - if (spi->mode & SPI_CPOL) - bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; - if (spi->mode & SPI_CPHA) - bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT | - BCM2835_AUX_SPI_CNTL0_CPHA_IN; - /* set transmit buffers and length */ bs->tx_buf = tfr->tx_buf; bs->rx_buf = tfr->rx_buf; @@ -388,6 +374,40 @@ static int bcm2835aux_spi_transfer_one(struct spi_master *master, return bcm2835aux_spi_transfer_one_irq(master, spi, tfr); } +static int bcm2835aux_spi_prepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct spi_device *spi = msg->spi; + struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + + bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE | + BCM2835_AUX_SPI_CNTL0_VAR_WIDTH | + BCM2835_AUX_SPI_CNTL0_MSBF_OUT; + bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN; + + /* handle all the modes */ + if (spi->mode & SPI_CPOL) + bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL; + if (spi->mode & SPI_CPHA) + bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT | + BCM2835_AUX_SPI_CNTL0_CPHA_IN; + + bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]); + bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]); + + return 0; +} + +static int bcm2835aux_spi_unprepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct bcm2835aux_spi *bs = spi_master_get_devdata(master); + + bcm2835aux_spi_reset_hw(bs); + + return 0; +} + static void bcm2835aux_spi_handle_err(struct spi_master *master, struct spi_message *msg) { @@ -416,6 +436,8 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev) master->num_chipselect = -1; master->transfer_one = bcm2835aux_spi_transfer_one; master->handle_err = bcm2835aux_spi_handle_err; + master->prepare_message = bcm2835aux_spi_prepare_message; + master->unprepare_message = bcm2835aux_spi_unprepare_message; master->dev.of_node = pdev->dev.of_node; bs = spi_master_get_devdata(master);