From patchwork Thu Jul 31 17:33:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grygorii Strashko X-Patchwork-Id: 34681 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pd0-f198.google.com (mail-pd0-f198.google.com [209.85.192.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id BF5E920540 for ; Thu, 31 Jul 2014 16:48:45 +0000 (UTC) Received: by mail-pd0-f198.google.com with SMTP id fp1sf17163072pdb.1 for ; Thu, 31 Jul 2014 09:48:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=KeMRzb5StonFLnmmR+HZj8HbF0AtGmY1Dgkw9gjdg/c=; b=FKaQ7ZVgik86CAiOSg1WhKO/fePTIA5KkT35fQET9oYygYAjI5F/xEZjr5jjBXCIz6 IEGcDW8bgorF1GM9/cLeqBoQNdXzZX0aDfhDHvLiwvm/Z3TqnQ4sqkUbCMQ1NA1rlUEJ lq+wCu/b9zGh6TmZLYYceNq4xGwB2Hxb/Le6Iyt3dQOOXh8iPwl1/CYKSPSDDsGHw5/e 1EmRklMYrmUuO03BC09d5JbScFfFyfJaxBDRSTkUWez69Ttpep2+6Vbrf16TcADbusK8 F8bwwBzJ98qc9U/I260GIKkCd+NBZL/5SGB+FT3w1ApPOjmkszUcbwlMHzOmZfV244gZ OZ8Q== X-Gm-Message-State: ALoCoQnvIls07v0W/yI550INcApWzR8MKTLO7XdEJgtpPopQ0vUWsoOyDdv2t/Ys08ZDjBFTN46e X-Received: by 10.66.145.33 with SMTP id sr1mr2007723pab.18.1406825325095; Thu, 31 Jul 2014 09:48:45 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.18.194 with SMTP id 60ls1018645qgf.7.gmail; Thu, 31 Jul 2014 09:48:44 -0700 (PDT) X-Received: by 10.52.141.76 with SMTP id rm12mr10607479vdb.71.1406825324843; Thu, 31 Jul 2014 09:48:44 -0700 (PDT) Received: from mail-vc0-f176.google.com (mail-vc0-f176.google.com [209.85.220.176]) by mx.google.com with ESMTPS id ag1si5015929vec.32.2014.07.31.09.48.44 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 31 Jul 2014 09:48:44 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) client-ip=209.85.220.176; Received: by mail-vc0-f176.google.com with SMTP id id10so4650691vcb.35 for ; Thu, 31 Jul 2014 09:48:44 -0700 (PDT) X-Received: by 10.52.248.146 with SMTP id ym18mr16359727vdc.8.1406825324755; Thu, 31 Jul 2014 09:48:44 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.37.5 with SMTP id tc5csp33453vcb; Thu, 31 Jul 2014 09:48:44 -0700 (PDT) X-Received: by 10.70.41.79 with SMTP id d15mr2966056pdl.15.1406825323323; Thu, 31 Jul 2014 09:48:43 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bc15si3302625pdb.17.2014.07.31.09.48.42 for ; Thu, 31 Jul 2014 09:48:43 -0700 (PDT) Received-SPF: none (google.com: devicetree-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752182AbaGaQsj (ORCPT + 6 others); Thu, 31 Jul 2014 12:48:39 -0400 Received: from devils.ext.ti.com ([198.47.26.153]:49753 "EHLO devils.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752715AbaGaQsh (ORCPT ); Thu, 31 Jul 2014 12:48:37 -0400 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id s6VGm8ht020210; Thu, 31 Jul 2014 11:48:08 -0500 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6VGm8kR010734; Thu, 31 Jul 2014 11:48:08 -0500 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.174.1; Thu, 31 Jul 2014 11:48:08 -0500 Received: from localhost (dlep60.itg.ti.com [157.170.170.21]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s6VGm7QG010072; Thu, 31 Jul 2014 11:48:08 -0500 From: Grygorii Strashko To: , Mark Brown , CC: , Rob Herring , Ian Campbell , , Murali Karicheri , Grygorii Strashko Subject: [PATCH 2/2] spi: davinci: add support to configure gpio cs through dt Date: Thu, 31 Jul 2014 20:33:15 +0300 Message-ID: <1406827995-30913-3-git-send-email-grygorii.strashko@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1406827995-30913-1-git-send-email-grygorii.strashko@ti.com> References: <1406827995-30913-1-git-send-email-grygorii.strashko@ti.com> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: devicetree@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: patch@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.176 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Murali Karicheri Currently driver supports only configuration of GPIO CS through platform data. This patch enhances the driver to configure GPIO CS through DT. Also update the DT binding documentation to reflect the availability of cs-gpios. Signed-off-by: Murali Karicheri Signed-off-by: Grygorii Strashko --- .../devicetree/bindings/spi/spi-davinci.txt | 9 ++- drivers/spi/spi-davinci.c | 59 +++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt index 6d0ac8d..f80887b 100644 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt @@ -8,7 +8,8 @@ Required properties: - "ti,dm6441-spi" for SPI used similar to that on DM644x SoC family - "ti,da830-spi" for SPI used similar to that on DA8xx SoC family - reg: Offset and length of SPI controller register space -- num-cs: Number of chip selects +- num-cs: Number of chip selects. This includes internal as well as + GPIO chip selects. - ti,davinci-spi-intr-line: interrupt line used to connect the SPI IP to the interrupt controller within the SoC. Possible values are 0 and 1. Manual says one of the two possible interrupt @@ -17,6 +18,12 @@ Required properties: - interrupts: interrupt number mapped to CPU. - clocks: spi clk phandle +Optional: +- cs-gpios: gpio chip selects + For example to have 3 internal CS and 2 GPIO CS, user could define + cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; + where first three are internal CS and last two are GPIO CS. + Example of a NOR flash slave device (n25q032) connected to DaVinci SPI controller device over the SPI bus. diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 2477af4..6aa04d1 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -207,17 +208,28 @@ static inline void clear_io_bits(void __iomem *addr, u32 bits) static void davinci_spi_chipselect(struct spi_device *spi, int value) { struct davinci_spi *dspi; + struct device_node *np = spi->dev.of_node; struct davinci_spi_platform_data *pdata; + struct spi_master *master = spi->master; u8 chip_sel = spi->chip_select; u16 spidat1 = CS_DEFAULT; bool gpio_chipsel = false; + int gpio; dspi = spi_master_get_devdata(spi->master); pdata = &dspi->pdata; - if (pdata->chip_sel && chip_sel < pdata->num_chipselect && - pdata->chip_sel[chip_sel] != SPI_INTERN_CS) + if (np && master->cs_gpios != NULL && spi->cs_gpio >= 0) { + /* SPI core parse and update master->cs_gpio */ gpio_chipsel = true; + gpio = spi->cs_gpio; + } else if (pdata->chip_sel && + chip_sel < pdata->num_chipselect && + pdata->chip_sel[chip_sel] != SPI_INTERN_CS) { + /* platform data defines chip_sel */ + gpio_chipsel = true; + gpio = pdata->chip_sel[chip_sel]; + } /* * Board specific chip select logic decides the polarity and cs @@ -225,9 +237,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) */ if (gpio_chipsel) { if (value == BITBANG_CS_ACTIVE) - gpio_set_value(pdata->chip_sel[chip_sel], 0); + gpio_set_value(gpio, 0); else - gpio_set_value(pdata->chip_sel[chip_sel], 1); + gpio_set_value(gpio, 1); } else { if (value == BITBANG_CS_ACTIVE) { spidat1 |= SPIDAT1_CSHOLD_MASK; @@ -390,17 +402,36 @@ static int davinci_spi_setup(struct spi_device *spi) int retval = 0; struct davinci_spi *dspi; struct davinci_spi_platform_data *pdata; + struct spi_master *master = spi->master; + struct device_node *np = spi->dev.of_node; + bool internal_cs = true; dspi = spi_master_get_devdata(spi->master); pdata = &dspi->pdata; if (!(spi->mode & SPI_NO_CS)) { - if ((pdata->chip_sel == NULL) || - (pdata->chip_sel[spi->chip_select] == SPI_INTERN_CS)) - set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); - + if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) { + retval = + gpio_request(spi->cs_gpio, dev_name(&spi->dev)); + if (retval) { + dev_err(&spi->dev, + "GPIO %d request failed\n", + spi->cs_gpio); + return -ENODEV; + } + gpio_direction_output(spi->cs_gpio, + !(spi->mode & SPI_CS_HIGH)); + internal_cs = false; + } else if (pdata->chip_sel && + spi->chip_select < pdata->num_chipselect && + pdata->chip_sel[spi->chip_select] != SPI_INTERN_CS) { + internal_cs = false; + } } + if (internal_cs) + set_io_bits(dspi->base + SPIPC0, 1 << spi->chip_select); + if (spi->mode & SPI_READY) set_io_bits(dspi->base + SPIPC0, SPIPC0_SPIENA_MASK); @@ -412,6 +443,15 @@ static int davinci_spi_setup(struct spi_device *spi) return retval; } +static void davinci_spi_cleanup(struct spi_device *spi) +{ + struct spi_master *master = spi->master; + struct device_node *np = spi->dev.of_node; + + if (np && (master->cs_gpios != NULL) && (spi->cs_gpio >= 0)) + gpio_free(spi->cs_gpio); +} + static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status) { struct device *sdev = dspi->bitbang.master->dev.parent; @@ -810,6 +850,8 @@ static int spi_davinci_get_pdata(struct platform_device *pdev, /* * default num_cs is 1 and all chipsel are internal to the chip + * indicated by chip_sel being NULL or cs_gpios being NULL or + * set to -ENOENT. num-cs includes internal as well as gpios. * indicated by chip_sel being NULL. GPIO based CS is not * supported yet in DT bindings. */ @@ -921,6 +963,7 @@ static int davinci_spi_probe(struct platform_device *pdev) master->num_chipselect = pdata->num_chipselect; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16); master->setup = davinci_spi_setup; + master->cleanup = davinci_spi_cleanup; dspi->bitbang.chipselect = davinci_spi_chipselect; dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;