Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 324599
b: refs/heads/master
c: aee815b
h: refs/heads/master
i:
  324597: d7d928a
  324595: 5240c38
  324591: 3ba5790
v: v3
  • Loading branch information
H Hartley Sweeten authored and Greg Kroah-Hartman committed Aug 17, 2012
1 parent 450a153 commit d045000
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b9616b18c1dbbc3bfad9c1801fb96f41c26449e2
refs/heads/master: aee815b53bca1cfa092ecd742fc59512b8030336
63 changes: 26 additions & 37 deletions trunk/drivers/staging/comedi/drivers/cb_pcimdda.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,62 +110,51 @@ static int cb_pcimdda_ao_winsn(struct comedi_device *dev,
unsigned int *data)
{
struct cb_pcimdda_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan);
unsigned int val = 0;
int i;
int chan = CR_CHAN(insn->chanspec);
unsigned long offset = dev->iobase + chan * 2;

/* Writing a list of values to an AO channel is probably not
* very useful, but that's how the interface is defined. */
for (i = 0; i < insn->n; i++) {
/* first, load the low byte */
outb((char)(data[i] & 0x00ff), offset);
/* next, write the high byte -- only after this is written is
the channel voltage updated in the DAC, unless
we're in simultaneous xfer mode (jumper on card)
then a rinsn is necessary to actually update the DAC --
see cb_pcimdda_ao_rinsn() below... */
outb((char)(data[i] >> 8 & 0x00ff), offset + 1);

/* for testing only.. the actual rinsn SHOULD do an inw!
(see the stuff about simultaneous XFER mode on this board) */
devpriv->ao_readback[chan] = data[i];
val = data[i];

/*
* Write the LSB then MSB.
*
* If the simultaneous xfer mode is selected by the
* jumper on the card, a read instruction is needed
* in order to initiate the simultaneous transfer.
* Otherwise, the DAC will be updated when the MSB
* is written.
*/
outb(val & 0x00ff, offset);
outb((val >> 8) & 0x00ff, offset + 1);
}

/* return the number of samples read/written */
return i;
}
/* Cache the last value for readback */
devpriv->ao_readback[chan] = val;

/* AO subdevices should have a read insn as well as a write insn.
return insn->n;
}

Usually this means copying a value stored in devpriv->ao_readback.
However, since this board has this jumper setting called "Simultaneous
Xfer mode" (off by default), we will support it. Simultaneaous xfer
mode is accomplished by loading ALL the values you want for AO in all the
channels, then READing off one of the AO registers to initiate the
instantaneous simultaneous update of all DAC outputs, which makes
all AO channels update simultaneously. This is useful for some control
applications, I would imagine.
*/
static int cb_pcimdda_ao_rinsn(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct cb_pcimdda_private *devpriv = dev->private;
int i;
int chan = CR_CHAN(insn->chanspec);
unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan);
int i;

for (i = 0; i < insn->n; i++) {
inw(dev->iobase + chan * 2);
/*
* should I set data[i] to the result of the actual read
* on the register or the cached unsigned int in
* devpriv->ao_readback[]?
*/
/* Initiate the simultaneous transfer */
inw(offset);

data[i] = devpriv->ao_readback[chan];
}

return i;
return insn->n;
}

static struct pci_dev *cb_pcimdda_probe(struct comedi_device *dev,
Expand Down

0 comments on commit d045000

Please sign in to comment.