From 6174801d7e9ff27b3a589fe766f4cd75de14c31b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 20 Oct 2014 11:34:20 -0700 Subject: [PATCH] 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: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci3120.c | 45 +++++-------------- .../staging/comedi/drivers/addi_apci_3120.c | 16 +++++++ 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c index fbe17917cea1..47b1741758d1 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c @@ -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_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 */ #define APCI3120_ENABLE_EXT_TRIGGER 0x8000 /* ANALOG OUTPUT AND INPUT DEFINE */ #define APCI3120_UNIPOLAR 0x80 #define APCI3120_BIPOLAR 0x00 -#define APCI3120_ANALOG_OUTPUT_1 0x08 -#define APCI3120_ANALOG_OUTPUT_2 0x0a #define APCI3120_1_GAIN 0x00 #define APCI3120_2_GAIN 0x10 #define APCI3120_5_GAIN 0x20 @@ -1923,31 +1911,20 @@ static int apci3120_ao_insn_write(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data) { - unsigned int ui_Channel; - int ret; - - ui_Channel = CR_CHAN(insn->chanspec); + unsigned int chan = CR_CHAN(insn->chanspec); + int i; - 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); - if (ret) - return ret; + ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0); + if (ret) + return ret; - if (ui_Channel <= 3) - /* - * 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); + outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val), + dev->iobase + APCI3120_AO_REG(chan)); + } return insn->n; } diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c index 6b4a51db9c9e..abc85bf000ff 100644 --- a/drivers/staging/comedi/drivers/addi_apci_3120.c +++ b/drivers/staging/comedi/drivers/addi_apci_3120.c @@ -7,6 +7,22 @@ #include "comedi_fc.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 { BOARD_APCI3120, BOARD_APCI3001, -- 2.30.2