drivers/mfd/mc13xxx-core.c
Source file repositories/reference/linux-study-clean/drivers/mfd/mc13xxx-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/mc13xxx-core.c- Extension
.c- Size
- 13306 bytes
- Lines
- 514
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/module.hlinux/of.hlinux/of_device.hlinux/platform_device.hlinux/mfd/core.hmc13xxx.h
Detected Declarations
struct mc13xxx_adcdone_datafunction mc13xxx_lockfunction mc13xxx_unlockfunction mc13xxx_reg_readfunction mc13xxx_reg_writefunction mc13xxx_reg_rmwfunction mc13xxx_irq_maskfunction mc13xxx_irq_unmaskfunction mc13xxx_irq_statusfunction mc13xxx_irq_requestfunction mc13xxx_irq_freefunction mc13xxx_print_revisionfunction mc34708_print_revisionfunction mc13xxx_get_flagsfunction mc13xxx_handler_adcdonefunction mc13xxx_adc_do_conversionfunction mc13xxx_add_subdevice_pdatafunction mc13xxx_add_subdevicefunction mc13xxx_probe_flags_dtfunction mc13xxx_probe_flags_dtfunction mc13xxx_common_initfunction mc13xxx_common_exitexport mc13xxx_lockexport mc13xxx_unlockexport mc13xxx_reg_readexport mc13xxx_reg_writeexport mc13xxx_reg_rmwexport mc13xxx_irq_maskexport mc13xxx_irq_unmaskexport mc13xxx_irq_statusexport mc13xxx_irq_requestexport mc13xxx_irq_freeexport mc13xxx_variant_mc13783export mc13xxx_variant_mc13892export mc13xxx_variant_mc34708export mc13xxx_get_flagsexport mc13xxx_adc_do_conversionexport mc13xxx_common_initexport mc13xxx_common_exit
Annotated Snippet
struct mc13xxx_adcdone_data {
struct mc13xxx *mc13xxx;
struct completion done;
};
static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
{
struct mc13xxx_adcdone_data *adcdone_data = data;
complete_all(&adcdone_data->done);
return IRQ_HANDLED;
}
#define MC13XXX_ADC_WORKING (1 << 0)
int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
unsigned int channel, u8 ato, bool atox,
unsigned int *sample)
{
u32 adc0, adc1, old_adc0;
int i, ret;
struct mc13xxx_adcdone_data adcdone_data = {
.mc13xxx = mc13xxx,
};
init_completion(&adcdone_data.done);
dev_dbg(mc13xxx->dev, "%s\n", __func__);
mc13xxx_lock(mc13xxx);
if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) {
ret = -EBUSY;
goto out;
}
mc13xxx->adcflags |= MC13XXX_ADC_WORKING;
ret = mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0);
if (ret)
goto out;
adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2 |
MC13XXX_ADC0_CHRGRAWDIV;
adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC;
/*
* Channels mapped through ADIN7:
* 7 - General purpose ADIN7
* 16 - UID
* 17 - Die temperature
*/
if (channel > 7 && channel < 16) {
adc1 |= MC13XXX_ADC1_ADSEL;
} else if (channel == 16) {
adc0 |= MC13XXX_ADC0_ADIN7SEL_UID;
channel = 7;
} else if (channel == 17) {
adc0 |= MC13XXX_ADC0_ADIN7SEL_DIE;
channel = 7;
}
switch (mode) {
case MC13XXX_ADC_MODE_TS:
adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 |
MC13XXX_ADC0_TSMOD1;
adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
break;
case MC13XXX_ADC_MODE_SINGLE_CHAN:
adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK;
adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT;
adc1 |= MC13XXX_ADC1_RAND;
break;
case MC13XXX_ADC_MODE_MULT_CHAN:
adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK;
adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
break;
default:
mc13xxx_unlock(mc13xxx);
return -EINVAL;
}
adc1 |= ato << MC13783_ADC1_ATO_SHIFT;
if (atox)
adc1 |= MC13783_ADC1_ATOX;
dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/module.h`, `linux/of.h`, `linux/of_device.h`, `linux/platform_device.h`, `linux/mfd/core.h`, `mc13xxx.h`.
- Detected declarations: `struct mc13xxx_adcdone_data`, `function mc13xxx_lock`, `function mc13xxx_unlock`, `function mc13xxx_reg_read`, `function mc13xxx_reg_write`, `function mc13xxx_reg_rmw`, `function mc13xxx_irq_mask`, `function mc13xxx_irq_unmask`, `function mc13xxx_irq_status`, `function mc13xxx_irq_request`.
- 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.