drivers/spi/spi-rzv2h-rspi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-rzv2h-rspi.c
Extension
.c
Size
22384 bytes
Lines
866
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 rzv2h_rspi_best_clock {
	struct clk *clk;
	unsigned long clk_rate;
	unsigned long error;
	u32 actual_hz;
	u8 brdv;
	u8 spr;
};

struct rzv2h_rspi_info {
	void (*find_tclk_rate)(struct clk *clk, u32 hz,
			       struct rzv2h_rspi_best_clock *best_clk);
	void (*find_pclk_rate)(struct clk *clk, u32 hz,
			       struct rzv2h_rspi_best_clock *best_clk);
	const char *tclk_name;
	unsigned int fifo_size;
	unsigned int num_clks;
};

struct rzv2h_rspi_priv {
	struct spi_controller *controller;
	const struct rzv2h_rspi_info *info;
	struct platform_device *pdev;
	void __iomem *base;
	struct clk *tclk;
	struct clk *pclk;
	wait_queue_head_t wait;
	unsigned int bytes_per_word;
	int irq_rx;
	u32 last_speed_hz;
	u32 freq;
	u16 status;
	u8 spr;
	u8 brdv;
	bool use_pclk;
	bool dma_callbacked;
};

#define RZV2H_RSPI_TX(func, type)					\
static inline void rzv2h_rspi_tx_##type(struct rzv2h_rspi_priv *rspi,	\
					const void *txbuf,		\
					unsigned int index) {		\
	type buf = ((type *)txbuf)[index];				\
	func(buf, rspi->base + RSPI_SPDR);				\
}

#define RZV2H_RSPI_RX(func, type)					\
static inline void rzv2h_rspi_rx_##type(struct rzv2h_rspi_priv *rspi,	\
					void *rxbuf,			\
					unsigned int index) {		\
	type buf = func(rspi->base + RSPI_SPDR);			\
	((type *)rxbuf)[index] = buf;					\
}

RZV2H_RSPI_TX(writel, u32)
RZV2H_RSPI_TX(writew, u16)
RZV2H_RSPI_TX(writeb, u8)
/* The read access size for RSPI_SPDR is fixed at 32 bits */
RZV2H_RSPI_RX(readl, u32)
RZV2H_RSPI_RX(readl, u16)
RZV2H_RSPI_RX(readl, u8)

static void rzv2h_rspi_reg_rmw(const struct rzv2h_rspi_priv *rspi,
				int reg_offs, u32 bit_mask, u32 value)
{
	u32 tmp;

	value <<= __ffs(bit_mask);
	tmp = (readl(rspi->base + reg_offs) & ~bit_mask) | value;
	writel(tmp, rspi->base + reg_offs);
}

static inline void rzv2h_rspi_spe_disable(const struct rzv2h_rspi_priv *rspi)
{
	rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 0);
}

static inline void rzv2h_rspi_spe_enable(const struct rzv2h_rspi_priv *rspi)
{
	rzv2h_rspi_reg_rmw(rspi, RSPI_SPCR, RSPI_SPCR_SPE, 1);
}

static inline void rzv2h_rspi_clear_fifos(const struct rzv2h_rspi_priv *rspi)
{
	writeb(1, rspi->base + RSPI_SPFCR);
}

static inline void rzv2h_rspi_clear_all_irqs(struct rzv2h_rspi_priv *rspi)
{
	writew(RSPI_SPSRC_CLEAR, rspi->base + RSPI_SPSRC);

Annotation

Implementation Notes