static int ni_ai_cmdtest()

in drivers/ni_mio_common.c [2002:2143]


static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
			 struct comedi_cmd *cmd)
{
	const struct ni_board_struct *board = dev->board_ptr;
	struct ni_private *devpriv = dev->private;
	int err = 0;
	unsigned int sources;

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

	err |= comedi_check_trigger_src(&cmd->start_src,
					TRIG_NOW | TRIG_INT | TRIG_EXT);
	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
					TRIG_TIMER | TRIG_EXT);

	sources = TRIG_TIMER | TRIG_EXT;
	if (devpriv->is_611x || devpriv->is_6143)
		sources |= TRIG_NOW;
	err |= comedi_check_trigger_src(&cmd->convert_src, sources);

	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->start_src);
	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
	err |= comedi_check_trigger_is_unique(cmd->convert_src);
	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 */

	switch (cmd->start_src) {
	case TRIG_NOW:
	case TRIG_INT:
		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
		break;
	case TRIG_EXT:
		err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->start_arg),
						  NI_AI_StartTrigger,
						  &devpriv->routing_tables, 1);
		break;
	}

	if (cmd->scan_begin_src == TRIG_TIMER) {
		err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
			ni_min_ai_scan_period_ns(dev, cmd->chanlist_len));
		err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
						    devpriv->clock_ns *
						    0xffffff);
	} else if (cmd->scan_begin_src == TRIG_EXT) {
		/* external trigger */
		err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->scan_begin_arg),
						  NI_AI_SampleClock,
						  &devpriv->routing_tables, 1);
	} else {		/* TRIG_OTHER */
		err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
	}

	if (cmd->convert_src == TRIG_TIMER) {
		if (devpriv->is_611x || devpriv->is_6143) {
			err |= comedi_check_trigger_arg_is(&cmd->convert_arg,
							   0);
		} else {
			err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
							    board->ai_speed);
			err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
							    devpriv->clock_ns *
							    0xffff);
		}
	} else if (cmd->convert_src == TRIG_EXT) {
		/* external trigger */
		err |= ni_check_trigger_arg_roffs(CR_CHAN(cmd->convert_arg),
						  NI_AI_ConvertClock,
						  &devpriv->routing_tables, 1);
	} else if (cmd->convert_src == TRIG_NOW) {
		err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
	}

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

	if (cmd->stop_src == TRIG_COUNT) {
		unsigned int max_count = 0x01000000;

		if (devpriv->is_611x)
			max_count -= num_adc_stages_611x;
		err |= comedi_check_trigger_arg_max(&cmd->stop_arg, max_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 */

	if (cmd->scan_begin_src == TRIG_TIMER) {
		unsigned int tmp = cmd->scan_begin_arg;

		cmd->scan_begin_arg =
		    ni_timer_to_ns(dev, ni_ns_to_timer(dev,
						       cmd->scan_begin_arg,
						       cmd->flags));
		if (tmp != cmd->scan_begin_arg)
			err++;
	}
	if (cmd->convert_src == TRIG_TIMER) {
		if (!devpriv->is_611x && !devpriv->is_6143) {
			unsigned int tmp = cmd->convert_arg;

			cmd->convert_arg =
			    ni_timer_to_ns(dev, ni_ns_to_timer(dev,
							       cmd->convert_arg,
							       cmd->flags));
			if (tmp != cmd->convert_arg)
				err++;
			if (cmd->scan_begin_src == TRIG_TIMER &&
			    cmd->scan_begin_arg <
			    cmd->convert_arg * cmd->scan_end_arg) {
				cmd->scan_begin_arg =
				    cmd->convert_arg * cmd->scan_end_arg;
				err++;
			}
		}
	}

	if (err)
		return 4;

	return 0;
}