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