drivers/i2c/busses/i2c-jz4780.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-jz4780.c
Extension
.c
Size
21613 bytes
Lines
862
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 ingenic_i2c_config {
	enum ingenic_i2c_version version;

	int fifosize;
	int tx_level;
	int rx_level;
};

struct jz4780_i2c {
	void __iomem		*iomem;
	int			 irq;
	struct clk		*clk;
	struct i2c_adapter	 adap;
	const struct ingenic_i2c_config *cdata;

	/* lock to protect rbuf and wbuf between xfer_rd/wr and irq handler */
	spinlock_t		lock;

	/* beginning of lock scope */
	unsigned char		*rbuf;
	int			rd_total_len;
	int			rd_data_xfered;
	int			rd_cmd_xfered;

	unsigned char		*wbuf;
	int			wt_len;

	int			is_write;
	int			stop_hold;
	int			speed;

	int			data_buf[BUFSIZE];
	int			cmd_buf[BUFSIZE];
	int			cmd;

	/* end of lock scope */
	struct completion	trans_waitq;
};

static inline unsigned short jz4780_i2c_readw(struct jz4780_i2c *i2c,
					      unsigned long offset)
{
	return readw(i2c->iomem + offset);
}

static inline void jz4780_i2c_writew(struct jz4780_i2c *i2c,
				     unsigned long offset, unsigned short val)
{
	writew(val, i2c->iomem + offset);
}

static int jz4780_i2c_disable(struct jz4780_i2c *i2c)
{
	unsigned short regval;
	unsigned long loops = 5;

	jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 0);

	do {
		regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA);
		if (!(regval & JZ4780_I2C_ENB_I2C))
			return 0;

		usleep_range(5000, 15000);
	} while (--loops);

	dev_err(&i2c->adap.dev, "disable failed: ENSTA=0x%04x\n", regval);
	return -ETIMEDOUT;
}

static int jz4780_i2c_enable(struct jz4780_i2c *i2c)
{
	unsigned short regval;
	unsigned long loops = 5;

	jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 1);

	do {
		regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA);
		if (regval & JZ4780_I2C_ENB_I2C)
			return 0;

		usleep_range(5000, 15000);
	} while (--loops);

	dev_err(&i2c->adap.dev, "enable failed: ENSTA=0x%04x\n", regval);
	return -ETIMEDOUT;
}

static int jz4780_i2c_set_target(struct jz4780_i2c *i2c, unsigned char address)

Annotation

Implementation Notes