18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * SPI master driver using generic bitbanged GPIO 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2006,2008 David Brownell 68c2ecf20Sopenharmony_ci * Copyright (C) 2017 Linus Walleij 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include <linux/module.h> 108c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 118c2ecf20Sopenharmony_ci#include <linux/gpio/consumer.h> 128c2ecf20Sopenharmony_ci#include <linux/of.h> 138c2ecf20Sopenharmony_ci#include <linux/of_device.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 168c2ecf20Sopenharmony_ci#include <linux/spi/spi_bitbang.h> 178c2ecf20Sopenharmony_ci#include <linux/spi/spi_gpio.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * This bitbanging SPI master driver should help make systems usable 228c2ecf20Sopenharmony_ci * when a native hardware SPI engine is not available, perhaps because 238c2ecf20Sopenharmony_ci * its driver isn't yet working or because the I/O pins it requires 248c2ecf20Sopenharmony_ci * are used for other purposes. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * platform_device->driver_data ... points to spi_gpio 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * spi->controller_state ... reserved for bitbang framework code 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * spi->master->dev.driver_data ... points to spi_gpio->bitbang 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistruct spi_gpio { 348c2ecf20Sopenharmony_ci struct spi_bitbang bitbang; 358c2ecf20Sopenharmony_ci struct gpio_desc *sck; 368c2ecf20Sopenharmony_ci struct gpio_desc *miso; 378c2ecf20Sopenharmony_ci struct gpio_desc *mosi; 388c2ecf20Sopenharmony_ci struct gpio_desc **cs_gpios; 398c2ecf20Sopenharmony_ci}; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------*/ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* 448c2ecf20Sopenharmony_ci * Because the overhead of going through four GPIO procedure calls 458c2ecf20Sopenharmony_ci * per transferred bit can make performance a problem, this code 468c2ecf20Sopenharmony_ci * is set up so that you can use it in either of two ways: 478c2ecf20Sopenharmony_ci * 488c2ecf20Sopenharmony_ci * - The slow generic way: set up platform_data to hold the GPIO 498c2ecf20Sopenharmony_ci * numbers used for MISO/MOSI/SCK, and issue procedure calls for 508c2ecf20Sopenharmony_ci * each of them. This driver can handle several such busses. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * - The quicker inlined way: only helps with platform GPIO code 538c2ecf20Sopenharmony_ci * that inlines operations for constant GPIOs. This can give 548c2ecf20Sopenharmony_ci * you tight (fast!) inner loops, but each such bus needs a 558c2ecf20Sopenharmony_ci * new driver. You'll define a new C file, with Makefile and 568c2ecf20Sopenharmony_ci * Kconfig support; the C code can be a total of six lines: 578c2ecf20Sopenharmony_ci * 588c2ecf20Sopenharmony_ci * #define DRIVER_NAME "myboard_spi2" 598c2ecf20Sopenharmony_ci * #define SPI_MISO_GPIO 119 608c2ecf20Sopenharmony_ci * #define SPI_MOSI_GPIO 120 618c2ecf20Sopenharmony_ci * #define SPI_SCK_GPIO 121 628c2ecf20Sopenharmony_ci * #define SPI_N_CHIPSEL 4 638c2ecf20Sopenharmony_ci * #include "spi-gpio.c" 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci#ifndef DRIVER_NAME 678c2ecf20Sopenharmony_ci#define DRIVER_NAME "spi_gpio" 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#define GENERIC_BITBANG /* vs tight inlines */ 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#endif 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------*/ 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic inline struct spi_gpio *__pure 768c2ecf20Sopenharmony_cispi_to_spi_gpio(const struct spi_device *spi) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci const struct spi_bitbang *bang; 798c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci bang = spi_master_get_devdata(spi->master); 828c2ecf20Sopenharmony_ci spi_gpio = container_of(bang, struct spi_gpio, bitbang); 838c2ecf20Sopenharmony_ci return spi_gpio; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* These helpers are in turn called by the bitbang inlines */ 878c2ecf20Sopenharmony_cistatic inline void setsck(const struct spi_device *spi, int is_on) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi_gpio->sck, is_on); 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_cistatic inline void setmosi(const struct spi_device *spi, int is_on) 958c2ecf20Sopenharmony_ci{ 968c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi_gpio->mosi, is_on); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic inline int getmiso(const struct spi_device *spi) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci if (spi->mode & SPI_3WIRE) 1068c2ecf20Sopenharmony_ci return !!gpiod_get_value_cansleep(spi_gpio->mosi); 1078c2ecf20Sopenharmony_ci else 1088c2ecf20Sopenharmony_ci return !!gpiod_get_value_cansleep(spi_gpio->miso); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* 1128c2ecf20Sopenharmony_ci * NOTE: this clocks "as fast as we can". It "should" be a function of the 1138c2ecf20Sopenharmony_ci * requested device clock. Software overhead means we usually have trouble 1148c2ecf20Sopenharmony_ci * reaching even one Mbit/sec (except when we can inline bitops), so for now 1158c2ecf20Sopenharmony_ci * we'll just assume we never need additional per-bit slowdowns. 1168c2ecf20Sopenharmony_ci */ 1178c2ecf20Sopenharmony_ci#define spidelay(nsecs) do {} while (0) 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#include "spi-bitbang-txrx.h" 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci/* 1228c2ecf20Sopenharmony_ci * These functions can leverage inline expansion of GPIO calls to shrink 1238c2ecf20Sopenharmony_ci * costs for a txrx bit, often by factors of around ten (by instruction 1248c2ecf20Sopenharmony_ci * count). That is particularly visible for larger word sizes, but helps 1258c2ecf20Sopenharmony_ci * even with default 8-bit words. 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci * REVISIT overheads calling these functions for each word also have 1288c2ecf20Sopenharmony_ci * significant performance costs. Having txrx_bufs() calls that inline 1298c2ecf20Sopenharmony_ci * the txrx_word() logic would help performance, e.g. on larger blocks 1308c2ecf20Sopenharmony_ci * used with flash storage or MMC/SD. There should also be ways to make 1318c2ecf20Sopenharmony_ci * GCC be less stupid about reloading registers inside the I/O loops, 1328c2ecf20Sopenharmony_ci * even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3? 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_cistatic u32 spi_gpio_txrx_word_mode0(struct spi_device *spi, 1368c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic u32 spi_gpio_txrx_word_mode1(struct spi_device *spi, 1428c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1438c2ecf20Sopenharmony_ci{ 1448c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic u32 spi_gpio_txrx_word_mode2(struct spi_device *spi, 1488c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); 1518c2ecf20Sopenharmony_ci} 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cistatic u32 spi_gpio_txrx_word_mode3(struct spi_device *spi, 1548c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1558c2ecf20Sopenharmony_ci{ 1568c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* 1608c2ecf20Sopenharmony_ci * These functions do not call setmosi or getmiso if respective flag 1618c2ecf20Sopenharmony_ci * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to 1628c2ecf20Sopenharmony_ci * call when such pin is not present or defined in the controller. 1638c2ecf20Sopenharmony_ci * A separate set of callbacks is defined to get highest possible 1648c2ecf20Sopenharmony_ci * speed in the generic case (when both MISO and MOSI lines are 1658c2ecf20Sopenharmony_ci * available), as optimiser will remove the checks when argument is 1668c2ecf20Sopenharmony_ci * constant. 1678c2ecf20Sopenharmony_ci */ 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi, 1708c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci flags = spi->master->flags; 1738c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_cistatic u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi, 1778c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci flags = spi->master->flags; 1808c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi, 1848c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci flags = spi->master->flags; 1878c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi, 1918c2ecf20Sopenharmony_ci unsigned nsecs, u32 word, u8 bits, unsigned flags) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci flags = spi->master->flags; 1948c2ecf20Sopenharmony_ci return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci/*----------------------------------------------------------------------*/ 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cistatic void spi_gpio_chipselect(struct spi_device *spi, int is_active) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* set initial clock line level */ 2048c2ecf20Sopenharmony_ci if (is_active) 2058c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi_gpio->sck, spi->mode & SPI_CPOL); 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci /* Drive chip select line, if we have one */ 2088c2ecf20Sopenharmony_ci if (spi_gpio->cs_gpios) { 2098c2ecf20Sopenharmony_ci struct gpio_desc *cs = spi_gpio->cs_gpios[spi->chip_select]; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci /* SPI chip selects are normally active-low */ 2128c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active); 2138c2ecf20Sopenharmony_ci } 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic int spi_gpio_setup(struct spi_device *spi) 2178c2ecf20Sopenharmony_ci{ 2188c2ecf20Sopenharmony_ci struct gpio_desc *cs; 2198c2ecf20Sopenharmony_ci int status = 0; 2208c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci /* 2238c2ecf20Sopenharmony_ci * The CS GPIOs have already been 2248c2ecf20Sopenharmony_ci * initialized from the descriptor lookup. 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_ci if (spi_gpio->cs_gpios) { 2278c2ecf20Sopenharmony_ci cs = spi_gpio->cs_gpios[spi->chip_select]; 2288c2ecf20Sopenharmony_ci if (!spi->controller_state && cs) 2298c2ecf20Sopenharmony_ci status = gpiod_direction_output(cs, 2308c2ecf20Sopenharmony_ci !(spi->mode & SPI_CS_HIGH)); 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci if (!status) 2348c2ecf20Sopenharmony_ci status = spi_bitbang_setup(spi); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci return status; 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cistatic int spi_gpio_set_direction(struct spi_device *spi, bool output) 2408c2ecf20Sopenharmony_ci{ 2418c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); 2428c2ecf20Sopenharmony_ci int ret; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci if (output) 2458c2ecf20Sopenharmony_ci return gpiod_direction_output(spi_gpio->mosi, 1); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci /* 2488c2ecf20Sopenharmony_ci * Only change MOSI to an input if using 3WIRE mode. 2498c2ecf20Sopenharmony_ci * Otherwise, MOSI could be left floating if there is 2508c2ecf20Sopenharmony_ci * no pull resistor connected to the I/O pin, or could 2518c2ecf20Sopenharmony_ci * be left logic high if there is a pull-up. Transmitting 2528c2ecf20Sopenharmony_ci * logic high when only clocking MISO data in can put some 2538c2ecf20Sopenharmony_ci * SPI devices in to a bad state. 2548c2ecf20Sopenharmony_ci */ 2558c2ecf20Sopenharmony_ci if (spi->mode & SPI_3WIRE) { 2568c2ecf20Sopenharmony_ci ret = gpiod_direction_input(spi_gpio->mosi); 2578c2ecf20Sopenharmony_ci if (ret) 2588c2ecf20Sopenharmony_ci return ret; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci /* 2618c2ecf20Sopenharmony_ci * Send a turnaround high impedance cycle when switching 2628c2ecf20Sopenharmony_ci * from output to input. Theoretically there should be 2638c2ecf20Sopenharmony_ci * a clock delay here, but as has been noted above, the 2648c2ecf20Sopenharmony_ci * nsec delay function for bit-banged GPIO is simply 2658c2ecf20Sopenharmony_ci * {} because bit-banging just doesn't get fast enough 2668c2ecf20Sopenharmony_ci * anyway. 2678c2ecf20Sopenharmony_ci */ 2688c2ecf20Sopenharmony_ci if (spi->mode & SPI_3WIRE_HIZ) { 2698c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi_gpio->sck, 2708c2ecf20Sopenharmony_ci !(spi->mode & SPI_CPOL)); 2718c2ecf20Sopenharmony_ci gpiod_set_value_cansleep(spi_gpio->sck, 2728c2ecf20Sopenharmony_ci !!(spi->mode & SPI_CPOL)); 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic void spi_gpio_cleanup(struct spi_device *spi) 2788c2ecf20Sopenharmony_ci{ 2798c2ecf20Sopenharmony_ci spi_bitbang_cleanup(spi); 2808c2ecf20Sopenharmony_ci} 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci/* 2838c2ecf20Sopenharmony_ci * It can be convenient to use this driver with pins that have alternate 2848c2ecf20Sopenharmony_ci * functions associated with a "native" SPI controller if a driver for that 2858c2ecf20Sopenharmony_ci * controller is not available, or is missing important functionality. 2868c2ecf20Sopenharmony_ci * 2878c2ecf20Sopenharmony_ci * On platforms which can do so, configure MISO with a weak pullup unless 2888c2ecf20Sopenharmony_ci * there's an external pullup on that signal. That saves power by avoiding 2898c2ecf20Sopenharmony_ci * floating signals. (A weak pulldown would save power too, but many 2908c2ecf20Sopenharmony_ci * drivers expect to see all-ones data as the no slave "response".) 2918c2ecf20Sopenharmony_ci */ 2928c2ecf20Sopenharmony_cistatic int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci spi_gpio->mosi = devm_gpiod_get_optional(dev, "mosi", GPIOD_OUT_LOW); 2958c2ecf20Sopenharmony_ci if (IS_ERR(spi_gpio->mosi)) 2968c2ecf20Sopenharmony_ci return PTR_ERR(spi_gpio->mosi); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN); 2998c2ecf20Sopenharmony_ci if (IS_ERR(spi_gpio->miso)) 3008c2ecf20Sopenharmony_ci return PTR_ERR(spi_gpio->miso); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); 3038c2ecf20Sopenharmony_ci return PTR_ERR_OR_ZERO(spi_gpio->sck); 3048c2ecf20Sopenharmony_ci} 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci#ifdef CONFIG_OF 3078c2ecf20Sopenharmony_cistatic const struct of_device_id spi_gpio_dt_ids[] = { 3088c2ecf20Sopenharmony_ci { .compatible = "spi-gpio" }, 3098c2ecf20Sopenharmony_ci {} 3108c2ecf20Sopenharmony_ci}; 3118c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, spi_gpio_dt_ids); 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistatic int spi_gpio_probe_dt(struct platform_device *pdev, 3148c2ecf20Sopenharmony_ci struct spi_master *master) 3158c2ecf20Sopenharmony_ci{ 3168c2ecf20Sopenharmony_ci master->dev.of_node = pdev->dev.of_node; 3178c2ecf20Sopenharmony_ci master->use_gpio_descriptors = true; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci return 0; 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci#else 3228c2ecf20Sopenharmony_cistatic inline int spi_gpio_probe_dt(struct platform_device *pdev, 3238c2ecf20Sopenharmony_ci struct spi_master *master) 3248c2ecf20Sopenharmony_ci{ 3258c2ecf20Sopenharmony_ci return 0; 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci#endif 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic int spi_gpio_probe_pdata(struct platform_device *pdev, 3308c2ecf20Sopenharmony_ci struct spi_master *master) 3318c2ecf20Sopenharmony_ci{ 3328c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 3338c2ecf20Sopenharmony_ci struct spi_gpio_platform_data *pdata = dev_get_platdata(dev); 3348c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio = spi_master_get_devdata(master); 3358c2ecf20Sopenharmony_ci int i; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci#ifdef GENERIC_BITBANG 3388c2ecf20Sopenharmony_ci if (!pdata || !pdata->num_chipselect) 3398c2ecf20Sopenharmony_ci return -ENODEV; 3408c2ecf20Sopenharmony_ci#endif 3418c2ecf20Sopenharmony_ci /* 3428c2ecf20Sopenharmony_ci * The master needs to think there is a chipselect even if not 3438c2ecf20Sopenharmony_ci * connected 3448c2ecf20Sopenharmony_ci */ 3458c2ecf20Sopenharmony_ci master->num_chipselect = pdata->num_chipselect ?: 1; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci spi_gpio->cs_gpios = devm_kcalloc(dev, master->num_chipselect, 3488c2ecf20Sopenharmony_ci sizeof(*spi_gpio->cs_gpios), 3498c2ecf20Sopenharmony_ci GFP_KERNEL); 3508c2ecf20Sopenharmony_ci if (!spi_gpio->cs_gpios) 3518c2ecf20Sopenharmony_ci return -ENOMEM; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci for (i = 0; i < master->num_chipselect; i++) { 3548c2ecf20Sopenharmony_ci spi_gpio->cs_gpios[i] = devm_gpiod_get_index(dev, "cs", i, 3558c2ecf20Sopenharmony_ci GPIOD_OUT_HIGH); 3568c2ecf20Sopenharmony_ci if (IS_ERR(spi_gpio->cs_gpios[i])) 3578c2ecf20Sopenharmony_ci return PTR_ERR(spi_gpio->cs_gpios[i]); 3588c2ecf20Sopenharmony_ci } 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci return 0; 3618c2ecf20Sopenharmony_ci} 3628c2ecf20Sopenharmony_ci 3638c2ecf20Sopenharmony_cistatic int spi_gpio_probe(struct platform_device *pdev) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci int status; 3668c2ecf20Sopenharmony_ci struct spi_master *master; 3678c2ecf20Sopenharmony_ci struct spi_gpio *spi_gpio; 3688c2ecf20Sopenharmony_ci struct device *dev = &pdev->dev; 3698c2ecf20Sopenharmony_ci struct spi_bitbang *bb; 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci master = devm_spi_alloc_master(dev, sizeof(*spi_gpio)); 3728c2ecf20Sopenharmony_ci if (!master) 3738c2ecf20Sopenharmony_ci return -ENOMEM; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci if (pdev->dev.of_node) 3768c2ecf20Sopenharmony_ci status = spi_gpio_probe_dt(pdev, master); 3778c2ecf20Sopenharmony_ci else 3788c2ecf20Sopenharmony_ci status = spi_gpio_probe_pdata(pdev, master); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci if (status) 3818c2ecf20Sopenharmony_ci return status; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci spi_gpio = spi_master_get_devdata(master); 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci status = spi_gpio_request(dev, spi_gpio); 3868c2ecf20Sopenharmony_ci if (status) 3878c2ecf20Sopenharmony_ci return status; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); 3908c2ecf20Sopenharmony_ci master->mode_bits = SPI_3WIRE | SPI_3WIRE_HIZ | SPI_CPHA | SPI_CPOL | 3918c2ecf20Sopenharmony_ci SPI_CS_HIGH; 3928c2ecf20Sopenharmony_ci if (!spi_gpio->mosi) { 3938c2ecf20Sopenharmony_ci /* HW configuration without MOSI pin 3948c2ecf20Sopenharmony_ci * 3958c2ecf20Sopenharmony_ci * No setting SPI_MASTER_NO_RX here - if there is only 3968c2ecf20Sopenharmony_ci * a MOSI pin connected the host can still do RX by 3978c2ecf20Sopenharmony_ci * changing the direction of the line. 3988c2ecf20Sopenharmony_ci */ 3998c2ecf20Sopenharmony_ci master->flags = SPI_MASTER_NO_TX; 4008c2ecf20Sopenharmony_ci } 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci master->bus_num = pdev->id; 4038c2ecf20Sopenharmony_ci master->setup = spi_gpio_setup; 4048c2ecf20Sopenharmony_ci master->cleanup = spi_gpio_cleanup; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_ci bb = &spi_gpio->bitbang; 4078c2ecf20Sopenharmony_ci bb->master = master; 4088c2ecf20Sopenharmony_ci /* 4098c2ecf20Sopenharmony_ci * There is some additional business, apart from driving the CS GPIO 4108c2ecf20Sopenharmony_ci * line, that we need to do on selection. This makes the local 4118c2ecf20Sopenharmony_ci * callback for chipselect always get called. 4128c2ecf20Sopenharmony_ci */ 4138c2ecf20Sopenharmony_ci master->flags |= SPI_MASTER_GPIO_SS; 4148c2ecf20Sopenharmony_ci bb->chipselect = spi_gpio_chipselect; 4158c2ecf20Sopenharmony_ci bb->set_line_direction = spi_gpio_set_direction; 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci if (master->flags & SPI_MASTER_NO_TX) { 4188c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0; 4198c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1; 4208c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2; 4218c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3; 4228c2ecf20Sopenharmony_ci } else { 4238c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; 4248c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; 4258c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; 4268c2ecf20Sopenharmony_ci bb->txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3; 4278c2ecf20Sopenharmony_ci } 4288c2ecf20Sopenharmony_ci bb->setup_transfer = spi_bitbang_setup_transfer; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci status = spi_bitbang_init(&spi_gpio->bitbang); 4318c2ecf20Sopenharmony_ci if (status) 4328c2ecf20Sopenharmony_ci return status; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci return devm_spi_register_master(&pdev->dev, master); 4358c2ecf20Sopenharmony_ci} 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:" DRIVER_NAME); 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_cistatic struct platform_driver spi_gpio_driver = { 4408c2ecf20Sopenharmony_ci .driver = { 4418c2ecf20Sopenharmony_ci .name = DRIVER_NAME, 4428c2ecf20Sopenharmony_ci .of_match_table = of_match_ptr(spi_gpio_dt_ids), 4438c2ecf20Sopenharmony_ci }, 4448c2ecf20Sopenharmony_ci .probe = spi_gpio_probe, 4458c2ecf20Sopenharmony_ci}; 4468c2ecf20Sopenharmony_cimodule_platform_driver(spi_gpio_driver); 4478c2ecf20Sopenharmony_ci 4488c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); 4498c2ecf20Sopenharmony_ciMODULE_AUTHOR("David Brownell"); 4508c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 451