X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=kernel%2Fdrivers%2Fstaging%2Fcomedi%2Fdrivers%2Fdas1800.c;h=3be10963f98b6bd2296ee1972118fbd562091738;hb=52f993b8e89487ec9ee15a7fb4979e0f09a45b27;hp=53baf37cd21a6ab71e6eea8bb66a524e51f8e24e;hpb=9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00;p=kvmfornfv.git diff --git a/kernel/drivers/staging/comedi/drivers/das1800.c b/kernel/drivers/staging/comedi/drivers/das1800.c index 53baf37cd..3be10963f 100644 --- a/kernel/drivers/staging/comedi/drivers/das1800.c +++ b/kernel/drivers/staging/comedi/drivers/das1800.c @@ -444,9 +444,9 @@ static const struct comedi_lrange range_ao_2 = { static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, uint16_t sample) { - const struct das1800_board *thisboard = dev->board_ptr; + const struct das1800_board *board = dev->board_ptr; - sample += 1 << (thisboard->resolution - 1); + sample += 1 << (board->resolution - 1); return sample; } @@ -567,14 +567,17 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) struct comedi_isadma_desc *desc; int i; - outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ - outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ - outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ + /* disable and stop conversions */ + outb(0x0, dev->iobase + DAS1800_STATUS); + outb(0x0, dev->iobase + DAS1800_CONTROL_B); + outb(0x0, dev->iobase + DAS1800_CONTROL_A); - for (i = 0; i < 2; i++) { - desc = &dma->desc[i]; - if (desc->chan) - comedi_isadma_disable(desc->chan); + if (dma) { + for (i = 0; i < 2; i++) { + desc = &dma->desc[i]; + if (desc->chan) + comedi_isadma_disable(desc->chan); + } } return 0; @@ -725,7 +728,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct das1800_board *thisboard = dev->board_ptr; + const struct das1800_board *board = dev->board_ptr; int err = 0; unsigned int arg; @@ -765,7 +768,7 @@ static int das1800_ai_do_cmdtest(struct comedi_device *dev, if (cmd->convert_src == TRIG_TIMER) { err |= comedi_check_trigger_arg_min(&cmd->convert_arg, - thisboard->ai_speed); + board->ai_speed); } err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1); @@ -934,13 +937,14 @@ static void das1800_ai_setup_dma(struct comedi_device *dev, { struct das1800_private *devpriv = dev->private; struct comedi_isadma *dma = devpriv->dma; - struct comedi_isadma_desc *desc = &dma->desc[0]; + struct comedi_isadma_desc *desc; unsigned int bytes; if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) return; dma->cur_dma = 0; + desc = &dma->desc[0]; /* determine a dma transfer size to fill buffer in 0.3 sec */ bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000); @@ -1048,7 +1052,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct das1800_board *thisboard = dev->board_ptr; + const struct das1800_board *board = dev->board_ptr; int i, n; int chan, range, aref, chan_range; int timeout = 1000; @@ -1098,7 +1102,7 @@ static int das1800_ai_rinsn(struct comedi_device *dev, dpnt = inw(dev->iobase + DAS1800_FIFO); /* shift data to offset binary for bipolar ranges */ if ((conv_flags & UB) == 0) - dpnt += 1 << (thisboard->resolution - 1); + dpnt += 1 << (board->resolution - 1); data[n] = dpnt; } exit: @@ -1112,16 +1116,16 @@ static int das1800_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct das1800_board *thisboard = dev->board_ptr; + const struct das1800_board *board = dev->board_ptr; struct das1800_private *devpriv = dev->private; int chan = CR_CHAN(insn->chanspec); /* int range = CR_RANGE(insn->chanspec); */ - int update_chan = thisboard->ao_n_chan - 1; + int update_chan = board->ao_n_chan - 1; unsigned short output; unsigned long irq_flags; /* card expects two's complement data */ - output = data[0] - (1 << (thisboard->resolution - 1)); + output = data[0] - (1 << (board->resolution - 1)); /* if the write is to the 'update' channel, we need to remember its value */ if (chan == update_chan) devpriv->ao_update_bits = output; @@ -1216,72 +1220,77 @@ static void das1800_free_dma(struct comedi_device *dev) comedi_isadma_free(devpriv->dma); } -static int das1800_probe(struct comedi_device *dev) +static const struct das1800_board *das1800_probe(struct comedi_device *dev) { const struct das1800_board *board = dev->board_ptr; - int index; + int index = board ? board - das1800_boards : -EINVAL; int id; - /* calc the offset to the boardinfo that was found by the core */ - index = board - das1800_boards; - - /* verify that the board id matches the boardinfo */ + /* + * The dev->board_ptr will be set by comedi_device_attach() if the + * board name provided by the user matches a board->name in this + * driver. If so, this function sanity checks the id to verify that + * the board is correct. + * + * If the dev->board_ptr is not set, the user is trying to attach + * an unspecified board to this driver. In this case the id is used + * to 'probe' for the correct dev->board_ptr. + */ id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; switch (id) { case 0x3: if (index == das1801st_da || index == das1802st_da || index == das1701st_da || index == das1702st_da) - return index; + return board; index = das1801st; break; case 0x4: if (index == das1802hr_da || index == das1702hr_da) - return index; + return board; index = das1802hr; break; case 0x5: if (index == das1801ao || index == das1802ao || index == das1701ao || index == das1702ao) - return index; + return board; index = das1801ao; break; case 0x6: if (index == das1802hr || index == das1702hr) - return index; + return board; index = das1802hr; break; case 0x7: if (index == das1801st || index == das1802st || index == das1701st || index == das1702st) - return index; + return board; index = das1801st; break; case 0x8: if (index == das1801hc || index == das1802hc) - return index; + return board; index = das1801hc; break; default: dev_err(dev->class_dev, "Board model: probe returned 0x%x (unknown, please report)\n", id); - break; + return NULL; } dev_err(dev->class_dev, "Board model (probed, not recommended): %s series\n", das1800_boards[index].name); - return index; + return &das1800_boards[index]; } static int das1800_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct das1800_board *thisboard; + const struct das1800_board *board; struct das1800_private *devpriv; struct comedi_subdevice *s; unsigned int irq = it->options[1]; - int board; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); @@ -1293,17 +1302,15 @@ static int das1800_attach(struct comedi_device *dev, return ret; board = das1800_probe(dev); - if (board < 0) { + if (!board) { dev_err(dev->class_dev, "unable to determine board type\n"); return -ENODEV; } - - dev->board_ptr = das1800_boards + board; - thisboard = dev->board_ptr; - dev->board_name = thisboard->name; + dev->board_ptr = board; + dev->board_name = board->name; /* if it is an 'ao' board with fancy analog out then we need extra io ports */ - if (thisboard->ao_ability == 2) { + if (board->ao_ability == 2) { unsigned long iobase2 = dev->iobase + IOBASE2; ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE); @@ -1363,11 +1370,11 @@ static int das1800_attach(struct comedi_device *dev, s = &dev->subdevices[0]; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; - if (thisboard->common) + if (board->common) s->subdev_flags |= SDF_COMMON; - s->n_chan = thisboard->qram_len; - s->maxdata = (1 << thisboard->resolution) - 1; - s->range_table = thisboard->range_ai; + s->n_chan = board->qram_len; + s->maxdata = (1 << board->resolution) - 1; + s->range_table = board->range_ai; s->insn_read = das1800_ai_rinsn; if (dev->irq) { dev->read_subdev = s; @@ -1381,11 +1388,11 @@ static int das1800_attach(struct comedi_device *dev, /* analog out */ s = &dev->subdevices[1]; - if (thisboard->ao_ability == 1) { + if (board->ao_ability == 1) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->ao_n_chan; - s->maxdata = (1 << thisboard->resolution) - 1; + s->n_chan = board->ao_n_chan; + s->maxdata = (1 << board->resolution) - 1; s->range_table = &range_bipolar10; s->insn_write = das1800_ao_winsn; } else { @@ -1405,7 +1412,7 @@ static int das1800_attach(struct comedi_device *dev, s = &dev->subdevices[3]; s->type = COMEDI_SUBD_DO; s->subdev_flags = SDF_WRITABLE; - s->n_chan = thisboard->do_n_chan; + s->n_chan = board->do_n_chan; s->maxdata = 1; s->range_table = &range_digital; s->insn_bits = das1800_do_wbits; @@ -1416,9 +1423,9 @@ static int das1800_attach(struct comedi_device *dev, outb(0, dev->iobase + DAS1800_DIGITAL); /* initialize analog out channels */ - if (thisboard->ao_ability == 1) { + if (board->ao_ability == 1) { /* select 'update' dac channel for baseAddress + 0x0 */ - outb(DAC(thisboard->ao_n_chan - 1), + outb(DAC(board->ao_n_chan - 1), dev->iobase + DAS1800_SELECT); outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); }