drivers/spi/spi-rspi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-rspi.c
Extension
.c
Size
37221 bytes
Lines
1417
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rspi_data {
	void __iomem *addr;
	u32 speed_hz;
	struct spi_controller *ctlr;
	struct platform_device *pdev;
	wait_queue_head_t wait;
	spinlock_t lock;		/* Protects RMW-access to RSPI_SSLP */
	struct clk *clk;
	u16 spcmd;
	u8 spsr;
	u8 sppcr;
	int rx_irq, tx_irq;
	const struct spi_ops *ops;

	unsigned dma_callbacked:1;
	unsigned byte_access:1;
};

static void rspi_write8(const struct rspi_data *rspi, u8 data, u16 offset)
{
	iowrite8(data, rspi->addr + offset);
}

static void rspi_write16(const struct rspi_data *rspi, u16 data, u16 offset)
{
	iowrite16(data, rspi->addr + offset);
}

static void rspi_write32(const struct rspi_data *rspi, u32 data, u16 offset)
{
	iowrite32(data, rspi->addr + offset);
}

static u8 rspi_read8(const struct rspi_data *rspi, u16 offset)
{
	return ioread8(rspi->addr + offset);
}

static u16 rspi_read16(const struct rspi_data *rspi, u16 offset)
{
	return ioread16(rspi->addr + offset);
}

static void rspi_write_data(const struct rspi_data *rspi, u16 data)
{
	if (rspi->byte_access)
		rspi_write8(rspi, data, RSPI_SPDR);
	else /* 16 bit */
		rspi_write16(rspi, data, RSPI_SPDR);
}

static u16 rspi_read_data(const struct rspi_data *rspi)
{
	if (rspi->byte_access)
		return rspi_read8(rspi, RSPI_SPDR);
	else /* 16 bit */
		return rspi_read16(rspi, RSPI_SPDR);
}

/* optional functions */
struct spi_ops {
	int (*set_config_register)(struct rspi_data *rspi, int access_size);
	int (*transfer_one)(struct spi_controller *ctlr,
			    struct spi_device *spi, struct spi_transfer *xfer);
	u16 extra_mode_bits;
	u16 min_div;
	u16 max_div;
	u16 flags;
	u16 fifo_size;
	u8 num_hw_ss;
};

static void rspi_set_rate(struct rspi_data *rspi)
{
	unsigned long clksrc;
	int brdv = 0, spbr;

	clksrc = clk_get_rate(rspi->clk);
	spbr = DIV_ROUND_UP(clksrc, 2 * rspi->speed_hz) - 1;
	while (spbr > 255 && brdv < 3) {
		brdv++;
		spbr = DIV_ROUND_UP(spbr + 1, 2) - 1;
	}

	rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR);
	rspi->spcmd |= SPCMD_BRDV(brdv);
	rspi->speed_hz = DIV_ROUND_UP(clksrc, (2U << brdv) * (spbr + 1));
}

/*

Annotation

Implementation Notes