Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | /* Digital Input IRQ Function Selection */
#define APCI1564_DI_INT_OR (0 << 1)
#define APCI1564_DI_INT_AND (1 << 1)
/* Digital Input Interrupt Enable Disable. */
#define APCI1564_DI_INT_ENABLE 0x4
#define APCI1564_DI_INT_DISABLE 0xfffffffb
/* Digital Output Interrupt Enable Disable. */
#define APCI1564_DO_VCC_INT_ENABLE 0x1
#define APCI1564_DO_VCC_INT_DISABLE 0xfffffffe
#define APCI1564_DO_CC_INT_ENABLE 0x2
#define APCI1564_DO_CC_INT_DISABLE 0xfffffffd
/* TIMER COUNTER WATCHDOG DEFINES */
#define ADDIDATA_TIMER 0
#define ADDIDATA_COUNTER 1
#define ADDIDATA_WATCHDOG 2
static int apci1564_timer_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
unsigned int ctrl;
devpriv->tsk_current = current;
/* First Stop The Timer */
ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
ctrl &= 0xfffff9fe;
/* Stop The Timer */
outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
if (data[1] == 1) {
/* Enable timer int & disable all the other int sources */
outl(0x02, devpriv->timer + ADDI_TCW_CTRL_REG);
outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
outl(0x0, dev->iobase + APCI1564_DO_IRQ_REG);
outl(0x0, dev->iobase + APCI1564_WDOG_IRQ_REG);
if (devpriv->counters) {
unsigned long iobase;
iobase = devpriv->counters + ADDI_TCW_IRQ_REG;
outl(0x0, iobase + APCI1564_COUNTER(0));
outl(0x0, iobase + APCI1564_COUNTER(1));
outl(0x0, iobase + APCI1564_COUNTER(2));
}
} else {
/* disable Timer interrupt */
outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
}
/* Loading Timebase */
outl(data[2], devpriv->timer + ADDI_TCW_TIMEBASE_REG);
/* Loading the Reload value */
outl(data[3], devpriv->timer + ADDI_TCW_RELOAD_REG);
ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
ctrl &= 0xfff719e2;
ctrl |= (2 << 13) | 0x10;
/* mode 2 */
outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
return insn->n;
}
static int apci1564_timer_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
unsigned int ctrl;
ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
switch (data[1]) {
case 0: /* Stop The Timer */
ctrl &= 0xfffff9fe;
break;
case 1: /* Enable the Timer */
ctrl &= 0xfffff9ff;
ctrl |= 0x1;
break;
}
outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
return insn->n;
}
static int apci1564_timer_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
/* Stores the status of the Timer */
data[0] = inl(devpriv->timer + ADDI_TCW_STATUS_REG) & 0x1;
/* Stores the Actual value of the Timer */
data[1] = inl(devpriv->timer + ADDI_TCW_VAL_REG);
return insn->n;
}
static int apci1564_counter_insn_config(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
unsigned int ctrl;
devpriv->tsk_current = current;
/* First Stop The Counter */
ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
ctrl &= 0xfffff9fe;
/* Stop The Timer */
outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
/* Set the reload value */
outl(data[3], iobase + ADDI_TCW_RELOAD_REG);
/* Set the mode : */
/* - Disable the hardware */
/* - Disable the counter mode */
/* - Disable the warning */
/* - Disable the reset */
/* - Disable the timer mode */
/* - Enable the counter mode */
ctrl &= 0xfffc19e2;
ctrl |= 0x80000 | (data[4] << 16);
outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
/* Enable or Disable Interrupt */
ctrl &= 0xfffff9fd;
ctrl |= (data[1] << 1);
outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
/* Set the Up/Down selection */
ctrl &= 0xfffbf9ff;
ctrl |= (data[6] << 18);
outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
return insn->n;
}
static int apci1564_counter_insn_write(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
unsigned int ctrl;
ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
switch (data[1]) {
case 0: /* Stops the Counter subdevice */
ctrl = 0;
break;
case 1: /* Start the Counter subdevice */
ctrl &= 0xfffff9ff;
ctrl |= 0x1;
break;
case 2: /* Clears the Counter subdevice */
ctrl &= 0xfffff9ff;
ctrl |= 0x400;
break;
}
outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
return insn->n;
}
static int apci1564_counter_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
struct apci1564_private *devpriv = dev->private;
unsigned int chan = CR_CHAN(insn->chanspec);
unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
unsigned int status;
/* Read the Counter Actual Value. */
data[0] = inl(iobase + ADDI_TCW_VAL_REG);
status = inl(iobase + ADDI_TCW_STATUS_REG);
data[1] = (status >> 1) & 1; /* software trigger status */
data[2] = (status >> 2) & 1; /* hardware trigger status */
data[3] = (status >> 3) & 1; /* software clear status */
data[4] = (status >> 0) & 1; /* overflow status */
return insn->n;
}
|