drivers/i2c/busses/i2c-cadence.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-cadence.c
Extension
.c
Size
47333 bytes
Lines
1673
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 cdns_i2c {
	struct device		*dev;
	void __iomem *membase;
	struct i2c_adapter adap;
	struct i2c_msg *p_msg;
	int err_status;
	struct completion xfer_done;
	unsigned char *p_send_buf;
	unsigned char *p_recv_buf;
	unsigned int send_count;
	unsigned int recv_count;
	unsigned int curr_recv_count;
	unsigned long input_clk;
	unsigned int i2c_clk;
	unsigned int bus_hold_flag;
	struct clk *clk;
	struct notifier_block clk_rate_change_nb;
	struct reset_control *reset;
	u32 quirks;
	u32 ctrl_reg;
	struct i2c_bus_recovery_info rinfo;
#if IS_ENABLED(CONFIG_I2C_SLAVE)
	u16 ctrl_reg_diva_divb;
	struct i2c_client *slave;
	enum cdns_i2c_mode dev_mode;
	enum cdns_i2c_slave_state slave_state;
#endif
	u32 fifo_depth;
	unsigned int transfer_size;
	bool atomic;
	int err_status_atomic;
};

struct cdns_platform_data {
	u32 quirks;
};

#define to_cdns_i2c(_nb)	container_of(_nb, struct cdns_i2c, \
					     clk_rate_change_nb)

/**
 * cdns_i2c_init -  Controller initialisation
 * @id:		Device private data structure
 *
 * Initialise the i2c controller.
 *
 */
static void cdns_i2c_init(struct cdns_i2c *id)
{
	cdns_i2c_writereg(id->ctrl_reg, CDNS_I2C_CR_OFFSET);
	/*
	 * Cadence I2C controller has a bug wherein it generates
	 * invalid read transaction after HW timeout in master receiver mode.
	 * HW timeout is not used by this driver and the interrupt is disabled.
	 * But the feature itself cannot be disabled. Hence maximum value
	 * is written to this register to reduce the chances of error.
	 */
	cdns_i2c_writereg(CDNS_I2C_TIMEOUT_MAX, CDNS_I2C_TIME_OUT_OFFSET);
}

/**
 * cdns_i2c_runtime_suspend -  Runtime suspend method for the driver
 * @dev:	Address of the platform_device structure
 *
 * Put the driver into low power mode.
 *
 * Return: 0 always
 */
static int cdns_i2c_runtime_suspend(struct device *dev)
{
	struct cdns_i2c *xi2c = dev_get_drvdata(dev);

	clk_disable(xi2c->clk);

	return 0;
}

/**
 * cdns_i2c_runtime_resume - Runtime resume
 * @dev:	Address of the platform_device structure
 *
 * Runtime resume callback.
 *
 * Return: 0 on success and error value on error
 */
static int cdns_i2c_runtime_resume(struct device *dev)
{
	struct cdns_i2c *xi2c = dev_get_drvdata(dev);
	int ret;

Annotation

Implementation Notes