From: H Hartley Sweeten Date: Wed, 25 Sep 2013 22:35:50 +0000 (-0700) Subject: staging: comedi: pcl726: tidy up pcl726_ao_insn() X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=1821e389ab651c63bc0d9370780be81c19a7c90c;p=linux-beck.git staging: comedi: pcl726: tidy up pcl726_ao_insn() For aesthetics, rename the function to help with greps. The offset binary value from the core should be saved for read back. Move the saving of the value in the private data so it occurs before the value is possibly munged for bipolar outputs. Use the comedi_offset_munge() helper to munge the offset binary value to two's complement for bipolar outputs. According to the November 2011 users manual, the write order must be MSB them LSB. Update the comment. Modify the register map defines to handle the channel offset calculation. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c index 17a4095be11b..fa14f3e90f8a 100644 --- a/drivers/staging/comedi/drivers/pcl726.c +++ b/drivers/staging/comedi/drivers/pcl726.c @@ -71,8 +71,8 @@ Interrupts are not supported. #define PCL727_SIZE 32 #define PCL728_SIZE 8 -#define PCL726_DAC0_HI 0 -#define PCL726_DAC0_LO 1 +#define PCL726_AO_MSB_REG(x) (0x00 + ((x) * 2)) +#define PCL726_AO_LSB_REG(x) (0x01 + ((x) * 2)) #define PCL726_DO_HI 12 #define PCL726_DO_LO 13 @@ -187,31 +187,31 @@ struct pcl726_private { unsigned int ao_readback[12]; }; -static int pcl726_ao_insn(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int pcl726_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct pcl726_private *devpriv = dev->private; unsigned int chan = CR_CHAN(insn->chanspec); unsigned int range = CR_RANGE(insn->chanspec); - int hi, lo; - int n; + unsigned int val; + int i; + + for (i = 0; i < insn->n; i++) { + val = data[i]; + devpriv->ao_readback[chan] = val; - for (n = 0; n < insn->n; n++) { - lo = data[n] & 0xff; - hi = (data[n] >> 8) & 0xf; + /* bipolar data to the DAC is two's complement */ if (comedi_chan_range_is_bipolar(s, chan, range)) - hi ^= 0x8; - /* - * the programming info did not say which order - * to write bytes. switch the order of the next - * two lines if you get glitches. - */ - outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan); - outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan); - devpriv->ao_readback[chan] = data[n]; + val = comedi_offset_munge(s, val); + + /* order is important, MSB then LSB */ + outb((val >> 8) & 0xff, dev->iobase + PCL726_AO_MSB_REG(chan)); + outb(val & 0xff, dev->iobase + PCL726_AO_LSB_REG(chan)); } - return n; + return insn->n; } static int pcl726_ao_insn_read(struct comedi_device *dev, @@ -322,7 +322,7 @@ static int pcl726_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->n_chan = board->n_aochan; s->maxdata = 0xfff; s->len_chanlist = 1; - s->insn_write = pcl726_ao_insn; + s->insn_write = pcl726_ao_insn_write; s->insn_read = pcl726_ao_insn_read; s->range_table_list = devpriv->rangelist; for (i = 0; i < board->n_aochan; i++) {