drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c
Extension
.c
Size
4500 bytes
Lines
170
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

#include <linux/delay.h>
#include <linux/i2c-algo-bit.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/types.h>

#include "psb_drv.h"
#include "psb_intel_reg.h"


/*
 * LPC GPIO based I2C bus for LVDS of Atom E6xx
 */

/*-----------------------------------------------------------------------------
 * LPC Register Offsets. Used for LVDS GPIO Bit Bashing. Registers are part
 * Atom E6xx [D31:F0]
 ----------------------------------------------------------------------------*/
#define RGEN    0x20
#define RGIO    0x24
#define RGLVL   0x28
#define RGTPE   0x2C
#define RGTNE   0x30
#define RGGPE   0x34
#define RGSMI   0x38
#define RGTS    0x3C

/* The LVDS GPIO clock lines are GPIOSUS[3]
 * The LVDS GPIO data lines are GPIOSUS[4]
 */
#define GPIO_CLOCK	0x08
#define GPIO_DATA	0x10

#define LPC_READ_REG(chan, r) inl((chan)->reg + (r))
#define LPC_WRITE_REG(chan, r, val) outl((val), (chan)->reg + (r))

static int get_clock(void *data)
{
	struct gma_i2c_chan *chan = data;
	u32 val;

	val = LPC_READ_REG(chan, RGIO);
	val |= GPIO_CLOCK;
	LPC_WRITE_REG(chan, RGIO, val);
	LPC_READ_REG(chan, RGLVL);
	val = (LPC_READ_REG(chan, RGLVL) & GPIO_CLOCK) ? 1 : 0;

	return val;
}

static int get_data(void *data)
{
	struct gma_i2c_chan *chan = data;
	u32 val;

	val = LPC_READ_REG(chan, RGIO);
	val |= GPIO_DATA;
	LPC_WRITE_REG(chan, RGIO, val);
	LPC_READ_REG(chan, RGLVL);
	val = (LPC_READ_REG(chan, RGLVL) & GPIO_DATA) ? 1 : 0;

	return val;
}

static void set_clock(void *data, int state_high)
{
	struct gma_i2c_chan *chan = data;
	u32 val;

	if (state_high) {
		val = LPC_READ_REG(chan, RGIO);
		val |= GPIO_CLOCK;
		LPC_WRITE_REG(chan, RGIO, val);
	} else {
		val = LPC_READ_REG(chan, RGIO);
		val &= ~GPIO_CLOCK;
		LPC_WRITE_REG(chan, RGIO, val);
		val = LPC_READ_REG(chan, RGLVL);
		val &= ~GPIO_CLOCK;
		LPC_WRITE_REG(chan, RGLVL, val);
	}
}

static void set_data(void *data, int state_high)
{
	struct gma_i2c_chan *chan = data;

Annotation

Implementation Notes