drivers/i2c/busses/i2c-rk3x.c

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

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-rk3x.c
Extension
.c
Size
37603 bytes
Lines
1414
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_spec_values {
	unsigned long min_hold_start_ns;
	unsigned long min_low_ns;
	unsigned long min_high_ns;
	unsigned long min_setup_start_ns;
	unsigned long max_data_hold_ns;
	unsigned long min_data_setup_ns;
	unsigned long min_setup_stop_ns;
	unsigned long min_hold_buffer_ns;
};

static const struct i2c_spec_values standard_mode_spec = {
	.min_hold_start_ns = 4000,
	.min_low_ns = 4700,
	.min_high_ns = 4000,
	.min_setup_start_ns = 4700,
	.max_data_hold_ns = 3450,
	.min_data_setup_ns = 250,
	.min_setup_stop_ns = 4000,
	.min_hold_buffer_ns = 4700,
};

static const struct i2c_spec_values fast_mode_spec = {
	.min_hold_start_ns = 600,
	.min_low_ns = 1300,
	.min_high_ns = 600,
	.min_setup_start_ns = 600,
	.max_data_hold_ns = 900,
	.min_data_setup_ns = 100,
	.min_setup_stop_ns = 600,
	.min_hold_buffer_ns = 1300,
};

static const struct i2c_spec_values fast_mode_plus_spec = {
	.min_hold_start_ns = 260,
	.min_low_ns = 500,
	.min_high_ns = 260,
	.min_setup_start_ns = 260,
	.max_data_hold_ns = 400,
	.min_data_setup_ns = 50,
	.min_setup_stop_ns = 260,
	.min_hold_buffer_ns = 500,
};

/**
 * struct rk3x_i2c_calced_timings - calculated V1 timings
 * @div_low: Divider output for low
 * @div_high: Divider output for high
 * @tuning: Used to adjust setup/hold data time,
 * setup/hold start time and setup stop time for
 * v1's calc_timings, the tuning should all be 0
 * for old hardware anyone using v0's calc_timings.
 */
struct rk3x_i2c_calced_timings {
	unsigned long div_low;
	unsigned long div_high;
	unsigned int tuning;
};

enum rk3x_i2c_state {
	STATE_IDLE,
	STATE_START,
	STATE_READ,
	STATE_WRITE,
	STATE_STOP
};

/**
 * struct rk3x_i2c_soc_data - SOC-specific data
 * @grf_offset: offset inside the grf regmap for setting the i2c type
 * @calc_timings: Callback function for i2c timing information calculated
 */
struct rk3x_i2c_soc_data {
	int grf_offset;
	int (*calc_timings)(unsigned long, struct i2c_timings *,
			    struct rk3x_i2c_calced_timings *);
};

/**
 * struct rk3x_i2c - private data of the controller
 * @adap: corresponding I2C adapter
 * @dev: device for this controller
 * @soc_data: related soc data struct
 * @regs: virtual memory area
 * @clk: function clk for rk3399 or function & Bus clks for others
 * @pclk: Bus clk for rk3399
 * @clk_rate_nb: i2c clk rate change notify
 * @irq: irq number
 * @t: I2C known timing information
 * @lock: spinlock for the i2c bus

Annotation

Implementation Notes