drivers/media/pci/ivtv/ivtv-i2c.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/ivtv/ivtv-i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/ivtv/ivtv-i2c.c
Extension
.c
Size
20470 bytes
Lines
740
Domain
Driver Families
Bucket
drivers/media
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

if (sd->grp_id == hw) {
			result = sd;
			break;
		}
	}
	spin_unlock(&itv->v4l2_dev.lock);
	return result;
}

/* Set the serial clock line to the desired state */
static void ivtv_setscl(struct ivtv *itv, int state)
{
	/* write them out */
	/* write bits are inverted */
	write_reg(~state, IVTV_REG_I2C_SETSCL_OFFSET);
}

/* Set the serial data line to the desired state */
static void ivtv_setsda(struct ivtv *itv, int state)
{
	/* write them out */
	/* write bits are inverted */
	write_reg(~state & 1, IVTV_REG_I2C_SETSDA_OFFSET);
}

/* Read the serial clock line */
static int ivtv_getscl(struct ivtv *itv)
{
	return read_reg(IVTV_REG_I2C_GETSCL_OFFSET) & 1;
}

/* Read the serial data line */
static int ivtv_getsda(struct ivtv *itv)
{
	return read_reg(IVTV_REG_I2C_GETSDA_OFFSET) & 1;
}

/* Implement a short delay by polling the serial clock line */
static void ivtv_scldelay(struct ivtv *itv)
{
	int i;

	for (i = 0; i < 5; ++i)
		ivtv_getscl(itv);
}

/* Wait for the serial clock line to become set to a specific value */
static int ivtv_waitscl(struct ivtv *itv, int val)
{
	int i;

	ivtv_scldelay(itv);
	for (i = 0; i < 1000; ++i) {
		if (ivtv_getscl(itv) == val)
			return 1;
	}
	return 0;
}

/* Wait for the serial data line to become set to a specific value */
static int ivtv_waitsda(struct ivtv *itv, int val)
{
	int i;

	ivtv_scldelay(itv);
	for (i = 0; i < 1000; ++i) {
		if (ivtv_getsda(itv) == val)
			return 1;
	}
	return 0;
}

/* Wait for the slave to issue an ACK */
static int ivtv_ack(struct ivtv *itv)
{
	int ret = 0;

	if (ivtv_getscl(itv) == 1) {
		IVTV_DEBUG_HI_I2C("SCL was high starting an ack\n");
		ivtv_setscl(itv, 0);
		if (!ivtv_waitscl(itv, 0)) {
			IVTV_DEBUG_I2C("Could not set SCL low starting an ack\n");
			return -EREMOTEIO;
		}
	}
	ivtv_setsda(itv, 1);
	ivtv_scldelay(itv);
	ivtv_setscl(itv, 1);
	if (!ivtv_waitsda(itv, 0)) {
		IVTV_DEBUG_I2C("Slave did not ack\n");

Annotation

Implementation Notes