drivers/i2c/busses/i2c-img-scb.c

Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-img-scb.c

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-img-scb.c
Extension
.c
Size
41702 bytes
Lines
1504
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 img_i2c_timings {
	const char *name;
	unsigned int max_bitrate;
	unsigned int tckh, tckl, tsdh, tsdl;
	unsigned int tp2s, tpl, tph;
};

/* The timings array must be ordered from slower to faster */
static struct img_i2c_timings timings[] = {
	/* Standard mode */
	{
		.name = "standard",
		.max_bitrate = I2C_MAX_STANDARD_MODE_FREQ,
		.tckh = 4000,
		.tckl = 4700,
		.tsdh = 4700,
		.tsdl = 8700,
		.tp2s = 4700,
		.tpl = 4700,
		.tph = 4000,
	},
	/* Fast mode */
	{
		.name = "fast",
		.max_bitrate = I2C_MAX_FAST_MODE_FREQ,
		.tckh = 600,
		.tckl = 1300,
		.tsdh = 600,
		.tsdl = 1200,
		.tp2s = 1300,
		.tpl = 600,
		.tph = 600,
	},
};

/* Reset dance */
static u8 img_i2c_reset_seq[] = { CMD_GEN_START,
				  CMD_GEN_DATA, 0xff,
				  CMD_RET_ACK,
				  CMD_GEN_START,
				  CMD_GEN_STOP,
				  0 };
/* Just issue a stop (after an abort condition) */
static u8 img_i2c_stop_seq[] = {  CMD_GEN_STOP,
				  0 };

/* We're interested in different interrupts depending on the mode */
static unsigned int img_i2c_int_enable_by_mode[] = {
	[MODE_INACTIVE]  = INT_ENABLE_MASK_INACTIVE,
	[MODE_RAW]       = INT_ENABLE_MASK_RAW,
	[MODE_ATOMIC]    = INT_ENABLE_MASK_ATOMIC,
	[MODE_AUTOMATIC] = INT_ENABLE_MASK_AUTOMATIC,
	[MODE_SEQUENCE]  = INT_ENABLE_MASK_ATOMIC,
	[MODE_FATAL]     = 0,
	[MODE_WAITSTOP]  = INT_ENABLE_MASK_WAITSTOP,
	[MODE_SUSPEND]   = 0,
};

/* Atomic command names */
static const char * const img_i2c_atomic_cmd_names[] = {
	[CMD_PAUSE]	= "PAUSE",
	[CMD_GEN_DATA]	= "GEN_DATA",
	[CMD_GEN_START]	= "GEN_START",
	[CMD_GEN_STOP]	= "GEN_STOP",
	[CMD_GEN_ACK]	= "GEN_ACK",
	[CMD_GEN_NACK]	= "GEN_NACK",
	[CMD_RET_DATA]	= "RET_DATA",
	[CMD_RET_ACK]	= "RET_ACK",
};

struct img_i2c {
	struct i2c_adapter adap;

	void __iomem *base;

	/*
	 * The scb core clock is used to get the input frequency, and to disable
	 * it after every set of transactions to save some power.
	 */
	struct clk *scb_clk, *sys_clk;
	unsigned int bitrate;
	bool need_wr_rd_fence;

	/* state */
	struct completion msg_complete;
	spinlock_t lock;	/* lock before doing anything with the state */
	struct i2c_msg msg;

	/* After the last transaction, wait for a stop bit */
	bool last_msg;

Annotation

Implementation Notes