drivers/iio/adc/xilinx-xadc-core.c
Source file repositories/reference/linux-study-clean/drivers/iio/adc/xilinx-xadc-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/adc/xilinx-xadc-core.c- Extension
.c- Size
- 39378 bytes
- Lines
- 1461
- 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.
- 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/clk.hlinux/device.hlinux/err.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/mod_devicetable.hlinux/module.hlinux/overflow.hlinux/platform_device.hlinux/property.hlinux/slab.hlinux/sysfs.hlinux/iio/buffer.hlinux/iio/events.hlinux/iio/iio.hlinux/iio/sysfs.hlinux/iio/trigger.hlinux/iio/trigger_consumer.hlinux/iio/triggered_buffer.hxilinx-xadc.h
Detected Declarations
function xadc_write_regfunction xadc_read_regfunction FIFOfunction xadc_zynq_drain_fifofunction xadc_zynq_update_intmskfunction xadc_zynq_write_adc_regfunction xadc_zynq_read_adc_regfunction xadc_zynq_transform_alarmfunction xadc_zynq_unmask_workerfunction xadc_zynq_interrupt_handlerfunction xadc_zynq_setupfunction xadc_zynq_get_dclk_ratefunction xadc_zynq_update_alarmfunction xadc_axi_read_adc_regfunction xadc_axi_write_adc_regfunction xadc_axi_setupfunction xadc_axi_interrupt_handlerfunction xadc_axi_update_alarmfunction xadc_axi_get_dclkfunction _xadc_update_adc_regfunction xadc_update_adc_regfunction xadc_get_dclk_ratefunction xadc_update_scan_modefunction xadc_scan_index_to_channelfunction xadc_trigger_handlerfunction xadc_trigger_set_statefunction xadc_power_adc_bfunction xadc_get_seq_modefunction xadc_postdisablefunction xadc_preenablefunction xadc_read_sampleratefunction xadc_read_rawfunction xadc_write_sampleratefunction xadc_write_rawfunction BITfunction xadc_parse_dtfunction xadc_cancel_delayed_workfunction xadc_probe
Annotated Snippet
if (xadc->trigger != NULL) {
ret = -EBUSY;
goto err_out;
} else {
xadc->trigger = trigger;
if (trigger == xadc->convst_trigger)
convst = XADC_CONF0_EC;
else
convst = 0;
}
ret = _xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF0_EC,
convst);
if (ret)
goto err_out;
} else {
xadc->trigger = NULL;
}
spin_lock_irqsave(&xadc->lock, flags);
xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS);
if (state)
val |= XADC_AXI_INT_EOS;
else
val &= ~XADC_AXI_INT_EOS;
xadc_write_reg(xadc, XADC_AXI_REG_IPIER, val);
spin_unlock_irqrestore(&xadc->lock, flags);
err_out:
mutex_unlock(&xadc->mutex);
return ret;
}
static const struct iio_trigger_ops xadc_trigger_ops = {
.set_trigger_state = &xadc_trigger_set_state,
};
static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
const char *name)
{
struct device *dev = indio_dev->dev.parent;
struct iio_trigger *trig;
int ret;
trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name,
iio_device_id(indio_dev), name);
if (trig == NULL)
return ERR_PTR(-ENOMEM);
trig->ops = &xadc_trigger_ops;
iio_trigger_set_drvdata(trig, iio_priv(indio_dev));
ret = devm_iio_trigger_register(dev, trig);
if (ret)
return ERR_PTR(ret);
return trig;
}
static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
{
uint16_t val;
/*
* As per datasheet the power-down bits are don't care in the
* UltraScale, but as per reality setting the power-down bit for the
* non-existing ADC-B powers down the main ADC, so just return and don't
* do anything.
*/
if (xadc->ops->type == XADC_TYPE_US)
return 0;
/* Powerdown the ADC-B when it is not needed. */
switch (seq_mode) {
case XADC_CONF1_SEQ_SIMULTANEOUS:
case XADC_CONF1_SEQ_INDEPENDENT:
val = 0;
break;
default:
val = XADC_CONF2_PD_ADC_B;
break;
}
return xadc_update_adc_reg(xadc, XADC_REG_CONF2, XADC_CONF2_PD_MASK,
val);
}
static int xadc_get_seq_mode(struct xadc *xadc, unsigned long scan_mode)
{
Annotation
- Immediate include surface: `linux/clk.h`, `linux/device.h`, `linux/err.h`, `linux/interrupt.h`, `linux/io.h`, `linux/kernel.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `function xadc_write_reg`, `function xadc_read_reg`, `function FIFO`, `function xadc_zynq_drain_fifo`, `function xadc_zynq_update_intmsk`, `function xadc_zynq_write_adc_reg`, `function xadc_zynq_read_adc_reg`, `function xadc_zynq_transform_alarm`, `function xadc_zynq_unmask_worker`, `function xadc_zynq_interrupt_handler`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source 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.