drivers/mfd/stmfx.c
Source file repositories/reference/linux-study-clean/drivers/mfd/stmfx.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/stmfx.c- Extension
.c- Size
- 13378 bytes
- Lines
- 562
- Domain
- Driver Families
- Bucket
- drivers/mfd
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/bitfield.hlinux/i2c.hlinux/interrupt.hlinux/irq.hlinux/mfd/core.hlinux/mfd/stmfx.hlinux/module.hlinux/regulator/consumer.h
Detected Declarations
function Copyrightfunction stmfx_reg_writeablefunction stmfx_func_to_maskfunction stmfx_function_enablefunction stmfx_function_disablefunction stmfx_irq_bus_lockfunction stmfx_irq_bus_sync_unlockfunction stmfx_irq_maskfunction stmfx_irq_unmaskfunction stmfx_irq_handlerfunction stmfx_irq_mapfunction stmfx_irq_unmapfunction stmfx_irq_exitfunction stmfx_irq_initfunction stmfx_chip_resetfunction stmfx_chip_initfunction stmfx_chip_exitfunction stmfx_probefunction stmfx_removefunction stmfx_suspendfunction stmfx_resumeexport stmfx_function_enableexport stmfx_function_disable
Annotated Snippet
if (ret) {
dev_err(&client->dev, "VDD enable failed: %d\n", ret);
return ret;
}
}
ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id);
if (ret) {
dev_err(&client->dev, "Error reading chip ID: %d\n", ret);
goto err;
}
/*
* Check that ID is the complement of the I2C address:
* STMFX I2C address follows the 7-bit format (MSB), that's why
* client->addr is shifted.
*
* STMFX_I2C_ADDR| STMFX | Linux
* input pin | I2C device address | I2C device address
*---------------------------------------------------------
* 0 | b: 1000 010x h:0x84 | 0x42
* 1 | b: 1000 011x h:0x86 | 0x43
*/
if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (client->addr << 1)) {
dev_err(&client->dev, "Unknown chip ID: %#x\n", id);
ret = -EINVAL;
goto err;
}
ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB,
version, ARRAY_SIZE(version));
if (ret) {
dev_err(&client->dev, "Error reading FW version: %d\n", ret);
goto err;
}
dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n",
id, version[0], version[1]);
ret = stmfx_chip_reset(stmfx);
if (ret) {
dev_err(&client->dev, "Failed to reset chip: %d\n", ret);
goto err;
}
return 0;
err:
if (stmfx->vdd)
regulator_disable(stmfx->vdd);
return ret;
}
static void stmfx_chip_exit(struct i2c_client *client)
{
struct stmfx *stmfx = i2c_get_clientdata(client);
regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0);
regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0);
if (stmfx->vdd) {
int ret;
ret = regulator_disable(stmfx->vdd);
if (ret)
dev_err(&client->dev,
"Failed to disable vdd regulator: %pe\n",
ERR_PTR(ret));
}
}
static int stmfx_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct stmfx *stmfx;
int ret;
stmfx = devm_kzalloc(dev, sizeof(*stmfx), GFP_KERNEL);
if (!stmfx)
return -ENOMEM;
i2c_set_clientdata(client, stmfx);
stmfx->dev = dev;
stmfx->map = devm_regmap_init_i2c(client, &stmfx_regmap_config);
if (IS_ERR(stmfx->map)) {
ret = PTR_ERR(stmfx->map);
dev_err(dev, "Failed to allocate register map: %d\n", ret);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/i2c.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/mfd/core.h`, `linux/mfd/stmfx.h`, `linux/module.h`, `linux/regulator/consumer.h`.
- Detected declarations: `function Copyright`, `function stmfx_reg_writeable`, `function stmfx_func_to_mask`, `function stmfx_function_enable`, `function stmfx_function_disable`, `function stmfx_irq_bus_lock`, `function stmfx_irq_bus_sync_unlock`, `function stmfx_irq_mask`, `function stmfx_irq_unmask`, `function stmfx_irq_handler`.
- Atlas domain: Driver Families / drivers/mfd.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.