drivers/comedi/drivers/das16m1.c
Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/das16m1.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/drivers/das16m1.c- Extension
.c- Size
- 17173 bytes
- Lines
- 626
- Domain
- Driver Families
- Bucket
- drivers/comedi
- 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/module.hlinux/slab.hlinux/interrupt.hlinux/comedi/comedidev.hlinux/comedi/comedi_8255.hlinux/comedi/comedi_8254.h
Detected Declarations
struct das16m1_privatefunction das16m1_ai_set_queuefunction das16m1_ai_mungefunction das16m1_ai_check_chanlistfunction das16m1_ai_cmdtestfunction das16m1_ai_cmdfunction das16m1_ai_cancelfunction das16m1_ai_eocfunction das16m1_ai_insn_readfunction das16m1_di_insn_bitsfunction das16m1_do_insn_bitsfunction das16m1_handlerfunction das16m1_ai_pollfunction das16m1_interruptfunction das16m1_irq_bitsfunction das16m1_attachfunction das16m1_detach
Annotated Snippet
struct das16m1_private {
struct comedi_8254 *counter;
unsigned int intr_ctrl;
unsigned int adc_count;
u16 initial_hw_count;
unsigned short ai_buffer[DAS16M1_AI_FIFO_SZ];
unsigned long extra_iobase;
};
static void das16m1_ai_set_queue(struct comedi_device *dev,
unsigned int *chanspec, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++) {
unsigned int chan = CR_CHAN(chanspec[i]);
unsigned int range = CR_RANGE(chanspec[i]);
outb(i, dev->iobase + DAS16M1_Q_ADDR_REG);
outb(DAS16M1_Q_CHAN(chan) | DAS16M1_Q_RANGE(range),
dev->iobase + DAS16M1_Q_REG);
}
}
static void das16m1_ai_munge(struct comedi_device *dev,
struct comedi_subdevice *s,
void *data, unsigned int num_bytes,
unsigned int start_chan_index)
{
unsigned short *array = data;
unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
unsigned int i;
/*
* The fifo values have the channel number in the lower 4-bits and
* the sample in the upper 12-bits. This just shifts the values
* to remove the channel numbers.
*/
for (i = 0; i < nsamples; i++)
array[i] = DAS16M1_AI_TO_SAMPLE(array[i]);
}
static int das16m1_ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
int i;
if (cmd->chanlist_len == 1)
return 0;
if ((cmd->chanlist_len % 2) != 0) {
dev_dbg(dev->class_dev,
"chanlist must be of even length or length 1\n");
return -EINVAL;
}
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int chan = CR_CHAN(cmd->chanlist[i]);
if ((i % 2) != (chan % 2)) {
dev_dbg(dev->class_dev,
"even/odd channels must go have even/odd chanlist indices\n");
return -EINVAL;
}
}
return 0;
}
static int das16m1_ai_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
int err = 0;
/* Step 1 : check if triggers are trivially valid */
err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW);
err |= comedi_check_trigger_src(&cmd->convert_src,
TRIG_TIMER | TRIG_EXT);
err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
if (err)
return 1;
/* Step 2a : make sure trigger sources are unique */
Annotation
- Immediate include surface: `linux/module.h`, `linux/slab.h`, `linux/interrupt.h`, `linux/comedi/comedidev.h`, `linux/comedi/comedi_8255.h`, `linux/comedi/comedi_8254.h`.
- Detected declarations: `struct das16m1_private`, `function das16m1_ai_set_queue`, `function das16m1_ai_munge`, `function das16m1_ai_check_chanlist`, `function das16m1_ai_cmdtest`, `function das16m1_ai_cmd`, `function das16m1_ai_cancel`, `function das16m1_ai_eoc`, `function das16m1_ai_insn_read`, `function das16m1_di_insn_bits`.
- Atlas domain: Driver Families / drivers/comedi.
- 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.