int das08_common_attach()

in drivers/das08.c [342:453]


int das08_common_attach(struct comedi_device *dev, unsigned long iobase)
{
	const struct das08_board_struct *board = dev->board_ptr;
	struct das08_private_struct *devpriv = dev->private;
	struct comedi_subdevice *s;
	int ret;
	int i;

	dev->iobase = iobase;

	dev->board_name = board->name;

	ret = comedi_alloc_subdevices(dev, 6);
	if (ret)
		return ret;

	s = &dev->subdevices[0];
	/* ai */
	if (board->ai_nbits) {
		s->type = COMEDI_SUBD_AI;
		/*
		 * XXX some boards actually have differential
		 * inputs instead of single ended.
		 * The driver does nothing with arefs though,
		 * so it's no big deal.
		 */
		s->subdev_flags = SDF_READABLE | SDF_GROUND;
		s->n_chan = 8;
		s->maxdata = (1 << board->ai_nbits) - 1;
		s->range_table = das08_ai_lranges[board->ai_pg];
		s->insn_read = das08_ai_insn_read;
		devpriv->pg_gainlist = das08_ai_gainlists[board->ai_pg];
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	s = &dev->subdevices[1];
	/* ao */
	if (board->ao_nbits) {
		s->type = COMEDI_SUBD_AO;
		s->subdev_flags = SDF_WRITABLE;
		s->n_chan = 2;
		s->maxdata = (1 << board->ao_nbits) - 1;
		s->range_table = &range_bipolar5;
		s->insn_write = das08_ao_insn_write;

		ret = comedi_alloc_subdev_readback(s);
		if (ret)
			return ret;

		/* initialize all channels to 0V */
		for (i = 0; i < s->n_chan; i++) {
			s->readback[i] = s->maxdata / 2;
			das08_ao_set_data(dev, i, s->readback[i]);
		}
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	s = &dev->subdevices[2];
	/* di */
	if (board->di_nchan) {
		s->type = COMEDI_SUBD_DI;
		s->subdev_flags = SDF_READABLE;
		s->n_chan = board->di_nchan;
		s->maxdata = 1;
		s->range_table = &range_digital;
		s->insn_bits = board->is_jr ? das08jr_di_insn_bits :
			       das08_di_insn_bits;
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	s = &dev->subdevices[3];
	/* do */
	if (board->do_nchan) {
		s->type = COMEDI_SUBD_DO;
		s->subdev_flags = SDF_WRITABLE;
		s->n_chan = board->do_nchan;
		s->maxdata = 1;
		s->range_table = &range_digital;
		s->insn_bits = board->is_jr ? das08jr_do_insn_bits :
			       das08_do_insn_bits;
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	s = &dev->subdevices[4];
	/* 8255 */
	if (board->i8255_offset != 0) {
		ret = subdev_8255_init(dev, s, NULL, board->i8255_offset);
		if (ret)
			return ret;
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	/* Counter subdevice (8254) */
	s = &dev->subdevices[5];
	if (board->i8254_offset) {
		dev->pacer = comedi_8254_init(dev->iobase + board->i8254_offset,
					      0, I8254_IO8, 0);
		if (!dev->pacer)
			return -ENOMEM;

		comedi_8254_subdevice_init(s, dev->pacer);
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	return 0;
}