drivers/i2c/busses/i2c-keba.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-keba.c
Extension
.c
Size
14162 bytes
Lines
595
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 ki2c {
	struct keba_i2c_auxdev *auxdev;
	void __iomem *base;
	struct i2c_adapter adapter;

	struct i2c_client **client;
	int client_size;
};

static int ki2c_inuse_lock(struct ki2c *ki2c)
{
	u8 sts;
	int ret;

	/*
	 * The I2C controller has an IN_USE bit for locking access to the
	 * controller. This enables the use of I2C controller by other none
	 * Linux processors.
	 *
	 * If the I2C controller is free, then the first read returns
	 * IN_USE == 0. After that the I2C controller is locked and further
	 * reads of IN_USE return 1.
	 *
	 * The I2C controller is unlocked by writing 1 into IN_USE.
	 *
	 * The IN_USE bit acts as a hardware semaphore for the I2C controller.
	 * Poll for semaphore, but sleep while polling to free the CPU.
	 */
	ret = readb_poll_timeout(ki2c->base + KI2C_STATUS_REG,
				 sts, (sts & KI2C_STATUS_IN_USE) == 0,
				 KI2C_INUSE_SLEEP_US, KI2C_INUSE_TIMEOUT_US);
	if (ret)
		dev_err(&ki2c->auxdev->auxdev.dev, "%s err!\n", __func__);

	return ret;
}

static void ki2c_inuse_unlock(struct ki2c *ki2c)
{
	/* unlock the controller by writing 1 into IN_USE */
	iowrite8(KI2C_STATUS_IN_USE, ki2c->base + KI2C_STATUS_REG);
}

static int ki2c_wait_for_bit(void __iomem *addr, u8 mask, unsigned long timeout)
{
	u8 val;

	return readb_poll_timeout(addr, val, (val & mask), KI2C_POLL_DELAY_US,
				  jiffies_to_usecs(timeout));
}

static int ki2c_wait_for_mcf(struct ki2c *ki2c)
{
	return ki2c_wait_for_bit(ki2c->base + KI2C_STATUS_REG, KI2C_STATUS_MCF,
				 ki2c->adapter.timeout);
}

static int ki2c_wait_for_data(struct ki2c *ki2c)
{
	int ret;

	ret = ki2c_wait_for_mcf(ki2c);
	if (ret < 0)
		return ret;

	return ki2c_wait_for_bit(ki2c->base + KI2C_STATUS_REG,
				 KI2C_STATUS_ACK_CYC,
				 ki2c->adapter.timeout);
}

static int ki2c_wait_for_data_ack(struct ki2c *ki2c)
{
	unsigned int reg;
	int ret;

	ret = ki2c_wait_for_data(ki2c);
	if (ret < 0)
		return ret;

	/* RXAK == 0 means ACK reveived */
	reg = ioread8(ki2c->base + KI2C_STATUS_REG);
	if (reg & KI2C_STATUS_RXAK)
		return -EIO;

	return 0;
}

static int ki2c_has_capability(struct ki2c *ki2c, unsigned int cap)
{
	unsigned int reg = ioread8(ki2c->base + KI2C_CAPABILITY_REG);

Annotation

Implementation Notes