drivers/iio/adc/dln2-adc.c
Source file repositories/reference/linux-study-clean/drivers/iio/adc/dln2-adc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/adc/dln2-adc.c- Extension
.c- Size
- 17048 bytes
- Lines
- 689
- 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/kernel.hlinux/module.hlinux/types.hlinux/platform_device.hlinux/mfd/dln2.hlinux/iio/iio.hlinux/iio/sysfs.hlinux/iio/trigger.hlinux/iio/trigger_consumer.hlinux/iio/triggered_buffer.hlinux/iio/buffer.hlinux/iio/kfifo_buf.h
Detected Declarations
struct dln2_adc_demux_tablestruct dln2_adcstruct dln2_adc_port_chanstruct dln2_adc_get_all_valsfunction dln2_adc_add_demuxfunction dln2_adc_update_demuxfunction dln2_adc_get_chan_countfunction dln2_adc_set_port_resolutionfunction dln2_adc_set_chan_enabledfunction dln2_adc_set_port_enabledfunction dln2_adc_set_chan_periodfunction dln2_adc_readfunction dln2_adc_read_allfunction dln2_adc_read_rawfunction dln2_adc_write_rawfunction dln2_update_scan_modefunction dln2_adc_trigger_hfunction dln2_adc_triggered_buffer_postenablefunction dln2_adc_triggered_buffer_predisablefunction dln2_adc_eventfunction dln2_adc_probefunction dln2_adc_remove
Annotated Snippet
struct dln2_adc_demux_table {
unsigned int from;
unsigned int to;
unsigned int length;
};
struct dln2_adc {
struct platform_device *pdev;
struct iio_chan_spec iio_channels[DLN2_ADC_MAX_CHANNELS + 1];
int port, trigger_chan;
struct iio_trigger *trig;
struct mutex mutex;
/* Cached sample period in milliseconds */
unsigned int sample_period;
/* Demux table */
unsigned int demux_count;
struct dln2_adc_demux_table demux[DLN2_ADC_MAX_CHANNELS];
};
struct dln2_adc_port_chan {
u8 port;
u8 chan;
};
struct dln2_adc_get_all_vals {
__le16 channel_mask;
__le16 values[DLN2_ADC_MAX_CHANNELS];
};
static void dln2_adc_add_demux(struct dln2_adc *dln2,
unsigned int in_loc, unsigned int out_loc,
unsigned int length)
{
struct dln2_adc_demux_table *p = dln2->demux_count ?
&dln2->demux[dln2->demux_count - 1] : NULL;
if (p && p->from + p->length == in_loc &&
p->to + p->length == out_loc) {
p->length += length;
} else if (dln2->demux_count < DLN2_ADC_MAX_CHANNELS) {
p = &dln2->demux[dln2->demux_count++];
p->from = in_loc;
p->to = out_loc;
p->length = length;
}
}
static void dln2_adc_update_demux(struct dln2_adc *dln2)
{
int in_ind = -1, out_ind;
unsigned int in_loc = 0, out_loc = 0;
struct iio_dev *indio_dev = platform_get_drvdata(dln2->pdev);
/* Clear out any old demux */
dln2->demux_count = 0;
/* Optimize all 8-channels case */
if (iio_get_masklength(indio_dev) &&
(*indio_dev->active_scan_mask & 0xff) == 0xff) {
dln2_adc_add_demux(dln2, 0, 0, 16);
return;
}
/* Build demux table from fixed 8-channels to active_scan_mask */
iio_for_each_active_channel(indio_dev, out_ind) {
/* Handle timestamp separately */
if (out_ind == DLN2_ADC_MAX_CHANNELS)
break;
for (++in_ind; in_ind != out_ind; ++in_ind)
in_loc += 2;
dln2_adc_add_demux(dln2, in_loc, out_loc, 2);
out_loc += 2;
in_loc += 2;
}
}
static int dln2_adc_get_chan_count(struct dln2_adc *dln2)
{
int ret;
u8 port = dln2->port;
u8 count;
int olen = sizeof(count);
ret = dln2_transfer(dln2->pdev, DLN2_ADC_GET_CHANNEL_COUNT,
&port, sizeof(port), &count, &olen);
if (ret < 0) {
dev_dbg(&dln2->pdev->dev, "Problem in %s\n", __func__);
return ret;
}
if (olen < sizeof(count))
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/types.h`, `linux/platform_device.h`, `linux/mfd/dln2.h`, `linux/iio/iio.h`, `linux/iio/sysfs.h`, `linux/iio/trigger.h`.
- Detected declarations: `struct dln2_adc_demux_table`, `struct dln2_adc`, `struct dln2_adc_port_chan`, `struct dln2_adc_get_all_vals`, `function dln2_adc_add_demux`, `function dln2_adc_update_demux`, `function dln2_adc_get_chan_count`, `function dln2_adc_set_port_resolution`, `function dln2_adc_set_chan_enabled`, `function dln2_adc_set_port_enabled`.
- 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.