drivers/i2c/busses/i2c-cpm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-cpm.c
Extension
.c
Size
17339 bytes
Lines
716
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 i2c_ram {
	ushort  rbase;		/* Rx Buffer descriptor base address */
	ushort  tbase;		/* Tx Buffer descriptor base address */
	u_char  rfcr;		/* Rx function code */
	u_char  tfcr;		/* Tx function code */
	ushort  mrblr;		/* Max receive buffer length */
	uint    rstate;		/* Internal */
	uint    rdp;		/* Internal */
	ushort  rbptr;		/* Rx Buffer descriptor pointer */
	ushort  rbc;		/* Internal */
	uint    rxtmp;		/* Internal */
	uint    tstate;		/* Internal */
	uint    tdp;		/* Internal */
	ushort  tbptr;		/* Tx Buffer descriptor pointer */
	ushort  tbc;		/* Internal */
	uint    txtmp;		/* Internal */
	char    res1[4];	/* Reserved */
	ushort  rpbase;		/* Relocation pointer */
	char    res2[2];	/* Reserved */
	/* The following elements are only for CPM2 */
	char    res3[4];	/* Reserved */
	uint    sdmatmp;	/* Internal */
};

#define I2COM_START	0x80
#define I2COM_MASTER	0x01
#define I2CER_TXE	0x10
#define I2CER_BUSY	0x04
#define I2CER_TXB	0x02
#define I2CER_RXB	0x01
#define I2MOD_EN	0x01

/* I2C Registers */
struct i2c_reg {
	u8	i2mod;
	u8	res1[3];
	u8	i2add;
	u8	res2[3];
	u8	i2brg;
	u8	res3[3];
	u8	i2com;
	u8	res4[3];
	u8	i2cer;
	u8	res5[3];
	u8	i2cmr;
};

struct cpm_i2c {
	char *base;
	struct platform_device *ofdev;
	struct i2c_adapter adap;
	uint dp_addr;
	int version; /* CPM1=1, CPM2=2 */
	int irq;
	int cp_command;
	int freq;
	struct i2c_reg __iomem *i2c_reg;
	struct i2c_ram __iomem *i2c_ram;
	u16 i2c_addr;
	wait_queue_head_t i2c_wait;
	cbd_t __iomem *tbase;
	cbd_t __iomem *rbase;
	u_char *txbuf[CPM_MAXBD];
	u_char *rxbuf[CPM_MAXBD];
	dma_addr_t txdma[CPM_MAXBD];
	dma_addr_t rxdma[CPM_MAXBD];
};

static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
{
	struct cpm_i2c *cpm;
	struct i2c_reg __iomem *i2c_reg;
	struct i2c_adapter *adap = dev_id;
	int i;

	cpm = i2c_get_adapdata(dev_id);
	i2c_reg = cpm->i2c_reg;

	/* Clear interrupt. */
	i = in_8(&i2c_reg->i2cer);
	out_8(&i2c_reg->i2cer, i);

	dev_dbg(&adap->dev, "Interrupt: %x\n", i);

	wake_up(&cpm->i2c_wait);

	return i ? IRQ_HANDLED : IRQ_NONE;
}

static void cpm_reset_i2c_params(struct cpm_i2c *cpm)

Annotation

Implementation Notes