1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Hardware driver for NI 660x devices
4 */
5
6/*
7 * Driver: ni_660x
8 * Description: National Instruments 660x counter/timer boards
9 * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
10 * PCI-6608, PXI-6608, PCI-6624, PXI-6624
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: Mon, 16 Jan 2017 14:00:43 +0000
17 * Status: experimental
18 *
19 * Encoders work. PulseGeneration (both single pulse and pulse train)
20 * works. Buffered commands work for input but not output.
21 *
22 * References:
23 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
24 * DAQ 6601/6602 User Manual (NI 322137B-01)
25 */
26
27#include <linux/module.h>
28#include <linux/interrupt.h>
29#include <linux/comedi/comedi_pci.h>
30
31#include "mite.h"
32#include "ni_tio.h"
33#include "ni_routes.h"
34
35/* See Register-Level Programmer Manual page 3.1 */
36enum ni_660x_register {
37 /* see enum ni_gpct_register */
38 NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS,
39 NI660X_STC_DIO_OUTPUT,
40 NI660X_STC_DIO_CONTROL,
41 NI660X_STC_DIO_SERIAL_INPUT,
42 NI660X_DIO32_INPUT,
43 NI660X_DIO32_OUTPUT,
44 NI660X_CLK_CFG,
45 NI660X_GLOBAL_INT_STATUS,
46 NI660X_DMA_CFG,
47 NI660X_GLOBAL_INT_CFG,
48 NI660X_IO_CFG_0_1,
49 NI660X_IO_CFG_2_3,
50 NI660X_IO_CFG_4_5,
51 NI660X_IO_CFG_6_7,
52 NI660X_IO_CFG_8_9,
53 NI660X_IO_CFG_10_11,
54 NI660X_IO_CFG_12_13,
55 NI660X_IO_CFG_14_15,
56 NI660X_IO_CFG_16_17,
57 NI660X_IO_CFG_18_19,
58 NI660X_IO_CFG_20_21,
59 NI660X_IO_CFG_22_23,
60 NI660X_IO_CFG_24_25,
61 NI660X_IO_CFG_26_27,
62 NI660X_IO_CFG_28_29,
63 NI660X_IO_CFG_30_31,
64 NI660X_IO_CFG_32_33,
65 NI660X_IO_CFG_34_35,
66 NI660X_IO_CFG_36_37,
67 NI660X_IO_CFG_38_39,
68 NI660X_NUM_REGS,
69};
70
71#define NI660X_CLK_CFG_COUNTER_SWAP BIT(21)
72
73#define NI660X_GLOBAL_INT_COUNTER0 BIT(8)
74#define NI660X_GLOBAL_INT_COUNTER1 BIT(9)
75#define NI660X_GLOBAL_INT_COUNTER2 BIT(10)
76#define NI660X_GLOBAL_INT_COUNTER3 BIT(11)
77#define NI660X_GLOBAL_INT_CASCADE BIT(29)
78#define NI660X_GLOBAL_INT_GLOBAL_POL BIT(30)
79#define NI660X_GLOBAL_INT_GLOBAL BIT(31)
80
81#define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c)))
82#define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
83#define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
84#define NI660X_DMA_CFG_RESET(_c) NI660X_DMA_CFG_SEL((_c), 0x80)
85
86#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2))
87#define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8))
88#define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3)
89#define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12))
90#define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7)
91
92struct ni_660x_register_data {
93 int offset; /* Offset from base address from GPCT chip */
94 char size; /* 2 or 4 bytes */
95};
96
97static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = {
98 [NITIO_G0_INT_ACK] = { 0x004, 2 }, /* write */
99 [NITIO_G0_STATUS] = { .offset: 0x004, .size: 2 }, /* read */
100 [NITIO_G1_INT_ACK] = { .offset: 0x006, .size: 2 }, /* write */
101 [NITIO_G1_STATUS] = { .offset: 0x006, .size: 2 }, /* read */
102 [NITIO_G01_STATUS] = { .offset: 0x008, .size: 2 }, /* read */
103 [NITIO_G0_CMD] = { .offset: 0x00c, .size: 2 }, /* write */
104 [NI660X_STC_DIO_PARALLEL_INPUT] = { .offset: 0x00e, .size: 2 }, /* read */
105 [NITIO_G1_CMD] = { .offset: 0x00e, .size: 2 }, /* write */
106 [NITIO_G0_HW_SAVE] = { .offset: 0x010, .size: 4 }, /* read */
107 [NITIO_G1_HW_SAVE] = { .offset: 0x014, .size: 4 }, /* read */
108 [NI660X_STC_DIO_OUTPUT] = { .offset: 0x014, .size: 2 }, /* write */
109 [NI660X_STC_DIO_CONTROL] = { .offset: 0x016, .size: 2 }, /* write */
110 [NITIO_G0_SW_SAVE] = { .offset: 0x018, .size: 4 }, /* read */
111 [NITIO_G1_SW_SAVE] = { .offset: 0x01c, .size: 4 }, /* read */
112 [NITIO_G0_MODE] = { .offset: 0x034, .size: 2 }, /* write */
113 [NITIO_G01_STATUS1] = { .offset: 0x036, .size: 2 }, /* read */
114 [NITIO_G1_MODE] = { .offset: 0x036, .size: 2 }, /* write */
115 [NI660X_STC_DIO_SERIAL_INPUT] = { .offset: 0x038, .size: 2 }, /* read */
116 [NITIO_G0_LOADA] = { .offset: 0x038, .size: 4 }, /* write */
117 [NITIO_G01_STATUS2] = { .offset: 0x03a, .size: 2 }, /* read */
118 [NITIO_G0_LOADB] = { .offset: 0x03c, .size: 4 }, /* write */
119 [NITIO_G1_LOADA] = { .offset: 0x040, .size: 4 }, /* write */
120 [NITIO_G1_LOADB] = { .offset: 0x044, .size: 4 }, /* write */
121 [NITIO_G0_INPUT_SEL] = { .offset: 0x048, .size: 2 }, /* write */
122 [NITIO_G1_INPUT_SEL] = { .offset: 0x04a, .size: 2 }, /* write */
123 [NITIO_G0_AUTO_INC] = { .offset: 0x088, .size: 2 }, /* write */
124 [NITIO_G1_AUTO_INC] = { .offset: 0x08a, .size: 2 }, /* write */
125 [NITIO_G01_RESET] = { .offset: 0x090, .size: 2 }, /* write */
126 [NITIO_G0_INT_ENA] = { .offset: 0x092, .size: 2 }, /* write */
127 [NITIO_G1_INT_ENA] = { .offset: 0x096, .size: 2 }, /* write */
128 [NITIO_G0_CNT_MODE] = { .offset: 0x0b0, .size: 2 }, /* write */
129 [NITIO_G1_CNT_MODE] = { .offset: 0x0b2, .size: 2 }, /* write */
130 [NITIO_G0_GATE2] = { .offset: 0x0b4, .size: 2 }, /* write */
131 [NITIO_G1_GATE2] = { .offset: 0x0b6, .size: 2 }, /* write */
132 [NITIO_G0_DMA_CFG] = { .offset: 0x0b8, .size: 2 }, /* write */
133 [NITIO_G0_DMA_STATUS] = { .offset: 0x0b8, .size: 2 }, /* read */
134 [NITIO_G1_DMA_CFG] = { .offset: 0x0ba, .size: 2 }, /* write */
135 [NITIO_G1_DMA_STATUS] = { .offset: 0x0ba, .size: 2 }, /* read */
136 [NITIO_G2_INT_ACK] = { .offset: 0x104, .size: 2 }, /* write */
137 [NITIO_G2_STATUS] = { .offset: 0x104, .size: 2 }, /* read */
138 [NITIO_G3_INT_ACK] = { .offset: 0x106, .size: 2 }, /* write */
139 [NITIO_G3_STATUS] = { .offset: 0x106, .size: 2 }, /* read */
140 [NITIO_G23_STATUS] = { .offset: 0x108, .size: 2 }, /* read */
141 [NITIO_G2_CMD] = { .offset: 0x10c, .size: 2 }, /* write */
142 [NITIO_G3_CMD] = { .offset: 0x10e, .size: 2 }, /* write */
143 [NITIO_G2_HW_SAVE] = { .offset: 0x110, .size: 4 }, /* read */
144 [NITIO_G3_HW_SAVE] = { .offset: 0x114, .size: 4 }, /* read */
145 [NITIO_G2_SW_SAVE] = { .offset: 0x118, .size: 4 }, /* read */
146 [NITIO_G3_SW_SAVE] = { .offset: 0x11c, .size: 4 }, /* read */
147 [NITIO_G2_MODE] = { .offset: 0x134, .size: 2 }, /* write */
148 [NITIO_G23_STATUS1] = { .offset: 0x136, .size: 2 }, /* read */
149 [NITIO_G3_MODE] = { .offset: 0x136, .size: 2 }, /* write */
150 [NITIO_G2_LOADA] = { .offset: 0x138, .size: 4 }, /* write */
151 [NITIO_G23_STATUS2] = { .offset: 0x13a, .size: 2 }, /* read */
152 [NITIO_G2_LOADB] = { .offset: 0x13c, .size: 4 }, /* write */
153 [NITIO_G3_LOADA] = { .offset: 0x140, .size: 4 }, /* write */
154 [NITIO_G3_LOADB] = { .offset: 0x144, .size: 4 }, /* write */
155 [NITIO_G2_INPUT_SEL] = { .offset: 0x148, .size: 2 }, /* write */
156 [NITIO_G3_INPUT_SEL] = { .offset: 0x14a, .size: 2 }, /* write */
157 [NITIO_G2_AUTO_INC] = { .offset: 0x188, .size: 2 }, /* write */
158 [NITIO_G3_AUTO_INC] = { .offset: 0x18a, .size: 2 }, /* write */
159 [NITIO_G23_RESET] = { .offset: 0x190, .size: 2 }, /* write */
160 [NITIO_G2_INT_ENA] = { .offset: 0x192, .size: 2 }, /* write */
161 [NITIO_G3_INT_ENA] = { .offset: 0x196, .size: 2 }, /* write */
162 [NITIO_G2_CNT_MODE] = { .offset: 0x1b0, .size: 2 }, /* write */
163 [NITIO_G3_CNT_MODE] = { .offset: 0x1b2, .size: 2 }, /* write */
164 [NITIO_G2_GATE2] = { .offset: 0x1b4, .size: 2 }, /* write */
165 [NITIO_G3_GATE2] = { .offset: 0x1b6, .size: 2 }, /* write */
166 [NITIO_G2_DMA_CFG] = { .offset: 0x1b8, .size: 2 }, /* write */
167 [NITIO_G2_DMA_STATUS] = { .offset: 0x1b8, .size: 2 }, /* read */
168 [NITIO_G3_DMA_CFG] = { .offset: 0x1ba, .size: 2 }, /* write */
169 [NITIO_G3_DMA_STATUS] = { .offset: 0x1ba, .size: 2 }, /* read */
170 [NI660X_DIO32_INPUT] = { .offset: 0x414, .size: 4 }, /* read */
171 [NI660X_DIO32_OUTPUT] = { .offset: 0x510, .size: 4 }, /* write */
172 [NI660X_CLK_CFG] = { .offset: 0x73c, .size: 4 }, /* write */
173 [NI660X_GLOBAL_INT_STATUS] = { .offset: 0x754, .size: 4 }, /* read */
174 [NI660X_DMA_CFG] = { .offset: 0x76c, .size: 4 }, /* write */
175 [NI660X_GLOBAL_INT_CFG] = { .offset: 0x770, .size: 4 }, /* write */
176 [NI660X_IO_CFG_0_1] = { .offset: 0x77c, .size: 2 }, /* read/write */
177 [NI660X_IO_CFG_2_3] = { .offset: 0x77e, .size: 2 }, /* read/write */
178 [NI660X_IO_CFG_4_5] = { .offset: 0x780, .size: 2 }, /* read/write */
179 [NI660X_IO_CFG_6_7] = { .offset: 0x782, .size: 2 }, /* read/write */
180 [NI660X_IO_CFG_8_9] = { .offset: 0x784, .size: 2 }, /* read/write */
181 [NI660X_IO_CFG_10_11] = { .offset: 0x786, .size: 2 }, /* read/write */
182 [NI660X_IO_CFG_12_13] = { .offset: 0x788, .size: 2 }, /* read/write */
183 [NI660X_IO_CFG_14_15] = { .offset: 0x78a, .size: 2 }, /* read/write */
184 [NI660X_IO_CFG_16_17] = { .offset: 0x78c, .size: 2 }, /* read/write */
185 [NI660X_IO_CFG_18_19] = { .offset: 0x78e, .size: 2 }, /* read/write */
186 [NI660X_IO_CFG_20_21] = { .offset: 0x790, .size: 2 }, /* read/write */
187 [NI660X_IO_CFG_22_23] = { .offset: 0x792, .size: 2 }, /* read/write */
188 [NI660X_IO_CFG_24_25] = { .offset: 0x794, .size: 2 }, /* read/write */
189 [NI660X_IO_CFG_26_27] = { .offset: 0x796, .size: 2 }, /* read/write */
190 [NI660X_IO_CFG_28_29] = { .offset: 0x798, .size: 2 }, /* read/write */
191 [NI660X_IO_CFG_30_31] = { .offset: 0x79a, .size: 2 }, /* read/write */
192 [NI660X_IO_CFG_32_33] = { .offset: 0x79c, .size: 2 }, /* read/write */
193 [NI660X_IO_CFG_34_35] = { .offset: 0x79e, .size: 2 }, /* read/write */
194 [NI660X_IO_CFG_36_37] = { .offset: 0x7a0, .size: 2 }, /* read/write */
195 [NI660X_IO_CFG_38_39] = { .offset: 0x7a2, .size: 2 } /* read/write */
196};
197
198#define NI660X_CHIP_OFFSET 0x800
199
200enum ni_660x_boardid {
201 BOARD_PCI6601,
202 BOARD_PCI6602,
203 BOARD_PXI6602,
204 BOARD_PCI6608,
205 BOARD_PXI6608,
206 BOARD_PCI6624,
207 BOARD_PXI6624
208};
209
210struct ni_660x_board {
211 const char *name;
212 unsigned int n_chips; /* total number of TIO chips */
213};
214
215static const struct ni_660x_board ni_660x_boards[] = {
216 [BOARD_PCI6601] = {
217 .name = "PCI-6601",
218 .n_chips = 1,
219 },
220 [BOARD_PCI6602] = {
221 .name = "PCI-6602",
222 .n_chips = 2,
223 },
224 [BOARD_PXI6602] = {
225 .name = "PXI-6602",
226 .n_chips = 2,
227 },
228 [BOARD_PCI6608] = {
229 .name = "PCI-6608",
230 .n_chips = 2,
231 },
232 [BOARD_PXI6608] = {
233 .name = "PXI-6608",
234 .n_chips = 2,
235 },
236 [BOARD_PCI6624] = {
237 .name = "PCI-6624",
238 .n_chips = 2,
239 },
240 [BOARD_PXI6624] = {
241 .name = "PXI-6624",
242 .n_chips = 2,
243 },
244};
245
246#define NI660X_NUM_PFI_CHANNELS 40
247
248/* there are only up to 3 dma channels, but the register layout allows for 4 */
249#define NI660X_MAX_DMA_CHANNEL 4
250
251#define NI660X_COUNTERS_PER_CHIP 4
252#define NI660X_MAX_CHIPS 2
253#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \
254 NI660X_COUNTERS_PER_CHIP)
255
256struct ni_660x_private {
257 struct mite *mite;
258 struct ni_gpct_device *counter_dev;
259 struct mite_ring *ring[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP];
260 /* protects mite channel request/release */
261 spinlock_t mite_channel_lock;
262 /* prevents races between interrupt and comedi_poll */
263 spinlock_t interrupt_lock;
264 unsigned int dma_cfg[NI660X_MAX_CHIPS];
265 unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
266 u64 io_dir;
267 struct ni_route_tables routing_tables;
268};
269
270static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
271 unsigned int bits, unsigned int reg)
272{
273 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
274 ni_660x_reg_data[reg].offset;
275
276 if (ni_660x_reg_data[reg].size == 2)
277 writew(val: bits, addr: dev->mmio + addr);
278 else
279 writel(val: bits, addr: dev->mmio + addr);
280}
281
282static unsigned int ni_660x_read(struct comedi_device *dev,
283 unsigned int chip, unsigned int reg)
284{
285 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
286 ni_660x_reg_data[reg].offset;
287
288 if (ni_660x_reg_data[reg].size == 2)
289 return readw(addr: dev->mmio + addr);
290 return readl(addr: dev->mmio + addr);
291}
292
293static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits,
294 enum ni_gpct_register reg)
295{
296 struct comedi_device *dev = counter->counter_dev->dev;
297
298 ni_660x_write(dev, chip: counter->chip_index, bits, reg);
299}
300
301static unsigned int ni_660x_gpct_read(struct ni_gpct *counter,
302 enum ni_gpct_register reg)
303{
304 struct comedi_device *dev = counter->counter_dev->dev;
305
306 return ni_660x_read(dev, chip: counter->chip_index, reg);
307}
308
309static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
310 unsigned int mite_channel,
311 struct ni_gpct *counter)
312{
313 struct ni_660x_private *devpriv = dev->private;
314 unsigned int chip = counter->chip_index;
315
316 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
317 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel,
318 counter->counter_index);
319 ni_660x_write(dev, chip, bits: devpriv->dma_cfg[chip] |
320 NI660X_DMA_CFG_RESET(mite_channel),
321 reg: NI660X_DMA_CFG);
322}
323
324static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
325 unsigned int mite_channel,
326 struct ni_gpct *counter)
327{
328 struct ni_660x_private *devpriv = dev->private;
329 unsigned int chip = counter->chip_index;
330
331 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
332 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
333 ni_660x_write(dev, chip, bits: devpriv->dma_cfg[chip], reg: NI660X_DMA_CFG);
334}
335
336static int ni_660x_request_mite_channel(struct comedi_device *dev,
337 struct ni_gpct *counter,
338 enum comedi_io_direction direction)
339{
340 struct ni_660x_private *devpriv = dev->private;
341 struct mite_ring *ring;
342 struct mite_channel *mite_chan;
343 unsigned long flags;
344
345 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
346 ring = devpriv->ring[counter->chip_index][counter->counter_index];
347 mite_chan = mite_request_channel(mite: devpriv->mite, ring);
348 if (!mite_chan) {
349 spin_unlock_irqrestore(lock: &devpriv->mite_channel_lock, flags);
350 dev_err(dev->class_dev,
351 "failed to reserve mite dma channel for counter\n");
352 return -EBUSY;
353 }
354 mite_chan->dir = direction;
355 ni_tio_set_mite_channel(counter, mite_chan);
356 ni_660x_set_dma_channel(dev, mite_channel: mite_chan->channel, counter);
357 spin_unlock_irqrestore(lock: &devpriv->mite_channel_lock, flags);
358 return 0;
359}
360
361static void ni_660x_release_mite_channel(struct comedi_device *dev,
362 struct ni_gpct *counter)
363{
364 struct ni_660x_private *devpriv = dev->private;
365 unsigned long flags;
366
367 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
368 if (counter->mite_chan) {
369 struct mite_channel *mite_chan = counter->mite_chan;
370
371 ni_660x_unset_dma_channel(dev, mite_channel: mite_chan->channel, counter);
372 ni_tio_set_mite_channel(counter, NULL);
373 mite_release_channel(mite_chan);
374 }
375 spin_unlock_irqrestore(lock: &devpriv->mite_channel_lock, flags);
376}
377
378static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
379{
380 struct ni_gpct *counter = s->private;
381 int retval;
382
383 retval = ni_660x_request_mite_channel(dev, counter, direction: COMEDI_INPUT);
384 if (retval) {
385 dev_err(dev->class_dev,
386 "no dma channel available for use by counter\n");
387 return retval;
388 }
389 ni_tio_acknowledge(counter);
390
391 return ni_tio_cmd(dev, s);
392}
393
394static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
395{
396 struct ni_gpct *counter = s->private;
397 int retval;
398
399 retval = ni_tio_cancel(counter);
400 ni_660x_release_mite_channel(dev, counter);
401 return retval;
402}
403
404static void set_tio_counterswap(struct comedi_device *dev, int chip)
405{
406 unsigned int bits = 0;
407
408 /*
409 * See P. 3.5 of the Register-Level Programming manual.
410 * The CounterSwap bit has to be set on the second chip,
411 * otherwise it will try to use the same pins as the
412 * first chip.
413 */
414 if (chip)
415 bits = NI660X_CLK_CFG_COUNTER_SWAP;
416
417 ni_660x_write(dev, chip, bits, reg: NI660X_CLK_CFG);
418}
419
420static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
421 struct comedi_subdevice *s)
422{
423 struct ni_gpct *counter = s->private;
424
425 ni_tio_handle_interrupt(counter, s);
426 comedi_handle_events(dev, s);
427}
428
429static irqreturn_t ni_660x_interrupt(int irq, void *d)
430{
431 struct comedi_device *dev = d;
432 struct ni_660x_private *devpriv = dev->private;
433 struct comedi_subdevice *s;
434 unsigned int i;
435 unsigned long flags;
436
437 if (!dev->attached)
438 return IRQ_NONE;
439 /* make sure dev->attached is checked before doing anything else */
440 smp_mb();
441
442 /* lock to avoid race with comedi_poll */
443 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
444 for (i = 0; i < dev->n_subdevices; ++i) {
445 s = &dev->subdevices[i];
446 if (s->type == COMEDI_SUBD_COUNTER)
447 ni_660x_handle_gpct_interrupt(dev, s);
448 }
449 spin_unlock_irqrestore(lock: &devpriv->interrupt_lock, flags);
450 return IRQ_HANDLED;
451}
452
453static int ni_660x_input_poll(struct comedi_device *dev,
454 struct comedi_subdevice *s)
455{
456 struct ni_660x_private *devpriv = dev->private;
457 struct ni_gpct *counter = s->private;
458 unsigned long flags;
459
460 /* lock to avoid race with comedi_poll */
461 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
462 mite_sync_dma(mite_chan: counter->mite_chan, s);
463 spin_unlock_irqrestore(lock: &devpriv->interrupt_lock, flags);
464 return comedi_buf_read_n_available(s);
465}
466
467static int ni_660x_buf_change(struct comedi_device *dev,
468 struct comedi_subdevice *s)
469{
470 struct ni_660x_private *devpriv = dev->private;
471 struct ni_gpct *counter = s->private;
472 struct mite_ring *ring;
473 int ret;
474
475 ring = devpriv->ring[counter->chip_index][counter->counter_index];
476 ret = mite_buf_change(ring, s);
477 if (ret < 0)
478 return ret;
479
480 return 0;
481}
482
483static int ni_660x_allocate_private(struct comedi_device *dev)
484{
485 struct ni_660x_private *devpriv;
486 unsigned int i;
487
488 devpriv = comedi_alloc_devpriv(dev, size: sizeof(*devpriv));
489 if (!devpriv)
490 return -ENOMEM;
491
492 spin_lock_init(&devpriv->mite_channel_lock);
493 spin_lock_init(&devpriv->interrupt_lock);
494 for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i)
495 devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER;
496
497 return 0;
498}
499
500static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
501{
502 const struct ni_660x_board *board = dev->board_ptr;
503 struct ni_660x_private *devpriv = dev->private;
504 unsigned int i;
505 unsigned int j;
506
507 for (i = 0; i < board->n_chips; ++i) {
508 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) {
509 devpriv->ring[i][j] = mite_alloc_ring(mite: devpriv->mite);
510 if (!devpriv->ring[i][j])
511 return -ENOMEM;
512 }
513 }
514 return 0;
515}
516
517static void ni_660x_free_mite_rings(struct comedi_device *dev)
518{
519 const struct ni_660x_board *board = dev->board_ptr;
520 struct ni_660x_private *devpriv = dev->private;
521 unsigned int i;
522 unsigned int j;
523
524 for (i = 0; i < board->n_chips; ++i) {
525 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j)
526 mite_free_ring(ring: devpriv->ring[i][j]);
527 }
528}
529
530static int ni_660x_dio_insn_bits(struct comedi_device *dev,
531 struct comedi_subdevice *s,
532 struct comedi_insn *insn,
533 unsigned int *data)
534{
535 unsigned int shift = CR_CHAN(insn->chanspec);
536 unsigned int mask = data[0] << shift;
537 unsigned int bits = data[1] << shift;
538
539 /*
540 * There are 40 channels in this subdevice but only 32 are usable
541 * as DIO. The shift adjusts the mask/bits to account for the base
542 * channel in insn->chanspec. The state update can then be handled
543 * normally for the 32 usable channels.
544 */
545 if (mask) {
546 s->state &= ~mask;
547 s->state |= (bits & mask);
548 ni_660x_write(dev, chip: 0, bits: s->state, reg: NI660X_DIO32_OUTPUT);
549 }
550
551 /*
552 * Return the input channels, shifted back to account for the base
553 * channel.
554 */
555 data[1] = ni_660x_read(dev, chip: 0, reg: NI660X_DIO32_INPUT) >> shift;
556
557 return insn->n;
558}
559
560static void ni_660x_select_pfi_output(struct comedi_device *dev,
561 unsigned int chan, unsigned int out_sel)
562{
563 const struct ni_660x_board *board = dev->board_ptr;
564 unsigned int active_chip = 0;
565 unsigned int idle_chip = 0;
566 unsigned int bits;
567
568 if (chan >= NI_PFI(0))
569 /* allow new and old names of pfi channels to work. */
570 chan -= NI_PFI(0);
571
572 if (board->n_chips > 1) {
573 if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
574 chan >= 8 && chan <= 23) {
575 /* counters 4-7 pfi channels */
576 active_chip = 1;
577 idle_chip = 0;
578 } else {
579 /* counters 0-3 pfi channels */
580 active_chip = 0;
581 idle_chip = 1;
582 }
583 }
584
585 if (idle_chip != active_chip) {
586 /* set the pfi channel to high-z on the inactive chip */
587 bits = ni_660x_read(dev, chip: idle_chip, NI660X_IO_CFG(chan));
588 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
589 bits |= NI660X_IO_CFG_OUT_SEL(chan, 0); /* high-z */
590 ni_660x_write(dev, chip: idle_chip, bits, NI660X_IO_CFG(chan));
591 }
592
593 /* set the pfi channel output on the active chip */
594 bits = ni_660x_read(dev, chip: active_chip, NI660X_IO_CFG(chan));
595 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
596 bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
597 ni_660x_write(dev, chip: active_chip, bits, NI660X_IO_CFG(chan));
598}
599
600static void ni_660x_set_pfi_direction(struct comedi_device *dev,
601 unsigned int chan,
602 unsigned int direction)
603{
604 struct ni_660x_private *devpriv = dev->private;
605 u64 bit;
606
607 if (chan >= NI_PFI(0))
608 /* allow new and old names of pfi channels to work. */
609 chan -= NI_PFI(0);
610
611 bit = 1ULL << chan;
612
613 if (direction == COMEDI_OUTPUT) {
614 devpriv->io_dir |= bit;
615 /* reset the output to currently assigned output value */
616 ni_660x_select_pfi_output(dev, chan, out_sel: devpriv->io_cfg[chan]);
617 } else {
618 devpriv->io_dir &= ~bit;
619 /* set pin to high-z; do not change currently assigned route */
620 ni_660x_select_pfi_output(dev, chan, out_sel: 0);
621 }
622}
623
624static unsigned int ni_660x_get_pfi_direction(struct comedi_device *dev,
625 unsigned int chan)
626{
627 struct ni_660x_private *devpriv = dev->private;
628 u64 bit;
629
630 if (chan >= NI_PFI(0))
631 /* allow new and old names of pfi channels to work. */
632 chan -= NI_PFI(0);
633
634 bit = 1ULL << chan;
635
636 return (devpriv->io_dir & bit) ? COMEDI_OUTPUT : COMEDI_INPUT;
637}
638
639static int ni_660x_set_pfi_routing(struct comedi_device *dev,
640 unsigned int chan, unsigned int source)
641{
642 struct ni_660x_private *devpriv = dev->private;
643
644 if (chan >= NI_PFI(0))
645 /* allow new and old names of pfi channels to work. */
646 chan -= NI_PFI(0);
647
648 switch (source) {
649 case NI_660X_PFI_OUTPUT_COUNTER:
650 if (chan < 8)
651 return -EINVAL;
652 break;
653 case NI_660X_PFI_OUTPUT_DIO:
654 if (chan > 31)
655 return -EINVAL;
656 break;
657 default:
658 return -EINVAL;
659 }
660
661 devpriv->io_cfg[chan] = source;
662 if (ni_660x_get_pfi_direction(dev, chan) == COMEDI_OUTPUT)
663 ni_660x_select_pfi_output(dev, chan, out_sel: devpriv->io_cfg[chan]);
664 return 0;
665}
666
667static int ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned int chan)
668{
669 struct ni_660x_private *devpriv = dev->private;
670
671 if (chan >= NI_PFI(0))
672 /* allow new and old names of pfi channels to work. */
673 chan -= NI_PFI(0);
674
675 return devpriv->io_cfg[chan];
676}
677
678static void ni_660x_set_pfi_filter(struct comedi_device *dev,
679 unsigned int chan, unsigned int value)
680{
681 unsigned int val;
682
683 if (chan >= NI_PFI(0))
684 /* allow new and old names of pfi channels to work. */
685 chan -= NI_PFI(0);
686
687 val = ni_660x_read(dev, chip: 0, NI660X_IO_CFG(chan));
688 val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
689 val |= NI660X_IO_CFG_IN_SEL(chan, value);
690 ni_660x_write(dev, chip: 0, bits: val, NI660X_IO_CFG(chan));
691}
692
693static int ni_660x_dio_insn_config(struct comedi_device *dev,
694 struct comedi_subdevice *s,
695 struct comedi_insn *insn,
696 unsigned int *data)
697{
698 unsigned int chan = CR_CHAN(insn->chanspec);
699 int ret;
700
701 switch (data[0]) {
702 case INSN_CONFIG_DIO_OUTPUT:
703 ni_660x_set_pfi_direction(dev, chan, direction: COMEDI_OUTPUT);
704 break;
705
706 case INSN_CONFIG_DIO_INPUT:
707 ni_660x_set_pfi_direction(dev, chan, direction: COMEDI_INPUT);
708 break;
709
710 case INSN_CONFIG_DIO_QUERY:
711 data[1] = ni_660x_get_pfi_direction(dev, chan);
712 break;
713
714 case INSN_CONFIG_SET_ROUTING:
715 ret = ni_660x_set_pfi_routing(dev, chan, source: data[1]);
716 if (ret)
717 return ret;
718 break;
719
720 case INSN_CONFIG_GET_ROUTING:
721 data[1] = ni_660x_get_pfi_routing(dev, chan);
722 break;
723
724 case INSN_CONFIG_FILTER:
725 ni_660x_set_pfi_filter(dev, chan, value: data[1]);
726 break;
727
728 default:
729 return -EINVAL;
730 }
731
732 return insn->n;
733}
734
735static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
736 unsigned int n_pairs,
737 unsigned int *pair_data)
738{
739 struct ni_660x_private *devpriv = dev->private;
740
741 return ni_get_valid_routes(tables: &devpriv->routing_tables, n_pairs,
742 pair_data);
743}
744
745/*
746 * Retrieves the current source of the output selector for the given
747 * destination. If the terminal for the destination is not already configured
748 * as an output, this function returns -EINVAL as error.
749 *
750 * Return: The register value of the destination output selector;
751 * -EINVAL if terminal is not configured for output.
752 */
753static inline int get_output_select_source(int dest, struct comedi_device *dev)
754{
755 struct ni_660x_private *devpriv = dev->private;
756 int reg = -1;
757
758 if (channel_is_pfi(channel: dest)) {
759 if (ni_660x_get_pfi_direction(dev, chan: dest) == COMEDI_OUTPUT)
760 reg = ni_660x_get_pfi_routing(dev, chan: dest);
761 } else if (channel_is_rtsi(channel: dest)) {
762 dev_dbg(dev->class_dev,
763 "%s: unhandled rtsi destination (%d) queried\n",
764 __func__, dest);
765 /*
766 * The following can be enabled when RTSI routing info is
767 * determined (not currently documented):
768 * if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
769 * reg = ni_get_rtsi_routing(dev, dest);
770
771 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
772 * dest = NI_RGOUT0; ** prepare for lookup below **
773 * reg = get_rgout0_reg(dev);
774 * } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
775 * reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
776 * const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
777
778 * dest = NI_RTSI_BRD(i); ** prepare for lookup **
779 * reg = get_ith_rtsi_brd_reg(i, dev);
780 * }
781 * }
782 */
783 } else if (channel_is_ctr(channel: dest)) {
784 reg = ni_tio_get_routing(counter_dev: devpriv->counter_dev, destination: dest);
785 } else {
786 dev_dbg(dev->class_dev,
787 "%s: unhandled destination (%d) queried\n",
788 __func__, dest);
789 }
790
791 if (reg >= 0)
792 return ni_find_route_source(CR_CHAN(reg), dest,
793 tables: &devpriv->routing_tables);
794 return -EINVAL;
795}
796
797/*
798 * Test a route:
799 *
800 * Return: -1 if not connectible;
801 * 0 if connectible and not connected;
802 * 1 if connectible and connected.
803 */
804static inline int test_route(unsigned int src, unsigned int dest,
805 struct comedi_device *dev)
806{
807 struct ni_660x_private *devpriv = dev->private;
808 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
809 tables: &devpriv->routing_tables);
810
811 if (reg < 0)
812 return -1;
813 if (get_output_select_source(dest, dev) != CR_CHAN(src))
814 return 0;
815 return 1;
816}
817
818/* Connect the actual route. */
819static inline int connect_route(unsigned int src, unsigned int dest,
820 struct comedi_device *dev)
821{
822 struct ni_660x_private *devpriv = dev->private;
823 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
824 tables: &devpriv->routing_tables);
825 s8 current_src;
826
827 if (reg < 0)
828 /* route is not valid */
829 return -EINVAL;
830
831 current_src = get_output_select_source(dest, dev);
832 if (current_src == CR_CHAN(src))
833 return -EALREADY;
834 if (current_src >= 0)
835 /* destination mux is already busy. complain, don't overwrite */
836 return -EBUSY;
837
838 /* The route is valid and available. Now connect... */
839 if (channel_is_pfi(CR_CHAN(dest))) {
840 /*
841 * set routing and then direction so that the output does not
842 * first get generated with the wrong pin
843 */
844 ni_660x_set_pfi_routing(dev, chan: dest, source: reg);
845 ni_660x_set_pfi_direction(dev, chan: dest, direction: COMEDI_OUTPUT);
846 } else if (channel_is_rtsi(CR_CHAN(dest))) {
847 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
848 __func__, dest);
849 return -EINVAL;
850 /*
851 * The following can be enabled when RTSI routing info is
852 * determined (not currently documented):
853 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
854 * int ret = incr_rgout0_src_use(src, dev);
855
856 * if (ret < 0)
857 * return ret;
858 * } else if (ni_rtsi_route_requires_mux(reg)) {
859 * ** Attempt to allocate and route (src->brd) **
860 * int brd = incr_rtsi_brd_src_use(src, dev);
861
862 * if (brd < 0)
863 * return brd;
864
865 * ** Now lookup the register value for (brd->dest) **
866 * reg = ni_lookup_route_register(brd, CR_CHAN(dest),
867 * &devpriv->routing_tables);
868 * }
869
870 * ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
871 * ni_set_rtsi_routing(dev, dest, reg);
872 */
873 } else if (channel_is_ctr(CR_CHAN(dest))) {
874 /*
875 * we are adding back the channel modifier info to set
876 * invert/edge info passed by the user
877 */
878 ni_tio_set_routing(counter_dev: devpriv->counter_dev, destination: dest,
879 register_value: reg | (src & ~CR_CHAN(-1)));
880 } else {
881 return -EINVAL;
882 }
883 return 0;
884}
885
886static inline int disconnect_route(unsigned int src, unsigned int dest,
887 struct comedi_device *dev)
888{
889 struct ni_660x_private *devpriv = dev->private;
890 s8 reg = ni_route_to_register(CR_CHAN(src), CR_CHAN(dest),
891 tables: &devpriv->routing_tables);
892
893 if (reg < 0)
894 /* route is not valid */
895 return -EINVAL;
896 if (get_output_select_source(dest, dev) != CR_CHAN(src))
897 /* cannot disconnect something not connected */
898 return -EINVAL;
899
900 /* The route is valid and is connected. Now disconnect... */
901 if (channel_is_pfi(CR_CHAN(dest))) {
902 unsigned int source = ((CR_CHAN(dest) - NI_PFI(0)) < 8)
903 ? NI_660X_PFI_OUTPUT_DIO
904 : NI_660X_PFI_OUTPUT_COUNTER;
905
906 /* set the pfi to high impedance, and disconnect */
907 ni_660x_set_pfi_direction(dev, chan: dest, direction: COMEDI_INPUT);
908 ni_660x_set_pfi_routing(dev, chan: dest, source);
909 } else if (channel_is_rtsi(CR_CHAN(dest))) {
910 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
911 __func__, dest);
912 return -EINVAL;
913 /*
914 * The following can be enabled when RTSI routing info is
915 * determined (not currently documented):
916 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
917 * int ret = decr_rgout0_src_use(src, dev);
918
919 * if (ret < 0)
920 * return ret;
921 * } else if (ni_rtsi_route_requires_mux(reg)) {
922 * ** find which RTSI_BRD line is source for rtsi pin **
923 * int brd = ni_find_route_source(
924 * ni_get_rtsi_routing(dev, dest), CR_CHAN(dest),
925 * &devpriv->routing_tables);
926
927 * if (brd < 0)
928 * return brd;
929
930 * ** decrement/disconnect RTSI_BRD line from source **
931 * decr_rtsi_brd_src_use(src, brd, dev);
932 * }
933
934 * ** set rtsi output selector to default state **
935 * reg = default_rtsi_routing[CR_CHAN(dest) - TRIGGER_LINE(0)];
936 * ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
937 * ni_set_rtsi_routing(dev, dest, reg);
938 */
939 } else if (channel_is_ctr(CR_CHAN(dest))) {
940 ni_tio_unset_routing(counter_dev: devpriv->counter_dev, destination: dest);
941 } else {
942 return -EINVAL;
943 }
944 return 0;
945}
946
947static int ni_global_insn_config(struct comedi_device *dev,
948 struct comedi_insn *insn,
949 unsigned int *data)
950{
951 switch (data[0]) {
952 case INSN_DEVICE_CONFIG_TEST_ROUTE:
953 data[0] = test_route(src: data[1], dest: data[2], dev);
954 return 2;
955 case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
956 return connect_route(src: data[1], dest: data[2], dev);
957 case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
958 return disconnect_route(src: data[1], dest: data[2], dev);
959 /*
960 * This case is already handled one level up.
961 * case INSN_DEVICE_CONFIG_GET_ROUTES:
962 */
963 default:
964 return -EINVAL;
965 }
966 return 1;
967}
968
969static void ni_660x_init_tio_chips(struct comedi_device *dev,
970 unsigned int n_chips)
971{
972 struct ni_660x_private *devpriv = dev->private;
973 unsigned int chip;
974 unsigned int chan;
975
976 /*
977 * We use the ioconfig registers to control dio direction, so zero
978 * output enables in stc dio control reg.
979 */
980 ni_660x_write(dev, chip: 0, bits: 0, reg: NI660X_STC_DIO_CONTROL);
981
982 for (chip = 0; chip < n_chips; ++chip) {
983 /* init dma configuration register */
984 devpriv->dma_cfg[chip] = 0;
985 for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
986 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
987 ni_660x_write(dev, chip, bits: devpriv->dma_cfg[chip],
988 reg: NI660X_DMA_CFG);
989
990 /* init ioconfig registers */
991 for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
992 ni_660x_write(dev, chip, bits: 0, NI660X_IO_CFG(chan));
993 }
994}
995
996static int ni_660x_auto_attach(struct comedi_device *dev,
997 unsigned long context)
998{
999 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1000 const struct ni_660x_board *board = NULL;
1001 struct ni_660x_private *devpriv;
1002 struct comedi_subdevice *s;
1003 struct ni_gpct_device *gpct_dev;
1004 unsigned int n_counters;
1005 int subdev;
1006 int ret;
1007 unsigned int i;
1008 unsigned int global_interrupt_config_bits;
1009
1010 if (context < ARRAY_SIZE(ni_660x_boards))
1011 board = &ni_660x_boards[context];
1012 if (!board)
1013 return -ENODEV;
1014 dev->board_ptr = board;
1015 dev->board_name = board->name;
1016
1017 ret = comedi_pci_enable(dev);
1018 if (ret)
1019 return ret;
1020
1021 ret = ni_660x_allocate_private(dev);
1022 if (ret < 0)
1023 return ret;
1024 devpriv = dev->private;
1025
1026 devpriv->mite = mite_attach(dev, use_win1: true); /* use win1 */
1027 if (!devpriv->mite)
1028 return -ENOMEM;
1029
1030 ret = ni_660x_alloc_mite_rings(dev);
1031 if (ret < 0)
1032 return ret;
1033
1034 ni_660x_init_tio_chips(dev, n_chips: board->n_chips);
1035
1036 /* prepare the device for globally-named routes. */
1037 if (ni_assign_device_routes(device_family: "ni_660x", board_name: board->name, NULL,
1038 tables: &devpriv->routing_tables) < 0) {
1039 dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
1040 __func__, board->name);
1041 dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
1042 __func__, board->name);
1043 } else {
1044 /*
1045 * only(?) assign insn_device_config if we have global names for
1046 * this device.
1047 */
1048 dev->insn_device_config = ni_global_insn_config;
1049 dev->get_valid_routes = _ni_get_valid_routes;
1050 }
1051
1052 n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
1053 gpct_dev = ni_gpct_device_construct(dev,
1054 write: ni_660x_gpct_write,
1055 read: ni_660x_gpct_read,
1056 ni_gpct_variant_660x,
1057 num_counters: n_counters,
1058 NI660X_COUNTERS_PER_CHIP,
1059 routing_tables: &devpriv->routing_tables);
1060 if (!gpct_dev)
1061 return -ENOMEM;
1062 devpriv->counter_dev = gpct_dev;
1063
1064 ret = comedi_alloc_subdevices(dev, num_subdevices: 2 + NI660X_MAX_COUNTERS);
1065 if (ret)
1066 return ret;
1067
1068 subdev = 0;
1069
1070 s = &dev->subdevices[subdev++];
1071 /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
1072 s->type = COMEDI_SUBD_UNUSED;
1073
1074 /*
1075 * Digital I/O subdevice
1076 *
1077 * There are 40 channels but only the first 32 can be digital I/Os.
1078 * The last 8 are dedicated to counters 0 and 1.
1079 *
1080 * Counter 0-3 signals are from the first TIO chip.
1081 * Counter 4-7 signals are from the second TIO chip.
1082 *
1083 * Comedi External
1084 * PFI Chan DIO Chan Counter Signal
1085 * ------- -------- --------------
1086 * 0 0
1087 * 1 1
1088 * 2 2
1089 * 3 3
1090 * 4 4
1091 * 5 5
1092 * 6 6
1093 * 7 7
1094 * 8 8 CTR 7 OUT
1095 * 9 9 CTR 7 AUX
1096 * 10 10 CTR 7 GATE
1097 * 11 11 CTR 7 SOURCE
1098 * 12 12 CTR 6 OUT
1099 * 13 13 CTR 6 AUX
1100 * 14 14 CTR 6 GATE
1101 * 15 15 CTR 6 SOURCE
1102 * 16 16 CTR 5 OUT
1103 * 17 17 CTR 5 AUX
1104 * 18 18 CTR 5 GATE
1105 * 19 19 CTR 5 SOURCE
1106 * 20 20 CTR 4 OUT
1107 * 21 21 CTR 4 AUX
1108 * 22 22 CTR 4 GATE
1109 * 23 23 CTR 4 SOURCE
1110 * 24 24 CTR 3 OUT
1111 * 25 25 CTR 3 AUX
1112 * 26 26 CTR 3 GATE
1113 * 27 27 CTR 3 SOURCE
1114 * 28 28 CTR 2 OUT
1115 * 29 29 CTR 2 AUX
1116 * 30 30 CTR 2 GATE
1117 * 31 31 CTR 2 SOURCE
1118 * 32 CTR 1 OUT
1119 * 33 CTR 1 AUX
1120 * 34 CTR 1 GATE
1121 * 35 CTR 1 SOURCE
1122 * 36 CTR 0 OUT
1123 * 37 CTR 0 AUX
1124 * 38 CTR 0 GATE
1125 * 39 CTR 0 SOURCE
1126 */
1127 s = &dev->subdevices[subdev++];
1128 s->type = COMEDI_SUBD_DIO;
1129 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1130 s->n_chan = NI660X_NUM_PFI_CHANNELS;
1131 s->maxdata = 1;
1132 s->range_table = &range_digital;
1133 s->insn_bits = ni_660x_dio_insn_bits;
1134 s->insn_config = ni_660x_dio_insn_config;
1135
1136 /*
1137 * Default the DIO channels as:
1138 * chan 0-7: DIO inputs
1139 * chan 8-39: counter signal inputs
1140 */
1141 for (i = 0; i < s->n_chan; ++i) {
1142 unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
1143 : NI_660X_PFI_OUTPUT_COUNTER;
1144
1145 ni_660x_set_pfi_routing(dev, chan: i, source);
1146 ni_660x_set_pfi_direction(dev, chan: i, direction: COMEDI_INPUT);/* high-z */
1147 }
1148
1149 /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */
1150 for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
1151 s = &dev->subdevices[subdev++];
1152 if (i < n_counters) {
1153 struct ni_gpct *counter = &gpct_dev->counters[i];
1154
1155 s->type = COMEDI_SUBD_COUNTER;
1156 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
1157 SDF_LSAMPL | SDF_CMD_READ;
1158 s->n_chan = 3;
1159 s->maxdata = 0xffffffff;
1160 s->insn_read = ni_tio_insn_read;
1161 s->insn_write = ni_tio_insn_write;
1162 s->insn_config = ni_tio_insn_config;
1163 s->len_chanlist = 1;
1164 s->do_cmd = ni_660x_cmd;
1165 s->do_cmdtest = ni_tio_cmdtest;
1166 s->cancel = ni_660x_cancel;
1167 s->poll = ni_660x_input_poll;
1168 s->buf_change = ni_660x_buf_change;
1169 s->async_dma_dir = DMA_BIDIRECTIONAL;
1170 s->private = counter;
1171
1172 ni_tio_init_counter(counter);
1173 } else {
1174 s->type = COMEDI_SUBD_UNUSED;
1175 }
1176 }
1177
1178 /*
1179 * To be safe, set counterswap bits on tio chips after all the counter
1180 * outputs have been set to high impedance mode.
1181 */
1182 for (i = 0; i < board->n_chips; ++i)
1183 set_tio_counterswap(dev, chip: i);
1184
1185 ret = request_irq(irq: pcidev->irq, handler: ni_660x_interrupt, IRQF_SHARED,
1186 name: dev->board_name, dev);
1187 if (ret < 0) {
1188 dev_warn(dev->class_dev, " irq not available\n");
1189 return ret;
1190 }
1191 dev->irq = pcidev->irq;
1192 global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
1193 if (board->n_chips > 1)
1194 global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
1195 ni_660x_write(dev, chip: 0, bits: global_interrupt_config_bits,
1196 reg: NI660X_GLOBAL_INT_CFG);
1197
1198 return 0;
1199}
1200
1201static void ni_660x_detach(struct comedi_device *dev)
1202{
1203 struct ni_660x_private *devpriv = dev->private;
1204
1205 if (dev->irq) {
1206 ni_660x_write(dev, chip: 0, bits: 0, reg: NI660X_GLOBAL_INT_CFG);
1207 free_irq(dev->irq, dev);
1208 }
1209 if (devpriv) {
1210 ni_gpct_device_destroy(counter_dev: devpriv->counter_dev);
1211 ni_660x_free_mite_rings(dev);
1212 mite_detach(mite: devpriv->mite);
1213 }
1214 if (dev->mmio)
1215 iounmap(addr: dev->mmio);
1216 comedi_pci_disable(dev);
1217}
1218
1219static struct comedi_driver ni_660x_driver = {
1220 .driver_name = "ni_660x",
1221 .module = THIS_MODULE,
1222 .auto_attach = ni_660x_auto_attach,
1223 .detach = ni_660x_detach,
1224};
1225
1226static int ni_660x_pci_probe(struct pci_dev *dev,
1227 const struct pci_device_id *id)
1228{
1229 return comedi_pci_auto_config(pcidev: dev, driver: &ni_660x_driver, context: id->driver_data);
1230}
1231
1232static const struct pci_device_id ni_660x_pci_table[] = {
1233 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
1234 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
1235 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
1236 { PCI_VDEVICE(NI, 0x2db0), BOARD_PCI6608 },
1237 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
1238 { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
1239 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
1240 { 0 }
1241};
1242MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
1243
1244static struct pci_driver ni_660x_pci_driver = {
1245 .name = "ni_660x",
1246 .id_table = ni_660x_pci_table,
1247 .probe = ni_660x_pci_probe,
1248 .remove = comedi_pci_auto_unconfig,
1249};
1250module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
1251
1252MODULE_AUTHOR("Comedi https://www.comedi.org");
1253MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
1254MODULE_LICENSE("GPL");
1255

source code of linux/drivers/comedi/drivers/ni_660x.c