drivers/iio/adc/rzn1-adc.c
Source file repositories/reference/linux-study-clean/drivers/iio/adc/rzn1-adc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/adc/rzn1-adc.c- Extension
.c- Size
- 13826 bytes
- Lines
- 491
- Domain
- Driver Families
- Bucket
- drivers/iio
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/array_size.hlinux/bitfield.hlinux/bits.hlinux/cleanup.hlinux/clk.hlinux/dev_printk.hlinux/err.hlinux/iio/iio.hlinux/io.hlinux/iopoll.hlinux/mod_devicetable.hlinux/module.hlinux/mutex.hlinux/platform_device.hlinux/pm_runtime.hlinux/regulator/consumer.hlinux/types.h
Detected Declarations
struct rzn1_adcfunction Copyrightfunction rzn1_adc_powerfunction rzn1_adc_vc_setup_conversionfunction rzn1_adc_vc_start_conversionfunction rzn1_adc_vc_stop_conversionfunction rzn1_adc_vc_wait_conversionfunction rzn1_adc_read_raw_chfunction scoped_guardfunction rzn1_adc_get_vref_mVfunction rzn1_adc_read_rawfunction rzn1_adc_set_iio_dev_channelsfunction rzn1_adc_core_get_regulatorsfunction rzn1_adc_probefunction rzn1_adc_pm_runtime_suspendfunction rzn1_adc_pm_runtime_resume
Annotated Snippet
struct rzn1_adc {
struct device *dev;
void __iomem *regs;
struct mutex lock; /* ADC lock */
int adc1_vref_mV; /* ADC1 Vref in mV. Negative if ADC1 is not used */
int adc2_vref_mV; /* ADC2 Vref in mV. Negative if ADC2 is not used */
};
static int rzn1_adc_power(struct rzn1_adc *rzn1_adc, bool power)
{
u32 v;
writel(power ? 0 : RZN1_ADC_CONFIG_ADC_POWER_DOWN,
rzn1_adc->regs + RZN1_ADC_CONFIG_REG);
/* Wait for the ADC_BUSY to clear */
return readl_poll_timeout_atomic(rzn1_adc->regs + RZN1_ADC_CONTROL_REG,
v, !(v & RZN1_ADC_CONTROL_ADC_BUSY),
0, 500);
}
static void rzn1_adc_vc_setup_conversion(struct rzn1_adc *rzn1_adc, u32 ch,
int adc1_ch, int adc2_ch)
{
u32 vc = 0;
if (adc1_ch != RZN1_ADC_NO_CHANNEL)
vc |= RZN1_ADC_VC_ADC1_ENABLE |
FIELD_PREP(RZN1_ADC_VC_ADC1_CHANNEL_SEL_MASK, adc1_ch);
if (adc2_ch != RZN1_ADC_NO_CHANNEL)
vc |= RZN1_ADC_VC_ADC2_ENABLE |
FIELD_PREP(RZN1_ADC_VC_ADC2_CHANNEL_SEL_MASK, adc2_ch);
writel(vc, rzn1_adc->regs + RZN1_ADC_VC_REG(ch));
}
static int rzn1_adc_vc_start_conversion(struct rzn1_adc *rzn1_adc, u32 ch)
{
u32 val;
val = readl(rzn1_adc->regs + RZN1_ADC_FORCE_REG);
if (val & RZN1_ADC_FORCE_VC(ch))
return -EBUSY;
writel(RZN1_ADC_FORCE_VC(ch), rzn1_adc->regs + RZN1_ADC_SET_FORCE_REG);
return 0;
}
static void rzn1_adc_vc_stop_conversion(struct rzn1_adc *rzn1_adc, u32 ch)
{
writel(RZN1_ADC_FORCE_VC(ch), rzn1_adc->regs + RZN1_ADC_CLEAR_FORCE_REG);
}
static int rzn1_adc_vc_wait_conversion(struct rzn1_adc *rzn1_adc, u32 ch,
u32 *adc1_data, u32 *adc2_data)
{
u32 data_reg;
int ret;
u32 v;
/*
* When a VC is selected, it needs 20 ADC clocks to perform the
* conversion.
*
* The worst case is when the 16 VCs need to perform a conversion and
* our VC is the lowest in term of priority.
*
* In that case, the conversion is performed in 16 * 20 ADC clocks.
*
* The ADC clock can be set from 4MHz to 20MHz. This leads to a worst
* case of 16 * 20 * 1/4Mhz = 80us.
*
* Round it up to 100us.
*/
/* Wait for the ADC_FORCE_VC(n) to clear */
ret = readl_poll_timeout_atomic(rzn1_adc->regs + RZN1_ADC_FORCE_REG,
v, !(v & RZN1_ADC_FORCE_VC(ch)),
0, 100);
if (ret)
return ret;
if (adc1_data) {
data_reg = readl(rzn1_adc->regs + RZN1_ADC_ADC1_DATA_REG(ch));
*adc1_data = FIELD_GET(RZN1_ADC_ADCX_DATA_DATA_MASK, data_reg);
}
if (adc2_data) {
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/bitfield.h`, `linux/bits.h`, `linux/cleanup.h`, `linux/clk.h`, `linux/dev_printk.h`, `linux/err.h`, `linux/iio/iio.h`.
- Detected declarations: `struct rzn1_adc`, `function Copyright`, `function rzn1_adc_power`, `function rzn1_adc_vc_setup_conversion`, `function rzn1_adc_vc_start_conversion`, `function rzn1_adc_vc_stop_conversion`, `function rzn1_adc_vc_wait_conversion`, `function rzn1_adc_read_raw_ch`, `function scoped_guard`, `function rzn1_adc_get_vref_mV`.
- Atlas domain: Driver Families / drivers/iio.
- 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.