1 static int apci1564_timer_insn_config(struct comedi_device *dev,
2 struct comedi_subdevice *s,
3 struct comedi_insn *insn,
6 struct apci1564_private *devpriv = dev->private;
9 devpriv->tsk_current = current;
12 ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
13 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
15 outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
18 /* Enable timer int & disable all the other int sources */
19 outl(ADDI_TCW_CTRL_IRQ_ENA,
20 devpriv->timer + ADDI_TCW_CTRL_REG);
21 outl(0x0, dev->iobase + APCI1564_DI_IRQ_REG);
22 outl(0x0, dev->iobase + APCI1564_DO_IRQ_REG);
23 outl(0x0, dev->iobase + APCI1564_WDOG_IRQ_REG);
24 if (devpriv->counters) {
27 iobase = devpriv->counters + ADDI_TCW_IRQ_REG;
28 outl(0x0, iobase + APCI1564_COUNTER(0));
29 outl(0x0, iobase + APCI1564_COUNTER(1));
30 outl(0x0, iobase + APCI1564_COUNTER(2));
33 /* disable Timer interrupt */
34 outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG);
37 /* Loading Timebase */
38 outl(data[2], devpriv->timer + ADDI_TCW_TIMEBASE_REG);
40 /* Loading the Reload value */
41 outl(data[3], devpriv->timer + ADDI_TCW_RELOAD_REG);
43 ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
44 ctrl &= ~(ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE_MASK |
45 ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
46 ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA |
47 ADDI_TCW_CTRL_WARN_ENA | ADDI_TCW_CTRL_ENA);
48 ctrl |= ADDI_TCW_CTRL_MODE(2) | ADDI_TCW_CTRL_TIMER_ENA;
49 outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
54 static int apci1564_timer_insn_write(struct comedi_device *dev,
55 struct comedi_subdevice *s,
56 struct comedi_insn *insn,
59 struct apci1564_private *devpriv = dev->private;
62 ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG);
63 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
65 case 0: /* Stop The Timer */
66 ctrl &= ~ADDI_TCW_CTRL_ENA;
68 case 1: /* Enable the Timer */
69 ctrl |= ADDI_TCW_CTRL_ENA;
72 outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG);
77 static int apci1564_timer_insn_read(struct comedi_device *dev,
78 struct comedi_subdevice *s,
79 struct comedi_insn *insn,
82 struct apci1564_private *devpriv = dev->private;
84 /* Stores the status of the Timer */
85 data[0] = inl(devpriv->timer + ADDI_TCW_STATUS_REG) &
86 ADDI_TCW_STATUS_OVERFLOW;
88 /* Stores the Actual value of the Timer */
89 data[1] = inl(devpriv->timer + ADDI_TCW_VAL_REG);
94 static int apci1564_counter_insn_config(struct comedi_device *dev,
95 struct comedi_subdevice *s,
96 struct comedi_insn *insn,
99 struct apci1564_private *devpriv = dev->private;
100 unsigned int chan = CR_CHAN(insn->chanspec);
101 unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
104 devpriv->tsk_current = current;
107 ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
108 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
110 outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
112 /* Set the reload value */
113 outl(data[3], iobase + ADDI_TCW_RELOAD_REG);
116 ctrl &= ~(ADDI_TCW_CTRL_EXT_CLK_MASK | ADDI_TCW_CTRL_MODE_MASK |
117 ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
118 ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA |
119 ADDI_TCW_CTRL_WARN_ENA | ADDI_TCW_CTRL_ENA);
120 ctrl |= ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_EXT_CLK(data[4]);
121 outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
123 /* Enable or Disable Interrupt */
124 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG |
125 ADDI_TCW_CTRL_IRQ_ENA);
127 ctrl |= ADDI_TCW_CTRL_IRQ_ENA;
128 outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
130 /* Set the Up/Down selection */
131 ctrl &= ~(ADDI_TCW_CTRL_CNT_UP | ADDI_TCW_CTRL_GATE |
134 ctrl |= ADDI_TCW_CTRL_CNT_UP;
135 outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
140 static int apci1564_counter_insn_write(struct comedi_device *dev,
141 struct comedi_subdevice *s,
142 struct comedi_insn *insn,
145 struct apci1564_private *devpriv = dev->private;
146 unsigned int chan = CR_CHAN(insn->chanspec);
147 unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
150 ctrl = inl(iobase + ADDI_TCW_CTRL_REG);
152 case 0: /* Stops the Counter subdevice */
155 case 1: /* Start the Counter subdevice */
156 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
157 ctrl |= ADDI_TCW_CTRL_ENA;
159 case 2: /* Clears the Counter subdevice */
160 ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG);
161 ctrl |= ADDI_TCW_CTRL_GATE;
164 outl(ctrl, iobase + ADDI_TCW_CTRL_REG);
169 static int apci1564_counter_insn_read(struct comedi_device *dev,
170 struct comedi_subdevice *s,
171 struct comedi_insn *insn,
174 struct apci1564_private *devpriv = dev->private;
175 unsigned int chan = CR_CHAN(insn->chanspec);
176 unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan);
179 /* Read the Counter Actual Value. */
180 data[0] = inl(iobase + ADDI_TCW_VAL_REG);
182 status = inl(iobase + ADDI_TCW_STATUS_REG);
183 data[1] = (status >> 1) & 1; /* software trigger status */
184 data[2] = (status >> 2) & 1; /* hardware trigger status */
185 data[3] = (status >> 3) & 1; /* software clear status */
186 data[4] = (status >> 0) & 1; /* overflow status */