From mboxrd@z Thu Jan 1 00:00:00 1970 From: Raffaele Recalcati Subject: [PATCH] spi: davinci: Added support for chip select using gpio Date: Mon, 28 Jun 2010 08:47:35 +0200 Message-ID: <1277707655-3468-1-git-send-email-lamiaposta71@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Cc: spi-devel-general@lists.sourceforge.net, David Brownell , Russell King , Thomas Koeller , Sudhakar Rajashekhara , linux-kernel@vger.kernel.org, Sandeep Paulraj , Grant Likely , Davide Bonfanti , Raffaele Recalcati , linux-arm-kernel@lists.infradead.org, Cyril Chemparathy , Philby John , Miguel Aguilar To: davinci-linux-open-source@linux.davincidsp.com Return-path: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org List-Id: linux-spi.vger.kernel.org From: Raffaele Recalcati It is not everytime possible, due to hardware constraints, to use the hw chip select available on spi port. So I add this possibility using a gpio as chip select. If controller_data variable is not null it is the gpio to be used as chip select. The default case is compatible with evmdm365. This patch has been developed against the http://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-davinci.git git tree and has been tested on bmx board (similar to dm365 evm but with gpio as spi chip select). Signed-off-by: Raffaele Recalcati Signed-off-by: Davide Bonfanti --- arch/arm/mach-davinci/dm365.c | 10 ++++++---- drivers/spi/davinci_spi.c | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index a146849..42fd4a4 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c @@ -677,10 +677,12 @@ void __init dm365_init_spi0(unsigned chipselect_mask, davinci_cfg_reg(DM365_SPI0_SDO); /* not all slaves will be wired up */ - if (chipselect_mask & BIT(0)) - davinci_cfg_reg(DM365_SPI0_SDENA0); - if (chipselect_mask & BIT(1)) - davinci_cfg_reg(DM365_SPI0_SDENA1); + if (!((unsigned long) info->controller_data)) { + if (chipselect_mask & BIT(0)) + davinci_cfg_reg(DM365_SPI0_SDENA0); + if (chipselect_mask & BIT(1)) + davinci_cfg_reg(DM365_SPI0_SDENA1); + } spi_register_board_info(info, len); diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 95afb6b..621ae46 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -270,18 +271,26 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value) pdata = davinci_spi->pdata; /* - * Board specific chip select logic decides the polarity and cs - * line for the controller - */ + * Board specific chip select logic decides the polarity and cs + * line for the controller + */ if (value == BITBANG_CS_INACTIVE) { - set_io_bits(davinci_spi->base + SPIDEF, CS_DEFAULT); - - data1_reg_val |= CS_DEFAULT << SPIDAT1_CSNR_SHIFT; - iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); - + if ((unsigned long) spi->controller_data) { + gpio_set_value(spi->controller_data, \ + !(spi->mode & SPI_CS_HIGH)); + } else { + set_io_bits(davinci_spi->base + SPIDEF, CS_DEFAULT); + + data1_reg_val |= CS_DEFAULT << SPIDAT1_CSNR_SHIFT; + iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); + } while ((ioread32(davinci_spi->base + SPIBUF) - & SPIBUF_RXEMPTY_MASK) == 0) + & SPIBUF_RXEMPTY_MASK) == 0) cpu_relax(); + } else { + if ((unsigned long) spi->controller_data) + gpio_set_value(spi->controller_data, \ + (spi->mode & SPI_CS_HIGH)); } } -- 1.7.0.4