staging: comedi: adl_pci9118: remove forward declarations
Move some of the functions to remove the need for the forward declarations. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
435c8851ea
commit
5e49e5152c
|
@ -346,25 +346,162 @@ struct pci9118_private {
|
||||||
|
|
||||||
static int check_channel_list(struct comedi_device *dev,
|
static int check_channel_list(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s, int n_chan,
|
struct comedi_subdevice *s, int n_chan,
|
||||||
unsigned int *chanlist, int frontadd,
|
unsigned int *chanlist, int frontadd, int backadd)
|
||||||
int backadd);
|
{
|
||||||
|
const struct boardtype *this_board = comedi_board(dev);
|
||||||
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
unsigned int i, differencial = 0, bipolar = 0;
|
||||||
|
|
||||||
|
/* correct channel and range number check itself comedi/range.c */
|
||||||
|
if (n_chan < 1) {
|
||||||
|
comedi_error(dev, "range/channel list is empty!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((frontadd + n_chan + backadd) > s->len_chanlist) {
|
||||||
|
printk
|
||||||
|
("comedi%d: range/channel list is too long for "
|
||||||
|
"actual configuration (%d>%d)!",
|
||||||
|
dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CR_AREF(chanlist[0]) == AREF_DIFF)
|
||||||
|
differencial = 1; /* all input must be diff */
|
||||||
|
if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
|
||||||
|
bipolar = 1; /* all input must be bipolar */
|
||||||
|
if (n_chan > 1)
|
||||||
|
for (i = 1; i < n_chan; i++) { /* check S.E/diff */
|
||||||
|
if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
|
||||||
|
(differencial)) {
|
||||||
|
comedi_error(dev,
|
||||||
|
"Differencial and single ended "
|
||||||
|
"inputs can't be mixtured!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
|
||||||
|
(bipolar)) {
|
||||||
|
comedi_error(dev,
|
||||||
|
"Bipolar and unipolar ranges "
|
||||||
|
"can't be mixtured!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!devpriv->usemux && differencial &&
|
||||||
|
(CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
|
||||||
|
comedi_error(dev,
|
||||||
|
"If AREF_DIFF is used then is "
|
||||||
|
"available only first 8 channels!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int setup_channel_list(struct comedi_device *dev,
|
static int setup_channel_list(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s, int n_chan,
|
struct comedi_subdevice *s, int n_chan,
|
||||||
unsigned int *chanlist, int rot, int frontadd,
|
unsigned int *chanlist, int rot, int frontadd,
|
||||||
int backadd, int usedma, char eoshandle);
|
int backadd, int usedma, char useeos)
|
||||||
static void start_pacer(struct comedi_device *dev, int mode,
|
{
|
||||||
unsigned int divisor1, unsigned int divisor2);
|
struct pci9118_private *devpriv = dev->private;
|
||||||
static int pci9118_reset(struct comedi_device *dev);
|
unsigned int i, differencial = 0, bipolar = 0;
|
||||||
static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source);
|
unsigned int scanquad, gain, ssh = 0x00;
|
||||||
static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source);
|
|
||||||
static int pci9118_ai_cancel(struct comedi_device *dev,
|
if (usedma == 1) {
|
||||||
struct comedi_subdevice *s);
|
rot = 8;
|
||||||
static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
|
usedma = 0;
|
||||||
struct comedi_subdevice *s,
|
}
|
||||||
unsigned int *tim1, unsigned int *tim2,
|
|
||||||
unsigned int flags, int chans,
|
if (CR_AREF(chanlist[0]) == AREF_DIFF)
|
||||||
unsigned int *div1, unsigned int *div2,
|
differencial = 1; /* all input must be diff */
|
||||||
char usessh, unsigned int chnsshfront);
|
if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
|
||||||
|
bipolar = 1; /* all input must be bipolar */
|
||||||
|
|
||||||
|
/* All is ok, so we can setup channel/range list */
|
||||||
|
|
||||||
|
if (!bipolar) {
|
||||||
|
devpriv->AdControlReg |= AdControl_UniP;
|
||||||
|
/* set unibipolar */
|
||||||
|
} else {
|
||||||
|
devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
|
||||||
|
/* enable bipolar */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (differencial) {
|
||||||
|
devpriv->AdControlReg |= AdControl_Diff;
|
||||||
|
/* enable diff inputs */
|
||||||
|
} else {
|
||||||
|
devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
|
||||||
|
/* set single ended inputs */
|
||||||
|
}
|
||||||
|
|
||||||
|
outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
|
||||||
|
/* setup mode */
|
||||||
|
|
||||||
|
outl(2, dev->iobase + PCI9118_SCANMOD);
|
||||||
|
/* gods know why this sequence! */
|
||||||
|
outl(0, dev->iobase + PCI9118_SCANMOD);
|
||||||
|
outl(1, dev->iobase + PCI9118_SCANMOD);
|
||||||
|
|
||||||
|
#ifdef PCI9118_PARANOIDCHECK
|
||||||
|
devpriv->chanlistlen = n_chan;
|
||||||
|
for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
|
||||||
|
devpriv->chanlist[i] = 0x55aa;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (frontadd) { /* insert channels for S&H */
|
||||||
|
ssh = devpriv->softsshsample;
|
||||||
|
for (i = 0; i < frontadd; i++) {
|
||||||
|
/* store range list to card */
|
||||||
|
scanquad = CR_CHAN(chanlist[0]);
|
||||||
|
/* get channel number; */
|
||||||
|
gain = CR_RANGE(chanlist[0]);
|
||||||
|
/* get gain number */
|
||||||
|
scanquad |= ((gain & 0x03) << 8);
|
||||||
|
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
||||||
|
ssh = devpriv->softsshhold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n_chan; i++) { /* store range list to card */
|
||||||
|
scanquad = CR_CHAN(chanlist[i]); /* get channel number */
|
||||||
|
#ifdef PCI9118_PARANOIDCHECK
|
||||||
|
devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
|
||||||
|
#endif
|
||||||
|
gain = CR_RANGE(chanlist[i]); /* get gain number */
|
||||||
|
scanquad |= ((gain & 0x03) << 8);
|
||||||
|
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backadd) { /* insert channels for fit onto 32bit DMA */
|
||||||
|
for (i = 0; i < backadd; i++) { /* store range list to card */
|
||||||
|
scanquad = CR_CHAN(chanlist[0]);
|
||||||
|
/* get channel number */
|
||||||
|
gain = CR_RANGE(chanlist[0]); /* get gain number */
|
||||||
|
scanquad |= ((gain & 0x03) << 8);
|
||||||
|
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef PCI9118_PARANOIDCHECK
|
||||||
|
devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
|
||||||
|
/* for 32bit operations */
|
||||||
|
if (useeos) {
|
||||||
|
for (i = 1; i < n_chan; i++) { /* store range list to card */
|
||||||
|
devpriv->chanlist[(n_chan + i) ^ usedma] =
|
||||||
|
(CR_CHAN(chanlist[i]) & 0xf) << rot;
|
||||||
|
}
|
||||||
|
devpriv->chanlist[(2 * n_chan) ^ usedma] =
|
||||||
|
devpriv->chanlist[0 ^ usedma];
|
||||||
|
/* for 32bit operations */
|
||||||
|
useeos = 2;
|
||||||
|
} else {
|
||||||
|
useeos = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
|
||||||
|
/* udelay(100); important delay, or first sample will be crippled */
|
||||||
|
|
||||||
|
return 1; /* we can serve this with scan logic */
|
||||||
|
}
|
||||||
|
|
||||||
static int pci9118_insn_read_ai(struct comedi_device *dev,
|
static int pci9118_insn_read_ai(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s,
|
struct comedi_subdevice *s,
|
||||||
|
@ -540,6 +677,147 @@ static int move_block_from_dma(struct comedi_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
|
||||||
|
{
|
||||||
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
|
||||||
|
if (source > 3)
|
||||||
|
return -1; /* incorrect source */
|
||||||
|
devpriv->exttrg_users |= (1 << source);
|
||||||
|
devpriv->IntControlReg |= Int_DTrg;
|
||||||
|
outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
|
||||||
|
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
|
||||||
|
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
||||||
|
/* allow INT in AMCC */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
|
||||||
|
{
|
||||||
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
|
||||||
|
if (source > 3)
|
||||||
|
return -1; /* incorrect source */
|
||||||
|
devpriv->exttrg_users &= ~(1 << source);
|
||||||
|
if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
|
||||||
|
devpriv->IntControlReg &= ~Int_DTrg;
|
||||||
|
if (!devpriv->IntControlReg) /* all IRQ disabled */
|
||||||
|
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
|
||||||
|
(~0x00001f00),
|
||||||
|
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
||||||
|
/* disable int in AMCC */
|
||||||
|
outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
|
||||||
|
struct comedi_subdevice *s,
|
||||||
|
unsigned int *tim1, unsigned int *tim2,
|
||||||
|
unsigned int flags, int chans,
|
||||||
|
unsigned int *div1, unsigned int *div2,
|
||||||
|
char usessh, unsigned int chnsshfront)
|
||||||
|
{
|
||||||
|
const struct boardtype *this_board = comedi_board(dev);
|
||||||
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 1:
|
||||||
|
case 4:
|
||||||
|
if (*tim2 < this_board->ai_ns_min)
|
||||||
|
*tim2 = this_board->ai_ns_min;
|
||||||
|
i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
|
||||||
|
tim2, flags & TRIG_ROUND_NEAREST);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (*tim2 < this_board->ai_ns_min)
|
||||||
|
*tim2 = this_board->ai_ns_min;
|
||||||
|
*div1 = *tim2 / devpriv->i8254_osc_base;
|
||||||
|
/* convert timer (burst) */
|
||||||
|
if (*div1 < this_board->ai_pacer_min)
|
||||||
|
*div1 = this_board->ai_pacer_min;
|
||||||
|
*div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
|
||||||
|
*div2 = *div2 / *div1; /* major timer is c1*c2 */
|
||||||
|
if (*div2 < chans)
|
||||||
|
*div2 = chans;
|
||||||
|
|
||||||
|
*tim2 = *div1 * devpriv->i8254_osc_base;
|
||||||
|
/* real convert timer */
|
||||||
|
|
||||||
|
if (usessh & (chnsshfront == 0)) /* use BSSH signal */
|
||||||
|
if (*div2 < (chans + 2))
|
||||||
|
*div2 = chans + 2;
|
||||||
|
|
||||||
|
*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_pacer(struct comedi_device *dev, int mode,
|
||||||
|
unsigned int divisor1, unsigned int divisor2)
|
||||||
|
{
|
||||||
|
outl(0x74, dev->iobase + PCI9118_CNTCTRL);
|
||||||
|
outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
|
||||||
|
/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
|
||||||
|
udelay(1);
|
||||||
|
|
||||||
|
if ((mode == 1) || (mode == 2) || (mode == 4)) {
|
||||||
|
outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
|
||||||
|
outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
|
||||||
|
outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
|
||||||
|
outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci9118_ai_cancel(struct comedi_device *dev,
|
||||||
|
struct comedi_subdevice *s)
|
||||||
|
{
|
||||||
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
|
||||||
|
if (devpriv->usedma)
|
||||||
|
outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
|
||||||
|
(~EN_A2P_TRANSFERS),
|
||||||
|
devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
|
||||||
|
pci9118_exttrg_del(dev, EXTTRG_AI);
|
||||||
|
start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
|
||||||
|
devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
|
||||||
|
outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
|
||||||
|
/*
|
||||||
|
* positive triggers, no S&H, no burst,
|
||||||
|
* burst stop, no post trigger,
|
||||||
|
* no about trigger, trigger stop
|
||||||
|
*/
|
||||||
|
devpriv->AdControlReg = 0x00;
|
||||||
|
outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
|
||||||
|
/*
|
||||||
|
* bipolar, S.E., use 8254, stop 8354,
|
||||||
|
* internal trigger, soft trigger,
|
||||||
|
* disable INT and DMA
|
||||||
|
*/
|
||||||
|
outl(0, dev->iobase + PCI9118_BURST);
|
||||||
|
outl(1, dev->iobase + PCI9118_SCANMOD);
|
||||||
|
outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
|
||||||
|
outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
|
||||||
|
|
||||||
|
devpriv->ai_do = 0;
|
||||||
|
devpriv->usedma = 0;
|
||||||
|
|
||||||
|
devpriv->ai_act_scan = 0;
|
||||||
|
devpriv->ai_act_dmapos = 0;
|
||||||
|
s->async->cur_chan = 0;
|
||||||
|
s->async->inttrig = NULL;
|
||||||
|
devpriv->ai_buf_ptr = 0;
|
||||||
|
devpriv->ai_neverending = 0;
|
||||||
|
devpriv->dma_actbuf = 0;
|
||||||
|
|
||||||
|
if (!devpriv->IntControlReg)
|
||||||
|
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
|
||||||
|
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
||||||
|
/* allow INT in AMCC */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static char pci9118_decode_error_status(struct comedi_device *dev,
|
static char pci9118_decode_error_status(struct comedi_device *dev,
|
||||||
struct comedi_subdevice *s,
|
struct comedi_subdevice *s,
|
||||||
unsigned char m)
|
unsigned char m)
|
||||||
|
@ -1581,306 +1859,6 @@ static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_channel_list(struct comedi_device *dev,
|
|
||||||
struct comedi_subdevice *s, int n_chan,
|
|
||||||
unsigned int *chanlist, int frontadd, int backadd)
|
|
||||||
{
|
|
||||||
const struct boardtype *this_board = comedi_board(dev);
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
unsigned int i, differencial = 0, bipolar = 0;
|
|
||||||
|
|
||||||
/* correct channel and range number check itself comedi/range.c */
|
|
||||||
if (n_chan < 1) {
|
|
||||||
comedi_error(dev, "range/channel list is empty!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((frontadd + n_chan + backadd) > s->len_chanlist) {
|
|
||||||
printk
|
|
||||||
("comedi%d: range/channel list is too long for "
|
|
||||||
"actual configuration (%d>%d)!",
|
|
||||||
dev->minor, n_chan, s->len_chanlist - frontadd - backadd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CR_AREF(chanlist[0]) == AREF_DIFF)
|
|
||||||
differencial = 1; /* all input must be diff */
|
|
||||||
if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
|
|
||||||
bipolar = 1; /* all input must be bipolar */
|
|
||||||
if (n_chan > 1)
|
|
||||||
for (i = 1; i < n_chan; i++) { /* check S.E/diff */
|
|
||||||
if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
|
|
||||||
(differencial)) {
|
|
||||||
comedi_error(dev,
|
|
||||||
"Differencial and single ended "
|
|
||||||
"inputs can't be mixtured!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
|
|
||||||
(bipolar)) {
|
|
||||||
comedi_error(dev,
|
|
||||||
"Bipolar and unipolar ranges "
|
|
||||||
"can't be mixtured!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (!devpriv->usemux && differencial &&
|
|
||||||
(CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
|
|
||||||
comedi_error(dev,
|
|
||||||
"If AREF_DIFF is used then is "
|
|
||||||
"available only first 8 channels!");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int setup_channel_list(struct comedi_device *dev,
|
|
||||||
struct comedi_subdevice *s, int n_chan,
|
|
||||||
unsigned int *chanlist, int rot, int frontadd,
|
|
||||||
int backadd, int usedma, char useeos)
|
|
||||||
{
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
unsigned int i, differencial = 0, bipolar = 0;
|
|
||||||
unsigned int scanquad, gain, ssh = 0x00;
|
|
||||||
|
|
||||||
if (usedma == 1) {
|
|
||||||
rot = 8;
|
|
||||||
usedma = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CR_AREF(chanlist[0]) == AREF_DIFF)
|
|
||||||
differencial = 1; /* all input must be diff */
|
|
||||||
if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
|
|
||||||
bipolar = 1; /* all input must be bipolar */
|
|
||||||
|
|
||||||
/* All is ok, so we can setup channel/range list */
|
|
||||||
|
|
||||||
if (!bipolar) {
|
|
||||||
devpriv->AdControlReg |= AdControl_UniP;
|
|
||||||
/* set unibipolar */
|
|
||||||
} else {
|
|
||||||
devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
|
|
||||||
/* enable bipolar */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (differencial) {
|
|
||||||
devpriv->AdControlReg |= AdControl_Diff;
|
|
||||||
/* enable diff inputs */
|
|
||||||
} else {
|
|
||||||
devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
|
|
||||||
/* set single ended inputs */
|
|
||||||
}
|
|
||||||
|
|
||||||
outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
|
|
||||||
/* setup mode */
|
|
||||||
|
|
||||||
outl(2, dev->iobase + PCI9118_SCANMOD);
|
|
||||||
/* gods know why this sequence! */
|
|
||||||
outl(0, dev->iobase + PCI9118_SCANMOD);
|
|
||||||
outl(1, dev->iobase + PCI9118_SCANMOD);
|
|
||||||
|
|
||||||
#ifdef PCI9118_PARANOIDCHECK
|
|
||||||
devpriv->chanlistlen = n_chan;
|
|
||||||
for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
|
|
||||||
devpriv->chanlist[i] = 0x55aa;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (frontadd) { /* insert channels for S&H */
|
|
||||||
ssh = devpriv->softsshsample;
|
|
||||||
for (i = 0; i < frontadd; i++) {
|
|
||||||
/* store range list to card */
|
|
||||||
scanquad = CR_CHAN(chanlist[0]);
|
|
||||||
/* get channel number; */
|
|
||||||
gain = CR_RANGE(chanlist[0]);
|
|
||||||
/* get gain number */
|
|
||||||
scanquad |= ((gain & 0x03) << 8);
|
|
||||||
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
|
||||||
ssh = devpriv->softsshhold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < n_chan; i++) { /* store range list to card */
|
|
||||||
scanquad = CR_CHAN(chanlist[i]); /* get channel number */
|
|
||||||
#ifdef PCI9118_PARANOIDCHECK
|
|
||||||
devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
|
|
||||||
#endif
|
|
||||||
gain = CR_RANGE(chanlist[i]); /* get gain number */
|
|
||||||
scanquad |= ((gain & 0x03) << 8);
|
|
||||||
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (backadd) { /* insert channels for fit onto 32bit DMA */
|
|
||||||
for (i = 0; i < backadd; i++) { /* store range list to card */
|
|
||||||
scanquad = CR_CHAN(chanlist[0]);
|
|
||||||
/* get channel number */
|
|
||||||
gain = CR_RANGE(chanlist[0]); /* get gain number */
|
|
||||||
scanquad |= ((gain & 0x03) << 8);
|
|
||||||
outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef PCI9118_PARANOIDCHECK
|
|
||||||
devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
|
|
||||||
/* for 32bit operations */
|
|
||||||
if (useeos) {
|
|
||||||
for (i = 1; i < n_chan; i++) { /* store range list to card */
|
|
||||||
devpriv->chanlist[(n_chan + i) ^ usedma] =
|
|
||||||
(CR_CHAN(chanlist[i]) & 0xf) << rot;
|
|
||||||
}
|
|
||||||
devpriv->chanlist[(2 * n_chan) ^ usedma] =
|
|
||||||
devpriv->chanlist[0 ^ usedma];
|
|
||||||
/* for 32bit operations */
|
|
||||||
useeos = 2;
|
|
||||||
} else {
|
|
||||||
useeos = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
|
|
||||||
/* udelay(100); important delay, or first sample will be crippled */
|
|
||||||
|
|
||||||
return 1; /* we can serve this with scan logic */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
|
|
||||||
struct comedi_subdevice *s,
|
|
||||||
unsigned int *tim1, unsigned int *tim2,
|
|
||||||
unsigned int flags, int chans,
|
|
||||||
unsigned int *div1, unsigned int *div2,
|
|
||||||
char usessh, unsigned int chnsshfront)
|
|
||||||
{
|
|
||||||
const struct boardtype *this_board = comedi_board(dev);
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case 1:
|
|
||||||
case 4:
|
|
||||||
if (*tim2 < this_board->ai_ns_min)
|
|
||||||
*tim2 = this_board->ai_ns_min;
|
|
||||||
i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
|
|
||||||
tim2, flags & TRIG_ROUND_NEAREST);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (*tim2 < this_board->ai_ns_min)
|
|
||||||
*tim2 = this_board->ai_ns_min;
|
|
||||||
*div1 = *tim2 / devpriv->i8254_osc_base;
|
|
||||||
/* convert timer (burst) */
|
|
||||||
if (*div1 < this_board->ai_pacer_min)
|
|
||||||
*div1 = this_board->ai_pacer_min;
|
|
||||||
*div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */
|
|
||||||
*div2 = *div2 / *div1; /* major timer is c1*c2 */
|
|
||||||
if (*div2 < chans)
|
|
||||||
*div2 = chans;
|
|
||||||
|
|
||||||
*tim2 = *div1 * devpriv->i8254_osc_base;
|
|
||||||
/* real convert timer */
|
|
||||||
|
|
||||||
if (usessh & (chnsshfront == 0)) /* use BSSH signal */
|
|
||||||
if (*div2 < (chans + 2))
|
|
||||||
*div2 = chans + 2;
|
|
||||||
|
|
||||||
*tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void start_pacer(struct comedi_device *dev, int mode,
|
|
||||||
unsigned int divisor1, unsigned int divisor2)
|
|
||||||
{
|
|
||||||
outl(0x74, dev->iobase + PCI9118_CNTCTRL);
|
|
||||||
outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
|
|
||||||
/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
|
|
||||||
udelay(1);
|
|
||||||
|
|
||||||
if ((mode == 1) || (mode == 2) || (mode == 4)) {
|
|
||||||
outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
|
|
||||||
outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
|
|
||||||
outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
|
|
||||||
outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
|
|
||||||
{
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
|
|
||||||
if (source > 3)
|
|
||||||
return -1; /* incorrect source */
|
|
||||||
devpriv->exttrg_users |= (1 << source);
|
|
||||||
devpriv->IntControlReg |= Int_DTrg;
|
|
||||||
outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
|
|
||||||
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
|
|
||||||
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
|
||||||
/* allow INT in AMCC */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
|
|
||||||
{
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
|
|
||||||
if (source > 3)
|
|
||||||
return -1; /* incorrect source */
|
|
||||||
devpriv->exttrg_users &= ~(1 << source);
|
|
||||||
if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */
|
|
||||||
devpriv->IntControlReg &= ~Int_DTrg;
|
|
||||||
if (!devpriv->IntControlReg) /* all IRQ disabled */
|
|
||||||
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
|
|
||||||
(~0x00001f00),
|
|
||||||
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
|
||||||
/* disable int in AMCC */
|
|
||||||
outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pci9118_ai_cancel(struct comedi_device *dev,
|
|
||||||
struct comedi_subdevice *s)
|
|
||||||
{
|
|
||||||
struct pci9118_private *devpriv = dev->private;
|
|
||||||
|
|
||||||
if (devpriv->usedma)
|
|
||||||
outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
|
|
||||||
(~EN_A2P_TRANSFERS),
|
|
||||||
devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */
|
|
||||||
pci9118_exttrg_del(dev, EXTTRG_AI);
|
|
||||||
start_pacer(dev, 0, 0, 0); /* stop 8254 counters */
|
|
||||||
devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
|
|
||||||
outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
|
|
||||||
/*
|
|
||||||
* positive triggers, no S&H, no burst,
|
|
||||||
* burst stop, no post trigger,
|
|
||||||
* no about trigger, trigger stop
|
|
||||||
*/
|
|
||||||
devpriv->AdControlReg = 0x00;
|
|
||||||
outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
|
|
||||||
/*
|
|
||||||
* bipolar, S.E., use 8254, stop 8354,
|
|
||||||
* internal trigger, soft trigger,
|
|
||||||
* disable INT and DMA
|
|
||||||
*/
|
|
||||||
outl(0, dev->iobase + PCI9118_BURST);
|
|
||||||
outl(1, dev->iobase + PCI9118_SCANMOD);
|
|
||||||
outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
|
|
||||||
outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
|
|
||||||
|
|
||||||
devpriv->ai_do = 0;
|
|
||||||
devpriv->usedma = 0;
|
|
||||||
|
|
||||||
devpriv->ai_act_scan = 0;
|
|
||||||
devpriv->ai_act_dmapos = 0;
|
|
||||||
s->async->cur_chan = 0;
|
|
||||||
s->async->inttrig = NULL;
|
|
||||||
devpriv->ai_buf_ptr = 0;
|
|
||||||
devpriv->ai_neverending = 0;
|
|
||||||
devpriv->dma_actbuf = 0;
|
|
||||||
|
|
||||||
if (!devpriv->IntControlReg)
|
|
||||||
outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
|
|
||||||
devpriv->iobase_a + AMCC_OP_REG_INTCSR);
|
|
||||||
/* allow INT in AMCC */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pci9118_reset(struct comedi_device *dev)
|
static int pci9118_reset(struct comedi_device *dev)
|
||||||
{
|
{
|
||||||
struct pci9118_private *devpriv = dev->private;
|
struct pci9118_private *devpriv = dev->private;
|
||||||
|
|
Loading…
Reference in New Issue