1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Support for NI general purpose counters |
4 | * |
5 | * Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net> |
6 | */ |
7 | |
8 | /* |
9 | * Module: ni_tio |
10 | * Description: National Instruments general purpose counters |
11 | * Author: J.P. Mellor <jpmellor@rose-hulman.edu>, |
12 | * Herman.Bruyninckx@mech.kuleuven.ac.be, |
13 | * Wim.Meeussen@mech.kuleuven.ac.be, |
14 | * Klaas.Gadeyne@mech.kuleuven.ac.be, |
15 | * Frank Mori Hess <fmhess@users.sourceforge.net> |
16 | * Updated: Thu Nov 16 09:50:32 EST 2006 |
17 | * Status: works |
18 | * |
19 | * This module is not used directly by end-users. Rather, it |
20 | * is used by other drivers (for example ni_660x and ni_pcimio) |
21 | * to provide support for NI's general purpose counters. It was |
22 | * originally based on the counter code from ni_660x.c and |
23 | * ni_mio_common.c. |
24 | * |
25 | * References: |
26 | * DAQ 660x Register-Level Programmer Manual (NI 370505A-01) |
27 | * DAQ 6601/6602 User Manual (NI 322137B-01) |
28 | * 340934b.pdf DAQ-STC reference manual |
29 | * |
30 | * TODO: Support use of both banks X and Y |
31 | */ |
32 | |
33 | #include <linux/module.h> |
34 | #include <linux/slab.h> |
35 | |
36 | #include "ni_tio_internal.h" |
37 | |
38 | /* |
39 | * clock sources for ni e and m series boards, |
40 | * get bits with GI_SRC_SEL() |
41 | */ |
42 | #define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */ |
43 | #define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x))) |
44 | #define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x))) |
45 | #define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */ |
46 | #define NI_M_NEXT_TC_CLK 0x13 |
47 | #define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */ |
48 | #define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */ |
49 | #define NI_M_PXI10_CLK 0x1d |
50 | #define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */ |
51 | #define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */ |
52 | #define NI_M_LOGIC_LOW_CLK 0x1f |
53 | #define NI_M_MAX_PFI_CHAN 15 |
54 | #define NI_M_MAX_RTSI_CHAN 7 |
55 | |
56 | /* |
57 | * clock sources for ni_660x boards, |
58 | * get bits with GI_SRC_SEL() |
59 | */ |
60 | #define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */ |
61 | #define NI_660X_SRC_PIN_I_CLK 0x1 |
62 | #define NI_660X_SRC_PIN_CLK(x) (0x2 + (x)) |
63 | #define NI_660X_NEXT_GATE_CLK 0xa |
64 | #define NI_660X_RTSI_CLK(x) (0xb + (x)) |
65 | #define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */ |
66 | #define NI_660X_NEXT_TC_CLK 0x13 |
67 | #define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */ |
68 | #define NI_660X_LOGIC_LOW_CLK 0x1f |
69 | #define NI_660X_MAX_SRC_PIN 7 |
70 | #define NI_660X_MAX_RTSI_CHAN 6 |
71 | |
72 | /* ni m series gate_select */ |
73 | #define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0 |
74 | #define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x))) |
75 | #define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x))) |
76 | #define NI_M_AI_START2_GATE_SEL 0x12 |
77 | #define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13 |
78 | #define NI_M_NEXT_OUT_GATE_SEL 0x14 |
79 | #define NI_M_AI_START1_GATE_SEL 0x1c |
80 | #define NI_M_NEXT_SRC_GATE_SEL 0x1d |
81 | #define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e |
82 | #define NI_M_LOGIC_LOW_GATE_SEL 0x1f |
83 | |
84 | /* ni_660x gate select */ |
85 | #define NI_660X_SRC_PIN_I_GATE_SEL 0x0 |
86 | #define NI_660X_GATE_PIN_I_GATE_SEL 0x1 |
87 | #define NI_660X_PIN_GATE_SEL(x) (0x2 + (x)) |
88 | #define NI_660X_NEXT_SRC_GATE_SEL 0xa |
89 | #define NI_660X_RTSI_GATE_SEL(x) (0xb + (x)) |
90 | #define NI_660X_NEXT_OUT_GATE_SEL 0x14 |
91 | #define NI_660X_LOGIC_LOW_GATE_SEL 0x1f |
92 | #define NI_660X_MAX_GATE_PIN 7 |
93 | |
94 | /* ni_660x second gate select */ |
95 | #define NI_660X_SRC_PIN_I_GATE2_SEL 0x0 |
96 | #define NI_660X_UD_PIN_I_GATE2_SEL 0x1 |
97 | #define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x)) |
98 | #define NI_660X_NEXT_SRC_GATE2_SEL 0xa |
99 | #define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x)) |
100 | #define NI_660X_NEXT_OUT_GATE2_SEL 0x14 |
101 | #define NI_660X_SELECTED_GATE2_SEL 0x1e |
102 | #define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f |
103 | #define NI_660X_MAX_UP_DOWN_PIN 7 |
104 | |
105 | static inline unsigned int GI_PRESCALE_X2(enum ni_gpct_variant variant) |
106 | { |
107 | switch (variant) { |
108 | case ni_gpct_variant_e_series: |
109 | default: |
110 | return 0; |
111 | case ni_gpct_variant_m_series: |
112 | return GI_M_PRESCALE_X2; |
113 | case ni_gpct_variant_660x: |
114 | return GI_660X_PRESCALE_X2; |
115 | } |
116 | } |
117 | |
118 | static inline unsigned int GI_PRESCALE_X8(enum ni_gpct_variant variant) |
119 | { |
120 | switch (variant) { |
121 | case ni_gpct_variant_e_series: |
122 | default: |
123 | return 0; |
124 | case ni_gpct_variant_m_series: |
125 | return GI_M_PRESCALE_X8; |
126 | case ni_gpct_variant_660x: |
127 | return GI_660X_PRESCALE_X8; |
128 | } |
129 | } |
130 | |
131 | static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev) |
132 | { |
133 | switch (counter_dev->variant) { |
134 | case ni_gpct_variant_e_series: |
135 | default: |
136 | return false; |
137 | case ni_gpct_variant_m_series: |
138 | case ni_gpct_variant_660x: |
139 | return true; |
140 | } |
141 | } |
142 | |
143 | /** |
144 | * ni_tio_write() - Write a TIO register using the driver provided callback. |
145 | * @counter: struct ni_gpct counter. |
146 | * @value: the value to write |
147 | * @reg: the register to write. |
148 | */ |
149 | void ni_tio_write(struct ni_gpct *counter, unsigned int value, |
150 | enum ni_gpct_register reg) |
151 | { |
152 | if (reg < NITIO_NUM_REGS) |
153 | counter->counter_dev->write(counter, value, reg); |
154 | } |
155 | EXPORT_SYMBOL_GPL(ni_tio_write); |
156 | |
157 | /** |
158 | * ni_tio_read() - Read a TIO register using the driver provided callback. |
159 | * @counter: struct ni_gpct counter. |
160 | * @reg: the register to read. |
161 | */ |
162 | unsigned int ni_tio_read(struct ni_gpct *counter, enum ni_gpct_register reg) |
163 | { |
164 | if (reg < NITIO_NUM_REGS) |
165 | return counter->counter_dev->read(counter, reg); |
166 | return 0; |
167 | } |
168 | EXPORT_SYMBOL_GPL(ni_tio_read); |
169 | |
170 | static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter) |
171 | { |
172 | unsigned int cidx = counter->counter_index; |
173 | |
174 | ni_tio_write(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx)); |
175 | } |
176 | |
177 | static int ni_tio_clock_period_ps(const struct ni_gpct *counter, |
178 | unsigned int generic_clock_source, |
179 | u64 *period_ps) |
180 | { |
181 | u64 clock_period_ps; |
182 | |
183 | switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { |
184 | case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: |
185 | clock_period_ps = 50000; |
186 | break; |
187 | case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: |
188 | clock_period_ps = 10000000; |
189 | break; |
190 | case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: |
191 | clock_period_ps = 12500; |
192 | break; |
193 | case NI_GPCT_PXI10_CLOCK_SRC_BITS: |
194 | clock_period_ps = 100000; |
195 | break; |
196 | default: |
197 | /* |
198 | * clock period is specified by user with prescaling |
199 | * already taken into account. |
200 | */ |
201 | *period_ps = counter->clock_period_ps; |
202 | return 0; |
203 | } |
204 | |
205 | switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { |
206 | case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: |
207 | break; |
208 | case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: |
209 | clock_period_ps *= 2; |
210 | break; |
211 | case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: |
212 | clock_period_ps *= 8; |
213 | break; |
214 | default: |
215 | return -EINVAL; |
216 | } |
217 | *period_ps = clock_period_ps; |
218 | return 0; |
219 | } |
220 | |
221 | static void ni_tio_set_bits_transient(struct ni_gpct *counter, |
222 | enum ni_gpct_register reg, |
223 | unsigned int mask, unsigned int value, |
224 | unsigned int transient) |
225 | { |
226 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
227 | unsigned int chip = counter->chip_index; |
228 | unsigned long flags; |
229 | |
230 | if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { |
231 | unsigned int *regs = counter_dev->regs[chip]; |
232 | |
233 | spin_lock_irqsave(&counter_dev->regs_lock, flags); |
234 | regs[reg] &= ~mask; |
235 | regs[reg] |= (value & mask); |
236 | ni_tio_write(counter, regs[reg] | transient, reg); |
237 | spin_unlock_irqrestore(lock: &counter_dev->regs_lock, flags); |
238 | } |
239 | } |
240 | |
241 | /** |
242 | * ni_tio_set_bits() - Safely write a counter register. |
243 | * @counter: struct ni_gpct counter. |
244 | * @reg: the register to write. |
245 | * @mask: the bits to change. |
246 | * @value: the new bits value. |
247 | * |
248 | * Used to write to, and update the software copy, a register whose bits may |
249 | * be twiddled in interrupt context, or whose software copy may be read in |
250 | * interrupt context. |
251 | */ |
252 | void ni_tio_set_bits(struct ni_gpct *counter, enum ni_gpct_register reg, |
253 | unsigned int mask, unsigned int value) |
254 | { |
255 | ni_tio_set_bits_transient(counter, reg, mask, value, transient: 0x0); |
256 | } |
257 | EXPORT_SYMBOL_GPL(ni_tio_set_bits); |
258 | |
259 | /** |
260 | * ni_tio_get_soft_copy() - Safely read the software copy of a counter register. |
261 | * @counter: struct ni_gpct counter. |
262 | * @reg: the register to read. |
263 | * |
264 | * Used to get the software copy of a register whose bits might be modified |
265 | * in interrupt context, or whose software copy might need to be read in |
266 | * interrupt context. |
267 | */ |
268 | unsigned int ni_tio_get_soft_copy(const struct ni_gpct *counter, |
269 | enum ni_gpct_register reg) |
270 | { |
271 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
272 | unsigned int chip = counter->chip_index; |
273 | unsigned int value = 0; |
274 | unsigned long flags; |
275 | |
276 | if (reg < NITIO_NUM_REGS && chip < counter_dev->num_chips) { |
277 | spin_lock_irqsave(&counter_dev->regs_lock, flags); |
278 | value = counter_dev->regs[chip][reg]; |
279 | spin_unlock_irqrestore(lock: &counter_dev->regs_lock, flags); |
280 | } |
281 | return value; |
282 | } |
283 | EXPORT_SYMBOL_GPL(ni_tio_get_soft_copy); |
284 | |
285 | static unsigned int ni_tio_clock_src_modifiers(const struct ni_gpct *counter) |
286 | { |
287 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
288 | unsigned int cidx = counter->counter_index; |
289 | unsigned int counting_mode_bits = |
290 | ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx)); |
291 | unsigned int bits = 0; |
292 | |
293 | if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) & |
294 | GI_SRC_POL_INVERT) |
295 | bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT; |
296 | if (counting_mode_bits & GI_PRESCALE_X2(variant: counter_dev->variant)) |
297 | bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS; |
298 | if (counting_mode_bits & GI_PRESCALE_X8(variant: counter_dev->variant)) |
299 | bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS; |
300 | return bits; |
301 | } |
302 | |
303 | static int ni_m_series_clock_src_select(const struct ni_gpct *counter, |
304 | unsigned int *clk_src) |
305 | { |
306 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
307 | unsigned int cidx = counter->counter_index; |
308 | unsigned int chip = counter->chip_index; |
309 | unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); |
310 | unsigned int clock_source = 0; |
311 | unsigned int src; |
312 | unsigned int i; |
313 | |
314 | src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, |
315 | NITIO_INPUT_SEL_REG(cidx))); |
316 | |
317 | switch (src) { |
318 | case NI_M_TIMEBASE_1_CLK: |
319 | clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; |
320 | break; |
321 | case NI_M_TIMEBASE_2_CLK: |
322 | clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; |
323 | break; |
324 | case NI_M_TIMEBASE_3_CLK: |
325 | if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) |
326 | clock_source = |
327 | NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS; |
328 | else |
329 | clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; |
330 | break; |
331 | case NI_M_LOGIC_LOW_CLK: |
332 | clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; |
333 | break; |
334 | case NI_M_NEXT_GATE_CLK: |
335 | if (counter_dev->regs[chip][second_gate_reg] & GI_SRC_SUBSEL) |
336 | clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS; |
337 | else |
338 | clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; |
339 | break; |
340 | case NI_M_PXI10_CLK: |
341 | clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS; |
342 | break; |
343 | case NI_M_NEXT_TC_CLK: |
344 | clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; |
345 | break; |
346 | default: |
347 | for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { |
348 | if (src == NI_M_RTSI_CLK(i)) { |
349 | clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); |
350 | break; |
351 | } |
352 | } |
353 | if (i <= NI_M_MAX_RTSI_CHAN) |
354 | break; |
355 | for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { |
356 | if (src == NI_M_PFI_CLK(i)) { |
357 | clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i); |
358 | break; |
359 | } |
360 | } |
361 | if (i <= NI_M_MAX_PFI_CHAN) |
362 | break; |
363 | return -EINVAL; |
364 | } |
365 | clock_source |= ni_tio_clock_src_modifiers(counter); |
366 | *clk_src = clock_source; |
367 | return 0; |
368 | } |
369 | |
370 | static int ni_660x_clock_src_select(const struct ni_gpct *counter, |
371 | unsigned int *clk_src) |
372 | { |
373 | unsigned int clock_source = 0; |
374 | unsigned int cidx = counter->counter_index; |
375 | unsigned int src; |
376 | unsigned int i; |
377 | |
378 | src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter, |
379 | NITIO_INPUT_SEL_REG(cidx))); |
380 | |
381 | switch (src) { |
382 | case NI_660X_TIMEBASE_1_CLK: |
383 | clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS; |
384 | break; |
385 | case NI_660X_TIMEBASE_2_CLK: |
386 | clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS; |
387 | break; |
388 | case NI_660X_TIMEBASE_3_CLK: |
389 | clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS; |
390 | break; |
391 | case NI_660X_LOGIC_LOW_CLK: |
392 | clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS; |
393 | break; |
394 | case NI_660X_SRC_PIN_I_CLK: |
395 | clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS; |
396 | break; |
397 | case NI_660X_NEXT_GATE_CLK: |
398 | clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS; |
399 | break; |
400 | case NI_660X_NEXT_TC_CLK: |
401 | clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS; |
402 | break; |
403 | default: |
404 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
405 | if (src == NI_660X_RTSI_CLK(i)) { |
406 | clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i); |
407 | break; |
408 | } |
409 | } |
410 | if (i <= NI_660X_MAX_RTSI_CHAN) |
411 | break; |
412 | for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) { |
413 | if (src == NI_660X_SRC_PIN_CLK(i)) { |
414 | clock_source = |
415 | NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i); |
416 | break; |
417 | } |
418 | } |
419 | if (i <= NI_660X_MAX_SRC_PIN) |
420 | break; |
421 | return -EINVAL; |
422 | } |
423 | clock_source |= ni_tio_clock_src_modifiers(counter); |
424 | *clk_src = clock_source; |
425 | return 0; |
426 | } |
427 | |
428 | static int ni_tio_generic_clock_src_select(const struct ni_gpct *counter, |
429 | unsigned int *clk_src) |
430 | { |
431 | switch (counter->counter_dev->variant) { |
432 | case ni_gpct_variant_e_series: |
433 | case ni_gpct_variant_m_series: |
434 | default: |
435 | return ni_m_series_clock_src_select(counter, clk_src); |
436 | case ni_gpct_variant_660x: |
437 | return ni_660x_clock_src_select(counter, clk_src); |
438 | } |
439 | } |
440 | |
441 | static void ni_tio_set_sync_mode(struct ni_gpct *counter) |
442 | { |
443 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
444 | unsigned int cidx = counter->counter_index; |
445 | static const u64 min_normal_sync_period_ps = 25000; |
446 | unsigned int mask = 0; |
447 | unsigned int bits = 0; |
448 | unsigned int reg; |
449 | unsigned int mode; |
450 | unsigned int clk_src = 0; |
451 | u64 ps = 0; |
452 | int ret; |
453 | bool force_alt_sync; |
454 | |
455 | /* only m series and 660x variants have counting mode registers */ |
456 | switch (counter_dev->variant) { |
457 | case ni_gpct_variant_e_series: |
458 | default: |
459 | return; |
460 | case ni_gpct_variant_m_series: |
461 | mask = GI_M_ALT_SYNC; |
462 | break; |
463 | case ni_gpct_variant_660x: |
464 | mask = GI_660X_ALT_SYNC; |
465 | break; |
466 | } |
467 | |
468 | reg = NITIO_CNT_MODE_REG(cidx); |
469 | mode = ni_tio_get_soft_copy(counter, reg); |
470 | switch (mode & GI_CNT_MODE_MASK) { |
471 | case GI_CNT_MODE_QUADX1: |
472 | case GI_CNT_MODE_QUADX2: |
473 | case GI_CNT_MODE_QUADX4: |
474 | case GI_CNT_MODE_SYNC_SRC: |
475 | force_alt_sync = true; |
476 | break; |
477 | default: |
478 | force_alt_sync = false; |
479 | break; |
480 | } |
481 | |
482 | ret = ni_tio_generic_clock_src_select(counter, clk_src: &clk_src); |
483 | if (ret) |
484 | return; |
485 | ret = ni_tio_clock_period_ps(counter, generic_clock_source: clk_src, period_ps: &ps); |
486 | if (ret) |
487 | return; |
488 | /* |
489 | * It's not clear what we should do if clock_period is unknown, so we |
490 | * are not using the alt sync bit in that case. |
491 | */ |
492 | if (force_alt_sync || (ps && ps < min_normal_sync_period_ps)) |
493 | bits = mask; |
494 | |
495 | ni_tio_set_bits(counter, reg, mask, bits); |
496 | } |
497 | |
498 | static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned int mode) |
499 | { |
500 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
501 | unsigned int cidx = counter->counter_index; |
502 | unsigned int mode_reg_mask; |
503 | unsigned int mode_reg_values; |
504 | unsigned int input_select_bits = 0; |
505 | /* these bits map directly on to the mode register */ |
506 | static const unsigned int mode_reg_direct_mask = |
507 | NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK | |
508 | NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK | |
509 | NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT | |
510 | NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT; |
511 | |
512 | mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING; |
513 | mode_reg_values = mode & mode_reg_direct_mask; |
514 | switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) { |
515 | case NI_GPCT_RELOAD_SOURCE_FIXED_BITS: |
516 | break; |
517 | case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS: |
518 | mode_reg_values |= GI_RELOAD_SRC_SWITCHING; |
519 | break; |
520 | case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS: |
521 | input_select_bits |= GI_GATE_SEL_LOAD_SRC; |
522 | mode_reg_mask |= GI_GATING_MODE_MASK; |
523 | mode_reg_values |= GI_LEVEL_GATING; |
524 | break; |
525 | default: |
526 | break; |
527 | } |
528 | ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), |
529 | mode_reg_mask, mode_reg_values); |
530 | |
531 | if (ni_tio_counting_mode_registers_present(counter_dev)) { |
532 | unsigned int bits = 0; |
533 | |
534 | bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT); |
535 | bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT)); |
536 | if (mode & NI_GPCT_INDEX_ENABLE_BIT) |
537 | bits |= GI_INDEX_MODE; |
538 | ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), |
539 | GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK | |
540 | GI_INDEX_MODE, bits); |
541 | ni_tio_set_sync_mode(counter); |
542 | } |
543 | |
544 | ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK, |
545 | GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT)); |
546 | |
547 | if (mode & NI_GPCT_OR_GATE_BIT) |
548 | input_select_bits |= GI_OR_GATE; |
549 | if (mode & NI_GPCT_INVERT_OUTPUT_BIT) |
550 | input_select_bits |= GI_OUTPUT_POL_INVERT; |
551 | ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), |
552 | GI_GATE_SEL_LOAD_SRC | GI_OR_GATE | |
553 | GI_OUTPUT_POL_INVERT, input_select_bits); |
554 | |
555 | return 0; |
556 | } |
557 | |
558 | int ni_tio_arm(struct ni_gpct *counter, bool arm, unsigned int start_trigger) |
559 | { |
560 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
561 | unsigned int cidx = counter->counter_index; |
562 | unsigned int transient_bits = 0; |
563 | |
564 | if (arm) { |
565 | unsigned int mask = 0; |
566 | unsigned int bits = 0; |
567 | |
568 | /* only m series and 660x have counting mode registers */ |
569 | switch (counter_dev->variant) { |
570 | case ni_gpct_variant_e_series: |
571 | default: |
572 | break; |
573 | case ni_gpct_variant_m_series: |
574 | mask = GI_M_HW_ARM_SEL_MASK; |
575 | break; |
576 | case ni_gpct_variant_660x: |
577 | mask = GI_660X_HW_ARM_SEL_MASK; |
578 | break; |
579 | } |
580 | |
581 | switch (start_trigger) { |
582 | case NI_GPCT_ARM_IMMEDIATE: |
583 | transient_bits |= GI_ARM; |
584 | break; |
585 | case NI_GPCT_ARM_PAIRED_IMMEDIATE: |
586 | transient_bits |= GI_ARM | GI_ARM_COPY; |
587 | break; |
588 | default: |
589 | /* |
590 | * for m series and 660x, pass-through the least |
591 | * significant bits so we can figure out what select |
592 | * later |
593 | */ |
594 | if (mask && (start_trigger & NI_GPCT_ARM_UNKNOWN)) { |
595 | bits |= GI_HW_ARM_ENA | |
596 | (GI_HW_ARM_SEL(start_trigger) & mask); |
597 | } else { |
598 | return -EINVAL; |
599 | } |
600 | break; |
601 | } |
602 | |
603 | if (mask) |
604 | ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), |
605 | GI_HW_ARM_ENA | mask, bits); |
606 | } else { |
607 | transient_bits |= GI_DISARM; |
608 | } |
609 | ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), |
610 | mask: 0, value: 0, transient: transient_bits); |
611 | return 0; |
612 | } |
613 | EXPORT_SYMBOL_GPL(ni_tio_arm); |
614 | |
615 | static int ni_660x_clk_src(unsigned int clock_source, unsigned int *bits) |
616 | { |
617 | unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; |
618 | unsigned int ni_660x_clock; |
619 | unsigned int i; |
620 | |
621 | switch (clk_src) { |
622 | case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: |
623 | ni_660x_clock = NI_660X_TIMEBASE_1_CLK; |
624 | break; |
625 | case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: |
626 | ni_660x_clock = NI_660X_TIMEBASE_2_CLK; |
627 | break; |
628 | case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: |
629 | ni_660x_clock = NI_660X_TIMEBASE_3_CLK; |
630 | break; |
631 | case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: |
632 | ni_660x_clock = NI_660X_LOGIC_LOW_CLK; |
633 | break; |
634 | case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS: |
635 | ni_660x_clock = NI_660X_SRC_PIN_I_CLK; |
636 | break; |
637 | case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: |
638 | ni_660x_clock = NI_660X_NEXT_GATE_CLK; |
639 | break; |
640 | case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: |
641 | ni_660x_clock = NI_660X_NEXT_TC_CLK; |
642 | break; |
643 | default: |
644 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
645 | if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { |
646 | ni_660x_clock = NI_660X_RTSI_CLK(i); |
647 | break; |
648 | } |
649 | } |
650 | if (i <= NI_660X_MAX_RTSI_CHAN) |
651 | break; |
652 | for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) { |
653 | if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) { |
654 | ni_660x_clock = NI_660X_SRC_PIN_CLK(i); |
655 | break; |
656 | } |
657 | } |
658 | if (i <= NI_660X_MAX_SRC_PIN) |
659 | break; |
660 | return -EINVAL; |
661 | } |
662 | *bits = GI_SRC_SEL(ni_660x_clock); |
663 | return 0; |
664 | } |
665 | |
666 | static int ni_m_clk_src(unsigned int clock_source, unsigned int *bits) |
667 | { |
668 | unsigned int clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK; |
669 | unsigned int ni_m_series_clock; |
670 | unsigned int i; |
671 | |
672 | switch (clk_src) { |
673 | case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS: |
674 | ni_m_series_clock = NI_M_TIMEBASE_1_CLK; |
675 | break; |
676 | case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS: |
677 | ni_m_series_clock = NI_M_TIMEBASE_2_CLK; |
678 | break; |
679 | case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: |
680 | ni_m_series_clock = NI_M_TIMEBASE_3_CLK; |
681 | break; |
682 | case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS: |
683 | ni_m_series_clock = NI_M_LOGIC_LOW_CLK; |
684 | break; |
685 | case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: |
686 | ni_m_series_clock = NI_M_NEXT_GATE_CLK; |
687 | break; |
688 | case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS: |
689 | ni_m_series_clock = NI_M_NEXT_TC_CLK; |
690 | break; |
691 | case NI_GPCT_PXI10_CLOCK_SRC_BITS: |
692 | ni_m_series_clock = NI_M_PXI10_CLK; |
693 | break; |
694 | case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: |
695 | ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK; |
696 | break; |
697 | case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: |
698 | ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK; |
699 | break; |
700 | default: |
701 | for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { |
702 | if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) { |
703 | ni_m_series_clock = NI_M_RTSI_CLK(i); |
704 | break; |
705 | } |
706 | } |
707 | if (i <= NI_M_MAX_RTSI_CHAN) |
708 | break; |
709 | for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { |
710 | if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) { |
711 | ni_m_series_clock = NI_M_PFI_CLK(i); |
712 | break; |
713 | } |
714 | } |
715 | if (i <= NI_M_MAX_PFI_CHAN) |
716 | break; |
717 | return -EINVAL; |
718 | } |
719 | *bits = GI_SRC_SEL(ni_m_series_clock); |
720 | return 0; |
721 | }; |
722 | |
723 | static void ni_tio_set_source_subselect(struct ni_gpct *counter, |
724 | unsigned int clock_source) |
725 | { |
726 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
727 | unsigned int cidx = counter->counter_index; |
728 | unsigned int chip = counter->chip_index; |
729 | unsigned int second_gate_reg = NITIO_GATE2_REG(cidx); |
730 | |
731 | if (counter_dev->variant != ni_gpct_variant_m_series) |
732 | return; |
733 | switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) { |
734 | /* Gi_Source_Subselect is zero */ |
735 | case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS: |
736 | case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS: |
737 | counter_dev->regs[chip][second_gate_reg] &= ~GI_SRC_SUBSEL; |
738 | break; |
739 | /* Gi_Source_Subselect is one */ |
740 | case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS: |
741 | case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS: |
742 | counter_dev->regs[chip][second_gate_reg] |= GI_SRC_SUBSEL; |
743 | break; |
744 | /* Gi_Source_Subselect doesn't matter */ |
745 | default: |
746 | return; |
747 | } |
748 | ni_tio_write(counter, counter_dev->regs[chip][second_gate_reg], |
749 | second_gate_reg); |
750 | } |
751 | |
752 | static int ni_tio_set_clock_src(struct ni_gpct *counter, |
753 | unsigned int clock_source, |
754 | unsigned int period_ns) |
755 | { |
756 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
757 | unsigned int cidx = counter->counter_index; |
758 | unsigned int bits = 0; |
759 | int ret; |
760 | |
761 | switch (counter_dev->variant) { |
762 | case ni_gpct_variant_660x: |
763 | ret = ni_660x_clk_src(clock_source, bits: &bits); |
764 | break; |
765 | case ni_gpct_variant_e_series: |
766 | case ni_gpct_variant_m_series: |
767 | default: |
768 | ret = ni_m_clk_src(clock_source, bits: &bits); |
769 | break; |
770 | } |
771 | if (ret) { |
772 | struct comedi_device *dev = counter_dev->dev; |
773 | |
774 | dev_err(dev->class_dev, "invalid clock source 0x%x\n" , |
775 | clock_source); |
776 | return ret; |
777 | } |
778 | |
779 | if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT) |
780 | bits |= GI_SRC_POL_INVERT; |
781 | ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), |
782 | GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits); |
783 | ni_tio_set_source_subselect(counter, clock_source); |
784 | |
785 | if (ni_tio_counting_mode_registers_present(counter_dev)) { |
786 | bits = 0; |
787 | switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) { |
788 | case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS: |
789 | break; |
790 | case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS: |
791 | bits |= GI_PRESCALE_X2(variant: counter_dev->variant); |
792 | break; |
793 | case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS: |
794 | bits |= GI_PRESCALE_X8(variant: counter_dev->variant); |
795 | break; |
796 | default: |
797 | return -EINVAL; |
798 | } |
799 | ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), |
800 | GI_PRESCALE_X2(variant: counter_dev->variant) | |
801 | GI_PRESCALE_X8(variant: counter_dev->variant), bits); |
802 | } |
803 | counter->clock_period_ps = period_ns * 1000; |
804 | ni_tio_set_sync_mode(counter); |
805 | return 0; |
806 | } |
807 | |
808 | static int ni_tio_get_clock_src(struct ni_gpct *counter, |
809 | unsigned int *clock_source, |
810 | unsigned int *period_ns) |
811 | { |
812 | u64 temp64 = 0; |
813 | int ret; |
814 | |
815 | ret = ni_tio_generic_clock_src_select(counter, clk_src: clock_source); |
816 | if (ret) |
817 | return ret; |
818 | ret = ni_tio_clock_period_ps(counter, generic_clock_source: *clock_source, period_ps: &temp64); |
819 | if (ret) |
820 | return ret; |
821 | do_div(temp64, 1000); /* ps to ns */ |
822 | *period_ns = temp64; |
823 | return 0; |
824 | } |
825 | |
826 | static inline void ni_tio_set_gate_raw(struct ni_gpct *counter, |
827 | unsigned int gate_source) |
828 | { |
829 | ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(counter->counter_index), |
830 | GI_GATE_SEL_MASK, GI_GATE_SEL(gate_source)); |
831 | } |
832 | |
833 | static inline void ni_tio_set_gate2_raw(struct ni_gpct *counter, |
834 | unsigned int gate_source) |
835 | { |
836 | ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index), |
837 | GI_GATE2_SEL_MASK, GI_GATE2_SEL(gate_source)); |
838 | } |
839 | |
840 | /* Set the mode bits for gate. */ |
841 | static inline void ni_tio_set_gate_mode(struct ni_gpct *counter, |
842 | unsigned int src) |
843 | { |
844 | unsigned int mode_bits = 0; |
845 | |
846 | if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT) { |
847 | /* |
848 | * Allowing bitwise comparison here to allow non-zero raw |
849 | * register value to be used for channel when disabling. |
850 | */ |
851 | mode_bits = GI_GATING_DISABLED; |
852 | } else { |
853 | if (src & CR_INVERT) |
854 | mode_bits |= GI_GATE_POL_INVERT; |
855 | if (src & CR_EDGE) |
856 | mode_bits |= GI_RISING_EDGE_GATING; |
857 | else |
858 | mode_bits |= GI_LEVEL_GATING; |
859 | } |
860 | ni_tio_set_bits(counter, NITIO_MODE_REG(counter->counter_index), |
861 | GI_GATE_POL_INVERT | GI_GATING_MODE_MASK, |
862 | mode_bits); |
863 | } |
864 | |
865 | /* |
866 | * Set the mode bits for gate2. |
867 | * |
868 | * Previously, the code this function represents did not actually write anything |
869 | * to the register. Rather, writing to this register was reserved for the code |
870 | * ni ni_tio_set_gate2_raw. |
871 | */ |
872 | static inline void ni_tio_set_gate2_mode(struct ni_gpct *counter, |
873 | unsigned int src) |
874 | { |
875 | /* |
876 | * The GI_GATE2_MODE bit was previously set in the code that also sets |
877 | * the gate2 source. |
878 | * We'll set mode bits _after_ source bits now, and thus, this function |
879 | * will effectively enable the second gate after all bits are set. |
880 | */ |
881 | unsigned int mode_bits = GI_GATE2_MODE; |
882 | |
883 | if (CR_CHAN(src) & NI_GPCT_DISABLED_GATE_SELECT) |
884 | /* |
885 | * Allowing bitwise comparison here to allow non-zero raw |
886 | * register value to be used for channel when disabling. |
887 | */ |
888 | mode_bits = GI_GATING_DISABLED; |
889 | if (src & CR_INVERT) |
890 | mode_bits |= GI_GATE2_POL_INVERT; |
891 | |
892 | ni_tio_set_bits(counter, NITIO_GATE2_REG(counter->counter_index), |
893 | GI_GATE2_POL_INVERT | GI_GATE2_MODE, mode_bits); |
894 | } |
895 | |
896 | static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source) |
897 | { |
898 | unsigned int chan = CR_CHAN(gate_source); |
899 | unsigned int gate_sel; |
900 | unsigned int i; |
901 | |
902 | switch (chan) { |
903 | case NI_GPCT_NEXT_SOURCE_GATE_SELECT: |
904 | gate_sel = NI_660X_NEXT_SRC_GATE_SEL; |
905 | break; |
906 | case NI_GPCT_NEXT_OUT_GATE_SELECT: |
907 | case NI_GPCT_LOGIC_LOW_GATE_SELECT: |
908 | case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: |
909 | case NI_GPCT_GATE_PIN_i_GATE_SELECT: |
910 | gate_sel = chan & 0x1f; |
911 | break; |
912 | default: |
913 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
914 | if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { |
915 | gate_sel = chan & 0x1f; |
916 | break; |
917 | } |
918 | } |
919 | if (i <= NI_660X_MAX_RTSI_CHAN) |
920 | break; |
921 | for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) { |
922 | if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) { |
923 | gate_sel = chan & 0x1f; |
924 | break; |
925 | } |
926 | } |
927 | if (i <= NI_660X_MAX_GATE_PIN) |
928 | break; |
929 | return -EINVAL; |
930 | } |
931 | ni_tio_set_gate_raw(counter, gate_source: gate_sel); |
932 | return 0; |
933 | } |
934 | |
935 | static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source) |
936 | { |
937 | unsigned int chan = CR_CHAN(gate_source); |
938 | unsigned int gate_sel; |
939 | unsigned int i; |
940 | |
941 | switch (chan) { |
942 | case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT: |
943 | case NI_GPCT_AI_START2_GATE_SELECT: |
944 | case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT: |
945 | case NI_GPCT_NEXT_OUT_GATE_SELECT: |
946 | case NI_GPCT_AI_START1_GATE_SELECT: |
947 | case NI_GPCT_NEXT_SOURCE_GATE_SELECT: |
948 | case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT: |
949 | case NI_GPCT_LOGIC_LOW_GATE_SELECT: |
950 | gate_sel = chan & 0x1f; |
951 | break; |
952 | default: |
953 | for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { |
954 | if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { |
955 | gate_sel = chan & 0x1f; |
956 | break; |
957 | } |
958 | } |
959 | if (i <= NI_M_MAX_RTSI_CHAN) |
960 | break; |
961 | for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { |
962 | if (chan == NI_GPCT_PFI_GATE_SELECT(i)) { |
963 | gate_sel = chan & 0x1f; |
964 | break; |
965 | } |
966 | } |
967 | if (i <= NI_M_MAX_PFI_CHAN) |
968 | break; |
969 | return -EINVAL; |
970 | } |
971 | ni_tio_set_gate_raw(counter, gate_source: gate_sel); |
972 | return 0; |
973 | } |
974 | |
975 | static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source) |
976 | { |
977 | unsigned int chan = CR_CHAN(gate_source); |
978 | unsigned int gate2_sel; |
979 | unsigned int i; |
980 | |
981 | switch (chan) { |
982 | case NI_GPCT_SOURCE_PIN_i_GATE_SELECT: |
983 | case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT: |
984 | case NI_GPCT_SELECTED_GATE_GATE_SELECT: |
985 | case NI_GPCT_NEXT_OUT_GATE_SELECT: |
986 | case NI_GPCT_LOGIC_LOW_GATE_SELECT: |
987 | gate2_sel = chan & 0x1f; |
988 | break; |
989 | case NI_GPCT_NEXT_SOURCE_GATE_SELECT: |
990 | gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL; |
991 | break; |
992 | default: |
993 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
994 | if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) { |
995 | gate2_sel = chan & 0x1f; |
996 | break; |
997 | } |
998 | } |
999 | if (i <= NI_660X_MAX_RTSI_CHAN) |
1000 | break; |
1001 | for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) { |
1002 | if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) { |
1003 | gate2_sel = chan & 0x1f; |
1004 | break; |
1005 | } |
1006 | } |
1007 | if (i <= NI_660X_MAX_UP_DOWN_PIN) |
1008 | break; |
1009 | return -EINVAL; |
1010 | } |
1011 | ni_tio_set_gate2_raw(counter, gate_source: gate2_sel); |
1012 | return 0; |
1013 | } |
1014 | |
1015 | static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source) |
1016 | { |
1017 | /* |
1018 | * FIXME: We don't know what the m-series second gate codes are, |
1019 | * so we'll just pass the bits through for now. |
1020 | */ |
1021 | ni_tio_set_gate2_raw(counter, gate_source); |
1022 | return 0; |
1023 | } |
1024 | |
1025 | int ni_tio_set_gate_src_raw(struct ni_gpct *counter, |
1026 | unsigned int gate, unsigned int src) |
1027 | { |
1028 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1029 | |
1030 | switch (gate) { |
1031 | case 0: |
1032 | /* 1. start by disabling gate */ |
1033 | ni_tio_set_gate_mode(counter, src: NI_GPCT_DISABLED_GATE_SELECT); |
1034 | /* 2. set the requested gate source */ |
1035 | ni_tio_set_gate_raw(counter, gate_source: src); |
1036 | /* 3. reenable & set mode to starts things back up */ |
1037 | ni_tio_set_gate_mode(counter, src); |
1038 | break; |
1039 | case 1: |
1040 | if (!ni_tio_has_gate2_registers(counter_dev)) |
1041 | return -EINVAL; |
1042 | |
1043 | /* 1. start by disabling gate */ |
1044 | ni_tio_set_gate2_mode(counter, src: NI_GPCT_DISABLED_GATE_SELECT); |
1045 | /* 2. set the requested gate source */ |
1046 | ni_tio_set_gate2_raw(counter, gate_source: src); |
1047 | /* 3. reenable & set mode to starts things back up */ |
1048 | ni_tio_set_gate2_mode(counter, src); |
1049 | break; |
1050 | default: |
1051 | return -EINVAL; |
1052 | } |
1053 | return 0; |
1054 | } |
1055 | EXPORT_SYMBOL_GPL(ni_tio_set_gate_src_raw); |
1056 | |
1057 | int ni_tio_set_gate_src(struct ni_gpct *counter, |
1058 | unsigned int gate, unsigned int src) |
1059 | { |
1060 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1061 | /* |
1062 | * mask off disable flag. This high bit still passes CR_CHAN. |
1063 | * Doing this allows one to both set the gate as disabled, but also |
1064 | * change the route value of the gate. |
1065 | */ |
1066 | int chan = CR_CHAN(src) & (~NI_GPCT_DISABLED_GATE_SELECT); |
1067 | int ret; |
1068 | |
1069 | switch (gate) { |
1070 | case 0: |
1071 | /* 1. start by disabling gate */ |
1072 | ni_tio_set_gate_mode(counter, src: NI_GPCT_DISABLED_GATE_SELECT); |
1073 | /* 2. set the requested gate source */ |
1074 | switch (counter_dev->variant) { |
1075 | case ni_gpct_variant_e_series: |
1076 | case ni_gpct_variant_m_series: |
1077 | ret = ni_m_set_gate(counter, gate_source: chan); |
1078 | break; |
1079 | case ni_gpct_variant_660x: |
1080 | ret = ni_660x_set_gate(counter, gate_source: chan); |
1081 | break; |
1082 | default: |
1083 | return -EINVAL; |
1084 | } |
1085 | if (ret) |
1086 | return ret; |
1087 | /* 3. reenable & set mode to starts things back up */ |
1088 | ni_tio_set_gate_mode(counter, src); |
1089 | break; |
1090 | case 1: |
1091 | if (!ni_tio_has_gate2_registers(counter_dev)) |
1092 | return -EINVAL; |
1093 | |
1094 | /* 1. start by disabling gate */ |
1095 | ni_tio_set_gate2_mode(counter, src: NI_GPCT_DISABLED_GATE_SELECT); |
1096 | /* 2. set the requested gate source */ |
1097 | switch (counter_dev->variant) { |
1098 | case ni_gpct_variant_m_series: |
1099 | ret = ni_m_set_gate2(counter, gate_source: chan); |
1100 | break; |
1101 | case ni_gpct_variant_660x: |
1102 | ret = ni_660x_set_gate2(counter, gate_source: chan); |
1103 | break; |
1104 | default: |
1105 | return -EINVAL; |
1106 | } |
1107 | if (ret) |
1108 | return ret; |
1109 | /* 3. reenable & set mode to starts things back up */ |
1110 | ni_tio_set_gate2_mode(counter, src); |
1111 | break; |
1112 | default: |
1113 | return -EINVAL; |
1114 | } |
1115 | return 0; |
1116 | } |
1117 | EXPORT_SYMBOL_GPL(ni_tio_set_gate_src); |
1118 | |
1119 | static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned int index, |
1120 | unsigned int source) |
1121 | { |
1122 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1123 | unsigned int cidx = counter->counter_index; |
1124 | unsigned int chip = counter->chip_index; |
1125 | unsigned int abz_reg, shift, mask; |
1126 | |
1127 | if (counter_dev->variant != ni_gpct_variant_m_series) |
1128 | return -EINVAL; |
1129 | |
1130 | abz_reg = NITIO_ABZ_REG(cidx); |
1131 | |
1132 | /* allow for new device-global names */ |
1133 | if (index == NI_GPCT_SOURCE_ENCODER_A || |
1134 | (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) { |
1135 | shift = 10; |
1136 | } else if (index == NI_GPCT_SOURCE_ENCODER_B || |
1137 | (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) { |
1138 | shift = 5; |
1139 | } else if (index == NI_GPCT_SOURCE_ENCODER_Z || |
1140 | (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) { |
1141 | shift = 0; |
1142 | } else { |
1143 | return -EINVAL; |
1144 | } |
1145 | |
1146 | mask = 0x1f << shift; |
1147 | if (source > 0x1f) |
1148 | source = 0x1f; /* Disable gate */ |
1149 | |
1150 | counter_dev->regs[chip][abz_reg] &= ~mask; |
1151 | counter_dev->regs[chip][abz_reg] |= (source << shift) & mask; |
1152 | ni_tio_write(counter, counter_dev->regs[chip][abz_reg], abz_reg); |
1153 | return 0; |
1154 | } |
1155 | |
1156 | static int ni_tio_get_other_src(struct ni_gpct *counter, unsigned int index, |
1157 | unsigned int *source) |
1158 | { |
1159 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1160 | unsigned int cidx = counter->counter_index; |
1161 | unsigned int abz_reg, shift, mask; |
1162 | |
1163 | if (counter_dev->variant != ni_gpct_variant_m_series) |
1164 | /* A,B,Z only valid for m-series */ |
1165 | return -EINVAL; |
1166 | |
1167 | abz_reg = NITIO_ABZ_REG(cidx); |
1168 | |
1169 | /* allow for new device-global names */ |
1170 | if (index == NI_GPCT_SOURCE_ENCODER_A || |
1171 | (index >= NI_CtrA(0) && index <= NI_CtrA(-1))) { |
1172 | shift = 10; |
1173 | } else if (index == NI_GPCT_SOURCE_ENCODER_B || |
1174 | (index >= NI_CtrB(0) && index <= NI_CtrB(-1))) { |
1175 | shift = 5; |
1176 | } else if (index == NI_GPCT_SOURCE_ENCODER_Z || |
1177 | (index >= NI_CtrZ(0) && index <= NI_CtrZ(-1))) { |
1178 | shift = 0; |
1179 | } else { |
1180 | return -EINVAL; |
1181 | } |
1182 | |
1183 | mask = 0x1f; |
1184 | |
1185 | *source = (ni_tio_get_soft_copy(counter, abz_reg) >> shift) & mask; |
1186 | return 0; |
1187 | } |
1188 | |
1189 | static int ni_660x_gate_to_generic_gate(unsigned int gate, unsigned int *src) |
1190 | { |
1191 | unsigned int source; |
1192 | unsigned int i; |
1193 | |
1194 | switch (gate) { |
1195 | case NI_660X_SRC_PIN_I_GATE_SEL: |
1196 | source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT; |
1197 | break; |
1198 | case NI_660X_GATE_PIN_I_GATE_SEL: |
1199 | source = NI_GPCT_GATE_PIN_i_GATE_SELECT; |
1200 | break; |
1201 | case NI_660X_NEXT_SRC_GATE_SEL: |
1202 | source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; |
1203 | break; |
1204 | case NI_660X_NEXT_OUT_GATE_SEL: |
1205 | source = NI_GPCT_NEXT_OUT_GATE_SELECT; |
1206 | break; |
1207 | case NI_660X_LOGIC_LOW_GATE_SEL: |
1208 | source = NI_GPCT_LOGIC_LOW_GATE_SELECT; |
1209 | break; |
1210 | default: |
1211 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
1212 | if (gate == NI_660X_RTSI_GATE_SEL(i)) { |
1213 | source = NI_GPCT_RTSI_GATE_SELECT(i); |
1214 | break; |
1215 | } |
1216 | } |
1217 | if (i <= NI_660X_MAX_RTSI_CHAN) |
1218 | break; |
1219 | for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) { |
1220 | if (gate == NI_660X_PIN_GATE_SEL(i)) { |
1221 | source = NI_GPCT_GATE_PIN_GATE_SELECT(i); |
1222 | break; |
1223 | } |
1224 | } |
1225 | if (i <= NI_660X_MAX_GATE_PIN) |
1226 | break; |
1227 | return -EINVAL; |
1228 | } |
1229 | *src = source; |
1230 | return 0; |
1231 | } |
1232 | |
1233 | static int ni_m_gate_to_generic_gate(unsigned int gate, unsigned int *src) |
1234 | { |
1235 | unsigned int source; |
1236 | unsigned int i; |
1237 | |
1238 | switch (gate) { |
1239 | case NI_M_TIMESTAMP_MUX_GATE_SEL: |
1240 | source = NI_GPCT_TIMESTAMP_MUX_GATE_SELECT; |
1241 | break; |
1242 | case NI_M_AI_START2_GATE_SEL: |
1243 | source = NI_GPCT_AI_START2_GATE_SELECT; |
1244 | break; |
1245 | case NI_M_PXI_STAR_TRIGGER_GATE_SEL: |
1246 | source = NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT; |
1247 | break; |
1248 | case NI_M_NEXT_OUT_GATE_SEL: |
1249 | source = NI_GPCT_NEXT_OUT_GATE_SELECT; |
1250 | break; |
1251 | case NI_M_AI_START1_GATE_SEL: |
1252 | source = NI_GPCT_AI_START1_GATE_SELECT; |
1253 | break; |
1254 | case NI_M_NEXT_SRC_GATE_SEL: |
1255 | source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; |
1256 | break; |
1257 | case NI_M_ANALOG_TRIG_OUT_GATE_SEL: |
1258 | source = NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT; |
1259 | break; |
1260 | case NI_M_LOGIC_LOW_GATE_SEL: |
1261 | source = NI_GPCT_LOGIC_LOW_GATE_SELECT; |
1262 | break; |
1263 | default: |
1264 | for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) { |
1265 | if (gate == NI_M_RTSI_GATE_SEL(i)) { |
1266 | source = NI_GPCT_RTSI_GATE_SELECT(i); |
1267 | break; |
1268 | } |
1269 | } |
1270 | if (i <= NI_M_MAX_RTSI_CHAN) |
1271 | break; |
1272 | for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) { |
1273 | if (gate == NI_M_PFI_GATE_SEL(i)) { |
1274 | source = NI_GPCT_PFI_GATE_SELECT(i); |
1275 | break; |
1276 | } |
1277 | } |
1278 | if (i <= NI_M_MAX_PFI_CHAN) |
1279 | break; |
1280 | return -EINVAL; |
1281 | } |
1282 | *src = source; |
1283 | return 0; |
1284 | } |
1285 | |
1286 | static int ni_660x_gate2_to_generic_gate(unsigned int gate, unsigned int *src) |
1287 | { |
1288 | unsigned int source; |
1289 | unsigned int i; |
1290 | |
1291 | switch (gate) { |
1292 | case NI_660X_SRC_PIN_I_GATE2_SEL: |
1293 | source = NI_GPCT_SOURCE_PIN_i_GATE_SELECT; |
1294 | break; |
1295 | case NI_660X_UD_PIN_I_GATE2_SEL: |
1296 | source = NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT; |
1297 | break; |
1298 | case NI_660X_NEXT_SRC_GATE2_SEL: |
1299 | source = NI_GPCT_NEXT_SOURCE_GATE_SELECT; |
1300 | break; |
1301 | case NI_660X_NEXT_OUT_GATE2_SEL: |
1302 | source = NI_GPCT_NEXT_OUT_GATE_SELECT; |
1303 | break; |
1304 | case NI_660X_SELECTED_GATE2_SEL: |
1305 | source = NI_GPCT_SELECTED_GATE_GATE_SELECT; |
1306 | break; |
1307 | case NI_660X_LOGIC_LOW_GATE2_SEL: |
1308 | source = NI_GPCT_LOGIC_LOW_GATE_SELECT; |
1309 | break; |
1310 | default: |
1311 | for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) { |
1312 | if (gate == NI_660X_RTSI_GATE2_SEL(i)) { |
1313 | source = NI_GPCT_RTSI_GATE_SELECT(i); |
1314 | break; |
1315 | } |
1316 | } |
1317 | if (i <= NI_660X_MAX_RTSI_CHAN) |
1318 | break; |
1319 | for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) { |
1320 | if (gate == NI_660X_UD_PIN_GATE2_SEL(i)) { |
1321 | source = NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i); |
1322 | break; |
1323 | } |
1324 | } |
1325 | if (i <= NI_660X_MAX_UP_DOWN_PIN) |
1326 | break; |
1327 | return -EINVAL; |
1328 | } |
1329 | *src = source; |
1330 | return 0; |
1331 | } |
1332 | |
1333 | static int ni_m_gate2_to_generic_gate(unsigned int gate, unsigned int *src) |
1334 | { |
1335 | /* |
1336 | * FIXME: the second gate sources for the m series are undocumented, |
1337 | * so we just return the raw bits for now. |
1338 | */ |
1339 | *src = gate; |
1340 | return 0; |
1341 | } |
1342 | |
1343 | static inline unsigned int ni_tio_get_gate_mode(struct ni_gpct *counter) |
1344 | { |
1345 | unsigned int mode = ni_tio_get_soft_copy(counter, |
1346 | NITIO_MODE_REG(counter->counter_index)); |
1347 | unsigned int ret = 0; |
1348 | |
1349 | if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) |
1350 | ret |= NI_GPCT_DISABLED_GATE_SELECT; |
1351 | if (mode & GI_GATE_POL_INVERT) |
1352 | ret |= CR_INVERT; |
1353 | if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING) |
1354 | ret |= CR_EDGE; |
1355 | |
1356 | return ret; |
1357 | } |
1358 | |
1359 | static inline unsigned int ni_tio_get_gate2_mode(struct ni_gpct *counter) |
1360 | { |
1361 | unsigned int mode = ni_tio_get_soft_copy(counter, |
1362 | NITIO_GATE2_REG(counter->counter_index)); |
1363 | unsigned int ret = 0; |
1364 | |
1365 | if (!(mode & GI_GATE2_MODE)) |
1366 | ret |= NI_GPCT_DISABLED_GATE_SELECT; |
1367 | if (mode & GI_GATE2_POL_INVERT) |
1368 | ret |= CR_INVERT; |
1369 | |
1370 | return ret; |
1371 | } |
1372 | |
1373 | static inline unsigned int ni_tio_get_gate_val(struct ni_gpct *counter) |
1374 | { |
1375 | return GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter, |
1376 | NITIO_INPUT_SEL_REG(counter->counter_index))); |
1377 | } |
1378 | |
1379 | static inline unsigned int ni_tio_get_gate2_val(struct ni_gpct *counter) |
1380 | { |
1381 | return GI_BITS_TO_GATE2(ni_tio_get_soft_copy(counter, |
1382 | NITIO_GATE2_REG(counter->counter_index))); |
1383 | } |
1384 | |
1385 | static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned int gate_index, |
1386 | unsigned int *gate_source) |
1387 | { |
1388 | unsigned int gate; |
1389 | int ret; |
1390 | |
1391 | switch (gate_index) { |
1392 | case 0: |
1393 | gate = ni_tio_get_gate_val(counter); |
1394 | switch (counter->counter_dev->variant) { |
1395 | case ni_gpct_variant_e_series: |
1396 | case ni_gpct_variant_m_series: |
1397 | default: |
1398 | ret = ni_m_gate_to_generic_gate(gate, src: gate_source); |
1399 | break; |
1400 | case ni_gpct_variant_660x: |
1401 | ret = ni_660x_gate_to_generic_gate(gate, src: gate_source); |
1402 | break; |
1403 | } |
1404 | if (ret) |
1405 | return ret; |
1406 | *gate_source |= ni_tio_get_gate_mode(counter); |
1407 | break; |
1408 | case 1: |
1409 | gate = ni_tio_get_gate2_val(counter); |
1410 | switch (counter->counter_dev->variant) { |
1411 | case ni_gpct_variant_e_series: |
1412 | case ni_gpct_variant_m_series: |
1413 | default: |
1414 | ret = ni_m_gate2_to_generic_gate(gate, src: gate_source); |
1415 | break; |
1416 | case ni_gpct_variant_660x: |
1417 | ret = ni_660x_gate2_to_generic_gate(gate, src: gate_source); |
1418 | break; |
1419 | } |
1420 | if (ret) |
1421 | return ret; |
1422 | *gate_source |= ni_tio_get_gate2_mode(counter); |
1423 | break; |
1424 | default: |
1425 | return -EINVAL; |
1426 | } |
1427 | return 0; |
1428 | } |
1429 | |
1430 | static int ni_tio_get_gate_src_raw(struct ni_gpct *counter, |
1431 | unsigned int gate_index, |
1432 | unsigned int *gate_source) |
1433 | { |
1434 | switch (gate_index) { |
1435 | case 0: |
1436 | *gate_source = ni_tio_get_gate_mode(counter) |
1437 | | ni_tio_get_gate_val(counter); |
1438 | break; |
1439 | case 1: |
1440 | *gate_source = ni_tio_get_gate2_mode(counter) |
1441 | | ni_tio_get_gate2_val(counter); |
1442 | break; |
1443 | default: |
1444 | return -EINVAL; |
1445 | } |
1446 | return 0; |
1447 | } |
1448 | |
1449 | int ni_tio_insn_config(struct comedi_device *dev, |
1450 | struct comedi_subdevice *s, |
1451 | struct comedi_insn *insn, |
1452 | unsigned int *data) |
1453 | { |
1454 | struct ni_gpct *counter = s->private; |
1455 | unsigned int cidx = counter->counter_index; |
1456 | unsigned int status; |
1457 | int ret = 0; |
1458 | |
1459 | switch (data[0]) { |
1460 | case INSN_CONFIG_SET_COUNTER_MODE: |
1461 | ret = ni_tio_set_counter_mode(counter, mode: data[1]); |
1462 | break; |
1463 | case INSN_CONFIG_ARM: |
1464 | ret = ni_tio_arm(counter, true, data[1]); |
1465 | break; |
1466 | case INSN_CONFIG_DISARM: |
1467 | ret = ni_tio_arm(counter, false, 0); |
1468 | break; |
1469 | case INSN_CONFIG_GET_COUNTER_STATUS: |
1470 | data[1] = 0; |
1471 | status = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); |
1472 | if (status & GI_ARMED(cidx)) { |
1473 | data[1] |= COMEDI_COUNTER_ARMED; |
1474 | if (status & GI_COUNTING(cidx)) |
1475 | data[1] |= COMEDI_COUNTER_COUNTING; |
1476 | } |
1477 | data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING; |
1478 | break; |
1479 | case INSN_CONFIG_SET_CLOCK_SRC: |
1480 | ret = ni_tio_set_clock_src(counter, clock_source: data[1], period_ns: data[2]); |
1481 | break; |
1482 | case INSN_CONFIG_GET_CLOCK_SRC: |
1483 | ret = ni_tio_get_clock_src(counter, clock_source: &data[1], period_ns: &data[2]); |
1484 | break; |
1485 | case INSN_CONFIG_SET_GATE_SRC: |
1486 | ret = ni_tio_set_gate_src(counter, data[1], data[2]); |
1487 | break; |
1488 | case INSN_CONFIG_GET_GATE_SRC: |
1489 | ret = ni_tio_get_gate_src(counter, gate_index: data[1], gate_source: &data[2]); |
1490 | break; |
1491 | case INSN_CONFIG_SET_OTHER_SRC: |
1492 | ret = ni_tio_set_other_src(counter, index: data[1], source: data[2]); |
1493 | break; |
1494 | case INSN_CONFIG_RESET: |
1495 | ni_tio_reset_count_and_disarm(counter); |
1496 | break; |
1497 | default: |
1498 | return -EINVAL; |
1499 | } |
1500 | return ret ? ret : insn->n; |
1501 | } |
1502 | EXPORT_SYMBOL_GPL(ni_tio_insn_config); |
1503 | |
1504 | /* |
1505 | * Retrieves the register value of the current source of the output selector for |
1506 | * the given destination. |
1507 | * |
1508 | * If the terminal for the destination is not already configured as an output, |
1509 | * this function returns -EINVAL as error. |
1510 | * |
1511 | * Return: the register value of the destination output selector; |
1512 | * -EINVAL if terminal is not configured for output. |
1513 | */ |
1514 | int ni_tio_get_routing(struct ni_gpct_device *counter_dev, unsigned int dest) |
1515 | { |
1516 | /* we need to know the actual counter below... */ |
1517 | int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS; |
1518 | struct ni_gpct *counter = &counter_dev->counters[ctr_index]; |
1519 | int ret = 1; |
1520 | unsigned int reg; |
1521 | |
1522 | if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) { |
1523 | ret = ni_tio_get_other_src(counter, index: dest, source: ®); |
1524 | } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) { |
1525 | ret = ni_tio_get_gate_src_raw(counter, gate_index: 0, gate_source: ®); |
1526 | } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) { |
1527 | ret = ni_tio_get_gate_src_raw(counter, gate_index: 1, gate_source: ®); |
1528 | /* |
1529 | * This case is not possible through this interface. A user must use |
1530 | * INSN_CONFIG_SET_CLOCK_SRC instead. |
1531 | * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) { |
1532 | * ret = ni_tio_set_clock_src(counter, ®, &period_ns); |
1533 | */ |
1534 | } |
1535 | |
1536 | if (ret) |
1537 | return -EINVAL; |
1538 | |
1539 | return reg; |
1540 | } |
1541 | EXPORT_SYMBOL_GPL(ni_tio_get_routing); |
1542 | |
1543 | /** |
1544 | * ni_tio_set_routing() - Sets the register value of the selector MUX for the given destination. |
1545 | * @counter_dev: Pointer to general counter device. |
1546 | * @dest: Device-global identifier of route destination. |
1547 | * @reg: |
1548 | * The first several bits of this value should store the desired |
1549 | * value to write to the register. All other bits are for |
1550 | * transmitting information that modify the mode of the particular |
1551 | * destination/gate. These mode bits might include a bitwise or of |
1552 | * CR_INVERT and CR_EDGE. Note that the calling function should |
1553 | * have already validated the correctness of this value. |
1554 | */ |
1555 | int ni_tio_set_routing(struct ni_gpct_device *counter_dev, unsigned int dest, |
1556 | unsigned int reg) |
1557 | { |
1558 | /* we need to know the actual counter below... */ |
1559 | int ctr_index = (dest - NI_COUNTER_NAMES_BASE) % NI_MAX_COUNTERS; |
1560 | struct ni_gpct *counter = &counter_dev->counters[ctr_index]; |
1561 | int ret; |
1562 | |
1563 | if (dest >= NI_CtrA(0) && dest <= NI_CtrZ(-1)) { |
1564 | ret = ni_tio_set_other_src(counter, index: dest, source: reg); |
1565 | } else if (dest >= NI_CtrGate(0) && dest <= NI_CtrGate(-1)) { |
1566 | ret = ni_tio_set_gate_src_raw(counter, 0, reg); |
1567 | } else if (dest >= NI_CtrAux(0) && dest <= NI_CtrAux(-1)) { |
1568 | ret = ni_tio_set_gate_src_raw(counter, 1, reg); |
1569 | /* |
1570 | * This case is not possible through this interface. A user must use |
1571 | * INSN_CONFIG_SET_CLOCK_SRC instead. |
1572 | * } else if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) { |
1573 | * ret = ni_tio_set_clock_src(counter, reg, period_ns); |
1574 | */ |
1575 | } else { |
1576 | return -EINVAL; |
1577 | } |
1578 | |
1579 | return ret; |
1580 | } |
1581 | EXPORT_SYMBOL_GPL(ni_tio_set_routing); |
1582 | |
1583 | /* |
1584 | * Sets the given destination MUX to its default value or disable it. |
1585 | * |
1586 | * Return: 0 if successful; -EINVAL if terminal is unknown. |
1587 | */ |
1588 | int ni_tio_unset_routing(struct ni_gpct_device *counter_dev, unsigned int dest) |
1589 | { |
1590 | if (dest >= NI_GATES_NAMES_BASE && dest <= NI_GATES_NAMES_MAX) |
1591 | /* Disable gate (via mode bits) and set to default 0-value */ |
1592 | return ni_tio_set_routing(counter_dev, dest, |
1593 | NI_GPCT_DISABLED_GATE_SELECT); |
1594 | /* |
1595 | * This case is not possible through this interface. A user must use |
1596 | * INSN_CONFIG_SET_CLOCK_SRC instead. |
1597 | * if (dest >= NI_CtrSource(0) && dest <= NI_CtrSource(-1)) |
1598 | * return ni_tio_set_clock_src(counter, reg, period_ns); |
1599 | */ |
1600 | |
1601 | return -EINVAL; |
1602 | } |
1603 | EXPORT_SYMBOL_GPL(ni_tio_unset_routing); |
1604 | |
1605 | static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev, |
1606 | struct comedi_subdevice *s) |
1607 | { |
1608 | struct ni_gpct *counter = s->private; |
1609 | unsigned int cidx = counter->counter_index; |
1610 | unsigned int val; |
1611 | |
1612 | ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); |
1613 | ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), |
1614 | GI_SAVE_TRACE, GI_SAVE_TRACE); |
1615 | |
1616 | /* |
1617 | * The count doesn't get latched until the next clock edge, so it is |
1618 | * possible the count may change (once) while we are reading. Since |
1619 | * the read of the SW_Save_Reg isn't atomic (apparently even when it's |
1620 | * a 32 bit register according to 660x docs), we need to read twice |
1621 | * and make sure the reading hasn't changed. If it has, a third read |
1622 | * will be correct since the count value will definitely have latched |
1623 | * by then. |
1624 | */ |
1625 | val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)); |
1626 | if (val != ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx))) |
1627 | val = ni_tio_read(counter, NITIO_SW_SAVE_REG(cidx)); |
1628 | |
1629 | return val; |
1630 | } |
1631 | |
1632 | int ni_tio_insn_read(struct comedi_device *dev, |
1633 | struct comedi_subdevice *s, |
1634 | struct comedi_insn *insn, |
1635 | unsigned int *data) |
1636 | { |
1637 | struct ni_gpct *counter = s->private; |
1638 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1639 | unsigned int channel = CR_CHAN(insn->chanspec); |
1640 | unsigned int cidx = counter->counter_index; |
1641 | unsigned int chip = counter->chip_index; |
1642 | int i; |
1643 | |
1644 | for (i = 0; i < insn->n; i++) { |
1645 | switch (channel) { |
1646 | case 0: |
1647 | data[i] = ni_tio_read_sw_save_reg(dev, s); |
1648 | break; |
1649 | case 1: |
1650 | data[i] = |
1651 | counter_dev->regs[chip][NITIO_LOADA_REG(cidx)]; |
1652 | break; |
1653 | case 2: |
1654 | data[i] = |
1655 | counter_dev->regs[chip][NITIO_LOADB_REG(cidx)]; |
1656 | break; |
1657 | } |
1658 | } |
1659 | return insn->n; |
1660 | } |
1661 | EXPORT_SYMBOL_GPL(ni_tio_insn_read); |
1662 | |
1663 | static unsigned int ni_tio_next_load_register(struct ni_gpct *counter) |
1664 | { |
1665 | unsigned int cidx = counter->counter_index; |
1666 | unsigned int bits = ni_tio_read(counter, NITIO_SHARED_STATUS_REG(cidx)); |
1667 | |
1668 | return (bits & GI_NEXT_LOAD_SRC(cidx)) |
1669 | ? NITIO_LOADB_REG(cidx) |
1670 | : NITIO_LOADA_REG(cidx); |
1671 | } |
1672 | |
1673 | int ni_tio_insn_write(struct comedi_device *dev, |
1674 | struct comedi_subdevice *s, |
1675 | struct comedi_insn *insn, |
1676 | unsigned int *data) |
1677 | { |
1678 | struct ni_gpct *counter = s->private; |
1679 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1680 | unsigned int channel = CR_CHAN(insn->chanspec); |
1681 | unsigned int cidx = counter->counter_index; |
1682 | unsigned int chip = counter->chip_index; |
1683 | unsigned int load_reg; |
1684 | unsigned int load_val; |
1685 | |
1686 | if (insn->n < 1) |
1687 | return 0; |
1688 | load_val = data[insn->n - 1]; |
1689 | switch (channel) { |
1690 | case 0: |
1691 | /* |
1692 | * Unsafe if counter is armed. |
1693 | * Should probably check status and return -EBUSY if armed. |
1694 | */ |
1695 | |
1696 | /* |
1697 | * Don't disturb load source select, just use whichever |
1698 | * load register is already selected. |
1699 | */ |
1700 | load_reg = ni_tio_next_load_register(counter); |
1701 | ni_tio_write(counter, load_val, load_reg); |
1702 | ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx), |
1703 | mask: 0, value: 0, GI_LOAD); |
1704 | /* restore load reg */ |
1705 | ni_tio_write(counter, counter_dev->regs[chip][load_reg], |
1706 | load_reg); |
1707 | break; |
1708 | case 1: |
1709 | counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = load_val; |
1710 | ni_tio_write(counter, load_val, NITIO_LOADA_REG(cidx)); |
1711 | break; |
1712 | case 2: |
1713 | counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = load_val; |
1714 | ni_tio_write(counter, load_val, NITIO_LOADB_REG(cidx)); |
1715 | break; |
1716 | default: |
1717 | return -EINVAL; |
1718 | } |
1719 | return insn->n; |
1720 | } |
1721 | EXPORT_SYMBOL_GPL(ni_tio_insn_write); |
1722 | |
1723 | void ni_tio_init_counter(struct ni_gpct *counter) |
1724 | { |
1725 | struct ni_gpct_device *counter_dev = counter->counter_dev; |
1726 | unsigned int cidx = counter->counter_index; |
1727 | unsigned int chip = counter->chip_index; |
1728 | |
1729 | ni_tio_reset_count_and_disarm(counter); |
1730 | |
1731 | /* initialize counter registers */ |
1732 | counter_dev->regs[chip][NITIO_AUTO_INC_REG(cidx)] = 0x0; |
1733 | ni_tio_write(counter, 0x0, NITIO_AUTO_INC_REG(cidx)); |
1734 | |
1735 | ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), |
1736 | ~0, GI_SYNC_GATE); |
1737 | |
1738 | ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0); |
1739 | |
1740 | counter_dev->regs[chip][NITIO_LOADA_REG(cidx)] = 0x0; |
1741 | ni_tio_write(counter, 0x0, NITIO_LOADA_REG(cidx)); |
1742 | |
1743 | counter_dev->regs[chip][NITIO_LOADB_REG(cidx)] = 0x0; |
1744 | ni_tio_write(counter, 0x0, NITIO_LOADB_REG(cidx)); |
1745 | |
1746 | ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0); |
1747 | |
1748 | if (ni_tio_counting_mode_registers_present(counter_dev)) |
1749 | ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0); |
1750 | |
1751 | if (ni_tio_has_gate2_registers(counter_dev)) { |
1752 | counter_dev->regs[chip][NITIO_GATE2_REG(cidx)] = 0x0; |
1753 | ni_tio_write(counter, 0x0, NITIO_GATE2_REG(cidx)); |
1754 | } |
1755 | |
1756 | ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0); |
1757 | |
1758 | ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0); |
1759 | } |
1760 | EXPORT_SYMBOL_GPL(ni_tio_init_counter); |
1761 | |
1762 | struct ni_gpct_device * |
1763 | ni_gpct_device_construct(struct comedi_device *dev, |
1764 | void (*write)(struct ni_gpct *counter, |
1765 | unsigned int value, |
1766 | enum ni_gpct_register reg), |
1767 | unsigned int (*read)(struct ni_gpct *counter, |
1768 | enum ni_gpct_register reg), |
1769 | enum ni_gpct_variant variant, |
1770 | unsigned int num_counters, |
1771 | unsigned int counters_per_chip, |
1772 | const struct ni_route_tables *routing_tables) |
1773 | { |
1774 | struct ni_gpct_device *counter_dev; |
1775 | struct ni_gpct *counter; |
1776 | unsigned int i; |
1777 | |
1778 | if (num_counters == 0 || counters_per_chip == 0) |
1779 | return NULL; |
1780 | |
1781 | counter_dev = kzalloc(size: sizeof(*counter_dev), GFP_KERNEL); |
1782 | if (!counter_dev) |
1783 | return NULL; |
1784 | |
1785 | counter_dev->dev = dev; |
1786 | counter_dev->write = write; |
1787 | counter_dev->read = read; |
1788 | counter_dev->variant = variant; |
1789 | counter_dev->routing_tables = routing_tables; |
1790 | |
1791 | spin_lock_init(&counter_dev->regs_lock); |
1792 | |
1793 | counter_dev->num_counters = num_counters; |
1794 | counter_dev->num_chips = DIV_ROUND_UP(num_counters, counters_per_chip); |
1795 | |
1796 | counter_dev->counters = kcalloc(n: num_counters, size: sizeof(*counter), |
1797 | GFP_KERNEL); |
1798 | counter_dev->regs = kcalloc(n: counter_dev->num_chips, |
1799 | size: sizeof(*counter_dev->regs), GFP_KERNEL); |
1800 | if (!counter_dev->regs || !counter_dev->counters) { |
1801 | kfree(objp: counter_dev->regs); |
1802 | kfree(objp: counter_dev->counters); |
1803 | kfree(objp: counter_dev); |
1804 | return NULL; |
1805 | } |
1806 | |
1807 | for (i = 0; i < num_counters; ++i) { |
1808 | counter = &counter_dev->counters[i]; |
1809 | counter->counter_dev = counter_dev; |
1810 | counter->chip_index = i / counters_per_chip; |
1811 | counter->counter_index = i % counters_per_chip; |
1812 | spin_lock_init(&counter->lock); |
1813 | } |
1814 | |
1815 | return counter_dev; |
1816 | } |
1817 | EXPORT_SYMBOL_GPL(ni_gpct_device_construct); |
1818 | |
1819 | void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev) |
1820 | { |
1821 | if (!counter_dev) |
1822 | return; |
1823 | kfree(objp: counter_dev->regs); |
1824 | kfree(objp: counter_dev->counters); |
1825 | kfree(objp: counter_dev); |
1826 | } |
1827 | EXPORT_SYMBOL_GPL(ni_gpct_device_destroy); |
1828 | |
1829 | static int __init ni_tio_init_module(void) |
1830 | { |
1831 | return 0; |
1832 | } |
1833 | module_init(ni_tio_init_module); |
1834 | |
1835 | static void __exit ni_tio_cleanup_module(void) |
1836 | { |
1837 | } |
1838 | module_exit(ni_tio_cleanup_module); |
1839 | |
1840 | MODULE_AUTHOR("Comedi <comedi@comedi.org>" ); |
1841 | MODULE_DESCRIPTION("Comedi support for NI general-purpose counters" ); |
1842 | MODULE_LICENSE("GPL" ); |
1843 | |