drivers/spi/spi-rzv2m-csi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-rzv2m-csi.c
Extension
.c
Size
18184 bytes
Lines
695
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 rzv2m_csi_priv {
	void __iomem *base;
	struct clk *csiclk;
	struct clk *pclk;
	struct device *dev;
	struct spi_controller *controller;
	const void *txbuf;
	void *rxbuf;
	unsigned int buffer_len;
	unsigned int bytes_sent;
	unsigned int bytes_received;
	unsigned int bytes_to_transfer;
	unsigned int words_to_transfer;
	unsigned int bytes_per_word;
	wait_queue_head_t wait;
	u32 errors;
	u32 status;
	bool target_aborted;
	bool use_ss_pin;
};

static void rzv2m_csi_reg_write_bit(const struct rzv2m_csi_priv *csi,
				    int reg_offs, int bit_mask, u32 value)
{
	int nr_zeros;
	u32 tmp;

	nr_zeros = count_trailing_zeros(bit_mask);
	value <<= nr_zeros;

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

static int rzv2m_csi_sw_reset(struct rzv2m_csi_priv *csi, int assert)
{
	u32 reg;

	rzv2m_csi_reg_write_bit(csi, CSI_CNT, CSI_CNT_CSIRST, assert);

	if (!assert)
		return 0;

	return readl_poll_timeout(csi->base + CSI_MODE, reg,
				  !(reg & CSI_MODE_CSOT), 0,
				  CSI_EN_DIS_TIMEOUT_US);
}

static int rzv2m_csi_start_stop_operation(const struct rzv2m_csi_priv *csi,
					  int enable, bool wait)
{
	u32 reg;

	rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_CSIE, enable);

	if (enable || !wait)
		return 0;

	return readl_poll_timeout(csi->base + CSI_MODE, reg,
				  !(reg & CSI_MODE_CSOT), 0,
				  CSI_EN_DIS_TIMEOUT_US);
}

static int rzv2m_csi_fill_txfifo(struct rzv2m_csi_priv *csi)
{
	unsigned int i;

	if (readl(csi->base + CSI_OFIFOL))
		return -EIO;

	if (csi->bytes_per_word == 2) {
		const u16 *buf = csi->txbuf;

		for (i = 0; i < csi->words_to_transfer; i++)
			writel(buf[i], csi->base + CSI_OFIFO);
	} else {
		const u8 *buf = csi->txbuf;

		for (i = 0; i < csi->words_to_transfer; i++)
			writel(buf[i], csi->base + CSI_OFIFO);
	}

	csi->txbuf += csi->bytes_to_transfer;
	csi->bytes_sent += csi->bytes_to_transfer;

	return 0;
}

static int rzv2m_csi_read_rxfifo(struct rzv2m_csi_priv *csi)
{

Annotation

Implementation Notes