drivers/i2c/busses/i2c-sprd.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-sprd.c
Extension
.c
Size
16370 bytes
Lines
655
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 sprd_i2c {
	struct i2c_adapter adap;
	struct device *dev;
	void __iomem *base;
	struct i2c_msg *msg;
	struct clk *clk;
	u32 src_clk;
	u32 bus_freq;
	struct completion complete;
	u8 *buf;
	u32 count;
	int irq;
	int err;
};

static void sprd_i2c_set_count(struct sprd_i2c *i2c_dev, u32 count)
{
	writel(count, i2c_dev->base + I2C_COUNT);
}

static void sprd_i2c_send_stop(struct sprd_i2c *i2c_dev, int stop)
{
	u32 tmp = readl(i2c_dev->base + I2C_CTL);

	if (stop)
		writel(tmp & ~STP_EN, i2c_dev->base + I2C_CTL);
	else
		writel(tmp | STP_EN, i2c_dev->base + I2C_CTL);
}

static void sprd_i2c_clear_start(struct sprd_i2c *i2c_dev)
{
	u32 tmp = readl(i2c_dev->base + I2C_CTL);

	writel(tmp & ~I2C_START, i2c_dev->base + I2C_CTL);
}

static void sprd_i2c_clear_ack(struct sprd_i2c *i2c_dev)
{
	u32 tmp = readl(i2c_dev->base + I2C_STATUS);

	writel(tmp & ~I2C_RX_ACK, i2c_dev->base + I2C_STATUS);
}

static void sprd_i2c_clear_irq(struct sprd_i2c *i2c_dev)
{
	u32 tmp = readl(i2c_dev->base + I2C_STATUS);

	writel(tmp & ~I2C_INT, i2c_dev->base + I2C_STATUS);
}

static void sprd_i2c_reset_fifo(struct sprd_i2c *i2c_dev)
{
	writel(I2C_RST, i2c_dev->base + ADDR_RST);
}

static void sprd_i2c_set_devaddr(struct sprd_i2c *i2c_dev, struct i2c_msg *m)
{
	writel(m->addr << 1, i2c_dev->base + I2C_ADDR_CFG);
}

static void sprd_i2c_write_bytes(struct sprd_i2c *i2c_dev, u8 *buf, u32 len)
{
	u32 i;

	for (i = 0; i < len; i++)
		writeb(buf[i], i2c_dev->base + I2C_TX);
}

static void sprd_i2c_read_bytes(struct sprd_i2c *i2c_dev, u8 *buf, u32 len)
{
	u32 i;

	for (i = 0; i < len; i++)
		buf[i] = readb(i2c_dev->base + I2C_RX);
}

static void sprd_i2c_set_full_thld(struct sprd_i2c *i2c_dev, u32 full_thld)
{
	u32 tmp = readl(i2c_dev->base + I2C_CTL);

	tmp &= ~FIFO_AF_LVL_MASK;
	tmp |= full_thld << FIFO_AF_LVL;
	writel(tmp, i2c_dev->base + I2C_CTL);
};

static void sprd_i2c_set_empty_thld(struct sprd_i2c *i2c_dev, u32 empty_thld)
{
	u32 tmp = readl(i2c_dev->base + I2C_CTL);

Annotation

Implementation Notes