Commit | Line | Data |
---|---|---|
cb7859a9 FMH |
1 | /* |
2 | drivers/ni_tio_internal.h | |
3 | Header file for NI general purpose counter support code (ni_tio.c and | |
4 | ni_tiocmd.c) | |
5 | ||
6 | COMEDI - Linux Control and Measurement Device Interface | |
7 | ||
8 | This program is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2 of the License, or | |
11 | (at your option) any later version. | |
12 | ||
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
cb7859a9 FMH |
17 | */ |
18 | ||
19 | #ifndef _COMEDI_NI_TIO_INTERNAL_H | |
20 | #define _COMEDI_NI_TIO_INTERNAL_H | |
21 | ||
22 | #include "ni_tio.h" | |
23 | ||
e062f51b | 24 | #define NITIO_AUTO_INC_REG(x) (NITIO_G0_AUTO_INC + (x)) |
12b19cf5 | 25 | #define GI_AUTO_INC_MASK 0xff |
e25ef744 | 26 | #define NITIO_CMD_REG(x) (NITIO_G0_CMD + (x)) |
b9a09764 HS |
27 | #define GI_ARM (1 << 0) |
28 | #define GI_SAVE_TRACE (1 << 1) | |
29 | #define GI_LOAD (1 << 2) | |
30 | #define GI_DISARM (1 << 4) | |
31 | #define GI_CNT_DIR(x) (((x) & 0x3) << 5) | |
32 | #define GI_CNT_DIR_MASK (3 << 5) | |
33 | #define GI_WRITE_SWITCH (1 << 7) | |
34 | #define GI_SYNC_GATE (1 << 8) | |
35 | #define GI_LITTLE_BIG_ENDIAN (1 << 9) | |
36 | #define GI_BANK_SWITCH_START (1 << 10) | |
37 | #define GI_BANK_SWITCH_MODE (1 << 11) | |
38 | #define GI_BANK_SWITCH_ENABLE (1 << 12) | |
39 | #define GI_ARM_COPY (1 << 13) | |
40 | #define GI_SAVE_TRACE_COPY (1 << 14) | |
41 | #define GI_DISARM_COPY (1 << 15) | |
e6b1624a | 42 | #define NITIO_HW_SAVE_REG(x) (NITIO_G0_HW_SAVE + (x)) |
67c68de0 | 43 | #define NITIO_SW_SAVE_REG(x) (NITIO_G0_SW_SAVE + (x)) |
0101791e | 44 | #define NITIO_MODE_REG(x) (NITIO_G0_MODE + (x)) |
720712f4 | 45 | #define NITIO_LOADA_REG(x) (NITIO_G0_LOADA + (x)) |
cc7a164b | 46 | #define NITIO_LOADB_REG(x) (NITIO_G0_LOADB + (x)) |
3da68f50 | 47 | #define NITIO_INPUT_SEL_REG(x) (NITIO_G0_INPUT_SEL + (x)) |
c2c6c288 HS |
48 | #define GI_READ_ACKS_IRQ (1 << 0) |
49 | #define GI_WRITE_ACKS_IRQ (1 << 1) | |
50 | #define GI_BITS_TO_SRC(x) (((x) >> 2) & 0x1f) | |
51 | #define GI_SRC_SEL(x) (((x) & 0x1f) << 2) | |
52 | #define GI_SRC_SEL_MASK (0x1f << 2) | |
53 | #define GI_BITS_TO_GATE(x) (((x) >> 7) & 0x1f) | |
54 | #define GI_GATE_SEL(x) (((x) & 0x1f) << 7) | |
55 | #define GI_GATE_SEL_MASK (0x1f << 7) | |
56 | #define GI_GATE_SEL_LOAD_SRC (1 << 12) | |
57 | #define GI_OR_GATE (1 << 13) | |
58 | #define GI_OUTPUT_POL_INVERT (1 << 14) | |
59 | #define GI_SRC_POL_INVERT (1 << 15) | |
0412ea46 | 60 | #define NITIO_CNT_MODE_REG(x) (NITIO_G0_CNT_MODE + (x)) |
ed404871 HS |
61 | #define GI_CNT_MODE(x) (((x) & 0x7) << 0) |
62 | #define GI_CNT_MODE_NORMAL GI_CNT_MODE(0) | |
63 | #define GI_CNT_MODE_QUADX1 GI_CNT_MODE(1) | |
64 | #define GI_CNT_MODE_QUADX2 GI_CNT_MODE(2) | |
65 | #define GI_CNT_MODE_QUADX4 GI_CNT_MODE(3) | |
66 | #define GI_CNT_MODE_TWO_PULSE GI_CNT_MODE(4) | |
67 | #define GI_CNT_MODE_SYNC_SRC GI_CNT_MODE(6) | |
68 | #define GI_CNT_MODE_MASK (7 << 0) | |
69 | #define GI_INDEX_MODE (1 << 4) | |
70 | #define GI_INDEX_PHASE(x) (((x) & 0x3) << 5) | |
71 | #define GI_INDEX_PHASE_MASK (3 << 5) | |
72 | #define GI_HW_ARM_ENA (1 << 7) | |
73 | #define GI_HW_ARM_SEL(x) ((x) << 8) | |
74 | #define GI_660X_HW_ARM_SEL_MASK (0x7 << 8) | |
75 | #define GI_M_HW_ARM_SEL_MASK (0x1f << 8) | |
76 | #define GI_660X_PRESCALE_X8 (1 << 12) | |
77 | #define GI_M_PRESCALE_X8 (1 << 13) | |
78 | #define GI_660X_ALT_SYNC (1 << 13) | |
79 | #define GI_M_ALT_SYNC (1 << 14) | |
80 | #define GI_660X_PRESCALE_X2 (1 << 14) | |
81 | #define GI_M_PRESCALE_X2 (1 << 15) | |
7a0894e0 | 82 | #define NITIO_GATE2_REG(x) (NITIO_G0_GATE2 + (x)) |
c9d766d0 | 83 | #define NITIO_SHARED_STATUS_REG(x) (NITIO_G01_STATUS + ((x) / 2)) |
fc31c52f | 84 | #define NITIO_RESET_REG(x) (NITIO_G01_RESET + ((x) / 2)) |
450a7c43 | 85 | #define NITIO_STATUS1_REG(x) (NITIO_G01_STATUS1 + ((x) / 2)) |
5f19efac | 86 | #define NITIO_STATUS2_REG(x) (NITIO_G01_STATUS2 + ((x) / 2)) |
1dd26c21 | 87 | #define NITIO_DMA_CFG_REG(x) (NITIO_G0_DMA_CFG + (x)) |
8cd3936e | 88 | #define NITIO_DMA_STATUS_REG(x) (NITIO_G0_DMA_STATUS + (x)) |
ff157abe | 89 | #define NITIO_ABZ_REG(x) (NITIO_G0_ABZ + (x)) |
e72ccb04 | 90 | #define NITIO_INT_ACK_REG(x) (NITIO_G0_INT_ACK + (x)) |
c9d766d0 | 91 | #define NITIO_STATUS_REG(x) (NITIO_G0_STATUS + (x)) |
94baf025 | 92 | #define NITIO_INT_ENA_REG(x) (NITIO_G0_INT_ENA + (x)) |
cb7859a9 | 93 | |
cb7859a9 FMH |
94 | enum Gi_Mode_Bits { |
95 | Gi_Gating_Mode_Mask = 0x3, | |
96 | Gi_Gating_Disabled_Bits = 0x0, | |
97 | Gi_Level_Gating_Bits = 0x1, | |
98 | Gi_Rising_Edge_Gating_Bits = 0x2, | |
99 | Gi_Falling_Edge_Gating_Bits = 0x3, | |
35c81aaa TK |
100 | Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with |
101 | * rising edge gating mode */ | |
cb7859a9 FMH |
102 | Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18, |
103 | Gi_Edge_Gate_Starts_Stops_Bits = 0x0, | |
104 | Gi_Edge_Gate_Stops_Starts_Bits = 0x8, | |
105 | Gi_Edge_Gate_Starts_Bits = 0x10, | |
106 | Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18, | |
107 | Gi_Stop_Mode_Mask = 0x60, | |
108 | Gi_Stop_on_Gate_Bits = 0x00, | |
109 | Gi_Stop_on_Gate_or_TC_Bits = 0x20, | |
110 | Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40, | |
111 | Gi_Load_Source_Select_Bit = 0x80, | |
112 | Gi_Output_Mode_Mask = 0x300, | |
113 | Gi_Output_TC_Pulse_Bits = 0x100, | |
114 | Gi_Output_TC_Toggle_Bits = 0x200, | |
115 | Gi_Output_TC_or_Gate_Toggle_Bits = 0x300, | |
116 | Gi_Counting_Once_Mask = 0xc00, | |
117 | Gi_No_Hardware_Disarm_Bits = 0x000, | |
118 | Gi_Disarm_at_TC_Bits = 0x400, | |
119 | Gi_Disarm_at_Gate_Bits = 0x800, | |
120 | Gi_Disarm_at_TC_or_Gate_Bits = 0xc00, | |
121 | Gi_Loading_On_TC_Bit = 0x1000, | |
122 | Gi_Gate_Polarity_Bit = 0x2000, | |
123 | Gi_Loading_On_Gate_Bit = 0x4000, | |
124 | Gi_Reload_Source_Switching_Bit = 0x8000 | |
125 | }; | |
126 | ||
127 | #define Gi_Second_Gate_Select_Shift 7 | |
128 | /*FIXME: m-series has a second gate subselect bit */ | |
129 | /*FIXME: m-series second gate sources are undocumented (by NI)*/ | |
130 | enum Gi_Second_Gate_Bits { | |
131 | Gi_Second_Gate_Mode_Bit = 0x1, | |
132 | Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift, | |
133 | Gi_Second_Gate_Polarity_Bit = 0x2000, | |
134 | Gi_Second_Gate_Subselect_Bit = 0x4000, /* m-series only */ | |
135 | Gi_Source_Subselect_Bit = 0x8000 /* m-series only */ | |
136 | }; | |
137 | static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select) | |
138 | { | |
139 | return (second_gate_select << Gi_Second_Gate_Select_Shift) & | |
0a85b6f0 | 140 | Gi_Second_Gate_Select_Mask; |
cb7859a9 FMH |
141 | } |
142 | ||
143 | enum Gxx_Status_Bits { | |
144 | G0_Save_Bit = 0x1, | |
145 | G1_Save_Bit = 0x2, | |
146 | G0_Counting_Bit = 0x4, | |
147 | G1_Counting_Bit = 0x8, | |
148 | G0_Next_Load_Source_Bit = 0x10, | |
149 | G1_Next_Load_Source_Bit = 0x20, | |
150 | G0_Stale_Data_Bit = 0x40, | |
151 | G1_Stale_Data_Bit = 0x80, | |
152 | G0_Armed_Bit = 0x100, | |
153 | G1_Armed_Bit = 0x200, | |
154 | G0_No_Load_Between_Gates_Bit = 0x400, | |
155 | G1_No_Load_Between_Gates_Bit = 0x800, | |
156 | G0_TC_Error_Bit = 0x1000, | |
157 | G1_TC_Error_Bit = 0x2000, | |
158 | G0_Gate_Error_Bit = 0x4000, | |
159 | G1_Gate_Error_Bit = 0x8000 | |
160 | }; | |
161 | static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index) | |
162 | { | |
163 | if (counter_index % 2) | |
164 | return G1_Counting_Bit; | |
165 | return G0_Counting_Bit; | |
166 | } | |
0a85b6f0 | 167 | |
cb7859a9 FMH |
168 | static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index) |
169 | { | |
170 | if (counter_index % 2) | |
171 | return G1_Armed_Bit; | |
172 | return G0_Armed_Bit; | |
173 | } | |
0a85b6f0 | 174 | |
cb7859a9 | 175 | static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned |
0a85b6f0 | 176 | counter_index) |
cb7859a9 FMH |
177 | { |
178 | if (counter_index % 2) | |
179 | return G1_Next_Load_Source_Bit; | |
180 | return G0_Next_Load_Source_Bit; | |
181 | } | |
0a85b6f0 | 182 | |
cb7859a9 FMH |
183 | static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index) |
184 | { | |
185 | if (counter_index % 2) | |
186 | return G1_Stale_Data_Bit; | |
187 | return G0_Stale_Data_Bit; | |
188 | } | |
0a85b6f0 | 189 | |
cb7859a9 FMH |
190 | static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index) |
191 | { | |
192 | if (counter_index % 2) | |
193 | return G1_TC_Error_Bit; | |
194 | return G0_TC_Error_Bit; | |
195 | } | |
0a85b6f0 | 196 | |
cb7859a9 FMH |
197 | static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index) |
198 | { | |
199 | if (counter_index % 2) | |
200 | return G1_Gate_Error_Bit; | |
201 | return G0_Gate_Error_Bit; | |
202 | } | |
203 | ||
204 | /* joint reset register bits */ | |
205 | static inline unsigned Gi_Reset_Bit(unsigned counter_index) | |
206 | { | |
207 | return 0x1 << (2 + (counter_index % 2)); | |
208 | } | |
209 | ||
210 | enum Gxx_Joint_Status2_Bits { | |
211 | G0_Output_Bit = 0x1, | |
212 | G1_Output_Bit = 0x2, | |
213 | G0_HW_Save_Bit = 0x1000, | |
214 | G1_HW_Save_Bit = 0x2000, | |
215 | G0_Permanent_Stale_Bit = 0x4000, | |
216 | G1_Permanent_Stale_Bit = 0x8000 | |
217 | }; | |
218 | static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned | |
0a85b6f0 | 219 | counter_index) |
cb7859a9 FMH |
220 | { |
221 | if (counter_index % 2) | |
222 | return G1_Permanent_Stale_Bit; | |
223 | return G0_Permanent_Stale_Bit; | |
224 | } | |
225 | ||
226 | enum Gi_DMA_Config_Reg_Bits { | |
227 | Gi_DMA_Enable_Bit = 0x1, | |
228 | Gi_DMA_Write_Bit = 0x2, | |
229 | Gi_DMA_Int_Bit = 0x4 | |
230 | }; | |
231 | ||
232 | enum Gi_DMA_Status_Reg_Bits { | |
233 | Gi_DMA_Readbank_Bit = 0x2000, | |
234 | Gi_DRQ_Error_Bit = 0x4000, | |
235 | Gi_DRQ_Status_Bit = 0x8000 | |
236 | }; | |
237 | ||
238 | enum G02_Interrupt_Acknowledge_Bits { | |
239 | G0_Gate_Error_Confirm_Bit = 0x20, | |
240 | G0_TC_Error_Confirm_Bit = 0x40 | |
241 | }; | |
242 | enum G13_Interrupt_Acknowledge_Bits { | |
243 | G1_Gate_Error_Confirm_Bit = 0x2, | |
244 | G1_TC_Error_Confirm_Bit = 0x4 | |
245 | }; | |
246 | static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index) | |
247 | { | |
248 | if (counter_index % 2) | |
249 | return G1_Gate_Error_Confirm_Bit; | |
250 | return G0_Gate_Error_Confirm_Bit; | |
251 | } | |
0a85b6f0 | 252 | |
cb7859a9 FMH |
253 | static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index) |
254 | { | |
255 | if (counter_index % 2) | |
256 | return G1_TC_Error_Confirm_Bit; | |
257 | return G0_TC_Error_Confirm_Bit; | |
258 | } | |
259 | ||
2696fb57 | 260 | /* bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers */ |
cb7859a9 FMH |
261 | enum Gxx_Interrupt_Acknowledge_Bits { |
262 | Gi_TC_Interrupt_Ack_Bit = 0x4000, | |
263 | Gi_Gate_Interrupt_Ack_Bit = 0x8000 | |
264 | }; | |
265 | ||
266 | enum Gi_Status_Bits { | |
267 | Gi_Gate_Interrupt_Bit = 0x4, | |
268 | Gi_TC_Bit = 0x8, | |
269 | Gi_Interrupt_Bit = 0x8000 | |
270 | }; | |
271 | ||
272 | enum G02_Interrupt_Enable_Bits { | |
273 | G0_TC_Interrupt_Enable_Bit = 0x40, | |
274 | G0_Gate_Interrupt_Enable_Bit = 0x100 | |
275 | }; | |
276 | enum G13_Interrupt_Enable_Bits { | |
277 | G1_TC_Interrupt_Enable_Bit = 0x200, | |
278 | G1_Gate_Interrupt_Enable_Bit = 0x400 | |
279 | }; | |
280 | static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index) | |
281 | { | |
282 | unsigned bit; | |
283 | ||
933df659 | 284 | if (counter_index % 2) |
cb7859a9 | 285 | bit = G1_Gate_Interrupt_Enable_Bit; |
933df659 | 286 | else |
cb7859a9 | 287 | bit = G0_Gate_Interrupt_Enable_Bit; |
cb7859a9 FMH |
288 | return bit; |
289 | } | |
290 | ||
291 | static inline void write_register(struct ni_gpct *counter, unsigned bits, | |
0a85b6f0 | 292 | enum ni_gpct_register reg) |
cb7859a9 | 293 | { |
12375292 | 294 | BUG_ON(reg >= NITIO_NUM_REGS); |
cb7859a9 FMH |
295 | counter->counter_dev->write_register(counter, bits, reg); |
296 | } | |
297 | ||
298 | static inline unsigned read_register(struct ni_gpct *counter, | |
0a85b6f0 | 299 | enum ni_gpct_register reg) |
cb7859a9 | 300 | { |
12375292 | 301 | BUG_ON(reg >= NITIO_NUM_REGS); |
cb7859a9 FMH |
302 | return counter->counter_dev->read_register(counter, reg); |
303 | } | |
304 | ||
0a85b6f0 MT |
305 | static inline int ni_tio_counting_mode_registers_present(const struct |
306 | ni_gpct_device | |
307 | *counter_dev) | |
cb7859a9 FMH |
308 | { |
309 | switch (counter_dev->variant) { | |
310 | case ni_gpct_variant_e_series: | |
311 | return 0; | |
cb7859a9 FMH |
312 | case ni_gpct_variant_m_series: |
313 | case ni_gpct_variant_660x: | |
314 | return 1; | |
cb7859a9 FMH |
315 | default: |
316 | BUG(); | |
317 | break; | |
318 | } | |
319 | return 0; | |
320 | } | |
321 | ||
322 | static inline void ni_tio_set_bits_transient(struct ni_gpct *counter, | |
0a85b6f0 MT |
323 | enum ni_gpct_register |
324 | register_index, unsigned bit_mask, | |
325 | unsigned bit_values, | |
326 | unsigned transient_bit_values) | |
cb7859a9 FMH |
327 | { |
328 | struct ni_gpct_device *counter_dev = counter->counter_dev; | |
329 | unsigned long flags; | |
330 | ||
12375292 | 331 | BUG_ON(register_index >= NITIO_NUM_REGS); |
5f74ea14 | 332 | spin_lock_irqsave(&counter_dev->regs_lock, flags); |
cb7859a9 FMH |
333 | counter_dev->regs[register_index] &= ~bit_mask; |
334 | counter_dev->regs[register_index] |= (bit_values & bit_mask); | |
335 | write_register(counter, | |
0a85b6f0 MT |
336 | counter_dev->regs[register_index] | transient_bit_values, |
337 | register_index); | |
cb7859a9 | 338 | mmiowb(); |
5f74ea14 | 339 | spin_unlock_irqrestore(&counter_dev->regs_lock, flags); |
cb7859a9 FMH |
340 | } |
341 | ||
342 | /* ni_tio_set_bits( ) is for safely writing to registers whose bits may be | |
35c81aaa TK |
343 | * twiddled in interrupt context, or whose software copy may be read in |
344 | * interrupt context. | |
345 | */ | |
cb7859a9 | 346 | static inline void ni_tio_set_bits(struct ni_gpct *counter, |
0a85b6f0 MT |
347 | enum ni_gpct_register register_index, |
348 | unsigned bit_mask, unsigned bit_values) | |
cb7859a9 FMH |
349 | { |
350 | ni_tio_set_bits_transient(counter, register_index, bit_mask, bit_values, | |
0a85b6f0 | 351 | 0x0); |
cb7859a9 FMH |
352 | } |
353 | ||
354 | /* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register | |
355 | whose bits might be modified in interrupt context, or whose software copy | |
356 | might need to be read in interrupt context. | |
357 | */ | |
358 | static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter, | |
0a85b6f0 MT |
359 | enum ni_gpct_register |
360 | register_index) | |
cb7859a9 FMH |
361 | { |
362 | struct ni_gpct_device *counter_dev = counter->counter_dev; | |
363 | unsigned long flags; | |
364 | unsigned value; | |
365 | ||
12375292 | 366 | BUG_ON(register_index >= NITIO_NUM_REGS); |
5f74ea14 | 367 | spin_lock_irqsave(&counter_dev->regs_lock, flags); |
cb7859a9 | 368 | value = counter_dev->regs[register_index]; |
5f74ea14 | 369 | spin_unlock_irqrestore(&counter_dev->regs_lock, flags); |
cb7859a9 FMH |
370 | return value; |
371 | } | |
372 | ||
373 | int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger); | |
374 | int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index, | |
0a85b6f0 | 375 | unsigned int gate_source); |
cb7859a9 FMH |
376 | |
377 | #endif /* _COMEDI_NI_TIO_INTERNAL_H */ |