summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2014-03-10 21:07:40 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-03-17 21:04:00 (GMT)
commit8d9c93b4481f03a4f7658b97d6dc8996470a71e5 (patch)
tree4788bd0baef61eaa07aa1647b805e412bc23282c /drivers
parenta7b31d3996a866408ebd6d16992d166b0207c7c1 (diff)
downloadlinux-8d9c93b4481f03a4f7658b97d6dc8996470a71e5.tar.xz
staging: comedi: c6xdigio: add readback of last pwm channel values
Add and (*insn_read) for the PWM subdevice to allow reading back the last value written to the channels. There are only 2 PWM channels and they have a maxdata of 500. Pack the last values in the subdevice 'state' instead of adding a private data struct to this driver. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Reviewed-by: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
index 20a5dfe..4114cf2 100644
--- a/drivers/staging/comedi/drivers/c6xdigio.c
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -162,13 +162,41 @@ static int c6xdigio_pwm_insn_write(struct comedi_device *dev,
unsigned int *data)
{
unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int val = (s->state >> (16 * chan)) & 0xffff;
int i;
for (i = 0; i < insn->n; i++) {
- c6xdigio_pwm_write(dev, chan, data[i]);
- /* devpriv->ao_readback[chan] = data[i]; */
+ val = data[i];
+ c6xdigio_pwm_write(dev, chan, val);
}
- return i;
+
+ /*
+ * There are only 2 PWM channels and they have a maxdata of 500.
+ * Instead of allocating private data to save the values in for
+ * readback this driver just packs the values for the two channels
+ * in the s->state.
+ */
+ s->state &= (0xffff << (16 * chan));
+ s->state |= (val << (16 * chan));
+
+ return insn->n;
+}
+
+static int c6xdigio_pwm_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int val;
+ int i;
+
+ val = (s->state >> (16 * chan)) & 0xffff;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = val;
+
+ return insn->n;
}
static int c6xdigio_encoder_insn_read(struct comedi_device *dev,
@@ -243,6 +271,7 @@ static int c6xdigio_attach(struct comedi_device *dev,
s->maxdata = 500;
s->range_table = &range_unknown;
s->insn_write = c6xdigio_pwm_insn_write;
+ s->insn_read = c6xdigio_pwm_insn_read;
s = &dev->subdevices[1];
/* encoder (counter) subdevice */