From patchwork Sun Jan 26 08:14:34 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 3539581 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6CCAA9F39E for ; Sun, 26 Jan 2014 08:15:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C1B7720142 for ; Sun, 26 Jan 2014 08:15:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0BBE320165 for ; Sun, 26 Jan 2014 08:15:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752511AbaAZIO6 (ORCPT ); Sun, 26 Jan 2014 03:14:58 -0500 Received: from guitar.tcltek.co.il ([192.115.133.116]:39209 "EHLO mx.tkos.co.il" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752465AbaAZIO6 (ORCPT ); Sun, 26 Jan 2014 03:14:58 -0500 Received: from tarshish.tkos.co.il (unknown [10.0.8.6]) by mx.tkos.co.il (Postfix) with ESMTPSA id 7E410440AB5; Sun, 26 Jan 2014 10:14:56 +0200 (IST) From: Baruch Siach To: Mark Brown Cc: linux-spi@vger.kernel.org, Baruch Siach Subject: [PATCH v2 3/5] spi: dw: add support for gpio controlled chip select Date: Sun, 26 Jan 2014 10:14:34 +0200 Message-Id: X-Mailer: git-send-email 1.8.5.2 In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 Signed-off-by: Baruch Siach --- drivers/spi/spi-dw.c | 26 +++++++++++++++++++++++--- drivers/spi/spi-dw.h | 6 +++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index bf98d63d92b3..69b8772b3ed8 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "spi-dw.h" @@ -265,6 +266,8 @@ static void giveback(struct dw_spi *dws) struct spi_transfer *last_transfer; unsigned long flags; struct spi_message *msg; + int cs_gpio = dws->cur_msg->spi->cs_gpio; + u16 mode = dws->cur_msg->spi->mode; spin_lock_irqsave(&dws->lock, flags); msg = dws->cur_msg; @@ -280,8 +283,12 @@ static void giveback(struct dw_spi *dws) struct spi_transfer, transfer_list); - if (!last_transfer->cs_change && dws->cs_control) - dws->cs_control(MRST_SPI_DEASSERT); + if (!last_transfer->cs_change) { + if (dws->cs_control) + dws->cs_control(MRST_SPI_DEASSERT); + if (gpio_is_valid(cs_gpio)) + gpio_set_value(cs_gpio, !(mode & SPI_CS_HIGH)); + } msg->state = NULL; if (msg->complete) @@ -509,7 +516,8 @@ static void pump_transfers(unsigned long data) dw_writew(dws, DW_SPI_CTRL0, cr0); spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); - spi_chip_sel(dws, spi->chip_select); + spi_chip_sel(dws, spi->chip_select, spi->cs_gpio, + spi->mode & SPI_CS_HIGH); /* Set the interrupt mask, for poll mode just disable all int */ spi_mask_intr(dws, 0xff); @@ -615,6 +623,7 @@ static int dw_spi_setup(struct spi_device *spi) { struct dw_spi_chip *chip_info = NULL; struct chip_data *chip; + int ret; /* Only alloc on first setup */ chip = spi_get_ctldata(spi); @@ -668,6 +677,17 @@ static int dw_spi_setup(struct spi_device *spi) | (spi->mode << SPI_MODE_OFFSET) | (chip->tmode << SPI_TMOD_OFFSET); + if (gpio_is_valid(spi->cs_gpio)) { + ret = devm_gpio_request(&spi->dev, spi->cs_gpio, + dev_name(&spi->dev)); + if (ret) + return ret; + ret = gpio_direction_output(spi->cs_gpio, + !(spi->mode & SPI_CS_HIGH)); + if (ret) + return ret; + } + return 0; } diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 587643dae11e..4a3a6d764b48 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -3,6 +3,7 @@ #include #include +#include /* Register offsets */ #define DW_SPI_CTRL0 0x00 @@ -186,13 +187,16 @@ static inline void spi_set_clk(struct dw_spi *dws, u16 div) dw_writel(dws, DW_SPI_BAUDR, div); } -static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) +static inline void spi_chip_sel(struct dw_spi *dws, u16 cs, int cs_gpio, + int gpio_active_val) { if (cs > dws->num_cs) return; if (dws->cs_control) dws->cs_control(1); + if (gpio_is_valid(cs_gpio)) + gpio_set_value(cs_gpio, gpio_active_val); dw_writel(dws, DW_SPI_SER, 1 << cs); }