drivers/spi/spi-gpio.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-gpio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-gpio.c- Extension
.c- Size
- 13387 bytes
- Lines
- 436
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/gpio/consumer.hlinux/kernel.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/property.hlinux/spi/spi.hlinux/spi/spi_bitbang.hlinux/spi/spi_gpio.hspi-bitbang-txrx.h
Detected Declarations
struct spi_gpiofunction spi_to_spi_gpiofunction setsckfunction setmosifunction getmisofunction spi_gpio_txrx_word_mode0function spi_gpio_txrx_word_mode1function spi_gpio_txrx_word_mode2function spi_gpio_txrx_word_mode3function spi_gpio_spec_txrx_word_mode1function spi_gpio_spec_txrx_word_mode2function spi_gpio_spec_txrx_word_mode3function spi_gpio_chipselectfunction spi_gpio_set_mosi_idlefunction spi_gpio_setupfunction spi_gpio_set_directionfunction spi_gpio_cleanupfunction spi_gpio_requestfunction spi_gpio_probe_pdatafunction spi_gpio_probe
Annotated Snippet
struct spi_gpio {
struct spi_bitbang bitbang;
struct gpio_desc *sck;
struct gpio_desc *miso;
struct gpio_desc *mosi;
struct gpio_desc **cs_gpios;
};
/*----------------------------------------------------------------------*/
#define DRIVER_NAME "spi_gpio"
/*----------------------------------------------------------------------*/
static inline struct spi_gpio *__pure
spi_to_spi_gpio(const struct spi_device *spi)
{
struct spi_bitbang *bang;
struct spi_gpio *spi_gpio;
bang = spi_controller_get_devdata(spi->controller);
spi_gpio = container_of(bang, struct spi_gpio, bitbang);
return spi_gpio;
}
/* These helpers are in turn called by the bitbang inlines */
static inline void setsck(const struct spi_device *spi, int is_on)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
gpiod_set_value_cansleep(spi_gpio->sck, is_on);
}
static inline void setmosi(const struct spi_device *spi, int is_on)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
gpiod_set_value_cansleep(spi_gpio->mosi, is_on);
}
static inline int getmiso(const struct spi_device *spi)
{
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
if (spi->mode & SPI_3WIRE)
return !!gpiod_get_value_cansleep(spi_gpio->mosi);
else
return !!gpiod_get_value_cansleep(spi_gpio->miso);
}
/*
* NOTE: this clocks "as fast as we can". It "should" be a function of the
* requested device clock. Software overhead means we usually have trouble
* reaching even one Mbit/sec (except when we can inline bitops), so for now
* we'll just assume we never need additional per-bit slowdowns.
*/
#define spidelay(nsecs) do {} while (0)
#include "spi-bitbang-txrx.h"
/*
* These functions can leverage inline expansion of GPIO calls to shrink
* costs for a txrx bit, often by factors of around ten (by instruction
* count). That is particularly visible for larger word sizes, but helps
* even with default 8-bit words.
*
* REVISIT overheads calling these functions for each word also have
* significant performance costs. Having txrx_bufs() calls that inline
* the txrx_word() logic would help performance, e.g. on larger blocks
* used with flash storage or MMC/SD. There should also be ways to make
* GCC be less stupid about reloading registers inside the I/O loops,
* even without inlined GPIO calls; __attribute__((hot)) on GCC 4.3?
*/
static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi,
unsigned int nsecs, u32 word, u8 bits, unsigned int flags)
{
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha0(spi, nsecs, 0, flags, word, bits);
else
return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
}
static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi,
unsigned int nsecs, u32 word, u8 bits, unsigned int flags)
{
if (unlikely(spi->mode & SPI_LSB_FIRST))
return bitbang_txrx_le_cpha1(spi, nsecs, 0, flags, word, bits);
else
return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits);
Annotation
- Immediate include surface: `linux/gpio/consumer.h`, `linux/kernel.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/platform_device.h`, `linux/property.h`, `linux/spi/spi.h`, `linux/spi/spi_bitbang.h`.
- Detected declarations: `struct spi_gpio`, `function spi_to_spi_gpio`, `function setsck`, `function setmosi`, `function getmiso`, `function spi_gpio_txrx_word_mode0`, `function spi_gpio_txrx_word_mode1`, `function spi_gpio_txrx_word_mode2`, `function spi_gpio_txrx_word_mode3`, `function spi_gpio_spec_txrx_word_mode1`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.