drivers/i2c/busses/i2c-kempld.c
Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-kempld.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/busses/i2c-kempld.c- Extension
.c- Size
- 9437 bytes
- Lines
- 397
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/platform_device.hlinux/i2c.hlinux/delay.hlinux/mfd/kempld.h
Detected Declarations
struct kempld_i2c_datafunction kempld_i2c_processfunction kempld_i2c_xferfunction kempld_i2c_device_initfunction kempld_i2c_funcfunction kempld_i2c_probefunction kempld_i2c_removefunction kempld_i2c_suspendfunction kempld_i2c_resume
Annotated Snippet
struct kempld_i2c_data {
struct device *dev;
struct kempld_device_data *pld;
struct i2c_adapter adap;
struct i2c_msg *msg;
int pos;
int nmsgs;
int state;
bool was_active;
};
static unsigned int bus_frequency = KEMPLD_I2C_FREQ_STD;
module_param(bus_frequency, uint, 0);
MODULE_PARM_DESC(bus_frequency, "Set I2C bus frequency in kHz (default="
__MODULE_STRING(KEMPLD_I2C_FREQ_STD)")");
static int i2c_bus = -1;
module_param(i2c_bus, int, 0);
MODULE_PARM_DESC(i2c_bus, "Set I2C bus number (default=-1 for dynamic assignment)");
static bool i2c_gpio_mux;
module_param(i2c_gpio_mux, bool, 0);
MODULE_PARM_DESC(i2c_gpio_mux, "Enable I2C port on GPIO out (default=false)");
/*
* kempld_get_mutex must be called prior to calling this function.
*/
static int kempld_i2c_process(struct kempld_i2c_data *i2c)
{
struct kempld_device_data *pld = i2c->pld;
u8 stat = kempld_read8(pld, KEMPLD_I2C_STAT);
struct i2c_msg *msg = i2c->msg;
u8 addr;
/* Ready? */
if (stat & I2C_STAT_TIP)
return -EBUSY;
if (i2c->state == STATE_DONE || i2c->state == STATE_ERROR) {
/* Stop has been sent */
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_IACK);
if (i2c->state == STATE_ERROR)
return -EIO;
return 0;
}
/* Error? */
if (stat & I2C_STAT_ARBLOST) {
i2c->state = STATE_ERROR;
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_STOP);
return -EAGAIN;
}
if (i2c->state == STATE_INIT) {
if (stat & I2C_STAT_BUSY)
return -EBUSY;
i2c->state = STATE_ADDR;
}
if (i2c->state == STATE_ADDR) {
/* 10 bit address? */
if (i2c->msg->flags & I2C_M_TEN) {
addr = i2c_10bit_addr_hi_from_msg(msg);
i2c->state = STATE_ADDR10;
} else {
addr = i2c_8bit_addr_from_msg(i2c->msg);
i2c->state = STATE_START;
}
kempld_write8(pld, KEMPLD_I2C_DATA, addr);
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_START);
return 0;
}
/* Second part of 10 bit addressing */
if (i2c->state == STATE_ADDR10) {
addr = i2c_10bit_addr_lo_from_msg(msg);
i2c->state = STATE_START;
kempld_write8(pld, KEMPLD_I2C_DATA, addr);
kempld_write8(pld, KEMPLD_I2C_CMD, I2C_CMD_WRITE);
return 0;
}
if (i2c->state == STATE_START || i2c->state == STATE_WRITE) {
i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/i2c.h`, `linux/delay.h`, `linux/mfd/kempld.h`.
- Detected declarations: `struct kempld_i2c_data`, `function kempld_i2c_process`, `function kempld_i2c_xfer`, `function kempld_i2c_device_init`, `function kempld_i2c_func`, `function kempld_i2c_probe`, `function kempld_i2c_remove`, `function kempld_i2c_suspend`, `function kempld_i2c_resume`.
- Atlas domain: Driver Families / drivers/i2c.
- Implementation status: source implementation candidate.
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.