From patchwork Tue Sep 29 21:15:53 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Heiner Kallweit X-Patchwork-Id: 7290381 Return-Path: X-Original-To: patchwork-linux-spi@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 D8ECABEEA4 for ; Tue, 29 Sep 2015 21:16:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A4D302068C for ; Tue, 29 Sep 2015 21:16:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 752292068F for ; Tue, 29 Sep 2015 21:16:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751867AbbI2VQy (ORCPT ); Tue, 29 Sep 2015 17:16:54 -0400 Received: from mail-wi0-f171.google.com ([209.85.212.171]:37510 "EHLO mail-wi0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751746AbbI2VQx (ORCPT ); Tue, 29 Sep 2015 17:16:53 -0400 Received: by wicfx3 with SMTP id fx3so34476325wic.0 for ; Tue, 29 Sep 2015 14:16:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:subject:to:cc:message-id:date:user-agent:mime-version :content-type:content-transfer-encoding; bh=nIr/RlCe3qmw6Tnup5x4U4Bjm372wheZtf34324B6dE=; b=NJqMXxpwsAPj8iw9jAKTGjuajrzEJ8pGe0waMknERyY2bjtzCuc29sTZPC83KhOjOA ugH4FeBytSmy2MIQJvo1fYFpwsPKCyJ9S0HMeNF9tdtriHBgX9O2tFhoiIZiJxsLbPrt F6CVtm82fG99ejqyXCWrBgQDe8UCXc/zCk4qqWE6tcM3oa7z/d0iLtDCerqv/6b9udbU X7HZmX4ay2aj9OIJHNYwweybr9xBjuniTtlLLYDaHQCIv/rsonyb9pSn/A91rv60E0wa SYnwqLuHeeG3DlrbpDtuVUPk1a/ncbQktvpKP2t+xTrpDr/snf7adX5AoYp+sxd/A4WT RcqQ== X-Received: by 10.180.85.229 with SMTP id k5mr28741225wiz.76.1443561412444; Tue, 29 Sep 2015 14:16:52 -0700 (PDT) Received: from ?IPv6:2003:62:5f33:d300:1523:ac93:90b7:c328? (p200300625F33D3001523AC9390B7C328.dip0.t-ipconnect.de. [2003:62:5f33:d300:1523:ac93:90b7:c328]) by smtp.googlemail.com with ESMTPSA id mx19sm25849621wic.0.2015.09.29.14.16.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 29 Sep 2015 14:16:51 -0700 (PDT) From: Heiner Kallweit Subject: [PATCH 2/2] spi: bitbang: switch to the generic implementation of transfer_one_message To: Mark Brown Cc: "linux-spi@vger.kernel.org" Message-ID: <560AFF89.5000907@gmail.com> Date: Tue, 29 Sep 2015 23:15:53 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_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 Change the bitbang driver to use the generic implementation of transfer_one_message. This simplifies the bitbang driver code and provides benefits like the statistics in the generic implementation. Successfully tested on a IMX6-based system (spi-imx) and on a MIPS-based router (OpenWRT with spi-ath79). Signed-off-by: Heiner Kallweit --- drivers/spi/spi-bitbang.c | 125 +++++++++++++--------------------------------- 1 file changed, 36 insertions(+), 89 deletions(-) diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index ad3168d..7f5ffbf 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -24,6 +24,8 @@ #include #include +#define SPI_BITBANG_CS_DELAY 100 + /*----------------------------------------------------------------------*/ @@ -265,100 +267,28 @@ static int spi_bitbang_prepare_hardware(struct spi_master *spi) } static int spi_bitbang_transfer_one(struct spi_master *master, - struct spi_message *m) + struct spi_device *spi, + struct spi_transfer *transfer) { - struct spi_bitbang *bitbang; - unsigned nsecs; - struct spi_transfer *t = NULL; - unsigned cs_change; - int status; - struct spi_device *spi = m->spi; - - bitbang = spi_master_get_devdata(master); - - /* FIXME this is made-up ... the correct value is known to - * word-at-a-time bitbang code, and presumably chipselect() - * should enforce these requirements too? - */ - nsecs = 100; - - cs_change = 1; - status = 0; - - list_for_each_entry(t, &m->transfers, transfer_list) { - - if (bitbang->setup_transfer) { - status = bitbang->setup_transfer(spi, t); - if (status < 0) - break; - } - - /* set up default clock polarity, and activate chip; - * this implicitly updates clock and spi modes as - * previously recorded for this device via setup(). - * (and also deselects any other chip that might be - * selected ...) - */ - if (cs_change) { - bitbang->chipselect(spi, BITBANG_CS_ACTIVE); - ndelay(nsecs); - } - cs_change = t->cs_change; - if (!t->tx_buf && !t->rx_buf && t->len) { - status = -EINVAL; - break; - } - - /* transfer data. the lower level code handles any - * new dma mappings it needs. our caller always gave - * us dma-safe buffers. - */ - if (t->len) { - /* REVISIT dma API still needs a designated - * DMA_ADDR_INVALID; ~0 might be better. - */ - if (!m->is_dma_mapped) - t->rx_dma = t->tx_dma = 0; - status = bitbang->txrx_bufs(spi, t); - } - if (status > 0) - m->actual_length += status; - if (status != t->len) { - /* always report some kind of error */ - if (status >= 0) - status = -EREMOTEIO; - break; - } - status = 0; + struct spi_bitbang *bitbang = spi_master_get_devdata(master); + int status = 0; - /* protocol tweaks before next transfer */ - if (t->delay_usecs) - udelay(t->delay_usecs); - - if (cs_change && - !list_is_last(&t->transfer_list, &m->transfers)) { - /* sometimes a short mid-message deselect of the chip - * may be needed to terminate a mode or command - */ - ndelay(nsecs); - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (bitbang->setup_transfer) { + status = bitbang->setup_transfer(spi, transfer); + if (status < 0) + goto out; } - m->status = status; + if (transfer->len) + status = bitbang->txrx_bufs(spi, transfer); - /* normally deactivate chipselect ... unless no error and - * cs_change has hinted that the next message will probably - * be for this chip too. - */ - if (!(status == 0 && cs_change)) { - ndelay(nsecs); - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); - ndelay(nsecs); - } + if (status == transfer->len) + status = 0; + else if (status >= 0) + status = -EREMOTEIO; - spi_finalize_current_message(master); +out: + spi_finalize_current_transfer(master); return status; } @@ -376,6 +306,22 @@ static int spi_bitbang_unprepare_hardware(struct spi_master *spi) return 0; } +static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) +{ + struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); + + /* SPI core provides CS high / low, but bitbang driver + * expects CS active + * spi device driver takes care of handling SPI_CS_HIGH + */ + enable = (!!(spi->mode & SPI_CS_HIGH) == enable); + + ndelay(SPI_BITBANG_CS_DELAY); + bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE : + BITBANG_CS_INACTIVE); + ndelay(SPI_BITBANG_CS_DELAY); +} + /*----------------------------------------------------------------------*/ /** @@ -424,7 +370,8 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; - master->transfer_one_message = spi_bitbang_transfer_one; + master->transfer_one = spi_bitbang_transfer_one; + master->set_cs = spi_bitbang_set_cs; if (!bitbang->txrx_bufs) { bitbang->use_dma = 0;