drivers/comedi/drivers/dmm32at.c

Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/dmm32at.c

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/dmm32at.c
Extension
.c
Size
18625 bytes
Lines
661
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (chan != (chan0 + i) % s->n_chan) {
			dev_dbg(dev->class_dev,
				"entries in chanlist must be consecutive channels, counting upwards\n");
			return -EINVAL;
		}
		if (range != range0) {
			dev_dbg(dev->class_dev,
				"entries in chanlist must all have the same gain\n");
			return -EINVAL;
		}
	}

	return 0;
}

static int dmm32at_ai_cmdtest(struct comedi_device *dev,
			      struct comedi_subdevice *s,
			      struct comedi_cmd *cmd)
{
	int err = 0;
	unsigned int arg;

	/* Step 1 : check if triggers are trivially valid */

	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
	err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
	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 */

	err |= comedi_check_trigger_is_unique(cmd->stop_src);

	/* Step 2b : and mutually compatible */

	if (err)
		return 2;

	/* Step 3: check if arguments are trivially valid */

	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);

	err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 1000000);
	err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 1000000000);

	if (cmd->convert_arg >= 17500)
		cmd->convert_arg = 20000;
	else if (cmd->convert_arg >= 12500)
		cmd->convert_arg = 15000;
	else if (cmd->convert_arg >= 7500)
		cmd->convert_arg = 10000;
	else
		cmd->convert_arg = 5000;

	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
					   cmd->chanlist_len);

	if (cmd->stop_src == TRIG_COUNT)
		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
	else /* TRIG_NONE */
		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);

	if (err)
		return 3;

	/* Step 4: fix up any arguments */

	arg = cmd->convert_arg * cmd->scan_end_arg;
	err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);

	if (err)
		return 4;

	/* Step 5: check channel list if it exists */
	if (cmd->chanlist && cmd->chanlist_len > 0)
		err |= dmm32at_ai_check_chanlist(dev, s, cmd);

	if (err)
		return 5;

	return 0;
}

static void dmm32at_setaitimer(struct comedi_device *dev, unsigned int nansec)
{
	unsigned long irq_flags;

Annotation

Implementation Notes