drivers/comedi/drivers/ni_labpc_common.c
Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/ni_labpc_common.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/comedi/drivers/ni_labpc_common.c- Extension
.c- Size
- 36175 bytes
- Lines
- 1363
- Domain
- Driver Families
- Bucket
- drivers/comedi
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/interrupt.hlinux/io.hlinux/delay.hlinux/slab.hlinux/comedi/comedidev.hlinux/comedi/comedi_8255.hlinux/comedi/comedi_8254.hni_labpc.hni_labpc_regs.hni_labpc_isadma.h
Detected Declarations
enum scan_modefunction labpc_inbfunction labpc_outbfunction labpc_readbfunction labpc_writebfunction labpc_cancelfunction labpc_ai_set_chan_and_gainfunction labpc_setup_cmd6_regfunction labpc_read_adc_fifofunction labpc_clear_adc_fifofunction labpc_ai_eocfunction labpc_ai_insn_readfunction labpc_use_continuous_modefunction labpc_ai_convert_periodfunction labpc_set_ai_convert_periodfunction labpc_ai_scan_periodfunction labpc_set_ai_scan_periodfunction labpc_adc_timingfunction labpc_ai_scan_modefunction labpc_ai_check_chanlistfunction labpc_ai_cmdtestfunction labpc_ai_cmdfunction labpc_drain_fifofunction comedifunction labpc_interruptfunction labpc_ao_writefunction labpc_ao_insn_writefunction labpc_serial_outfunction labpc_serial_infunction labpc_eeprom_readfunction labpc_eeprom_read_statusfunction labpc_eeprom_writefunction write_caldacfunction labpc_calib_insn_writefunction labpc_eeprom_readyfunction labpc_eeprom_insn_writefunction labpc_common_attachfunction labpc_common_detachexport labpc_common_attachexport labpc_common_detach
Annotated Snippet
switch (cmd->flags & CMDF_ROUND_MASK) {
default:
case CMDF_ROUND_NEAREST:
pacer->next_div = DIV_ROUND_CLOSEST(convert_period,
base_period);
pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period,
base_period);
break;
case CMDF_ROUND_UP:
pacer->next_div = DIV_ROUND_UP(convert_period,
base_period);
pacer->next_div2 = DIV_ROUND_UP(scan_period,
base_period);
break;
case CMDF_ROUND_DOWN:
pacer->next_div = convert_period / base_period;
pacer->next_div2 = scan_period / base_period;
break;
}
/* make sure a0 and b1 values are acceptable */
comedi_check_trigger_arg_min(&pacer->next_div, 2);
comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT);
comedi_check_trigger_arg_min(&pacer->next_div2, 2);
comedi_check_trigger_arg_max(&pacer->next_div2,
I8254_MAX_COUNT);
/* write corrected timings to command */
labpc_set_ai_convert_period(cmd, mode,
base_period * pacer->next_div);
labpc_set_ai_scan_period(cmd, mode,
base_period * pacer->next_div2);
} else if (scan_period) {
/*
* calculate cascaded counter values
* that give desired scan timing
* (pacer->next_div2 / pacer->next_div1)
*/
comedi_8254_cascade_ns_to_timer(pacer, &scan_period,
cmd->flags);
labpc_set_ai_scan_period(cmd, mode, scan_period);
} else if (convert_period) {
/*
* calculate cascaded counter values
* that give desired conversion timing
* (pacer->next_div / pacer->next_div1)
*/
comedi_8254_cascade_ns_to_timer(pacer, &convert_period,
cmd->flags);
/* transfer div2 value so correct timer gets updated */
pacer->next_div = pacer->next_div2;
labpc_set_ai_convert_period(cmd, mode, convert_period);
}
}
static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
{
unsigned int chan0;
unsigned int chan1;
if (cmd->chanlist_len == 1)
return MODE_SINGLE_CHAN;
/* chanlist may be NULL during cmdtest */
if (!cmd->chanlist)
return MODE_MULT_CHAN_UP;
chan0 = CR_CHAN(cmd->chanlist[0]);
chan1 = CR_CHAN(cmd->chanlist[1]);
if (chan0 < chan1)
return MODE_MULT_CHAN_UP;
if (chan0 > chan1)
return MODE_MULT_CHAN_DOWN;
return MODE_SINGLE_CHAN_INTERVAL;
}
static int labpc_ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{
enum scan_mode mode = labpc_ai_scan_mode(cmd);
unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
int i;
for (i = 0; i < cmd->chanlist_len; i++) {
unsigned int chan = CR_CHAN(cmd->chanlist[i]);
Annotation
- Immediate include surface: `linux/module.h`, `linux/interrupt.h`, `linux/io.h`, `linux/delay.h`, `linux/slab.h`, `linux/comedi/comedidev.h`, `linux/comedi/comedi_8255.h`, `linux/comedi/comedi_8254.h`.
- Detected declarations: `enum scan_mode`, `function labpc_inb`, `function labpc_outb`, `function labpc_readb`, `function labpc_writeb`, `function labpc_cancel`, `function labpc_ai_set_chan_and_gain`, `function labpc_setup_cmd6_reg`, `function labpc_read_adc_fifo`, `function labpc_clear_adc_fifo`.
- Atlas domain: Driver Families / drivers/comedi.
- Implementation status: integration 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.