drivers/i2c/busses/i2c-qcom-geni.c

Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-qcom-geni.c

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-qcom-geni.c
Extension
.c
Size
34378 bytes
Lines
1300
Domain
Driver Families
Bucket
drivers/i2c
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 geni_i2c_gpi_multi_desc_xfer {
	u32 msg_idx_cnt;
	u32 unmap_msg_cnt;
	u32 irq_cnt;
	void **dma_buf;
	dma_addr_t *dma_addr;
};

struct geni_i2c_dev {
	struct geni_se se;
	u32 tx_wm;
	int irq;
	int err;
	struct i2c_adapter adap;
	struct completion done;
	struct i2c_msg *cur;
	int cur_wr;
	int cur_rd;
	spinlock_t lock;
	struct clk *core_clk;
	u32 clk_freq_out;
	const struct geni_i2c_clk_fld *clk_fld;
	void *dma_buf;
	size_t xfer_len;
	dma_addr_t dma_addr;
	struct dma_chan *tx_c;
	struct dma_chan *rx_c;
	bool no_dma;
	bool gpi_mode;
	bool abort_done;
	bool is_tx_multi_desc_xfer;
	u32 num_msgs;
	struct geni_i2c_gpi_multi_desc_xfer i2c_multi_desc_config;
};

struct geni_i2c_desc {
	bool has_core_clk;
	char *icc_ddr;
	bool no_dma_support;
	unsigned int tx_fifo_depth;
};

struct geni_i2c_err_log {
	int err;
	const char *msg;
};

static const struct geni_i2c_err_log gi2c_log[] = {
	[GP_IRQ0] = {-EIO, "Unknown I2C err GP_IRQ0"},
	[NACK] = {-ENXIO, "NACK: slv unresponsive, check its power/reset-ln"},
	[GP_IRQ2] = {-EIO, "Unknown I2C err GP IRQ2"},
	[BUS_PROTO] = {-EPROTO, "Bus proto err, noisy/unexpected start/stop"},
	[ARB_LOST] = {-EAGAIN, "Bus arbitration lost, clock line undriveable"},
	[GP_IRQ5] = {-EIO, "Unknown I2C err GP IRQ5"},
	[GENI_OVERRUN] = {-EIO, "Cmd overrun, check GENI cmd-state machine"},
	[GENI_ILLEGAL_CMD] = {-EIO, "Illegal cmd, check GENI cmd-state machine"},
	[GENI_ABORT_DONE] = {-ETIMEDOUT, "Abort after timeout successful"},
	[GENI_TIMEOUT] = {-ETIMEDOUT, "I2C TXN timed out"},
};

struct geni_i2c_clk_fld {
	u32	clk_freq_out;
	u8	clk_div;
	u8	t_high_cnt;
	u8	t_low_cnt;
	u8	t_cycle_cnt;
};

/*
 * Hardware uses the underlying formula to calculate time periods of
 * SCL clock cycle. Firmware uses some additional cycles excluded from the
 * below formula and it is confirmed that the time periods are within
 * specification limits.
 *
 * time of high period of SCL: t_high = (t_high_cnt * clk_div) / source_clock
 * time of low period of SCL: t_low = (t_low_cnt * clk_div) / source_clock
 * time of full period of SCL: t_cycle = (t_cycle_cnt * clk_div) / source_clock
 * clk_freq_out = t / t_cycle
 * source_clock = 19.2 MHz
 */
static const struct geni_i2c_clk_fld geni_i2c_clk_map_19p2mhz[] = {
	{ I2C_MAX_STANDARD_MODE_FREQ, 7, 10, 12, 26 },
	{ I2C_MAX_FAST_MODE_FREQ, 2,  5, 11, 22 },
	{ I2C_MAX_FAST_MODE_PLUS_FREQ, 1, 2,  8, 18 },
	{}
};

/* source_clock = 32 MHz */
static const struct geni_i2c_clk_fld geni_i2c_clk_map_32mhz[] = {
	{ I2C_MAX_STANDARD_MODE_FREQ, 8, 14, 18, 38 },

Annotation

Implementation Notes