return -EBUSY;
 }
 
-static int rtd_ao_winsn(struct comedi_device *dev,
-                       struct comedi_subdevice *s, struct comedi_insn *insn,
-                       unsigned int *data)
+static int rtd_ao_insn_write(struct comedi_device *dev,
+                            struct comedi_subdevice *s,
+                            struct comedi_insn *insn,
+                            unsigned int *data)
 {
        struct rtd_private *devpriv = dev->private;
-       int i;
-       int chan = CR_CHAN(insn->chanspec);
-       int range = CR_RANGE(insn->chanspec);
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
        int ret;
+       int i;
 
        /* Configure the output range (table index matches the range values) */
        writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan));
 
        for (i = 0; i < insn->n; ++i) {
-               int val = data[i] << 3;
-
-               /* VERIFY: comedi range and offset conversions */
+               unsigned int val = data[i];
 
-               if ((range > 1) && (data[i] < 2048)) {  /* bipolar */
-                       /* offset and sign extend */
-                       val = (((int)data[i]) - 2048) << 3;
-               } else {        /* unipolor */
-                       val = data[i] << 3;
+               /* bipolar uses 2's complement values with an extended sign */
+               if (comedi_range_is_bipolar(s, range)) {
+                       val = comedi_offset_munge(s, val);
+                       val |= (val & ((s->maxdata + 1) >> 1)) << 1;
                }
 
+               /* shift the 12-bit data (+ sign) to match the register */
+               val <<= 3;
+
                writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan));
                writew(0, dev->mmio + LAS0_UPDATE_DAC(chan));
 
-               s->readback[chan] = data[i];
-
                ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
                if (ret)
                        return ret;
+
+               s->readback[chan] = data[i];
        }
 
-       return i;
+       return insn->n;
 }
 
 static int rtd_dio_insn_bits(struct comedi_device *dev,
        s->n_chan       = 2;
        s->maxdata      = 0x0fff;
        s->range_table  = &rtd_ao_range;
-       s->insn_write   = rtd_ao_winsn;
+       s->insn_write   = rtd_ao_insn_write;
 
        ret = comedi_alloc_subdev_readback(s);
        if (ret)