drivers/i2c/busses/i2c-octeon-core.h

Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-octeon-core.h

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-octeon-core.h
Extension
.h
Size
8083 bytes
Lines
260
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 octeon_i2c_reg_offset {
	unsigned int sw_twsi;
	unsigned int twsi_int;
	unsigned int sw_twsi_ext;
	unsigned int mode;
	unsigned int block_ctl;
	unsigned int block_sts;
	unsigned int block_fifo;
};

#define OCTEON_REG_SW_TWSI(x)		((x)->roff.sw_twsi)
#define OCTEON_REG_TWSI_INT(x)		((x)->roff.twsi_int)
#define OCTEON_REG_SW_TWSI_EXT(x)	((x)->roff.sw_twsi_ext)
#define OCTEON_REG_MODE(x)		((x)->roff.mode)
#define OCTEON_REG_BLOCK_CTL(x)	((x)->roff.block_ctl)
#define OCTEON_REG_BLOCK_STS(x)	((x)->roff.block_sts)
#define OCTEON_REG_BLOCK_FIFO(x)	((x)->roff.block_fifo)

/* TWSX_MODE register */
#define TWSX_MODE_REFCLK_SRC	BIT(4)
#define TWSX_MODE_BLOCK_MODE	BIT(2)
#define TWSX_MODE_HS_MODE	BIT(0)
#define TWSX_MODE_HS_MASK	(TWSX_MODE_REFCLK_SRC | TWSX_MODE_HS_MODE)

/* TWSX_BLOCK_STS register */
#define TWSX_BLOCK_STS_RESET_PTR	BIT(0)

/* Set BUS_MON_RST to reset bus monitor */
#define BUS_MON_RST_MASK	BIT(3)

struct octeon_i2c {
	wait_queue_head_t queue;
	struct i2c_adapter adap;
	struct octeon_i2c_reg_offset roff;
	struct clk *clk;
	int irq;
	int hlc_irq;		/* For cn7890 only */
	u32 twsi_freq;
	int sys_freq;
	void __iomem *twsi_base;
	struct device *dev;
	bool hlc_enabled;
	bool block_enabled;
	bool broken_irq_mode;
	bool broken_irq_check;
	void (*int_enable)(struct octeon_i2c *);
	void (*int_disable)(struct octeon_i2c *);
	void (*hlc_int_enable)(struct octeon_i2c *);
	void (*hlc_int_disable)(struct octeon_i2c *);
	atomic_t int_enable_cnt;
	atomic_t hlc_int_enable_cnt;
	struct i2c_smbus_alert_setup alert_data;
	struct i2c_client *ara;
};

static inline void octeon_i2c_writeq_flush(u64 val, void __iomem *addr)
{
	__raw_writeq(val, addr);
	__raw_readq(addr);	/* wait for write to land */
}

/**
 * octeon_i2c_reg_write - write an I2C core register
 * @i2c: The struct octeon_i2c
 * @eop_reg: Register selector
 * @data: Value to be written
 *
 * The I2C core registers are accessed indirectly via the OCTEON_REG_SW_TWSI CSR.
 */
static inline void octeon_i2c_reg_write(struct octeon_i2c *i2c, u64 eop_reg, u8 data)
{
	int tries = 1000;
	u64 tmp;

	__raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
	do {
		tmp = __raw_readq(i2c->twsi_base + OCTEON_REG_SW_TWSI(i2c));
		if (--tries < 0)
			return;
	} while ((tmp & SW_TWSI_V) != 0);
}

#define octeon_i2c_ctl_write(i2c, val)					\
	octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_CTL, val)
#define octeon_i2c_data_write(i2c, val)					\
	octeon_i2c_reg_write(i2c, SW_TWSI_EOP_TWSI_DATA, val)

/**
 * octeon_i2c_reg_read - read lower bits of an I2C core register
 * @i2c: The struct octeon_i2c

Annotation

Implementation Notes