drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c
Extension
.c
Size
8375 bytes
Lines
334
Domain
Driver Families
Bucket
drivers/gpu
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 hdmi_i2c_dev {
	struct i2c_adapter *adap;
	struct mutex i2c_lock;
	struct completion complete;
	int status;
	struct i2c_msg *msg;
	int buf_offset;
};

static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev)
{
	u32 temp;

	temp = HDMI_READ(HDMI_HICR);
	temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
	HDMI_WRITE(HDMI_HICR, temp);
	HDMI_READ(HDMI_HICR);
}

static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev)
{
	HDMI_WRITE(HDMI_HICR, 0x0);
	HDMI_READ(HDMI_HICR);
}

static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
{
	struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	u32 temp;

	i2c_dev->status = I2C_STAT_INIT;
	i2c_dev->msg = pmsg;
	i2c_dev->buf_offset = 0;
	reinit_completion(&i2c_dev->complete);

	/* Enable I2C transaction */
	temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
	HDMI_WRITE(HDMI_HI2CHCR, temp);
	HDMI_READ(HDMI_HI2CHCR);

	while (i2c_dev->status != I2C_TRANSACTION_DONE)
		wait_for_completion_interruptible_timeout(&i2c_dev->complete,
								10 * HZ);

	return 0;
}

static int xfer_write(struct i2c_adapter *adap, struct i2c_msg *pmsg)
{
	/*
	 * XXX: i2c write seems isn't useful for EDID probe, don't do anything
	 */
	return 0;
}

static int oaktrail_hdmi_i2c_access(struct i2c_adapter *adap,
				struct i2c_msg *pmsg,
				int num)
{
	struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	int i;

	mutex_lock(&i2c_dev->i2c_lock);

	/* Enable i2c unit */
	HDMI_WRITE(HDMI_ICRH, 0x00008760);

	/* Enable irq */
	hdmi_i2c_irq_enable(hdmi_dev);
	for (i = 0; i < num; i++) {
		if (pmsg->len && pmsg->buf) {
			if (pmsg->flags & I2C_M_RD)
				xfer_read(adap, pmsg);
			else
				xfer_write(adap, pmsg);
		}
		pmsg++;         /* next message */
	}

	/* Disable irq */
	hdmi_i2c_irq_disable(hdmi_dev);

	mutex_unlock(&i2c_dev->i2c_lock);

	return i;
}

static u32 oaktrail_hdmi_i2c_func(struct i2c_adapter *adapter)

Annotation

Implementation Notes