drivers/comedi/drivers/pcmda12.c
Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/pcmda12.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/drivers/pcmda12.c- Extension
.c- Size
- 4604 bytes
- Lines
- 173
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/comedi/comedidev.h
Detected Declarations
struct pcmda12_privatefunction pcmda12_ao_insn_writefunction pcmda12_ao_insn_readfunction pcmda12_ao_resetfunction pcmda12_attach
Annotated Snippet
struct pcmda12_private {
int simultaneous_xfer_mode;
};
static int pcmda12_ao_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct pcmda12_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned int val = s->readback[chan];
unsigned long ioreg = dev->iobase + (chan * 2);
int i;
for (i = 0; i < insn->n; ++i) {
val = data[i];
outb(val & 0xff, ioreg);
outb((val >> 8) & 0xff, ioreg + 1);
/*
* Initiate transfer if not in simultaneaous xfer
* mode by reading one of the AO registers.
*/
if (!devpriv->simultaneous_xfer_mode)
inb(ioreg);
}
s->readback[chan] = val;
return insn->n;
}
static int pcmda12_ao_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct pcmda12_private *devpriv = dev->private;
/*
* Initiate simultaneaous xfer mode by reading one of the
* AO registers. All analog outputs will then be updated.
*/
if (devpriv->simultaneous_xfer_mode)
inb(dev->iobase);
return comedi_readback_insn_read(dev, s, insn, data);
}
static void pcmda12_ao_reset(struct comedi_device *dev,
struct comedi_subdevice *s)
{
int i;
for (i = 0; i < s->n_chan; ++i) {
outb(0, dev->iobase + (i * 2));
outb(0, dev->iobase + (i * 2) + 1);
}
/* Initiate transfer by reading one of the AO registers. */
inb(dev->iobase);
}
static int pcmda12_attach(struct comedi_device *dev,
struct comedi_devconfig *it)
{
struct pcmda12_private *devpriv;
struct comedi_subdevice *s;
int ret;
/*
* The datasheet says it requires 16 contiguous addresses and is
* "configurable on any even sixteen port boundary". So require
* a 32-byte boundary and assume it uses 10-bit addresses like
* similar boards.
*/
ret = comedi_check_request_region(dev, it->options[0], 0x10,
0, 0x3ff, 32);
if (ret)
return ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
devpriv->simultaneous_xfer_mode = it->options[1];
ret = comedi_alloc_subdevices(dev, 1);
if (ret)
return ret;
Annotation
- Immediate include surface: `linux/module.h`, `linux/comedi/comedidev.h`.
- Detected declarations: `struct pcmda12_private`, `function pcmda12_ao_insn_write`, `function pcmda12_ao_insn_read`, `function pcmda12_ao_reset`, `function pcmda12_attach`.
- Atlas domain: Driver Families / drivers/comedi.
- 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.