drivers/mfd/axp20x.c
Source file repositories/reference/linux-study-clean/drivers/mfd/axp20x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/axp20x.c- Extension
.c- Size
- 52451 bytes
- Lines
- 1480
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/bitops.hlinux/delay.hlinux/err.hlinux/interrupt.hlinux/kernel.hlinux/mfd/axp20x.hlinux/mfd/core.hlinux/module.hlinux/of.hlinux/property.hlinux/reboot.hlinux/regmap.hlinux/regulator/consumer.h
Detected Declarations
function axp192_get_irq_regfunction axp20x_power_offfunction axp20x_match_devicefunction axp20x_device_probefunction bitsfunction axp20x_device_removeexport axp20x_match_deviceexport axp20x_device_probeexport axp20x_device_remove
Annotated Snippet
if (cells_no_irq) {
axp20x->nr_cells = nr_cells_no_irq;
axp20x->cells = cells_no_irq;
} else {
axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
axp20x->cells = axp_regulator_only_cells;
}
}
dev_info(dev, "AXP20x variant %s found\n",
axp20x_model_names[axp20x->variant]);
return 0;
}
EXPORT_SYMBOL(axp20x_match_device);
int axp20x_device_probe(struct axp20x_dev *axp20x)
{
int ret;
/*
* The AXP806 supports either master/standalone or slave mode.
* Slave mode allows sharing the serial bus, even with multiple
* AXP806 which all have the same hardware address.
*
* This is done with extra "serial interface address extension",
* or AXP806_BUS_ADDR_EXT, and "register address extension", or
* AXP806_REG_ADDR_EXT, registers. The former is read-only, with
* 1 bit customizable at the factory, and 1 bit depending on the
* state of an external pin. The latter is writable. The device
* will only respond to operations to its other registers when
* the these device addressing bits (in the upper 4 bits of the
* registers) match.
*
* By default we support an AXP806 chained to an AXP809 in slave
* mode. Boards which use an AXP806 in master mode can set the
* property "x-powers,master-mode" to override the default.
*/
if (axp20x->variant == AXP806_ID) {
if (of_property_read_bool(axp20x->dev->of_node,
"x-powers,master-mode") ||
of_property_read_bool(axp20x->dev->of_node,
"x-powers,self-working-mode"))
regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
AXP806_REG_ADDR_EXT_ADDR_MASTER_MODE);
else
regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
}
/* Only if there is an interrupt line connected towards the CPU. */
if (axp20x->irq > 0) {
ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags,
-1, axp20x->regmap_irq_chip,
&axp20x->regmap_irqc);
if (ret) {
dev_err(axp20x->dev, "failed to add irq chip: %d\n",
ret);
return ret;
}
}
ret = mfd_add_devices(axp20x->dev, PLATFORM_DEVID_NONE, axp20x->cells,
axp20x->nr_cells, NULL, 0, NULL);
if (ret) {
dev_err(axp20x->dev, "failed to add MFD devices: %d\n", ret);
regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
return ret;
}
if (axp20x->variant != AXP288_ID)
devm_register_power_off_handler(axp20x->dev, axp20x_power_off, axp20x);
dev_info(axp20x->dev, "AXP20X driver loaded\n");
return 0;
}
EXPORT_SYMBOL(axp20x_device_probe);
void axp20x_device_remove(struct axp20x_dev *axp20x)
{
mfd_remove_devices(axp20x->dev);
regmap_del_irq_chip(axp20x->irq, axp20x->regmap_irqc);
}
EXPORT_SYMBOL(axp20x_device_remove);
MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X");
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/bitops.h`, `linux/delay.h`, `linux/err.h`, `linux/interrupt.h`, `linux/kernel.h`, `linux/mfd/axp20x.h`, `linux/mfd/core.h`.
- Detected declarations: `function axp192_get_irq_reg`, `function axp20x_power_off`, `function axp20x_match_device`, `function axp20x_device_probe`, `function bits`, `function axp20x_device_remove`, `export axp20x_match_device`, `export axp20x_device_probe`, `export axp20x_device_remove`.
- Atlas domain: Driver Families / drivers/mfd.
- Implementation status: integration 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.