drivers/iio/dac/adi-axi-dac.c
Source file repositories/reference/linux-study-clean/drivers/iio/dac/adi-axi-dac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/dac/adi-axi-dac.c- Extension
.c- Size
- 27784 bytes
- Lines
- 1043
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/adi-axi-common.hlinux/bitfield.hlinux/bits.hlinux/cleanup.hlinux/clk.hlinux/device.hlinux/err.hlinux/limits.hlinux/kstrtox.hlinux/math.hlinux/math64.hlinux/module.hlinux/mod_devicetable.hlinux/mutex.hlinux/platform_device.hlinux/property.hlinux/regmap.hlinux/units.hlinux/iio/backend.hlinux/iio/buffer-dmaengine.hlinux/iio/buffer.hlinux/iio/iio.had3552r-hs.h
Detected Declarations
struct axi_dac_infostruct axi_dac_statefunction axi_dac_enablefunction axi_dac_disablefunction axi_dac_free_bufferfunction __axi_dac_frequency_getfunction axi_dac_frequency_getfunction scoped_guardfunction axi_dac_scale_getfunction axi_dac_phase_getfunction __axi_dac_frequency_setfunction axi_dac_frequency_setfunction axi_dac_scale_setfunction axi_dac_phase_setfunction axi_dac_ext_info_setfunction axi_dac_ext_info_getfunction axi_dac_extend_chanfunction axi_dac_data_source_setfunction axi_dac_data_source_getfunction axi_dac_set_sample_ratefunction frequencyfunction axi_dac_reg_accessfunction axi_dac_ddr_enablefunction axi_dac_ddr_disablefunction axi_dac_wait_bus_freefunction axi_dac_data_stream_enablefunction axi_dac_data_stream_disablefunction axi_dac_data_transfer_addrfunction axi_dac_data_format_setfunction __axi_dac_bus_reg_writefunction axi_dac_bus_reg_writefunction axi_dac_bus_reg_readfunction axi_dac_bus_set_io_modefunction axi_dac_child_removefunction axi_dac_create_platform_devicefunction axi_dac_probefunction device_for_each_child_node_scoped
Annotated Snippet
struct axi_dac_info {
unsigned int version;
const struct iio_backend_info *backend_info;
bool has_dac_clk;
bool has_child_nodes;
};
struct axi_dac_state {
struct regmap *regmap;
struct device *dev;
/*
* lock to protect multiple accesses to the device registers and global
* data/variables.
*/
struct mutex lock;
const struct axi_dac_info *info;
u64 dac_clk;
u32 reg_config;
int dac_clk_rate;
};
static int axi_dac_enable(struct iio_backend *back)
{
struct axi_dac_state *st = iio_backend_get_priv(back);
unsigned int __val;
int ret;
guard(mutex)(&st->lock);
ret = regmap_set_bits(st->regmap, AXI_DAC_RSTN_REG,
AXI_DAC_RSTN_MMCM_RSTN);
if (ret)
return ret;
/*
* Make sure the DRP (Dynamic Reconfiguration Port) is locked. Not all
* designs really use it but if they don't we still get the lock bit
* set. So let's do it all the time so the code is generic.
*/
ret = regmap_read_poll_timeout(st->regmap, AXI_DAC_DRP_STATUS_REG,
__val,
__val & AXI_DAC_DRP_STATUS_DRP_LOCKED,
100, 1000);
if (ret)
return ret;
return regmap_set_bits(st->regmap, AXI_DAC_RSTN_REG,
AXI_DAC_RSTN_RSTN | AXI_DAC_RSTN_MMCM_RSTN);
}
static void axi_dac_disable(struct iio_backend *back)
{
struct axi_dac_state *st = iio_backend_get_priv(back);
guard(mutex)(&st->lock);
regmap_write(st->regmap, AXI_DAC_RSTN_REG, 0);
}
static struct iio_buffer *axi_dac_request_buffer(struct iio_backend *back,
struct iio_dev *indio_dev)
{
struct axi_dac_state *st = iio_backend_get_priv(back);
const char *dma_name;
if (device_property_read_string(st->dev, "dma-names", &dma_name))
dma_name = "tx";
return iio_dmaengine_buffer_setup_ext(st->dev, indio_dev, dma_name,
IIO_BUFFER_DIRECTION_OUT);
}
static void axi_dac_free_buffer(struct iio_backend *back,
struct iio_buffer *buffer)
{
iio_dmaengine_buffer_teardown(buffer);
}
enum {
AXI_DAC_FREQ_TONE_1,
AXI_DAC_FREQ_TONE_2,
AXI_DAC_SCALE_TONE_1,
AXI_DAC_SCALE_TONE_2,
AXI_DAC_PHASE_TONE_1,
AXI_DAC_PHASE_TONE_2,
};
static int __axi_dac_frequency_get(struct axi_dac_state *st, unsigned int chan,
unsigned int tone_2, unsigned int *freq)
{
u32 reg, raw;
int ret;
Annotation
- Immediate include surface: `linux/adi-axi-common.h`, `linux/bitfield.h`, `linux/bits.h`, `linux/cleanup.h`, `linux/clk.h`, `linux/device.h`, `linux/err.h`, `linux/limits.h`.
- Detected declarations: `struct axi_dac_info`, `struct axi_dac_state`, `function axi_dac_enable`, `function axi_dac_disable`, `function axi_dac_free_buffer`, `function __axi_dac_frequency_get`, `function axi_dac_frequency_get`, `function scoped_guard`, `function axi_dac_scale_get`, `function axi_dac_phase_get`.
- 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.