diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/me4000.c')
-rw-r--r-- | drivers/staging/comedi/drivers/me4000.c | 101 |
1 files changed, 25 insertions, 76 deletions
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c index 9a5c535451a1..6561b00bea59 100644 --- a/drivers/staging/comedi/drivers/me4000.c +++ b/drivers/staging/comedi/drivers/me4000.c @@ -176,8 +176,6 @@ broken. struct me4000_info { unsigned long plx_regbase; unsigned long timer_regbase; - - unsigned int ao_readback[4]; }; enum me4000_boardid { @@ -473,7 +471,7 @@ static int me4000_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data) { - const struct me4000_board *thisboard = comedi_board(dev); + const struct me4000_board *thisboard = dev->board_ptr; int chan = CR_CHAN(insn->chanspec); int rang = CR_RANGE(insn->chanspec); int aref = CR_AREF(insn->chanspec); @@ -601,7 +599,7 @@ static int me4000_ai_check_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - const struct me4000_board *board = comedi_board(dev); + const struct me4000_board *board = dev->board_ptr; unsigned int max_diff_chan = board->ai_diff_nchan; unsigned int aref0 = CR_AREF(cmd->chanlist[0]); int i; @@ -617,7 +615,7 @@ static int me4000_ai_check_chanlist(struct comedi_device *dev, return -EINVAL; } - if (aref == SDF_DIFF) { + if (aref == AREF_DIFF) { if (chan >= max_diff_chan) { dev_dbg(dev->class_dev, "Channel number to high\n"); @@ -652,10 +650,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *init_ticks = (cmd->start_arg * 33) / 1000; rest = (cmd->start_arg * 33) % 1000; - if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { + if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { if (rest > 33) (*init_ticks)++; - } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { + } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { if (rest) (*init_ticks)++; } @@ -665,10 +663,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *scan_ticks = (cmd->scan_begin_arg * 33) / 1000; rest = (cmd->scan_begin_arg * 33) % 1000; - if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { + if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { if (rest > 33) (*scan_ticks)++; - } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { + } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { if (rest) (*scan_ticks)++; } @@ -678,10 +676,10 @@ static int ai_round_cmd_args(struct comedi_device *dev, *chan_ticks = (cmd->convert_arg * 33) / 1000; rest = (cmd->convert_arg * 33) % 1000; - if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_NEAREST) { + if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { if (rest > 33) (*chan_ticks)++; - } else if ((cmd->flags & TRIG_ROUND_MASK) == TRIG_ROUND_UP) { + } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { if (rest) (*chan_ticks)++; } @@ -731,7 +729,7 @@ static int ai_write_chanlist(struct comedi_device *dev, else entry |= ME4000_AI_LIST_RANGE_BIPOLAR_10; - if (aref == SDF_DIFF) + if (aref == AREF_DIFF) entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; else entry |= ME4000_AI_LIST_INPUT_SINGLE_ENDED; @@ -851,7 +849,7 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, int err = 0; /* Only rounding flags are implemented */ - cmd->flags &= TRIG_ROUND_NEAREST | TRIG_ROUND_UP | TRIG_ROUND_DOWN; + cmd->flags &= CMDF_ROUND_NEAREST | CMDF_ROUND_UP | CMDF_ROUND_DOWN; /* Round the timer arguments */ ai_round_cmd_args(dev, s, cmd, &init_ticks, &scan_ticks, &chan_ticks); @@ -925,6 +923,11 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err |= -EINVAL; } + if (cmd->stop_src == TRIG_COUNT) + err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); + else /* TRIG_NONE */ + err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); + if (err) return 3; @@ -1031,13 +1034,6 @@ static int me4000_ai_do_cmd_test(struct comedi_device *dev, err++; } } - if (cmd->stop_src == TRIG_COUNT) { - if (cmd->stop_arg == 0) { - dev_err(dev->class_dev, "Invalid stop arg\n"); - cmd->stop_arg = 1; - err++; - } - } if (cmd->scan_end_src == TRIG_COUNT) { if (cmd->scan_end_arg == 0) { dev_err(dev->class_dev, "Invalid scan end arg\n"); @@ -1188,44 +1184,14 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id) return IRQ_HANDLED; } -/*============================================================================= - Analog output section - ===========================================================================*/ - static int me4000_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - const struct me4000_board *thisboard = comedi_board(dev); - struct me4000_info *info = dev->private; int chan = CR_CHAN(insn->chanspec); - int rang = CR_RANGE(insn->chanspec); - int aref = CR_AREF(insn->chanspec); unsigned int tmp; - if (insn->n == 0) { - return 0; - } else if (insn->n > 1) { - dev_err(dev->class_dev, "Invalid instruction length %d\n", - insn->n); - return -EINVAL; - } - - if (chan >= thisboard->ao_nchan) { - dev_err(dev->class_dev, "Invalid channel %d\n", insn->n); - return -EINVAL; - } - - if (rang != 0) { - dev_err(dev->class_dev, "Invalid range %d\n", insn->n); - return -EINVAL; - } - - if (aref != AREF_GROUND && aref != AREF_COMMON) { - dev_err(dev->class_dev, "Invalid aref %d\n", insn->n); - return -EINVAL; - } - /* Stop any running conversion */ tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan)); tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP; @@ -1238,26 +1204,7 @@ static int me4000_ao_insn_write(struct comedi_device *dev, outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan)); /* Store in the mirror */ - info->ao_readback[chan] = data[0]; - - return 1; -} - -static int me4000_ao_insn_read(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) -{ - struct me4000_info *info = dev->private; - int chan = CR_CHAN(insn->chanspec); - - if (insn->n == 0) { - return 0; - } else if (insn->n > 1) { - dev_err(dev->class_dev, "Invalid instruction length\n"); - return -EINVAL; - } - - data[0] = info->ao_readback[chan]; + s->readback[chan] = data[0]; return 1; } @@ -1507,7 +1454,11 @@ static int me4000_auto_attach(struct comedi_device *dev, s->maxdata = 0xFFFF; /* 16 bit DAC */ s->range_table = &range_bipolar10; s->insn_write = me4000_ao_insn_write; - s->insn_read = me4000_ao_insn_read; + s->insn_read = comedi_readback_insn_read; + + result = comedi_alloc_subdev_readback(s); + if (result) + return result; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1563,11 +1514,9 @@ static int me4000_auto_attach(struct comedi_device *dev, static void me4000_detach(struct comedi_device *dev) { - if (dev->irq) - free_irq(dev->irq, dev); if (dev->iobase) me4000_reset(dev); - comedi_pci_disable(dev); + comedi_pci_detach(dev); } static struct comedi_driver me4000_driver = { |