drivers/i2c/busses/i2c-designware-common.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-designware-common.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-designware-common.c- Extension
.c- Size
- 27312 bytes
- Lines
- 1065
- 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/acpi.hlinux/bitfield.hlinux/clk.hlinux/delay.hlinux/device.hlinux/err.hlinux/errno.hlinux/export.hlinux/i2c.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/module.hlinux/of.hlinux/pm.hlinux/pm_runtime.hlinux/property.hlinux/regmap.hlinux/swab.hlinux/types.hlinux/units.hi2c-designware-core.hlinux/platform_device.hlinux/dmi.h
Detected Declarations
function dw_reg_readfunction dw_reg_writefunction dw_reg_read_swabfunction dw_reg_write_swabfunction dw_reg_read_wordfunction dw_reg_write_wordfunction i2c_dw_init_regmapfunction i2c_dw_validate_speedfunction mscc_twi_set_sda_hold_timefunction i2c_dw_of_configurefunction i2c_dw_of_configurefunction i2c_dw_acpi_paramsfunction i2c_dw_acpi_configurefunction i2c_dw_acpi_round_bus_speedfunction i2c_dw_acpi_configurefunction i2c_dw_configure_modefunction i2c_dw_write_timingsfunction i2c_dw_set_modefunction i2c_dw_initfunction i2c_dw_adjust_bus_speedfunction i2c_dw_fw_parse_and_configurefunction i2c_dw_read_scl_regfunction i2c_dw_scl_hcntfunction i2c_dw_scl_lcntfunction i2c_dw_set_sda_holdfunction __i2c_dw_disablefunction i2c_dw_clk_ratefunction i2c_dw_prepare_clkfunction i2c_dw_acquire_lockfunction i2c_dw_release_lockfunction i2c_dw_wait_bus_not_busyfunction i2c_dw_handle_tx_abortfunction i2c_dw_set_fifo_sizefunction i2c_dw_funcfunction i2c_dw_disablefunction i2c_dw_isrfunction i2c_dw_probefunction i2c_dw_preparefunction i2c_dw_runtime_suspendfunction i2c_dw_suspendfunction i2c_dw_runtime_resumefunction i2c_dw_resumefunction i2c_dw_shutdownexport i2c_dw_initexport i2c_dw_fw_parse_and_configureexport i2c_dw_prepare_clkexport i2c_dw_disableexport i2c_dw_probe
Annotated Snippet
static inline void i2c_dw_of_configure(struct device *device) { }
#endif /* CONFIG_OF */
#ifdef CONFIG_ACPI
#include <linux/dmi.h>
/*
* The HCNT/LCNT information coming from ACPI should be the most accurate
* for given platform. However, some systems get it wrong. On such systems
* we get better results by calculating those based on the input clock.
*/
static const struct dmi_system_id i2c_dw_no_acpi_params[] = {
{
.ident = "Dell Inspiron 7348",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
},
},
{}
};
static void i2c_dw_acpi_params(struct device *device, char method[],
u16 *hcnt, u16 *lcnt, u32 *sda_hold)
{
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
acpi_handle handle = ACPI_HANDLE(device);
union acpi_object *obj;
if (dmi_check_system(i2c_dw_no_acpi_params))
return;
if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
return;
obj = (union acpi_object *)buf.pointer;
if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
const union acpi_object *objs = obj->package.elements;
*hcnt = (u16)objs[0].integer.value;
*lcnt = (u16)objs[1].integer.value;
*sda_hold = (u32)objs[2].integer.value;
}
kfree(buf.pointer);
}
static void i2c_dw_acpi_configure(struct device *device)
{
struct dw_i2c_dev *dev = dev_get_drvdata(device);
struct i2c_timings *t = &dev->timings;
u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
/*
* Try to get SDA hold time and *CNT values from an ACPI method for
* selected speed modes.
*/
i2c_dw_acpi_params(device, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht);
i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
i2c_dw_acpi_params(device, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht);
i2c_dw_acpi_params(device, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
switch (t->bus_freq_hz) {
case I2C_MAX_STANDARD_MODE_FREQ:
dev->sda_hold_time = ss_ht;
break;
case I2C_MAX_FAST_MODE_PLUS_FREQ:
dev->sda_hold_time = fp_ht;
break;
case I2C_MAX_HIGH_SPEED_MODE_FREQ:
dev->sda_hold_time = hs_ht;
break;
case I2C_MAX_FAST_MODE_FREQ:
default:
dev->sda_hold_time = fs_ht;
break;
}
}
static u32 i2c_dw_acpi_round_bus_speed(struct device *device)
{
u32 acpi_speed;
int i;
acpi_speed = i2c_acpi_find_bus_speed(device);
/*
* Some DSDTs use a non standard speed, round down to the lowest
* standard speed.
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/bitfield.h`, `linux/clk.h`, `linux/delay.h`, `linux/device.h`, `linux/err.h`, `linux/errno.h`, `linux/export.h`.
- Detected declarations: `function dw_reg_read`, `function dw_reg_write`, `function dw_reg_read_swab`, `function dw_reg_write_swab`, `function dw_reg_read_word`, `function dw_reg_write_word`, `function i2c_dw_init_regmap`, `function i2c_dw_validate_speed`, `function mscc_twi_set_sda_hold_time`, `function i2c_dw_of_configure`.
- 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.