drivers/iio/adc/sophgo-cv1800b-adc.c
Source file repositories/reference/linux-study-clean/drivers/iio/adc/sophgo-cv1800b-adc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/adc/sophgo-cv1800b-adc.c- Extension
.c- Size
- 6529 bytes
- Lines
- 228
- 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.
- 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/array_size.hlinux/bitfield.hlinux/bits.hlinux/cleanup.hlinux/clk.hlinux/completion.hlinux/err.hlinux/interrupt.hlinux/iopoll.hlinux/mod_devicetable.hlinux/module.hlinux/mutex.hlinux/platform_device.hlinux/types.hlinux/iio/iio.h
Detected Declarations
struct cv1800b_adcfunction cv1800b_adc_start_measurementfunction cv1800b_adc_waitfunction cv1800b_adc_read_rawfunction scoped_guardfunction cv1800b_adc_interrupt_handlerfunction cv1800b_adc_probe
Annotated Snippet
struct cv1800b_adc {
struct completion completion;
void __iomem *regs;
struct mutex lock; /* ADC Control and Result register */
struct clk *clk;
int irq;
};
static const struct iio_chan_spec sophgo_channels[] = {
CV1800B_ADC_CHANNEL(0),
CV1800B_ADC_CHANNEL(1),
CV1800B_ADC_CHANNEL(2),
};
static void cv1800b_adc_start_measurement(struct cv1800b_adc *saradc,
int channel)
{
writel(0, saradc->regs + CV1800B_ADC_CTRL_REG);
writel(CV1800B_ADC_SEL(channel) | CV1800B_ADC_EN,
saradc->regs + CV1800B_ADC_CTRL_REG);
}
static int cv1800b_adc_wait(struct cv1800b_adc *saradc)
{
if (saradc->irq < 0) {
u32 reg;
return readl_poll_timeout(saradc->regs + CV1800B_ADC_STATUS_REG,
reg, !(reg & CV1800B_ADC_BUSY),
500, CV1800B_READ_TIMEOUT_US);
}
return wait_for_completion_timeout(&saradc->completion,
msecs_to_jiffies(CV1800B_READ_TIMEOUT_MS)) > 0 ?
0 : -ETIMEDOUT;
}
static int cv1800b_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct cv1800b_adc *saradc = iio_priv(indio_dev);
switch (mask) {
case IIO_CHAN_INFO_RAW: {
u32 sample;
scoped_guard(mutex, &saradc->lock) {
int ret;
cv1800b_adc_start_measurement(saradc, chan->scan_index);
ret = cv1800b_adc_wait(saradc);
if (ret < 0)
return ret;
sample = readl(saradc->regs + CV1800B_ADC_CH_RESULT_REG(chan->scan_index));
}
if (!(sample & CV1800B_ADC_CH_VALID))
return -ENODATA;
*val = sample & CV1800B_ADC_CH_RESULT;
return IIO_VAL_INT;
}
case IIO_CHAN_INFO_SCALE:
*val = 3300;
*val2 = 12;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_SAMP_FREQ: {
u32 status_reg = readl(saradc->regs + CV1800B_ADC_CYC_SET_REG);
unsigned int clk_div = (1 + FIELD_GET(CV1800B_MASK_CLKDIV, status_reg));
unsigned int freq = clk_get_rate(saradc->clk) / clk_div;
unsigned int nb_startup_cycle = 1 + FIELD_GET(CV1800B_MASK_STARTUP_CYCLE, status_reg);
unsigned int nb_sample_cycle = 1 + FIELD_GET(CV1800B_MASK_SAMPLE_WINDOW, status_reg);
unsigned int nb_compare_cycle = 1 + FIELD_GET(CV1800B_MASK_COMPARE_CYCLE, status_reg);
*val = freq / (nb_startup_cycle + nb_sample_cycle + nb_compare_cycle);
return IIO_VAL_INT;
}
default:
return -EINVAL;
}
}
static irqreturn_t cv1800b_adc_interrupt_handler(int irq, void *private)
{
struct cv1800b_adc *saradc = private;
u32 reg = readl(saradc->regs + CV1800B_ADC_INTR_STA_REG);
if (!(FIELD_GET(CV1800B_ADC_INTR_STA_BIT, reg)))
return IRQ_NONE;
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/bitfield.h`, `linux/bits.h`, `linux/cleanup.h`, `linux/clk.h`, `linux/completion.h`, `linux/err.h`, `linux/interrupt.h`.
- Detected declarations: `struct cv1800b_adc`, `function cv1800b_adc_start_measurement`, `function cv1800b_adc_wait`, `function cv1800b_adc_read_raw`, `function scoped_guard`, `function cv1800b_adc_interrupt_handler`, `function cv1800b_adc_probe`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source implementation candidate.
- 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.