Commit | Line | Data |
---|---|---|
0658d6de HS |
1 | static int apci1564_timer_insn_config(struct comedi_device *dev, |
2 | struct comedi_subdevice *s, | |
3 | struct comedi_insn *insn, | |
4 | unsigned int *data) | |
c995fe94 | 5 | { |
4c95a2b6 | 6 | struct apci1564_private *devpriv = dev->private; |
0658d6de | 7 | unsigned int ctrl; |
843690b7 | 8 | |
4c95a2b6 | 9 | devpriv->tsk_current = current; |
0658d6de | 10 | |
d9fca73c | 11 | /* Stop the timer */ |
e23337dc | 12 | ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); |
d9fca73c HS |
13 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG | |
14 | ADDI_TCW_CTRL_ENA); | |
e23337dc | 15 | outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); |
0658d6de HS |
16 | |
17 | if (data[1] == 1) { | |
18 | /* Enable timer int & disable all the other int sources */ | |
d9fca73c HS |
19 | outl(ADDI_TCW_CTRL_IRQ_ENA, |
20 | devpriv->timer + ADDI_TCW_CTRL_REG); | |
0658d6de HS |
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) { | |
7d6156ed HS |
25 | unsigned long iobase; |
26 | ||
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)); | |
11975225 | 31 | } |
988bcffd | 32 | } else { |
0658d6de | 33 | /* disable Timer interrupt */ |
e23337dc | 34 | outl(0x0, devpriv->timer + ADDI_TCW_CTRL_REG); |
11975225 | 35 | } |
0658d6de HS |
36 | |
37 | /* Loading Timebase */ | |
e23337dc | 38 | outl(data[2], devpriv->timer + ADDI_TCW_TIMEBASE_REG); |
0658d6de HS |
39 | |
40 | /* Loading the Reload value */ | |
e23337dc | 41 | outl(data[3], devpriv->timer + ADDI_TCW_RELOAD_REG); |
0658d6de | 42 | |
e23337dc | 43 | ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); |
d9fca73c HS |
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; | |
e23337dc | 49 | outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); |
0658d6de | 50 | |
c995fe94 ADG |
51 | return insn->n; |
52 | } | |
53 | ||
0658d6de HS |
54 | static int apci1564_timer_insn_write(struct comedi_device *dev, |
55 | struct comedi_subdevice *s, | |
56 | struct comedi_insn *insn, | |
57 | unsigned int *data) | |
c995fe94 | 58 | { |
4c95a2b6 | 59 | struct apci1564_private *devpriv = dev->private; |
0658d6de HS |
60 | unsigned int ctrl; |
61 | ||
e23337dc | 62 | ctrl = inl(devpriv->timer + ADDI_TCW_CTRL_REG); |
9a2d58c7 | 63 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG); |
0658d6de HS |
64 | switch (data[1]) { |
65 | case 0: /* Stop The Timer */ | |
9a2d58c7 | 66 | ctrl &= ~ADDI_TCW_CTRL_ENA; |
0658d6de HS |
67 | break; |
68 | case 1: /* Enable the Timer */ | |
d9fca73c | 69 | ctrl |= ADDI_TCW_CTRL_ENA; |
0658d6de | 70 | break; |
11899188 | 71 | } |
e23337dc | 72 | outl(ctrl, devpriv->timer + ADDI_TCW_CTRL_REG); |
0658d6de | 73 | |
c995fe94 ADG |
74 | return insn->n; |
75 | } | |
76 | ||
0658d6de HS |
77 | static int apci1564_timer_insn_read(struct comedi_device *dev, |
78 | struct comedi_subdevice *s, | |
79 | struct comedi_insn *insn, | |
80 | unsigned int *data) | |
c995fe94 | 81 | { |
4c95a2b6 | 82 | struct apci1564_private *devpriv = dev->private; |
c995fe94 | 83 | |
0658d6de | 84 | /* Stores the status of the Timer */ |
18543b13 HS |
85 | data[0] = inl(devpriv->timer + ADDI_TCW_STATUS_REG) & |
86 | ADDI_TCW_STATUS_OVERFLOW; | |
c995fe94 | 87 | |
0658d6de | 88 | /* Stores the Actual value of the Timer */ |
e23337dc | 89 | data[1] = inl(devpriv->timer + ADDI_TCW_VAL_REG); |
c995fe94 | 90 | |
0658d6de HS |
91 | return insn->n; |
92 | } | |
c995fe94 | 93 | |
0658d6de HS |
94 | static int apci1564_counter_insn_config(struct comedi_device *dev, |
95 | struct comedi_subdevice *s, | |
96 | struct comedi_insn *insn, | |
97 | unsigned int *data) | |
98 | { | |
99 | struct apci1564_private *devpriv = dev->private; | |
100 | unsigned int chan = CR_CHAN(insn->chanspec); | |
7d6156ed | 101 | unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); |
0658d6de | 102 | unsigned int ctrl; |
c995fe94 | 103 | |
0658d6de | 104 | devpriv->tsk_current = current; |
c995fe94 | 105 | |
0658d6de | 106 | /* Stop The Timer */ |
d9fca73c HS |
107 | ctrl = inl(iobase + ADDI_TCW_CTRL_REG); |
108 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG | | |
109 | ADDI_TCW_CTRL_ENA); | |
7d6156ed | 110 | outl(ctrl, iobase + ADDI_TCW_CTRL_REG); |
0658d6de HS |
111 | |
112 | /* Set the reload value */ | |
7d6156ed | 113 | outl(data[3], iobase + ADDI_TCW_RELOAD_REG); |
0658d6de | 114 | |
d9fca73c HS |
115 | /* Set the mode */ |
116 | ctrl &= ~(ADDI_TCW_CTRL_EXT_CLK_MASK | ADDI_TCW_CTRL_MODE_MASK | | |
d9fca73c | 117 | ADDI_TCW_CTRL_TIMER_ENA | ADDI_TCW_CTRL_RESET_ENA | |
835f8fe9 | 118 | ADDI_TCW_CTRL_WARN_ENA); |
1f5d767f | 119 | ctrl |= ADDI_TCW_CTRL_CNTR_ENA | ADDI_TCW_CTRL_MODE(data[4]); |
7d6156ed | 120 | outl(ctrl, iobase + ADDI_TCW_CTRL_REG); |
0658d6de HS |
121 | |
122 | /* Enable or Disable Interrupt */ | |
d9fca73c HS |
123 | if (data[1]) |
124 | ctrl |= ADDI_TCW_CTRL_IRQ_ENA; | |
835f8fe9 HS |
125 | else |
126 | ctrl &= ~ADDI_TCW_CTRL_IRQ_ENA; | |
7d6156ed | 127 | outl(ctrl, iobase + ADDI_TCW_CTRL_REG); |
0658d6de HS |
128 | |
129 | /* Set the Up/Down selection */ | |
d9fca73c HS |
130 | if (data[6]) |
131 | ctrl |= ADDI_TCW_CTRL_CNT_UP; | |
835f8fe9 HS |
132 | else |
133 | ctrl &= ~ADDI_TCW_CTRL_CNT_UP; | |
7d6156ed | 134 | outl(ctrl, iobase + ADDI_TCW_CTRL_REG); |
0658d6de HS |
135 | |
136 | return insn->n; | |
137 | } | |
138 | ||
139 | static int apci1564_counter_insn_write(struct comedi_device *dev, | |
140 | struct comedi_subdevice *s, | |
141 | struct comedi_insn *insn, | |
142 | unsigned int *data) | |
143 | { | |
144 | struct apci1564_private *devpriv = dev->private; | |
145 | unsigned int chan = CR_CHAN(insn->chanspec); | |
7d6156ed | 146 | unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); |
0658d6de HS |
147 | unsigned int ctrl; |
148 | ||
7d6156ed | 149 | ctrl = inl(iobase + ADDI_TCW_CTRL_REG); |
c6288a3b | 150 | ctrl &= ~(ADDI_TCW_CTRL_GATE | ADDI_TCW_CTRL_TRIG); |
0658d6de HS |
151 | switch (data[1]) { |
152 | case 0: /* Stops the Counter subdevice */ | |
153 | ctrl = 0; | |
154 | break; | |
155 | case 1: /* Start the Counter subdevice */ | |
d9fca73c | 156 | ctrl |= ADDI_TCW_CTRL_ENA; |
0658d6de HS |
157 | break; |
158 | case 2: /* Clears the Counter subdevice */ | |
d9fca73c | 159 | ctrl |= ADDI_TCW_CTRL_GATE; |
0658d6de | 160 | break; |
11975225 | 161 | } |
7d6156ed | 162 | outl(ctrl, iobase + ADDI_TCW_CTRL_REG); |
0658d6de HS |
163 | |
164 | return insn->n; | |
165 | } | |
166 | ||
167 | static int apci1564_counter_insn_read(struct comedi_device *dev, | |
168 | struct comedi_subdevice *s, | |
169 | struct comedi_insn *insn, | |
170 | unsigned int *data) | |
171 | { | |
172 | struct apci1564_private *devpriv = dev->private; | |
173 | unsigned int chan = CR_CHAN(insn->chanspec); | |
7d6156ed | 174 | unsigned long iobase = devpriv->counters + APCI1564_COUNTER(chan); |
0658d6de HS |
175 | unsigned int status; |
176 | ||
177 | /* Read the Counter Actual Value. */ | |
7d6156ed | 178 | data[0] = inl(iobase + ADDI_TCW_VAL_REG); |
0658d6de | 179 | |
7d6156ed | 180 | status = inl(iobase + ADDI_TCW_STATUS_REG); |
0658d6de HS |
181 | data[1] = (status >> 1) & 1; /* software trigger status */ |
182 | data[2] = (status >> 2) & 1; /* hardware trigger status */ | |
183 | data[3] = (status >> 3) & 1; /* software clear status */ | |
184 | data[4] = (status >> 0) & 1; /* overflow status */ | |
185 | ||
c995fe94 ADG |
186 | return insn->n; |
187 | } |