drivers/spi/spi-bitbang.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-bitbang.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-bitbang.c
Extension
.c
Size
11692 bytes
Lines
451
Domain
Driver Families
Bucket
drivers/spi
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct spi_bitbang_cs {
	unsigned int nsecs;	/* (clock cycle time) / 2 */
	spi_bb_txrx_word_fn txrx_word;
	spi_bb_txrx_bufs_fn txrx_bufs;
};

static unsigned int bitbang_txrx_8(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u8		*tx = t->tx_buf;
	u8			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 0)) {
		u8		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)
			*rx++ = word;
		count -= 1;
	}
	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	return t->len - count;
}

static unsigned int bitbang_txrx_16(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u16		*tx = t->tx_buf;
	u16			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 1)) {
		u16		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)
			*rx++ = word;
		count -= 2;
	}
	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	return t->len - count;
}

static unsigned int bitbang_txrx_32(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u32		*tx = t->tx_buf;
	u32			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 3)) {
		u32		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFFFFFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)

Annotation

Implementation Notes