drivers/gpu/drm/gma500/intel_gmbus.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/gma500/intel_gmbus.c
Extension
.c
Size
12771 bytes
Lines
502
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 intel_gpio {
	struct i2c_adapter adapter;
	struct i2c_algo_bit_data algo;
	struct drm_psb_private *dev_priv;
	u32 reg;
};

void
gma_intel_i2c_reset(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
	GMBUS_REG_WRITE(GMBUS0, 0);
}

static void intel_i2c_quirk_set(struct drm_psb_private *dev_priv, bool enable)
{
	/* When using bit bashing for I2C, this bit needs to be set to 1 */
	/* FIXME: We are never Pineview, right?

	u32 val;

	if (!IS_PINEVIEW(dev_priv->dev))
		return;

	val = REG_READ(DSPCLK_GATE_D);
	if (enable)
		val |= DPCUNIT_CLOCK_GATE_DISABLE;
	else
		val &= ~DPCUNIT_CLOCK_GATE_DISABLE;
	REG_WRITE(DSPCLK_GATE_D, val);

	return;
	*/
}

static u32 get_reserved(struct intel_gpio *gpio)
{
	struct drm_psb_private *dev_priv = gpio->dev_priv;
	u32 reserved = 0;

	/* On most chips, these bits must be preserved in software. */
	reserved = GMBUS_REG_READ(gpio->reg) &
				     (GPIO_DATA_PULLUP_DISABLE |
				      GPIO_CLOCK_PULLUP_DISABLE);

	return reserved;
}

static int get_clock(void *data)
{
	struct intel_gpio *gpio = data;
	struct drm_psb_private *dev_priv = gpio->dev_priv;
	u32 reserved = get_reserved(gpio);
	GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK);
	GMBUS_REG_WRITE(gpio->reg, reserved);
	return (GMBUS_REG_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0;
}

static int get_data(void *data)
{
	struct intel_gpio *gpio = data;
	struct drm_psb_private *dev_priv = gpio->dev_priv;
	u32 reserved = get_reserved(gpio);
	GMBUS_REG_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK);
	GMBUS_REG_WRITE(gpio->reg, reserved);
	return (GMBUS_REG_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0;
}

static void set_clock(void *data, int state_high)
{
	struct intel_gpio *gpio = data;
	struct drm_psb_private *dev_priv = gpio->dev_priv;
	u32 reserved = get_reserved(gpio);
	u32 clock_bits;

	if (state_high)
		clock_bits = GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
	else
		clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK |
			GPIO_CLOCK_VAL_MASK;

	GMBUS_REG_WRITE(gpio->reg, reserved | clock_bits);
	GMBUS_REG_READ(gpio->reg); /* Posting */
}

static void set_data(void *data, int state_high)
{
	struct intel_gpio *gpio = data;
	struct drm_psb_private *dev_priv = gpio->dev_priv;
	u32 reserved = get_reserved(gpio);

Annotation

Implementation Notes