Commit 6174801d authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: addi_apci_3120: fix apci3120_ao_insn_write()

The comedi core expects (*insn_write) functions to write insn->n values and
return the number of values written or an errno. This function currently
returns insn->n but it only writes a single data value.

Fix the function to work like the core expects.

There are two registers used to update the analog outputs. Offset 0x08 is
used to update channels 0-3 and offset 0x0a to update channels 4-7. Bits
14 and 15 in each register set the mux to select which channel to update.
The lower 14 bits are the value used to set the DAC.

For aesthetics, tidy up the defines used for the register offsets and bits
in the registers.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b9ae2046
...@@ -96,24 +96,12 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY ...@@ -96,24 +96,12 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
#define APCI3120_SET4DIGITALOUTPUTON 1 #define APCI3120_SET4DIGITALOUTPUTON 1
#define APCI3120_SET4DIGITALOUTPUTOFF 0 #define APCI3120_SET4DIGITALOUTPUTOFF 0
/* analog output SELECT BIT */
#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
#define APCI3120_ANALOG_OP_CHANNEL_4 0xc000
#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
#define APCI3120_ANALOG_OP_CHANNEL_8 0xc000
/* Enable external trigger bit in nWrAddress */ /* Enable external trigger bit in nWrAddress */
#define APCI3120_ENABLE_EXT_TRIGGER 0x8000 #define APCI3120_ENABLE_EXT_TRIGGER 0x8000
/* ANALOG OUTPUT AND INPUT DEFINE */ /* ANALOG OUTPUT AND INPUT DEFINE */
#define APCI3120_UNIPOLAR 0x80 #define APCI3120_UNIPOLAR 0x80
#define APCI3120_BIPOLAR 0x00 #define APCI3120_BIPOLAR 0x00
#define APCI3120_ANALOG_OUTPUT_1 0x08
#define APCI3120_ANALOG_OUTPUT_2 0x0a
#define APCI3120_1_GAIN 0x00 #define APCI3120_1_GAIN 0x00
#define APCI3120_2_GAIN 0x10 #define APCI3120_2_GAIN 0x10
#define APCI3120_5_GAIN 0x20 #define APCI3120_5_GAIN 0x20
...@@ -1923,31 +1911,20 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, ...@@ -1923,31 +1911,20 @@ static int apci3120_ao_insn_write(struct comedi_device *dev,
struct comedi_insn *insn, struct comedi_insn *insn,
unsigned int *data) unsigned int *data)
{ {
unsigned int ui_Channel; unsigned int chan = CR_CHAN(insn->chanspec);
int ret; int i;
ui_Channel = CR_CHAN(insn->chanspec);
data[0] = ((((ui_Channel & 0x03) << 14) & 0xC000) | data[0]); for (i = 0; i < insn->n; i++) {
unsigned int val = data[i];
int ret;
ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
if (ret) if (ret)
return ret; return ret;
if (ui_Channel <= 3) outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
/* dev->iobase + APCI3120_AO_REG(chan));
* for channel 0-3 out at the register 1 (wrDac1-8) data[i] }
* typecasted to ushort since word write is to be done
*/
outw((unsigned short) data[0],
dev->iobase + APCI3120_ANALOG_OUTPUT_1);
else
/*
* for channel 4-7 out at the register 2 (wrDac5-8) data[i]
* typecasted to ushort since word write is to be done
*/
outw((unsigned short) data[0],
dev->iobase + APCI3120_ANALOG_OUTPUT_2);
return insn->n; return insn->n;
} }
...@@ -7,6 +7,22 @@ ...@@ -7,6 +7,22 @@
#include "comedi_fc.h" #include "comedi_fc.h"
#include "amcc_s5933.h" #include "amcc_s5933.h"
/*
* PCI BAR 0 register map (devpriv->amcc)
* see amcc_s5933.h for register and bit defines
*/
/*
* PCI BAR 1 register map (dev->iobase)
*/
#define APCI3120_AO_REG(x) (0x08 + (((x) / 4) * 2))
#define APCI3120_AO_MUX(x) (((x) & 0x3) << 14)
#define APCI3120_AO_DATA(x) ((x) << 0)
/*
* PCI BAR 2 register map (devpriv->addon)
*/
enum apci3120_boardid { enum apci3120_boardid {
BOARD_APCI3120, BOARD_APCI3120,
BOARD_APCI3001, BOARD_APCI3001,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment