drivers/i2c/busses/i2c-designware-master.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-designware-master.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-designware-master.c- Extension
.c- Size
- 28478 bytes
- Lines
- 1052
- Domain
- Driver Families
- Bucket
- drivers/i2c
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/err.hlinux/errno.hlinux/export.hlinux/gpio/consumer.hlinux/i2c.hlinux/interrupt.hlinux/io.hlinux/module.hlinux/pinctrl/consumer.hlinux/pm_runtime.hlinux/regmap.hlinux/reset.hi2c-designware-core.h
Detected Declarations
function driverfunction i2c_dw_xfer_initfunction i2c_dw_is_controller_activefunction i2c_dw_check_stopbitfunction i2c_dw_statusfunction amd_i2c_dw_xfer_quirkfunction Initiatefunction i2c_dw_recv_lenfunction i2c_dw_readfunction i2c_dw_read_clear_intrbitsfunction i2c_dw_process_transferfunction i2c_dw_isr_masterfunction i2c_dw_wait_transferfunction __i2c_dw_xfer_one_partfunction rarelyfunction i2c_dw_msg_is_validfunction i2c_dw_xfer_commonfunction i2c_dw_xferfunction i2c_dw_configure_masterfunction i2c_dw_prepare_recoveryfunction i2c_dw_unprepare_recoveryfunction i2c_dw_init_recovery_infofunction i2c_dw_probe_masterexport i2c_dw_configure_master
Annotated Snippet
if (dev->fp_hcnt && dev->fp_lcnt) {
dev->fs_hcnt = dev->fp_hcnt;
dev->fs_lcnt = dev->fp_lcnt;
} else {
ic_clk = i2c_dw_clk_rate(dev);
dev->fs_hcnt =
i2c_dw_scl_hcnt(dev,
DW_IC_FS_SCL_HCNT,
ic_clk,
260, /* tHIGH = 260 ns */
sda_falling_time,
0); /* No offset */
dev->fs_lcnt =
i2c_dw_scl_lcnt(dev,
DW_IC_FS_SCL_LCNT,
ic_clk,
500, /* tLOW = 500 ns */
scl_falling_time,
0); /* No offset */
}
fp_str = " Plus";
}
/*
* Calculate SCL timing parameters for fast mode if not set. They are
* needed also in high speed mode.
*/
if (!dev->fs_hcnt || !dev->fs_lcnt) {
ic_clk = i2c_dw_clk_rate(dev);
dev->fs_hcnt =
i2c_dw_scl_hcnt(dev,
DW_IC_FS_SCL_HCNT,
ic_clk,
600, /* tHD;STA = tHIGH = 0.6 us */
sda_falling_time,
0); /* No offset */
dev->fs_lcnt =
i2c_dw_scl_lcnt(dev,
DW_IC_FS_SCL_LCNT,
ic_clk,
1300, /* tLOW = 1.3 us */
scl_falling_time,
0); /* No offset */
}
dev_dbg(dev->dev, "Fast Mode%s HCNT:LCNT = %d:%d\n",
fp_str, dev->fs_hcnt, dev->fs_lcnt);
/* Check is high speed possible and fall back to fast mode if not */
if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) ==
DW_IC_CON_SPEED_HIGH) {
if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
!= DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH) {
dev_err(dev->dev, "High Speed not supported!\n");
t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
dev->master_cfg &= ~DW_IC_CON_SPEED_MASK;
dev->master_cfg |= DW_IC_CON_SPEED_FAST;
dev->hs_hcnt = 0;
dev->hs_lcnt = 0;
} else if (!dev->hs_hcnt || !dev->hs_lcnt) {
u32 t_high, t_low;
/*
* The legal values stated in the databook for bus
* capacitance are only 100pF and 400pF.
* If dev->bus_capacitance_pF is greater than or equals
* to 400, t_high and t_low are assumed to be
* appropriate values for 400pF, otherwise 100pF.
*/
if (dev->bus_capacitance_pF >= 400) {
/* assume bus capacitance is 400pF */
t_high = dev->clk_freq_optimized ? 160 : 120;
t_low = 320;
} else {
/* assume bus capacitance is 100pF */
t_high = 60;
t_low = dev->clk_freq_optimized ? 120 : 160;
}
ic_clk = i2c_dw_clk_rate(dev);
dev->hs_hcnt =
i2c_dw_scl_hcnt(dev,
DW_IC_HS_SCL_HCNT,
ic_clk,
t_high,
sda_falling_time,
0); /* No offset */
dev->hs_lcnt =
i2c_dw_scl_lcnt(dev,
DW_IC_HS_SCL_LCNT,
ic_clk,
t_low,
Annotation
- Immediate include surface: `linux/delay.h`, `linux/err.h`, `linux/errno.h`, `linux/export.h`, `linux/gpio/consumer.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/io.h`.
- Detected declarations: `function driver`, `function i2c_dw_xfer_init`, `function i2c_dw_is_controller_active`, `function i2c_dw_check_stopbit`, `function i2c_dw_status`, `function amd_i2c_dw_xfer_quirk`, `function Initiate`, `function i2c_dw_recv_len`, `function i2c_dw_read`, `function i2c_dw_read_clear_intrbits`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.