staging: comedi: comedi_test: simplify time since last AI scan
[deliverable/linux.git] / drivers / staging / comedi / drivers / ni_tio.c
CommitLineData
cb7859a9
FMH
1/*
2 comedi/drivers/ni_tio.c
3 Support for NI general purpose counters
4
5 Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
cb7859a9
FMH
16*/
17
18/*
9ade47ab
IA
19 * Module: ni_tio
20 * Description: National Instruments general purpose counters
21 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
22 * Herman.Bruyninckx@mech.kuleuven.ac.be,
23 * Wim.Meeussen@mech.kuleuven.ac.be,
24 * Klaas.Gadeyne@mech.kuleuven.ac.be,
25 * Frank Mori Hess <fmhess@users.sourceforge.net>
26 * Updated: Thu Nov 16 09:50:32 EST 2006
27 * Status: works
28 *
29 * This module is not used directly by end-users. Rather, it
30 * is used by other drivers (for example ni_660x and ni_pcimio)
31 * to provide support for NI's general purpose counters. It was
32 * originally based on the counter code from ni_660x.c and
33 * ni_mio_common.c.
34 *
35 * References:
36 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
37 * DAQ 6601/6602 User Manual (NI 322137B-01)
38 * 340934b.pdf DAQ-STC reference manual
39 */
cb7859a9 40
cb7859a9
FMH
41/*
42TODO:
43 Support use of both banks X and Y
44*/
45
ce157f80 46#include <linux/module.h>
0bdab509
HS
47#include <linux/slab.h>
48
cb7859a9
FMH
49#include "ni_tio_internal.h"
50
9ff506ec
HS
51/*
52 * clock sources for ni e and m series boards,
c2c6c288 53 * get bits with GI_SRC_SEL()
9ff506ec
HS
54 */
55#define NI_M_TIMEBASE_1_CLK 0x0 /* 20MHz */
56#define NI_M_PFI_CLK(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
57#define NI_M_RTSI_CLK(x) (((x) == 7) ? 0x1b : (0xb + (x)))
58#define NI_M_TIMEBASE_2_CLK 0x12 /* 100KHz */
59#define NI_M_NEXT_TC_CLK 0x13
60#define NI_M_NEXT_GATE_CLK 0x14 /* Gi_Src_SubSelect=0 */
61#define NI_M_PXI_STAR_TRIGGER_CLK 0x14 /* Gi_Src_SubSelect=1 */
62#define NI_M_PXI10_CLK 0x1d
63#define NI_M_TIMEBASE_3_CLK 0x1e /* 80MHz, Gi_Src_SubSelect=0 */
64#define NI_M_ANALOG_TRIGGER_OUT_CLK 0x1e /* Gi_Src_SubSelect=1 */
65#define NI_M_LOGIC_LOW_CLK 0x1f
66#define NI_M_MAX_PFI_CHAN 15
67#define NI_M_MAX_RTSI_CHAN 7
68
69/*
70 * clock sources for ni_660x boards,
c2c6c288 71 * get bits with GI_SRC_SEL()
9ff506ec
HS
72 */
73#define NI_660X_TIMEBASE_1_CLK 0x0 /* 20MHz */
74#define NI_660X_SRC_PIN_I_CLK 0x1
75#define NI_660X_SRC_PIN_CLK(x) (0x2 + (x))
76#define NI_660X_NEXT_GATE_CLK 0xa
77#define NI_660X_RTSI_CLK(x) (0xb + (x))
78#define NI_660X_TIMEBASE_2_CLK 0x12 /* 100KHz */
79#define NI_660X_NEXT_TC_CLK 0x13
80#define NI_660X_TIMEBASE_3_CLK 0x1e /* 80MHz */
81#define NI_660X_LOGIC_LOW_CLK 0x1f
82#define NI_660X_MAX_SRC_PIN 7
83#define NI_660X_MAX_RTSI_CHAN 6
84
85/* ni m series gate_select */
86#define NI_M_TIMESTAMP_MUX_GATE_SEL 0x0
87#define NI_M_PFI_GATE_SEL(x) (((x) < 10) ? (1 + (x)) : (0xb + (x)))
88#define NI_M_RTSI_GATE_SEL(x) (((x) == 7) ? 0x1b : (0xb + (x)))
89#define NI_M_AI_START2_GATE_SEL 0x12
90#define NI_M_PXI_STAR_TRIGGER_GATE_SEL 0x13
91#define NI_M_NEXT_OUT_GATE_SEL 0x14
92#define NI_M_AI_START1_GATE_SEL 0x1c
93#define NI_M_NEXT_SRC_GATE_SEL 0x1d
94#define NI_M_ANALOG_TRIG_OUT_GATE_SEL 0x1e
95#define NI_M_LOGIC_LOW_GATE_SEL 0x1f
96
97/* ni_660x gate select */
98#define NI_660X_SRC_PIN_I_GATE_SEL 0x0
99#define NI_660X_GATE_PIN_I_GATE_SEL 0x1
100#define NI_660X_PIN_GATE_SEL(x) (0x2 + (x))
101#define NI_660X_NEXT_SRC_GATE_SEL 0xa
102#define NI_660X_RTSI_GATE_SEL(x) (0xb + (x))
103#define NI_660X_NEXT_OUT_GATE_SEL 0x14
104#define NI_660X_LOGIC_LOW_GATE_SEL 0x1f
105#define NI_660X_MAX_GATE_PIN 7
106
107/* ni_660x second gate select */
108#define NI_660X_SRC_PIN_I_GATE2_SEL 0x0
109#define NI_660X_UD_PIN_I_GATE2_SEL 0x1
110#define NI_660X_UD_PIN_GATE2_SEL(x) (0x2 + (x))
111#define NI_660X_NEXT_SRC_GATE2_SEL 0xa
112#define NI_660X_RTSI_GATE2_SEL(x) (0xb + (x))
113#define NI_660X_NEXT_OUT_GATE2_SEL 0x14
114#define NI_660X_SELECTED_GATE2_SEL 0x1e
115#define NI_660X_LOGIC_LOW_GATE2_SEL 0x1f
116#define NI_660X_MAX_UP_DOWN_PIN 7
117
ed404871 118static inline unsigned GI_ALT_SYNC(enum ni_gpct_variant variant)
cb7859a9
FMH
119{
120 switch (variant) {
121 case ni_gpct_variant_e_series:
85603161 122 default:
cb7859a9 123 return 0;
cb7859a9 124 case ni_gpct_variant_m_series:
ed404871 125 return GI_M_ALT_SYNC;
cb7859a9 126 case ni_gpct_variant_660x:
ed404871 127 return GI_660X_ALT_SYNC;
cb7859a9 128 }
cb7859a9 129}
0a85b6f0 130
ed404871 131static inline unsigned GI_PRESCALE_X2(enum ni_gpct_variant variant)
cb7859a9
FMH
132{
133 switch (variant) {
134 case ni_gpct_variant_e_series:
85603161 135 default:
cb7859a9 136 return 0;
cb7859a9 137 case ni_gpct_variant_m_series:
ed404871 138 return GI_M_PRESCALE_X2;
cb7859a9 139 case ni_gpct_variant_660x:
ed404871 140 return GI_660X_PRESCALE_X2;
cb7859a9 141 }
cb7859a9 142}
0a85b6f0 143
ed404871 144static inline unsigned GI_PRESCALE_X8(enum ni_gpct_variant variant)
cb7859a9
FMH
145{
146 switch (variant) {
147 case ni_gpct_variant_e_series:
85603161 148 default:
cb7859a9 149 return 0;
cb7859a9 150 case ni_gpct_variant_m_series:
ed404871 151 return GI_M_PRESCALE_X8;
cb7859a9 152 case ni_gpct_variant_660x:
ed404871 153 return GI_660X_PRESCALE_X8;
cb7859a9 154 }
cb7859a9 155}
0a85b6f0 156
ed404871 157static inline unsigned GI_HW_ARM_SEL_MASK(enum ni_gpct_variant variant)
cb7859a9
FMH
158{
159 switch (variant) {
160 case ni_gpct_variant_e_series:
85603161 161 default:
cb7859a9 162 return 0;
cb7859a9 163 case ni_gpct_variant_m_series:
ed404871 164 return GI_M_HW_ARM_SEL_MASK;
cb7859a9 165 case ni_gpct_variant_660x:
ed404871 166 return GI_660X_HW_ARM_SEL_MASK;
cb7859a9 167 }
cb7859a9
FMH
168}
169
abfe2196 170static bool ni_tio_has_gate2_registers(const struct ni_gpct_device *counter_dev)
cb7859a9
FMH
171{
172 switch (counter_dev->variant) {
173 case ni_gpct_variant_e_series:
85603161 174 default:
abfe2196 175 return false;
cb7859a9
FMH
176 case ni_gpct_variant_m_series:
177 case ni_gpct_variant_660x:
abfe2196 178 return true;
cb7859a9 179 }
cb7859a9
FMH
180}
181
182static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
183{
fca7c1d7
HS
184 unsigned cidx = counter->counter_index;
185
dc613766 186 write_register(counter, GI_RESET(cidx), NITIO_RESET_REG(cidx));
cb7859a9
FMH
187}
188
099286dc
HS
189static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
190 unsigned generic_clock_source)
191{
192 uint64_t clock_period_ps;
193
194 switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
195 case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
196 clock_period_ps = 50000;
197 break;
198 case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
199 clock_period_ps = 10000000;
200 break;
201 case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
202 clock_period_ps = 12500;
203 break;
204 case NI_GPCT_PXI10_CLOCK_SRC_BITS:
205 clock_period_ps = 100000;
206 break;
207 default:
208 /*
209 * clock period is specified by user with prescaling
210 * already taken into account.
211 */
212 return counter->clock_period_ps;
213 }
214
215 switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
216 case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
217 break;
218 case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
219 clock_period_ps *= 2;
220 break;
221 case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
222 clock_period_ps *= 8;
223 break;
224 default:
225 BUG();
226 break;
227 }
228 return clock_period_ps;
229}
230
231static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
232{
233 struct ni_gpct_device *counter_dev = counter->counter_dev;
234 unsigned cidx = counter->counter_index;
235 const unsigned counting_mode_bits =
236 ni_tio_get_soft_copy(counter, NITIO_CNT_MODE_REG(cidx));
237 unsigned bits = 0;
238
239 if (ni_tio_get_soft_copy(counter, NITIO_INPUT_SEL_REG(cidx)) &
c2c6c288 240 GI_SRC_POL_INVERT)
099286dc 241 bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
ed404871 242 if (counting_mode_bits & GI_PRESCALE_X2(counter_dev->variant))
099286dc 243 bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
ed404871 244 if (counting_mode_bits & GI_PRESCALE_X8(counter_dev->variant))
099286dc
HS
245 bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
246 return bits;
247}
248
249static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
250{
251 struct ni_gpct_device *counter_dev = counter->counter_dev;
252 unsigned cidx = counter->counter_index;
253 const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
254 unsigned clock_source = 0;
c2c6c288 255 unsigned src;
099286dc 256 unsigned i;
099286dc 257
c2c6c288
HS
258 src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
259 NITIO_INPUT_SEL_REG(cidx)));
260
261 switch (src) {
099286dc
HS
262 case NI_M_TIMEBASE_1_CLK:
263 clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
264 break;
265 case NI_M_TIMEBASE_2_CLK:
266 clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
267 break;
268 case NI_M_TIMEBASE_3_CLK:
4359dcf3 269 if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
099286dc
HS
270 clock_source =
271 NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
272 else
273 clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
274 break;
275 case NI_M_LOGIC_LOW_CLK:
276 clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
277 break;
278 case NI_M_NEXT_GATE_CLK:
4359dcf3 279 if (counter_dev->regs[second_gate_reg] & GI_SRC_SUBSEL)
099286dc
HS
280 clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
281 else
282 clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
283 break;
284 case NI_M_PXI10_CLK:
285 clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
286 break;
287 case NI_M_NEXT_TC_CLK:
288 clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
289 break;
290 default:
291 for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
c2c6c288 292 if (src == NI_M_RTSI_CLK(i)) {
099286dc
HS
293 clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
294 break;
295 }
296 }
297 if (i <= NI_M_MAX_RTSI_CHAN)
298 break;
299 for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
c2c6c288 300 if (src == NI_M_PFI_CLK(i)) {
099286dc
HS
301 clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
302 break;
303 }
304 }
305 if (i <= NI_M_MAX_PFI_CHAN)
306 break;
307 BUG();
308 break;
309 }
310 clock_source |= ni_tio_clock_src_modifiers(counter);
311 return clock_source;
312}
313
314static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
315{
316 unsigned clock_source = 0;
317 unsigned cidx = counter->counter_index;
c2c6c288 318 unsigned src;
099286dc
HS
319 unsigned i;
320
c2c6c288
HS
321 src = GI_BITS_TO_SRC(ni_tio_get_soft_copy(counter,
322 NITIO_INPUT_SEL_REG(cidx)));
323
324 switch (src) {
099286dc
HS
325 case NI_660X_TIMEBASE_1_CLK:
326 clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
327 break;
328 case NI_660X_TIMEBASE_2_CLK:
329 clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
330 break;
331 case NI_660X_TIMEBASE_3_CLK:
332 clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
333 break;
334 case NI_660X_LOGIC_LOW_CLK:
335 clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
336 break;
337 case NI_660X_SRC_PIN_I_CLK:
338 clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
339 break;
340 case NI_660X_NEXT_GATE_CLK:
341 clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
342 break;
343 case NI_660X_NEXT_TC_CLK:
344 clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
345 break;
346 default:
347 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
c2c6c288 348 if (src == NI_660X_RTSI_CLK(i)) {
099286dc
HS
349 clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
350 break;
351 }
352 }
353 if (i <= NI_660X_MAX_RTSI_CHAN)
354 break;
355 for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
c2c6c288 356 if (src == NI_660X_SRC_PIN_CLK(i)) {
099286dc
HS
357 clock_source =
358 NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
359 break;
360 }
361 }
362 if (i <= NI_660X_MAX_SRC_PIN)
363 break;
364 BUG();
365 break;
366 }
367 clock_source |= ni_tio_clock_src_modifiers(counter);
368 return clock_source;
369}
370
371static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
372{
373 switch (counter->counter_dev->variant) {
374 case ni_gpct_variant_e_series:
375 case ni_gpct_variant_m_series:
376 default:
377 return ni_m_series_clock_src_select(counter);
378 case ni_gpct_variant_660x:
379 return ni_660x_clock_src_select(counter);
380 }
381}
382
cb7859a9
FMH
383static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
384{
385 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7
HS
386 unsigned cidx = counter->counter_index;
387 const unsigned counting_mode_reg = NITIO_CNT_MODE_REG(cidx);
cb7859a9 388 static const uint64_t min_normal_sync_period_ps = 25000;
ed404871 389 unsigned mode;
f6e22783 390 uint64_t clock_period_ps;
cb7859a9
FMH
391
392 if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
393 return;
394
ed404871
HS
395 mode = ni_tio_get_soft_copy(counter, counting_mode_reg);
396 switch (mode & GI_CNT_MODE_MASK) {
397 case GI_CNT_MODE_QUADX1:
398 case GI_CNT_MODE_QUADX2:
399 case GI_CNT_MODE_QUADX4:
400 case GI_CNT_MODE_SYNC_SRC:
cb7859a9
FMH
401 force_alt_sync = 1;
402 break;
403 default:
404 break;
405 }
f6e22783
HS
406
407 clock_period_ps = ni_tio_clock_period_ps(counter,
408 ni_tio_generic_clock_src_select(counter));
409
14f194a9
HS
410 /*
411 * It's not clear what we should do if clock_period is unknown, so we
412 * are not using the alt sync bit in that case, but allow the caller
413 * to decide by using the force_alt_sync parameter.
414 */
cb7859a9 415 if (force_alt_sync ||
0a85b6f0 416 (clock_period_ps && clock_period_ps < min_normal_sync_period_ps)) {
cb7859a9 417 ni_tio_set_bits(counter, counting_mode_reg,
ed404871
HS
418 GI_ALT_SYNC(counter_dev->variant),
419 GI_ALT_SYNC(counter_dev->variant));
cb7859a9
FMH
420 } else {
421 ni_tio_set_bits(counter, counting_mode_reg,
ed404871 422 GI_ALT_SYNC(counter_dev->variant),
0a85b6f0 423 0x0);
cb7859a9
FMH
424 }
425}
426
427static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
428{
429 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 430 unsigned cidx = counter->counter_index;
cb7859a9
FMH
431 unsigned mode_reg_mask;
432 unsigned mode_reg_values;
433 unsigned input_select_bits = 0;
434 /* these bits map directly on to the mode register */
435 static const unsigned mode_reg_direct_mask =
0a85b6f0
MT
436 NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
437 NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
438 NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
439 NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
cb7859a9 440
36d80f4a 441 mode_reg_mask = mode_reg_direct_mask | GI_RELOAD_SRC_SWITCHING;
cb7859a9
FMH
442 mode_reg_values = mode & mode_reg_direct_mask;
443 switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
444 case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
445 break;
446 case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
36d80f4a 447 mode_reg_values |= GI_RELOAD_SRC_SWITCHING;
cb7859a9
FMH
448 break;
449 case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
c2c6c288 450 input_select_bits |= GI_GATE_SEL_LOAD_SRC;
36d80f4a
HS
451 mode_reg_mask |= GI_GATING_MODE_MASK;
452 mode_reg_values |= GI_LEVEL_GATING;
cb7859a9
FMH
453 break;
454 default:
455 break;
456 }
fca7c1d7 457 ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
0a85b6f0 458 mode_reg_mask, mode_reg_values);
cb7859a9
FMH
459
460 if (ni_tio_counting_mode_registers_present(counter_dev)) {
ed404871
HS
461 unsigned bits = 0;
462
463 bits |= GI_CNT_MODE(mode >> NI_GPCT_COUNTING_MODE_SHIFT);
464 bits |= GI_INDEX_PHASE((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT));
3d34023a 465 if (mode & NI_GPCT_INDEX_ENABLE_BIT)
ed404871 466 bits |= GI_INDEX_MODE;
fca7c1d7 467 ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
ed404871
HS
468 GI_CNT_MODE_MASK | GI_INDEX_PHASE_MASK |
469 GI_INDEX_MODE, bits);
cb7859a9
FMH
470 ni_tio_set_sync_mode(counter, 0);
471 }
472
b9a09764
HS
473 ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_CNT_DIR_MASK,
474 GI_CNT_DIR(mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT));
cb7859a9 475
3d34023a 476 if (mode & NI_GPCT_OR_GATE_BIT)
c2c6c288 477 input_select_bits |= GI_OR_GATE;
3d34023a 478 if (mode & NI_GPCT_INVERT_OUTPUT_BIT)
c2c6c288 479 input_select_bits |= GI_OUTPUT_POL_INVERT;
fca7c1d7 480 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
c2c6c288
HS
481 GI_GATE_SEL_LOAD_SRC | GI_OR_GATE |
482 GI_OUTPUT_POL_INVERT, input_select_bits);
cb7859a9
FMH
483
484 return 0;
485}
486
487int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
488{
489 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 490 unsigned cidx = counter->counter_index;
cb7859a9
FMH
491 unsigned command_transient_bits = 0;
492
493 if (arm) {
494 switch (start_trigger) {
495 case NI_GPCT_ARM_IMMEDIATE:
b9a09764 496 command_transient_bits |= GI_ARM;
cb7859a9
FMH
497 break;
498 case NI_GPCT_ARM_PAIRED_IMMEDIATE:
b9a09764 499 command_transient_bits |= GI_ARM | GI_ARM_COPY;
cb7859a9
FMH
500 break;
501 default:
502 break;
503 }
504 if (ni_tio_counting_mode_registers_present(counter_dev)) {
ed404871
HS
505 unsigned bits = 0;
506 unsigned sel_mask;
507
508 sel_mask = GI_HW_ARM_SEL_MASK(counter_dev->variant);
cb7859a9
FMH
509
510 switch (start_trigger) {
511 case NI_GPCT_ARM_IMMEDIATE:
512 case NI_GPCT_ARM_PAIRED_IMMEDIATE:
513 break;
514 default:
515 if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
14f194a9
HS
516 /*
517 * pass-through the least significant
518 * bits so we can figure out what
519 * select later
520 */
ed404871
HS
521 bits |= GI_HW_ARM_ENA |
522 (GI_HW_ARM_SEL(start_trigger) &
523 sel_mask);
cb7859a9
FMH
524 } else {
525 return -EINVAL;
526 }
527 break;
528 }
fca7c1d7 529 ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
ed404871 530 GI_HW_ARM_ENA | sel_mask, bits);
cb7859a9
FMH
531 }
532 } else {
b9a09764 533 command_transient_bits |= GI_DISARM;
cb7859a9 534 }
fca7c1d7 535 ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
0a85b6f0 536 0, 0, command_transient_bits);
cb7859a9
FMH
537 return 0;
538}
3d34023a 539EXPORT_SYMBOL_GPL(ni_tio_arm);
cb7859a9 540
3e90b1c7 541static unsigned ni_660x_clk_src(unsigned int clock_source)
cb7859a9 542{
463daa7f 543 unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
cb7859a9
FMH
544 unsigned ni_660x_clock;
545 unsigned i;
cb7859a9 546
463daa7f 547 switch (clk_src) {
cb7859a9 548 case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
b8e58af6 549 ni_660x_clock = NI_660X_TIMEBASE_1_CLK;
cb7859a9
FMH
550 break;
551 case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
b8e58af6 552 ni_660x_clock = NI_660X_TIMEBASE_2_CLK;
cb7859a9
FMH
553 break;
554 case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
b8e58af6 555 ni_660x_clock = NI_660X_TIMEBASE_3_CLK;
cb7859a9
FMH
556 break;
557 case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
b8e58af6 558 ni_660x_clock = NI_660X_LOGIC_LOW_CLK;
cb7859a9
FMH
559 break;
560 case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
b8e58af6 561 ni_660x_clock = NI_660X_SRC_PIN_I_CLK;
cb7859a9
FMH
562 break;
563 case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
b8e58af6 564 ni_660x_clock = NI_660X_NEXT_GATE_CLK;
cb7859a9
FMH
565 break;
566 case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
b8e58af6 567 ni_660x_clock = NI_660X_NEXT_TC_CLK;
cb7859a9
FMH
568 break;
569 default:
eca7d872 570 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
463daa7f 571 if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
288cb1a8 572 ni_660x_clock = NI_660X_RTSI_CLK(i);
cb7859a9
FMH
573 break;
574 }
575 }
eca7d872 576 if (i <= NI_660X_MAX_RTSI_CHAN)
cb7859a9 577 break;
eca7d872 578 for (i = 0; i <= NI_660X_MAX_SRC_PIN; ++i) {
463daa7f 579 if (clk_src == NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
cdf4fce4 580 ni_660x_clock = NI_660X_SRC_PIN_CLK(i);
cb7859a9
FMH
581 break;
582 }
583 }
eca7d872 584 if (i <= NI_660X_MAX_SRC_PIN)
cb7859a9
FMH
585 break;
586 ni_660x_clock = 0;
587 BUG();
588 break;
589 }
c2c6c288 590 return GI_SRC_SEL(ni_660x_clock);
cb7859a9
FMH
591}
592
3e90b1c7 593static unsigned ni_m_clk_src(unsigned int clock_source)
cb7859a9 594{
99065954 595 unsigned clk_src = clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
cb7859a9
FMH
596 unsigned ni_m_series_clock;
597 unsigned i;
99065954
HS
598
599 switch (clk_src) {
cb7859a9 600 case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
c93a7406 601 ni_m_series_clock = NI_M_TIMEBASE_1_CLK;
cb7859a9
FMH
602 break;
603 case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
c93a7406 604 ni_m_series_clock = NI_M_TIMEBASE_2_CLK;
cb7859a9
FMH
605 break;
606 case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
c93a7406 607 ni_m_series_clock = NI_M_TIMEBASE_3_CLK;
cb7859a9
FMH
608 break;
609 case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
c93a7406 610 ni_m_series_clock = NI_M_LOGIC_LOW_CLK;
cb7859a9
FMH
611 break;
612 case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
c93a7406 613 ni_m_series_clock = NI_M_NEXT_GATE_CLK;
cb7859a9
FMH
614 break;
615 case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
c93a7406 616 ni_m_series_clock = NI_M_NEXT_TC_CLK;
cb7859a9
FMH
617 break;
618 case NI_GPCT_PXI10_CLOCK_SRC_BITS:
c93a7406 619 ni_m_series_clock = NI_M_PXI10_CLK;
cb7859a9
FMH
620 break;
621 case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
c93a7406 622 ni_m_series_clock = NI_M_PXI_STAR_TRIGGER_CLK;
cb7859a9
FMH
623 break;
624 case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
c93a7406 625 ni_m_series_clock = NI_M_ANALOG_TRIGGER_OUT_CLK;
cb7859a9
FMH
626 break;
627 default:
eca7d872 628 for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
99065954 629 if (clk_src == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
9f9d6446 630 ni_m_series_clock = NI_M_RTSI_CLK(i);
cb7859a9
FMH
631 break;
632 }
633 }
eca7d872 634 if (i <= NI_M_MAX_RTSI_CHAN)
cb7859a9 635 break;
eca7d872 636 for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
99065954 637 if (clk_src == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
1649d56d 638 ni_m_series_clock = NI_M_PFI_CLK(i);
cb7859a9
FMH
639 break;
640 }
641 }
eca7d872 642 if (i <= NI_M_MAX_PFI_CHAN)
cb7859a9 643 break;
0748e362 644 pr_err("invalid clock source 0x%lx\n",
0a85b6f0 645 (unsigned long)clock_source);
cb7859a9
FMH
646 BUG();
647 ni_m_series_clock = 0;
648 break;
649 }
c2c6c288 650 return GI_SRC_SEL(ni_m_series_clock);
cb7859a9
FMH
651};
652
653static void ni_tio_set_source_subselect(struct ni_gpct *counter,
0a85b6f0 654 unsigned int clock_source)
cb7859a9
FMH
655{
656 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7
HS
657 unsigned cidx = counter->counter_index;
658 const unsigned second_gate_reg = NITIO_GATE2_REG(cidx);
cb7859a9
FMH
659
660 if (counter_dev->variant != ni_gpct_variant_m_series)
661 return;
662 switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
663 /* Gi_Source_Subselect is zero */
664 case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
665 case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
4359dcf3 666 counter_dev->regs[second_gate_reg] &= ~GI_SRC_SUBSEL;
cb7859a9
FMH
667 break;
668 /* Gi_Source_Subselect is one */
669 case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
670 case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
4359dcf3 671 counter_dev->regs[second_gate_reg] |= GI_SRC_SUBSEL;
cb7859a9
FMH
672 break;
673 /* Gi_Source_Subselect doesn't matter */
674 default:
675 return;
cb7859a9
FMH
676 }
677 write_register(counter, counter_dev->regs[second_gate_reg],
0a85b6f0 678 second_gate_reg);
cb7859a9
FMH
679}
680
681static int ni_tio_set_clock_src(struct ni_gpct *counter,
0a85b6f0
MT
682 unsigned int clock_source,
683 unsigned int period_ns)
cb7859a9
FMH
684{
685 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 686 unsigned cidx = counter->counter_index;
3e90b1c7 687 unsigned bits = 0;
cb7859a9 688
3e90b1c7 689 /* FIXME: validate clock source */
cb7859a9
FMH
690 switch (counter_dev->variant) {
691 case ni_gpct_variant_660x:
3e90b1c7 692 bits |= ni_660x_clk_src(clock_source);
cb7859a9
FMH
693 break;
694 case ni_gpct_variant_e_series:
695 case ni_gpct_variant_m_series:
85603161 696 default:
3e90b1c7 697 bits |= ni_m_clk_src(clock_source);
cb7859a9 698 break;
cb7859a9
FMH
699 }
700 if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
c2c6c288 701 bits |= GI_SRC_POL_INVERT;
fca7c1d7 702 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
c2c6c288 703 GI_SRC_SEL_MASK | GI_SRC_POL_INVERT, bits);
cb7859a9 704 ni_tio_set_source_subselect(counter, clock_source);
cb7859a9 705
3e90b1c7
HS
706 if (ni_tio_counting_mode_registers_present(counter_dev)) {
707 bits = 0;
708 switch (clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
cb7859a9
FMH
709 case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
710 break;
711 case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
ed404871 712 bits |= GI_PRESCALE_X2(counter_dev->variant);
cb7859a9
FMH
713 break;
714 case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
ed404871 715 bits |= GI_PRESCALE_X8(counter_dev->variant);
cb7859a9
FMH
716 break;
717 default:
718 return -EINVAL;
cb7859a9 719 }
fca7c1d7 720 ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx),
ed404871
HS
721 GI_PRESCALE_X2(counter_dev->variant) |
722 GI_PRESCALE_X8(counter_dev->variant), bits);
cb7859a9 723 }
3e90b1c7 724 counter->clock_period_ps = period_ns * 1000;
cb7859a9
FMH
725 ni_tio_set_sync_mode(counter, 0);
726 return 0;
727}
728
cb7859a9 729static void ni_tio_get_clock_src(struct ni_gpct *counter,
0a85b6f0
MT
730 unsigned int *clock_source,
731 unsigned int *period_ns)
cb7859a9 732{
cb7859a9 733 uint64_t temp64;
f68d10c4 734
cb7859a9
FMH
735 *clock_source = ni_tio_generic_clock_src_select(counter);
736 temp64 = ni_tio_clock_period_ps(counter, *clock_source);
f68d10c4 737 do_div(temp64, 1000); /* ps to ns */
cb7859a9
FMH
738 *period_ns = temp64;
739}
740
d54bb5a7 741static int ni_660x_set_gate(struct ni_gpct *counter, unsigned int gate_source)
cb7859a9 742{
e09dd2c3 743 unsigned int chan = CR_CHAN(gate_source);
fca7c1d7 744 unsigned cidx = counter->counter_index;
e09dd2c3 745 unsigned gate_sel;
cb7859a9
FMH
746 unsigned i;
747
e09dd2c3 748 switch (chan) {
cb7859a9 749 case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
5a3d1ed8 750 gate_sel = NI_660X_NEXT_SRC_GATE_SEL;
cb7859a9
FMH
751 break;
752 case NI_GPCT_NEXT_OUT_GATE_SELECT:
753 case NI_GPCT_LOGIC_LOW_GATE_SELECT:
754 case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
755 case NI_GPCT_GATE_PIN_i_GATE_SELECT:
e09dd2c3 756 gate_sel = chan & 0x1f;
cb7859a9
FMH
757 break;
758 default:
eca7d872 759 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
e09dd2c3
HS
760 if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
761 gate_sel = chan & 0x1f;
cb7859a9
FMH
762 break;
763 }
764 }
eca7d872 765 if (i <= NI_660X_MAX_RTSI_CHAN)
cb7859a9 766 break;
eca7d872 767 for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
e09dd2c3
HS
768 if (chan == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
769 gate_sel = chan & 0x1f;
cb7859a9
FMH
770 break;
771 }
772 }
eca7d872 773 if (i <= NI_660X_MAX_GATE_PIN)
cb7859a9
FMH
774 break;
775 return -EINVAL;
cb7859a9 776 }
fca7c1d7 777 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
c2c6c288 778 GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
cb7859a9
FMH
779 return 0;
780}
781
d54bb5a7 782static int ni_m_set_gate(struct ni_gpct *counter, unsigned int gate_source)
cb7859a9 783{
7d2a6e54 784 unsigned int chan = CR_CHAN(gate_source);
fca7c1d7 785 unsigned cidx = counter->counter_index;
7d2a6e54 786 unsigned gate_sel;
cb7859a9
FMH
787 unsigned i;
788
7d2a6e54 789 switch (chan) {
cb7859a9
FMH
790 case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
791 case NI_GPCT_AI_START2_GATE_SELECT:
792 case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
793 case NI_GPCT_NEXT_OUT_GATE_SELECT:
794 case NI_GPCT_AI_START1_GATE_SELECT:
795 case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
796 case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
797 case NI_GPCT_LOGIC_LOW_GATE_SELECT:
7d2a6e54 798 gate_sel = chan & 0x1f;
cb7859a9
FMH
799 break;
800 default:
eca7d872 801 for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
7d2a6e54
HS
802 if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
803 gate_sel = chan & 0x1f;
cb7859a9
FMH
804 break;
805 }
806 }
eca7d872 807 if (i <= NI_M_MAX_RTSI_CHAN)
cb7859a9 808 break;
eca7d872 809 for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
7d2a6e54
HS
810 if (chan == NI_GPCT_PFI_GATE_SELECT(i)) {
811 gate_sel = chan & 0x1f;
cb7859a9
FMH
812 break;
813 }
814 }
eca7d872 815 if (i <= NI_M_MAX_PFI_CHAN)
cb7859a9
FMH
816 break;
817 return -EINVAL;
cb7859a9 818 }
fca7c1d7 819 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx),
c2c6c288 820 GI_GATE_SEL_MASK, GI_GATE_SEL(gate_sel));
cb7859a9
FMH
821 return 0;
822}
823
d54bb5a7 824static int ni_660x_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
cb7859a9
FMH
825{
826 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 827 unsigned cidx = counter->counter_index;
55205053
HS
828 unsigned int chan = CR_CHAN(gate_source);
829 unsigned gate2_reg = NITIO_GATE2_REG(cidx);
830 unsigned gate2_sel;
cb7859a9
FMH
831 unsigned i;
832
55205053 833 switch (chan) {
cb7859a9
FMH
834 case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
835 case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
836 case NI_GPCT_SELECTED_GATE_GATE_SELECT:
837 case NI_GPCT_NEXT_OUT_GATE_SELECT:
838 case NI_GPCT_LOGIC_LOW_GATE_SELECT:
55205053 839 gate2_sel = chan & 0x1f;
cb7859a9
FMH
840 break;
841 case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
7e3e7591 842 gate2_sel = NI_660X_NEXT_SRC_GATE2_SEL;
cb7859a9
FMH
843 break;
844 default:
eca7d872 845 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
55205053
HS
846 if (chan == NI_GPCT_RTSI_GATE_SELECT(i)) {
847 gate2_sel = chan & 0x1f;
cb7859a9
FMH
848 break;
849 }
850 }
eca7d872 851 if (i <= NI_660X_MAX_RTSI_CHAN)
cb7859a9 852 break;
eca7d872 853 for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
55205053
HS
854 if (chan == NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
855 gate2_sel = chan & 0x1f;
cb7859a9
FMH
856 break;
857 }
858 }
eca7d872 859 if (i <= NI_660X_MAX_UP_DOWN_PIN)
cb7859a9
FMH
860 break;
861 return -EINVAL;
95cd17c9 862 }
4359dcf3
HS
863 counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
864 counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
865 counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
55205053 866 write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
cb7859a9
FMH
867 return 0;
868}
869
d54bb5a7 870static int ni_m_set_gate2(struct ni_gpct *counter, unsigned int gate_source)
cb7859a9
FMH
871{
872 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 873 unsigned cidx = counter->counter_index;
d54bb5a7
HS
874 unsigned int chan = CR_CHAN(gate_source);
875 unsigned gate2_reg = NITIO_GATE2_REG(cidx);
876 unsigned gate2_sel;
cb7859a9 877
14f194a9
HS
878 /*
879 * FIXME: We don't know what the m-series second gate codes are,
880 * so we'll just pass the bits through for now.
881 */
d54bb5a7 882 switch (chan) {
cb7859a9 883 default:
d54bb5a7 884 gate2_sel = chan & 0x1f;
cb7859a9 885 break;
95cd17c9 886 }
4359dcf3
HS
887 counter_dev->regs[gate2_reg] |= GI_GATE2_MODE;
888 counter_dev->regs[gate2_reg] &= ~GI_GATE2_SEL_MASK;
889 counter_dev->regs[gate2_reg] |= GI_GATE2_SEL(gate2_sel);
d54bb5a7 890 write_register(counter, counter_dev->regs[gate2_reg], gate2_reg);
cb7859a9
FMH
891 return 0;
892}
893
894int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
0a85b6f0 895 unsigned int gate_source)
cb7859a9
FMH
896{
897 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 898 unsigned cidx = counter->counter_index;
d54bb5a7
HS
899 unsigned int chan = CR_CHAN(gate_source);
900 unsigned gate2_reg = NITIO_GATE2_REG(cidx);
7d9e68d3 901 unsigned mode = 0;
cb7859a9
FMH
902
903 switch (gate_index) {
904 case 0:
d54bb5a7 905 if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
fca7c1d7 906 ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
36d80f4a
HS
907 GI_GATING_MODE_MASK,
908 GI_GATING_DISABLED);
cb7859a9
FMH
909 return 0;
910 }
7d9e68d3 911 if (gate_source & CR_INVERT)
36d80f4a 912 mode |= GI_GATE_POL_INVERT;
7d9e68d3 913 if (gate_source & CR_EDGE)
36d80f4a 914 mode |= GI_RISING_EDGE_GATING;
7d9e68d3 915 else
36d80f4a 916 mode |= GI_LEVEL_GATING;
7d9e68d3 917 ni_tio_set_bits(counter, NITIO_MODE_REG(cidx),
36d80f4a 918 GI_GATE_POL_INVERT | GI_GATING_MODE_MASK,
7d9e68d3 919 mode);
cb7859a9
FMH
920 switch (counter_dev->variant) {
921 case ni_gpct_variant_e_series:
922 case ni_gpct_variant_m_series:
85603161 923 default:
d54bb5a7 924 return ni_m_set_gate(counter, gate_source);
cb7859a9 925 case ni_gpct_variant_660x:
d54bb5a7 926 return ni_660x_set_gate(counter, gate_source);
cb7859a9
FMH
927 }
928 break;
929 case 1:
dba0f57f 930 if (!ni_tio_has_gate2_registers(counter_dev))
cb7859a9 931 return -EINVAL;
dba0f57f 932
d54bb5a7 933 if (chan == NI_GPCT_DISABLED_GATE_SELECT) {
4359dcf3 934 counter_dev->regs[gate2_reg] &= ~GI_GATE2_MODE;
d54bb5a7
HS
935 write_register(counter, counter_dev->regs[gate2_reg],
936 gate2_reg);
cb7859a9
FMH
937 return 0;
938 }
4359dcf3
HS
939 if (gate_source & CR_INVERT)
940 counter_dev->regs[gate2_reg] |= GI_GATE2_POL_INVERT;
941 else
942 counter_dev->regs[gate2_reg] &= ~GI_GATE2_POL_INVERT;
cb7859a9
FMH
943 switch (counter_dev->variant) {
944 case ni_gpct_variant_m_series:
d54bb5a7 945 return ni_m_set_gate2(counter, gate_source);
cb7859a9 946 case ni_gpct_variant_660x:
d54bb5a7 947 return ni_660x_set_gate2(counter, gate_source);
cb7859a9
FMH
948 default:
949 BUG();
950 break;
951 }
952 break;
953 default:
954 return -EINVAL;
cb7859a9
FMH
955 }
956 return 0;
957}
3d34023a 958EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
cb7859a9
FMH
959
960static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
0a85b6f0 961 unsigned int source)
cb7859a9
FMH
962{
963 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 964 unsigned cidx = counter->counter_index;
bf4ec095 965 unsigned int abz_reg, shift, mask;
cb7859a9 966
bf4ec095
HS
967 if (counter_dev->variant != ni_gpct_variant_m_series)
968 return -EINVAL;
cb7859a9 969
bf4ec095
HS
970 abz_reg = NITIO_ABZ_REG(cidx);
971 switch (index) {
972 case NI_GPCT_SOURCE_ENCODER_A:
973 shift = 10;
974 break;
975 case NI_GPCT_SOURCE_ENCODER_B:
976 shift = 5;
977 break;
978 case NI_GPCT_SOURCE_ENCODER_Z:
979 shift = 0;
980 break;
981 default:
982 return -EINVAL;
cb7859a9 983 }
bf4ec095
HS
984 mask = 0x1f << shift;
985 if (source > 0x1f)
986 source = 0x1f; /* Disable gate */
987
988 counter_dev->regs[abz_reg] &= ~mask;
989 counter_dev->regs[abz_reg] |= (source << shift) & mask;
990 write_register(counter, counter_dev->regs[abz_reg], abz_reg);
991 return 0;
cb7859a9
FMH
992}
993
d00193be 994static unsigned ni_660x_gate_to_generic_gate(unsigned gate)
cb7859a9
FMH
995{
996 unsigned i;
997
d00193be 998 switch (gate) {
5a3d1ed8 999 case NI_660X_SRC_PIN_I_GATE_SEL:
cb7859a9 1000 return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
5a3d1ed8 1001 case NI_660X_GATE_PIN_I_GATE_SEL:
cb7859a9 1002 return NI_GPCT_GATE_PIN_i_GATE_SELECT;
5a3d1ed8 1003 case NI_660X_NEXT_SRC_GATE_SEL:
cb7859a9 1004 return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
5a3d1ed8 1005 case NI_660X_NEXT_OUT_GATE_SEL:
cb7859a9 1006 return NI_GPCT_NEXT_OUT_GATE_SELECT;
5a3d1ed8 1007 case NI_660X_LOGIC_LOW_GATE_SEL:
cb7859a9 1008 return NI_GPCT_LOGIC_LOW_GATE_SELECT;
cb7859a9 1009 default:
eca7d872 1010 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
d00193be 1011 if (gate == NI_660X_RTSI_GATE_SEL(i))
cb7859a9 1012 return NI_GPCT_RTSI_GATE_SELECT(i);
cb7859a9 1013 }
eca7d872 1014 for (i = 0; i <= NI_660X_MAX_GATE_PIN; ++i) {
d00193be 1015 if (gate == NI_660X_PIN_GATE_SEL(i))
cb7859a9 1016 return NI_GPCT_GATE_PIN_GATE_SELECT(i);
cb7859a9 1017 }
cb7859a9
FMH
1018 BUG();
1019 break;
1020 }
1021 return 0;
1022};
1023
d00193be 1024static unsigned ni_m_gate_to_generic_gate(unsigned gate)
cb7859a9
FMH
1025{
1026 unsigned i;
1027
d00193be 1028 switch (gate) {
390db7a3 1029 case NI_M_TIMESTAMP_MUX_GATE_SEL:
cb7859a9 1030 return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
390db7a3 1031 case NI_M_AI_START2_GATE_SEL:
cb7859a9 1032 return NI_GPCT_AI_START2_GATE_SELECT;
390db7a3 1033 case NI_M_PXI_STAR_TRIGGER_GATE_SEL:
cb7859a9 1034 return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
390db7a3 1035 case NI_M_NEXT_OUT_GATE_SEL:
cb7859a9 1036 return NI_GPCT_NEXT_OUT_GATE_SELECT;
390db7a3 1037 case NI_M_AI_START1_GATE_SEL:
cb7859a9 1038 return NI_GPCT_AI_START1_GATE_SELECT;
390db7a3 1039 case NI_M_NEXT_SRC_GATE_SEL:
cb7859a9 1040 return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
390db7a3 1041 case NI_M_ANALOG_TRIG_OUT_GATE_SEL:
cb7859a9 1042 return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
390db7a3 1043 case NI_M_LOGIC_LOW_GATE_SEL:
cb7859a9 1044 return NI_GPCT_LOGIC_LOW_GATE_SELECT;
cb7859a9 1045 default:
eca7d872 1046 for (i = 0; i <= NI_M_MAX_RTSI_CHAN; ++i) {
d00193be 1047 if (gate == NI_M_RTSI_GATE_SEL(i))
cb7859a9 1048 return NI_GPCT_RTSI_GATE_SELECT(i);
cb7859a9 1049 }
eca7d872 1050 for (i = 0; i <= NI_M_MAX_PFI_CHAN; ++i) {
d00193be 1051 if (gate == NI_M_PFI_GATE_SEL(i))
cb7859a9 1052 return NI_GPCT_PFI_GATE_SELECT(i);
cb7859a9 1053 }
cb7859a9
FMH
1054 BUG();
1055 break;
1056 }
1057 return 0;
1058};
1059
d00193be 1060static unsigned ni_660x_gate2_to_generic_gate(unsigned gate)
cb7859a9
FMH
1061{
1062 unsigned i;
1063
d00193be 1064 switch (gate) {
7e3e7591 1065 case NI_660X_SRC_PIN_I_GATE2_SEL:
cb7859a9 1066 return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
7e3e7591 1067 case NI_660X_UD_PIN_I_GATE2_SEL:
cb7859a9 1068 return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
7e3e7591 1069 case NI_660X_NEXT_SRC_GATE2_SEL:
cb7859a9 1070 return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
7e3e7591 1071 case NI_660X_NEXT_OUT_GATE2_SEL:
cb7859a9 1072 return NI_GPCT_NEXT_OUT_GATE_SELECT;
7e3e7591 1073 case NI_660X_SELECTED_GATE2_SEL:
cb7859a9 1074 return NI_GPCT_SELECTED_GATE_GATE_SELECT;
7e3e7591 1075 case NI_660X_LOGIC_LOW_GATE2_SEL:
cb7859a9 1076 return NI_GPCT_LOGIC_LOW_GATE_SELECT;
cb7859a9 1077 default:
eca7d872 1078 for (i = 0; i <= NI_660X_MAX_RTSI_CHAN; ++i) {
d00193be 1079 if (gate == NI_660X_RTSI_GATE2_SEL(i))
cb7859a9 1080 return NI_GPCT_RTSI_GATE_SELECT(i);
cb7859a9 1081 }
eca7d872 1082 for (i = 0; i <= NI_660X_MAX_UP_DOWN_PIN; ++i) {
d00193be 1083 if (gate == NI_660X_UD_PIN_GATE2_SEL(i))
cb7859a9 1084 return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
cb7859a9 1085 }
cb7859a9
FMH
1086 BUG();
1087 break;
1088 }
1089 return 0;
1090};
1091
d00193be 1092static unsigned ni_m_gate2_to_generic_gate(unsigned gate)
cb7859a9 1093{
14f194a9
HS
1094 /*
1095 * FIXME: the second gate sources for the m series are undocumented,
1096 * so we just return the raw bits for now.
1097 */
d00193be 1098 switch (gate) {
cb7859a9 1099 default:
d00193be 1100 return gate;
cb7859a9
FMH
1101 }
1102 return 0;
1103};
1104
1105static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
0a85b6f0 1106 unsigned int *gate_source)
cb7859a9
FMH
1107{
1108 struct ni_gpct_device *counter_dev = counter->counter_dev;
fca7c1d7 1109 unsigned cidx = counter->counter_index;
d00193be
HS
1110 unsigned mode = ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx));
1111 unsigned gate2_reg = NITIO_GATE2_REG(cidx);
c2c6c288 1112 unsigned gate;
cb7859a9
FMH
1113
1114 switch (gate_index) {
1115 case 0:
36d80f4a 1116 if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED) {
cb7859a9
FMH
1117 *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
1118 return 0;
cb7859a9 1119 }
89660697 1120
c2c6c288
HS
1121 gate = GI_BITS_TO_GATE(ni_tio_get_soft_copy(counter,
1122 NITIO_INPUT_SEL_REG(cidx)));
89660697 1123
cb7859a9
FMH
1124 switch (counter_dev->variant) {
1125 case ni_gpct_variant_e_series:
1126 case ni_gpct_variant_m_series:
85603161 1127 default:
c2c6c288 1128 *gate_source = ni_m_gate_to_generic_gate(gate);
cb7859a9
FMH
1129 break;
1130 case ni_gpct_variant_660x:
c2c6c288 1131 *gate_source = ni_660x_gate_to_generic_gate(gate);
cb7859a9 1132 break;
cb7859a9 1133 }
36d80f4a 1134 if (mode & GI_GATE_POL_INVERT)
cb7859a9 1135 *gate_source |= CR_INVERT;
36d80f4a 1136 if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
cb7859a9 1137 *gate_source |= CR_EDGE;
cb7859a9
FMH
1138 break;
1139 case 1:
36d80f4a 1140 if ((mode & GI_GATING_MODE_MASK) == GI_GATING_DISABLED ||
4359dcf3 1141 !(counter_dev->regs[gate2_reg] & GI_GATE2_MODE)) {
cb7859a9
FMH
1142 *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
1143 return 0;
cb7859a9 1144 }
89660697 1145
4359dcf3 1146 gate = GI_BITS_TO_GATE2(counter_dev->regs[gate2_reg]);
d00193be 1147
cb7859a9
FMH
1148 switch (counter_dev->variant) {
1149 case ni_gpct_variant_e_series:
1150 case ni_gpct_variant_m_series:
85603161 1151 default:
c2c6c288 1152 *gate_source = ni_m_gate2_to_generic_gate(gate);
cb7859a9
FMH
1153 break;
1154 case ni_gpct_variant_660x:
c2c6c288 1155 *gate_source = ni_660x_gate2_to_generic_gate(gate);
cb7859a9 1156 break;
cb7859a9 1157 }
4359dcf3 1158 if (counter_dev->regs[gate2_reg] & GI_GATE2_POL_INVERT)
cb7859a9 1159 *gate_source |= CR_INVERT;
cb7859a9 1160 /* second gate can't have edge/level mode set independently */
36d80f4a 1161 if ((mode & GI_GATING_MODE_MASK) != GI_LEVEL_GATING)
cb7859a9 1162 *gate_source |= CR_EDGE;
cb7859a9
FMH
1163 break;
1164 default:
1165 return -EINVAL;
cb7859a9
FMH
1166 }
1167 return 0;
1168}
1169
cac04c0f
HS
1170int ni_tio_insn_config(struct comedi_device *dev,
1171 struct comedi_subdevice *s,
1172 struct comedi_insn *insn,
1173 unsigned int *data)
cb7859a9 1174{
cac04c0f 1175 struct ni_gpct *counter = s->private;
704c6dba
HS
1176 unsigned cidx = counter->counter_index;
1177 unsigned status;
cac04c0f 1178
cb7859a9
FMH
1179 switch (data[0]) {
1180 case INSN_CONFIG_SET_COUNTER_MODE:
1181 return ni_tio_set_counter_mode(counter, data[1]);
cb7859a9
FMH
1182 case INSN_CONFIG_ARM:
1183 return ni_tio_arm(counter, 1, data[1]);
cb7859a9
FMH
1184 case INSN_CONFIG_DISARM:
1185 ni_tio_arm(counter, 0, 0);
1186 return 0;
cb7859a9 1187 case INSN_CONFIG_GET_COUNTER_STATUS:
704c6dba
HS
1188 data[1] = 0;
1189 status = read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
24a675c5 1190 if (status & GI_ARMED(cidx)) {
704c6dba 1191 data[1] |= COMEDI_COUNTER_ARMED;
24a675c5 1192 if (status & GI_COUNTING(cidx))
704c6dba
HS
1193 data[1] |= COMEDI_COUNTER_COUNTING;
1194 }
01ca8f97 1195 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
cb7859a9 1196 return 0;
cb7859a9
FMH
1197 case INSN_CONFIG_SET_CLOCK_SRC:
1198 return ni_tio_set_clock_src(counter, data[1], data[2]);
cb7859a9
FMH
1199 case INSN_CONFIG_GET_CLOCK_SRC:
1200 ni_tio_get_clock_src(counter, &data[1], &data[2]);
1201 return 0;
cb7859a9
FMH
1202 case INSN_CONFIG_SET_GATE_SRC:
1203 return ni_tio_set_gate_src(counter, data[1], data[2]);
cb7859a9
FMH
1204 case INSN_CONFIG_GET_GATE_SRC:
1205 return ni_tio_get_gate_src(counter, data[1], &data[2]);
cb7859a9
FMH
1206 case INSN_CONFIG_SET_OTHER_SRC:
1207 return ni_tio_set_other_src(counter, data[1], data[2]);
cb7859a9
FMH
1208 case INSN_CONFIG_RESET:
1209 ni_tio_reset_count_and_disarm(counter);
1210 return 0;
cb7859a9
FMH
1211 default:
1212 break;
1213 }
1214 return -EINVAL;
1215}
3d34023a 1216EXPORT_SYMBOL_GPL(ni_tio_insn_config);
cb7859a9 1217
27c4d23c
HS
1218static unsigned int ni_tio_read_sw_save_reg(struct comedi_device *dev,
1219 struct comedi_subdevice *s)
1220{
1221 struct ni_gpct *counter = s->private;
1222 unsigned cidx = counter->counter_index;
56bd1ac7 1223 unsigned int val;
27c4d23c 1224
b9a09764 1225 ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0);
27c4d23c 1226 ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
b9a09764 1227 GI_SAVE_TRACE, GI_SAVE_TRACE);
27c4d23c
HS
1228
1229 /*
1230 * The count doesn't get latched until the next clock edge, so it is
1231 * possible the count may change (once) while we are reading. Since
1232 * the read of the SW_Save_Reg isn't atomic (apparently even when it's
1233 * a 32 bit register according to 660x docs), we need to read twice
1234 * and make sure the reading hasn't changed. If it has, a third read
1235 * will be correct since the count value will definitely have latched
1236 * by then.
1237 */
56bd1ac7
HS
1238 val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
1239 if (val != read_register(counter, NITIO_SW_SAVE_REG(cidx)))
1240 val = read_register(counter, NITIO_SW_SAVE_REG(cidx));
1241
1242 return val;
27c4d23c
HS
1243}
1244
9014d816
HS
1245int ni_tio_insn_read(struct comedi_device *dev,
1246 struct comedi_subdevice *s,
1247 struct comedi_insn *insn,
1248 unsigned int *data)
cb7859a9 1249{
9014d816 1250 struct ni_gpct *counter = s->private;
cb7859a9 1251 struct ni_gpct_device *counter_dev = counter->counter_dev;
27c4d23c 1252 unsigned int channel = CR_CHAN(insn->chanspec);
fca7c1d7 1253 unsigned cidx = counter->counter_index;
27c4d23c 1254 int i;
cb7859a9 1255
27c4d23c
HS
1256 for (i = 0; i < insn->n; i++) {
1257 switch (channel) {
1258 case 0:
1259 data[i] = ni_tio_read_sw_save_reg(dev, s);
1260 break;
1261 case 1:
1262 data[i] = counter_dev->regs[NITIO_LOADA_REG(cidx)];
1263 break;
1264 case 2:
1265 data[i] = counter_dev->regs[NITIO_LOADB_REG(cidx)];
1266 break;
1267 }
95cd17c9 1268 }
27c4d23c 1269 return insn->n;
cb7859a9 1270}
9014d816 1271EXPORT_SYMBOL_GPL(ni_tio_insn_read);
cb7859a9
FMH
1272
1273static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
1274{
fca7c1d7
HS
1275 unsigned cidx = counter->counter_index;
1276 const unsigned bits =
1277 read_register(counter, NITIO_SHARED_STATUS_REG(cidx));
cb7859a9 1278
24a675c5 1279 return (bits & GI_NEXT_LOAD_SRC(cidx))
89660697
HS
1280 ? NITIO_LOADB_REG(cidx)
1281 : NITIO_LOADA_REG(cidx);
cb7859a9
FMH
1282}
1283
10f74377
HS
1284int ni_tio_insn_write(struct comedi_device *dev,
1285 struct comedi_subdevice *s,
1286 struct comedi_insn *insn,
1287 unsigned int *data)
cb7859a9 1288{
10f74377 1289 struct ni_gpct *counter = s->private;
cb7859a9
FMH
1290 struct ni_gpct_device *counter_dev = counter->counter_dev;
1291 const unsigned channel = CR_CHAN(insn->chanspec);
fca7c1d7 1292 unsigned cidx = counter->counter_index;
cb7859a9
FMH
1293 unsigned load_reg;
1294
1295 if (insn->n < 1)
1296 return 0;
1297 switch (channel) {
1298 case 0:
14f194a9
HS
1299 /*
1300 * Unsafe if counter is armed.
1301 * Should probably check status and return -EBUSY if armed.
1302 */
1303
1304 /*
1305 * Don't disturb load source select, just use whichever
1306 * load register is already selected.
1307 */
cb7859a9
FMH
1308 load_reg = ni_tio_next_load_register(counter);
1309 write_register(counter, data[0], load_reg);
fca7c1d7 1310 ni_tio_set_bits_transient(counter, NITIO_CMD_REG(cidx),
b9a09764 1311 0, 0, GI_LOAD);
14f194a9 1312 /* restore load reg */
cb7859a9
FMH
1313 write_register(counter, counter_dev->regs[load_reg], load_reg);
1314 break;
1315 case 1:
fca7c1d7
HS
1316 counter_dev->regs[NITIO_LOADA_REG(cidx)] = data[0];
1317 write_register(counter, data[0], NITIO_LOADA_REG(cidx));
cb7859a9
FMH
1318 break;
1319 case 2:
fca7c1d7
HS
1320 counter_dev->regs[NITIO_LOADB_REG(cidx)] = data[0];
1321 write_register(counter, data[0], NITIO_LOADB_REG(cidx));
cb7859a9
FMH
1322 break;
1323 default:
1324 return -EINVAL;
cb7859a9
FMH
1325 }
1326 return 0;
1327}
10f74377 1328EXPORT_SYMBOL_GPL(ni_tio_insn_write);
f688d4a7 1329
25e529b0
HS
1330void ni_tio_init_counter(struct ni_gpct *counter)
1331{
1332 struct ni_gpct_device *counter_dev = counter->counter_dev;
1333 unsigned cidx = counter->counter_index;
1334
1335 ni_tio_reset_count_and_disarm(counter);
1336
1337 /* initialize counter registers */
1338 counter_dev->regs[NITIO_AUTO_INC_REG(cidx)] = 0x0;
1339 write_register(counter, 0x0, NITIO_AUTO_INC_REG(cidx));
1340
1341 ni_tio_set_bits(counter, NITIO_CMD_REG(cidx),
b9a09764 1342 ~0, GI_SYNC_GATE);
25e529b0
HS
1343
1344 ni_tio_set_bits(counter, NITIO_MODE_REG(cidx), ~0, 0);
1345
1346 counter_dev->regs[NITIO_LOADA_REG(cidx)] = 0x0;
1347 write_register(counter, 0x0, NITIO_LOADA_REG(cidx));
1348
1349 counter_dev->regs[NITIO_LOADB_REG(cidx)] = 0x0;
1350 write_register(counter, 0x0, NITIO_LOADB_REG(cidx));
1351
1352 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), ~0, 0);
1353
1354 if (ni_tio_counting_mode_registers_present(counter_dev))
1355 ni_tio_set_bits(counter, NITIO_CNT_MODE_REG(cidx), ~0, 0);
1356
dba0f57f 1357 if (ni_tio_has_gate2_registers(counter_dev)) {
25e529b0
HS
1358 counter_dev->regs[NITIO_GATE2_REG(cidx)] = 0x0;
1359 write_register(counter, 0x0, NITIO_GATE2_REG(cidx));
1360 }
1361
1362 ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), ~0, 0x0);
1363
1364 ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), ~0, 0x0);
1365}
1366EXPORT_SYMBOL_GPL(ni_tio_init_counter);
1367
8477c5d4
HS
1368struct ni_gpct_device *
1369ni_gpct_device_construct(struct comedi_device *dev,
1370 void (*write_register)(struct ni_gpct *counter,
1371 unsigned bits,
1372 enum ni_gpct_register reg),
1373 unsigned (*read_register)(struct ni_gpct *counter,
1374 enum ni_gpct_register reg),
1375 enum ni_gpct_variant variant,
1376 unsigned num_counters)
1377{
1378 struct ni_gpct_device *counter_dev;
1379 struct ni_gpct *counter;
1380 unsigned i;
1381
1382 if (num_counters == 0)
1383 return NULL;
1384
1385 counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL);
1386 if (!counter_dev)
1387 return NULL;
1388
1389 counter_dev->dev = dev;
1390 counter_dev->write_register = write_register;
1391 counter_dev->read_register = read_register;
1392 counter_dev->variant = variant;
1393
1394 spin_lock_init(&counter_dev->regs_lock);
1395
1396 counter_dev->counters = kcalloc(num_counters, sizeof(*counter),
1397 GFP_KERNEL);
1398 if (!counter_dev->counters) {
1399 kfree(counter_dev);
1400 return NULL;
1401 }
1402
1403 for (i = 0; i < num_counters; ++i) {
1404 counter = &counter_dev->counters[i];
1405 counter->counter_dev = counter_dev;
1406 spin_lock_init(&counter->lock);
1407 }
1408 counter_dev->num_counters = num_counters;
1409
1410 return counter_dev;
1411}
1412EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
1413
1414void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
1415{
1416 if (!counter_dev->counters)
1417 return;
1418 kfree(counter_dev->counters);
1419 kfree(counter_dev);
1420}
1421EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
1422
f688d4a7
HS
1423static int __init ni_tio_init_module(void)
1424{
1425 return 0;
1426}
1427module_init(ni_tio_init_module);
1428
1429static void __exit ni_tio_cleanup_module(void)
1430{
1431}
1432module_exit(ni_tio_cleanup_module);
1433
1434MODULE_AUTHOR("Comedi <comedi@comedi.org>");
1435MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
1436MODULE_LICENSE("GPL");
This page took 0.802948 seconds and 5 git commands to generate.