1d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* 2ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely * SPI master driver using generic bitbanged GPIO 3d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 4d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * Copyright (C) 2006,2008 David Brownell 5d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 6d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * This program is free software; you can redistribute it and/or modify 7d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * it under the terms of the GNU General Public License as published by 8d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * the Free Software Foundation; either version 2 of the License, or 9d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * (at your option) any later version. 10d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 11d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * This program is distributed in the hope that it will be useful, 12d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * GNU General Public License for more details. 15d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 16d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * You should have received a copy of the GNU General Public License 17d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * along with this program; if not, write to the Free Software 18d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell */ 20d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/kernel.h> 21d7614de422c0b55db0c1013a6c72330187536004Paul Gortmaker#include <linux/module.h> 22d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/init.h> 23d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/platform_device.h> 24d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/gpio.h> 25d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 26d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/spi/spi.h> 27d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/spi/spi_bitbang.h> 28d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#include <linux/spi/spi_gpio.h> 29d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 30d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 31d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* 32d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * This bitbanging SPI master driver should help make systems usable 33d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * when a native hardware SPI engine is not available, perhaps because 34d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * its driver isn't yet working or because the I/O pins it requires 35d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * are used for other purposes. 36d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 37d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * platform_device->driver_data ... points to spi_gpio 38d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 39d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * spi->controller_state ... reserved for bitbang framework code 40d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * spi->controller_data ... holds chipselect GPIO 41d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 42d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * spi->master->dev.driver_data ... points to spi_gpio->bitbang 43d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell */ 44d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 45d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstruct spi_gpio { 46d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_bitbang bitbang; 47d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_gpio_platform_data pdata; 48d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct platform_device *pdev; 49d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell}; 50d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 51d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/*----------------------------------------------------------------------*/ 52d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 53d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* 54d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * Because the overhead of going through four GPIO procedure calls 55d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * per transferred bit can make performance a problem, this code 56d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * is set up so that you can use it in either of two ways: 57d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 58d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * - The slow generic way: set up platform_data to hold the GPIO 59d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * numbers used for MISO/MOSI/SCK, and issue procedure calls for 60d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * each of them. This driver can handle several such busses. 61d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 62d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * - The quicker inlined way: only helps with platform GPIO code 63d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * that inlines operations for constant GPIOs. This can give 64d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * you tight (fast!) inner loops, but each such bus needs a 65d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * new driver. You'll define a new C file, with Makefile and 66d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * Kconfig support; the C code can be a total of six lines: 67d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 68d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * #define DRIVER_NAME "myboard_spi2" 69d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * #define SPI_MISO_GPIO 119 70d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * #define SPI_MOSI_GPIO 120 71d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * #define SPI_SCK_GPIO 121 72d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * #define SPI_N_CHIPSEL 4 73ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely * #include "spi-gpio.c" 74d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell */ 75d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 76d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#ifndef DRIVER_NAME 77d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define DRIVER_NAME "spi_gpio" 78d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 79d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define GENERIC_BITBANG /* vs tight inlines */ 80d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 81d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* all functions referencing these symbols must define pdata */ 82d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define SPI_MISO_GPIO ((pdata)->miso) 83d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define SPI_MOSI_GPIO ((pdata)->mosi) 84d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define SPI_SCK_GPIO ((pdata)->sck) 85d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 86d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define SPI_N_CHIPSEL ((pdata)->num_chipselect) 87d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 88d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#endif 89d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 90d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/*----------------------------------------------------------------------*/ 91d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 92d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic inline const struct spi_gpio_platform_data * __pure 93d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellspi_to_pdata(const struct spi_device *spi) 94d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 95d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell const struct spi_bitbang *bang; 96d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell const struct spi_gpio *spi_gpio; 97d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 98d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell bang = spi_master_get_devdata(spi->master); 99d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio = container_of(bang, struct spi_gpio, bitbang); 100d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return &spi_gpio->pdata; 101d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 102d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 103d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* this is #defined to avoid unused-variable warnings when inlining */ 104d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define pdata spi_to_pdata(spi) 105d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 106d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic inline void setsck(const struct spi_device *spi, int is_on) 107d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 108d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell gpio_set_value(SPI_SCK_GPIO, is_on); 109d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 110d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 111d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic inline void setmosi(const struct spi_device *spi, int is_on) 112d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 113d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell gpio_set_value(SPI_MOSI_GPIO, is_on); 114d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 115d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 116d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic inline int getmiso(const struct spi_device *spi) 117d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 118be50344e604f956891fc0013f1ba78823a758124Michael Buesch return !!gpio_get_value(SPI_MISO_GPIO); 119d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 120d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 121d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#undef pdata 122d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 123d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* 124d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * NOTE: this clocks "as fast as we can". It "should" be a function of the 125d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * requested device clock. Software overhead means we usually have trouble 126d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * reaching even one Mbit/sec (except when we can inline bitops), so for now 127d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * we'll just assume we never need additional per-bit slowdowns. 128d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell */ 129d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#define spidelay(nsecs) do {} while (0) 130d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 131ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#include "spi-bitbang-txrx.h" 132d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 133d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/* 134d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * These functions can leverage inline expansion of GPIO calls to shrink 135d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * costs for a txrx bit, often by factors of around ten (by instruction 136d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * count). That is particularly visible for larger word sizes, but helps 137d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * even with default 8-bit words. 138d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * 139d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * REVISIT overheads calling these functions for each word also have 140d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * significant performance costs. Having txrx_bufs() calls that inline 141d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * the txrx_word() logic would help performance, e.g. on larger blocks 142d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * used with flash storage or MMC/SD. There should also be ways to make 143d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * GCC be less stupid about reloading registers inside the I/O loops, 144d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? 145d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell */ 146d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 147d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, 148d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned nsecs, u32 word, u8 bits) 149d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 15004bb2a031cf95b34b7432dd47b318a932a895b4cMarek Szyprowski return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); 151d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 152d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 153d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, 154d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned nsecs, u32 word, u8 bits) 155d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 15604bb2a031cf95b34b7432dd47b318a932a895b4cMarek Szyprowski return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); 157d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 158d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 159d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, 160d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned nsecs, u32 word, u8 bits) 161d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 16204bb2a031cf95b34b7432dd47b318a932a895b4cMarek Szyprowski return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); 163d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 164d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 165d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, 166d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned nsecs, u32 word, u8 bits) 167d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 16804bb2a031cf95b34b7432dd47b318a932a895b4cMarek Szyprowski return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); 169d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 170d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 1713c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski/* 1723c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * These functions do not call setmosi or getmiso if respective flag 1733c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to 1743c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * call when such pin is not present or defined in the controller. 1753c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * A separate set of callbacks is defined to get highest possible 1763c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * speed in the generic case (when both MISO and MOSI lines are 1773c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * available), as optimiser will remove the checks when argument is 1783c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski * constant. 1793c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski */ 1803c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 1813c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowskistatic u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, 1823c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned nsecs, u32 word, u8 bits) 1833c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski{ 1843c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned flags = spi->master->flags; 1853c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); 1863c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski} 1873c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 1883c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowskistatic u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, 1893c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned nsecs, u32 word, u8 bits) 1903c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski{ 1913c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned flags = spi->master->flags; 1923c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); 1933c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski} 1943c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 1953c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowskistatic u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, 1963c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned nsecs, u32 word, u8 bits) 1973c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski{ 1983c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned flags = spi->master->flags; 1993c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); 2003c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski} 2013c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 2023c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowskistatic u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, 2033c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned nsecs, u32 word, u8 bits) 2043c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski{ 2053c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski unsigned flags = spi->master->flags; 2063c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); 2073c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski} 2083c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 209d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell/*----------------------------------------------------------------------*/ 210d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 211d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic void spi_gpio_chipselect(struct spi_device *spi, int is_active) 212d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 213d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned long cs = (unsigned long) spi->controller_data; 214d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 215d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell /* set initial clock polarity */ 216d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (is_active) 217d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell setsck(spi, spi->mode & SPI_CPOL); 218d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 219bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch if (cs != SPI_GPIO_NO_CHIPSELECT) { 220bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch /* SPI is normally active-low */ 221bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); 222bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch } 223d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 224d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 225d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic int spi_gpio_setup(struct spi_device *spi) 226d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 227d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned long cs = (unsigned long) spi->controller_data; 228d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell int status = 0; 229d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 230d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (spi->bits_per_word > 32) 231d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return -EINVAL; 232d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 233d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (!spi->controller_state) { 234bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch if (cs != SPI_GPIO_NO_CHIPSELECT) { 235bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch status = gpio_request(cs, dev_name(&spi->dev)); 236bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch if (status) 237bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch return status; 238bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); 239bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch } 240d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell } 241d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (!status) 242d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell status = spi_bitbang_setup(spi); 243d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (status) { 244bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT) 245d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell gpio_free(cs); 246d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell } 247d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return status; 248d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 249d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 250d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic void spi_gpio_cleanup(struct spi_device *spi) 251d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 252d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell unsigned long cs = (unsigned long) spi->controller_data; 253d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 254bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch if (cs != SPI_GPIO_NO_CHIPSELECT) 255bfb9bcdbda9a61bca469bf899a589918c60c4c18Michael Buesch gpio_free(cs); 256d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_bitbang_cleanup(spi); 257d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 258d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 259c65b53ba4f9ca4520078bab23099579da3bf0446Manuel Laussstatic int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in) 260d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 261d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell int value; 262d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 263d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell value = gpio_request(pin, label); 264d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (value == 0) { 265d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (is_in) 266d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell value = gpio_direction_input(pin); 267d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell else 268d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell value = gpio_direction_output(pin, 0); 269d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell } 270d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return value; 271d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 272d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 273c65b53ba4f9ca4520078bab23099579da3bf0446Manuel Laussstatic int __devinit 2743c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowskispi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, 2753c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski u16 *res_flags) 276d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 277d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell int value; 278d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 279d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell /* NOTE: SPI_*_GPIO symbols may reference "pdata" */ 280d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 2813c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) { 2823c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false); 2833c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (value) 2843c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski goto done; 2853c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } else { 2863c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski /* HW configuration without MOSI pin */ 2873c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski *res_flags |= SPI_MASTER_NO_TX; 2883c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } 289d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 2903c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) { 2913c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski value = spi_gpio_alloc(SPI_MISO_GPIO, label, true); 2923c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (value) 2933c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski goto free_mosi; 2943c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } else { 2953c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski /* HW configuration without MISO pin */ 2963c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski *res_flags |= SPI_MASTER_NO_RX; 2973c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } 298d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 299d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell value = spi_gpio_alloc(SPI_SCK_GPIO, label, false); 300d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (value) 301d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell goto free_miso; 302d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 303d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell goto done; 304d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 305d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellfree_miso: 3063c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) 3073c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MISO_GPIO); 308d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellfree_mosi: 3093c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) 3103c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MOSI_GPIO); 311d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownelldone: 312d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return value; 313d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 314d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 315940ab88962bc1aff3273a8356d64577a6e386736Grant Likelystatic int __devinit spi_gpio_probe(struct platform_device *pdev) 316d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 317d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell int status; 318d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_master *master; 319d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_gpio *spi_gpio; 320d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_gpio_platform_data *pdata; 3213c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski u16 master_flags = 0; 322d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 323d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell pdata = pdev->dev.platform_data; 324d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#ifdef GENERIC_BITBANG 325d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (!pdata || !pdata->num_chipselect) 326d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return -ENODEV; 327d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell#endif 328d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 3293c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags); 330d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (status < 0) 331d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return status; 332d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 333d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell master = spi_alloc_master(&pdev->dev, sizeof *spi_gpio); 334d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (!master) { 335d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell status = -ENOMEM; 336d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell goto gpio_free; 337d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell } 338d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio = spi_master_get_devdata(master); 339d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell platform_set_drvdata(pdev, spi_gpio); 340d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 341d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->pdev = pdev; 342d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (pdata) 343d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->pdata = *pdata; 344d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 3453c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski master->flags = master_flags; 346d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell master->bus_num = pdev->id; 347d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell master->num_chipselect = SPI_N_CHIPSEL; 348d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell master->setup = spi_gpio_setup; 349d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell master->cleanup = spi_gpio_cleanup; 350d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 351d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->bitbang.master = spi_master_get(master); 352d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->bitbang.chipselect = spi_gpio_chipselect; 3533c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski 35423699f98f84f20195fddd0263d05a8ccb8694676Roel Kluin if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { 3553c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; 3563c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; 3573c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; 3583c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; 3593c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } else { 3603c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0; 3613c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1; 3623c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2; 3633c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3; 3643c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski } 365d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer; 366d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio->bitbang.flags = SPI_CS_HIGH; 367d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 368d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell status = spi_bitbang_start(&spi_gpio->bitbang); 369d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell if (status < 0) { 370d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_master_put(spi_gpio->bitbang.master); 371d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellgpio_free: 3723c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) 3733c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MISO_GPIO); 3743c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) 3753c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MOSI_GPIO); 376d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell gpio_free(SPI_SCK_GPIO); 377d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_master_put(master); 378d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell } 379d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 380d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return status; 381d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 382d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 383940ab88962bc1aff3273a8356d64577a6e386736Grant Likelystatic int __devexit spi_gpio_remove(struct platform_device *pdev) 384d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell{ 385d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_gpio *spi_gpio; 386d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell struct spi_gpio_platform_data *pdata; 387d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell int status; 388d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 389d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_gpio = platform_get_drvdata(pdev); 390d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell pdata = pdev->dev.platform_data; 391d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 392d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell /* stop() unregisters child devices too */ 393d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell status = spi_bitbang_stop(&spi_gpio->bitbang); 394d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell spi_master_put(spi_gpio->bitbang.master); 395d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 396d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell platform_set_drvdata(pdev, NULL); 397d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 3983c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) 3993c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MISO_GPIO); 4003c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) 4013c8e1a84fd6b984a7bce8816db2e3defc57bbfe4Marek Szyprowski gpio_free(SPI_MOSI_GPIO); 402d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell gpio_free(SPI_SCK_GPIO); 403d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 404d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell return status; 405d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell} 406d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 407d29389de0b0ee1715333bafc6ac3f22a75aa4313David BrownellMODULE_ALIAS("platform:" DRIVER_NAME); 408d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 409d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownellstatic struct platform_driver spi_gpio_driver = { 410d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell .driver.name = DRIVER_NAME, 411d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell .driver.owner = THIS_MODULE, 412940ab88962bc1aff3273a8356d64577a6e386736Grant Likely .probe = spi_gpio_probe, 413940ab88962bc1aff3273a8356d64577a6e386736Grant Likely .remove = __devexit_p(spi_gpio_remove), 414d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell}; 415940ab88962bc1aff3273a8356d64577a6e386736Grant Likelymodule_platform_driver(spi_gpio_driver); 416d29389de0b0ee1715333bafc6ac3f22a75aa4313David Brownell 417d29389de0b0ee1715333bafc6ac3f22a75aa4313David BrownellMODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); 418d29389de0b0ee1715333bafc6ac3f22a75aa4313David BrownellMODULE_AUTHOR("David Brownell"); 419d29389de0b0ee1715333bafc6ac3f22a75aa4313David BrownellMODULE_LICENSE("GPL"); 420