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}
324
325static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
326 unsigned int mite_channel,
327 struct ni_gpct *counter)
328{
329 struct ni_660x_private *devpriv = dev->private;
330 unsigned int chip = counter->chip_index;
331
332 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
333 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
334 ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG);
335}
336
337static int ni_660x_request_mite_channel(struct comedi_device *dev,
338 struct ni_gpct *counter,
339 enum comedi_io_direction direction)
340{
341 struct ni_660x_private *devpriv = dev->private;
342 struct mite_ring *ring;
343 struct mite_channel *mite_chan;
344 unsigned long flags;
345
346 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
347 ring = devpriv->ring[counter->chip_index][counter->counter_index];
348 mite_chan = mite_request_channel(devpriv->mite, ring);
349 if (!mite_chan) {
350 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
351 dev_err(dev->class_dev,
352 "failed to reserve mite dma channel for counter\n");
353 return -EBUSY;
354 }
355 mite_chan->dir = direction;
356 ni_tio_set_mite_channel(counter, mite_chan);
357 ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
358 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
359 return 0;
360}
361
362static void ni_660x_release_mite_channel(struct comedi_device *dev,
363 struct ni_gpct *counter)
364{
365 struct ni_660x_private *devpriv = dev->private;
366 unsigned long flags;
367
368 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
369 if (counter->mite_chan) {
370 struct mite_channel *mite_chan = counter->mite_chan;
371
372 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
373 ni_tio_set_mite_channel(counter, NULL);
374 mite_release_channel(mite_chan);
375 }
376 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
377}
378
379static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
380{
381 struct ni_gpct *counter = s->private;
382 int retval;
383
384 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
385 if (retval) {
386 dev_err(dev->class_dev,
387 "no dma channel available for use by counter\n");
388 return retval;
389 }
390 ni_tio_acknowledge(counter);
391
392 return ni_tio_cmd(dev, s);
393}
394
395static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
396{
397 struct ni_gpct *counter = s->private;
398 int retval;
399
400 retval = ni_tio_cancel(counter);
401 ni_660x_release_mite_channel(dev, counter);
402 return retval;
403}
404
405static void set_tio_counterswap(struct comedi_device *dev, int chip)
406{
407 unsigned int bits = 0;
408
409
410
411
412
413
414
415 if (chip)
416 bits = NI660X_CLK_CFG_COUNTER_SWAP;
417
418 ni_660x_write(dev, chip, bits, NI660X_CLK_CFG);
419}
420
421static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
422 struct comedi_subdevice *s)
423{
424 struct ni_gpct *counter = s->private;
425
426 ni_tio_handle_interrupt(counter, s);
427 comedi_handle_events(dev, s);
428}
429
430static irqreturn_t ni_660x_interrupt(int irq, void *d)
431{
432 struct comedi_device *dev = d;
433 struct ni_660x_private *devpriv = dev->private;
434 struct comedi_subdevice *s;
435 unsigned int i;
436 unsigned long flags;
437
438 if (!dev->attached)
439 return IRQ_NONE;
440
441 smp_mb();
442
443
444 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
445 for (i = 0; i < dev->n_subdevices; ++i) {
446 s = &dev->subdevices[i];
447 if (s->type == COMEDI_SUBD_COUNTER)
448 ni_660x_handle_gpct_interrupt(dev, s);
449 }
450 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
451 return IRQ_HANDLED;
452}
453
454static int ni_660x_input_poll(struct comedi_device *dev,
455 struct comedi_subdevice *s)
456{
457 struct ni_660x_private *devpriv = dev->private;
458 struct ni_gpct *counter = s->private;
459 unsigned long flags;
460
461
462 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
463 mite_sync_dma(counter->mite_chan, s);
464 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
465 return comedi_buf_read_n_available(s);
466}
467
468static int ni_660x_buf_change(struct comedi_device *dev,
469 struct comedi_subdevice *s)
470{
471 struct ni_660x_private *devpriv = dev->private;
472 struct ni_gpct *counter = s->private;
473 struct mite_ring *ring;
474 int ret;
475
476 ring = devpriv->ring[counter->chip_index][counter->counter_index];
477 ret = mite_buf_change(ring, s);
478 if (ret < 0)
479 return ret;
480
481 return 0;
482}
483
484static int ni_660x_allocate_private(struct comedi_device *dev)
485{
486 struct ni_660x_private *devpriv;
487 unsigned int i;
488
489 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
490 if (!devpriv)
491 return -ENOMEM;
492
493 spin_lock_init(&devpriv->mite_channel_lock);
494 spin_lock_init(&devpriv->interrupt_lock);
495 for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i)
496 devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER;
497
498 return 0;
499}
500
501static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
502{
503 const struct ni_660x_board *board = dev->board_ptr;
504 struct ni_660x_private *devpriv = dev->private;
505 unsigned int i;
506 unsigned int j;
507
508 for (i = 0; i < board->n_chips; ++i) {
509 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) {
510 devpriv->ring[i][j] = mite_alloc_ring(devpriv->mite);
511 if (!devpriv->ring[i][j])
512 return -ENOMEM;
513 }
514 }
515 return 0;
516}
517
518static void ni_660x_free_mite_rings(struct comedi_device *dev)
519{
520 const struct ni_660x_board *board = dev->board_ptr;
521 struct ni_660x_private *devpriv = dev->private;
522 unsigned int i;
523 unsigned int j;
524
525 for (i = 0; i < board->n_chips; ++i) {
526 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j)
527 mite_free_ring(devpriv->ring[i][j]);
528 }
529}
530
531static int ni_660x_dio_insn_bits(struct comedi_device *dev,
532 struct comedi_subdevice *s,
533 struct comedi_insn *insn,
534 unsigned int *data)
535{
536 unsigned int shift = CR_CHAN(insn->chanspec);
537 unsigned int mask = data[0] << shift;
538 unsigned int bits = data[1] << shift;
539
540
541
542
543
544
545
546 if (mask) {
547 s->state &= ~mask;
548 s->state |= (bits & mask);
549 ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT);
550 }
551
552
553
554
555
556 data[1] = ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> shift;
557
558 return insn->n;
559}
560
561static void ni_660x_select_pfi_output(struct comedi_device *dev,
562 unsigned int chan, unsigned int out_sel)
563{
564 const struct ni_660x_board *board = dev->board_ptr;
565 unsigned int active_chip = 0;
566 unsigned int idle_chip = 0;
567 unsigned int bits;
568
569 if (chan >= NI_PFI(0))
570
571 chan -= NI_PFI(0);
572
573 if (board->n_chips > 1) {
574 if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
575 chan >= 8 && chan <= 23) {
576
577 active_chip = 1;
578 idle_chip = 0;
579 } else {
580
581 active_chip = 0;
582 idle_chip = 1;
583 }
584 }
585
586 if (idle_chip != active_chip) {
587
588 bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan));
589 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
590 bits |= NI660X_IO_CFG_OUT_SEL(chan, 0);
591 ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan));
592 }
593
594
595 bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan));
596 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
597 bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
598 ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
599}
600
601static void ni_660x_set_pfi_direction(struct comedi_device *dev,
602 unsigned int chan,
603 unsigned int direction)
604{
605 struct ni_660x_private *devpriv = dev->private;
606 u64 bit;
607
608 if (chan >= NI_PFI(0))
609
610 chan -= NI_PFI(0);
611
612 bit = 1ULL << chan;
613
614 if (direction == COMEDI_OUTPUT) {
615 devpriv->io_dir |= bit;
616
617 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
618 } else {
619 devpriv->io_dir &= ~bit;
620
621 ni_660x_select_pfi_output(dev, chan, 0);
622 }
623}
624
625static unsigned int ni_660x_get_pfi_direction(struct comedi_device *dev,
626 unsigned int chan)
627{
628 struct ni_660x_private *devpriv = dev->private;
629 u64 bit;
630
631 if (chan >= NI_PFI(0))
632
633 chan -= NI_PFI(0);
634
635 bit = 1ULL << chan;
636
637 return (devpriv->io_dir & bit) ? COMEDI_OUTPUT : COMEDI_INPUT;
638}
639
640static int ni_660x_set_pfi_routing(struct comedi_device *dev,
641 unsigned int chan, unsigned int source)
642{
643 struct ni_660x_private *devpriv = dev->private;
644
645 if (chan >= NI_PFI(0))
646
647 chan -= NI_PFI(0);
648
649 switch (source) {
650 case NI_660X_PFI_OUTPUT_COUNTER:
651 if (chan < 8)
652 return -EINVAL;
653 break;
654 case NI_660X_PFI_OUTPUT_DIO:
655 if (chan > 31)
656 return -EINVAL;
657 break;
658 default:
659 return -EINVAL;
660 }
661
662 devpriv->io_cfg[chan] = source;
663 if (ni_660x_get_pfi_direction(dev, chan) == COMEDI_OUTPUT)
664 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
665 return 0;
666}
667
668static int ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned int chan)
669{
670 struct ni_660x_private *devpriv = dev->private;
671
672 if (chan >= NI_PFI(0))
673
674 chan -= NI_PFI(0);
675
676 return devpriv->io_cfg[chan];
677}
678
679static void ni_660x_set_pfi_filter(struct comedi_device *dev,
680 unsigned int chan, unsigned int value)
681{
682 unsigned int val;
683
684 if (chan >= NI_PFI(0))
685
686 chan -= NI_PFI(0);
687
688 val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
689 val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
690 val |= NI660X_IO_CFG_IN_SEL(chan, value);
691 ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
692}
693
694static int ni_660x_dio_insn_config(struct comedi_device *dev,
695 struct comedi_subdevice *s,
696 struct comedi_insn *insn,
697 unsigned int *data)
698{
699 unsigned int chan = CR_CHAN(insn->chanspec);
700 int ret;
701
702 switch (data[0]) {
703 case INSN_CONFIG_DIO_OUTPUT:
704 ni_660x_set_pfi_direction(dev, chan, COMEDI_OUTPUT);
705 break;
706
707 case INSN_CONFIG_DIO_INPUT:
708 ni_660x_set_pfi_direction(dev, chan, COMEDI_INPUT);
709 break;
710
711 case INSN_CONFIG_DIO_QUERY:
712 data[1] = ni_660x_get_pfi_direction(dev, chan);
713 break;
714
715 case INSN_CONFIG_SET_ROUTING:
716 ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
717 if (ret)
718 return ret;
719 break;
720
721 case INSN_CONFIG_GET_ROUTING:
722 data[1] = ni_660x_get_pfi_routing(dev, chan);
723 break;
724
725 case INSN_CONFIG_FILTER:
726 ni_660x_set_pfi_filter(dev, chan, data[1]);
727 break;
728
729 default:
730 return -EINVAL;
731 }
732
733 return insn->n;
734}
735
736static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
737 unsigned int n_pairs,
738 unsigned int *pair_data)
739{
740 struct ni_660x_private *devpriv = dev->private;
741
742 return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
743 pair_data);
744}
745
746
747
748
749
750
751
752
753
754static inline int get_output_select_source(int dest, struct comedi_device *dev)
755{
756 struct ni_660x_private *devpriv = dev->private;
757 int reg = -1;
758
759 if (channel_is_pfi(dest)) {
760 if (ni_660x_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
761 reg = ni_660x_get_pfi_routing(dev, dest);
762 } else if (channel_is_rtsi(dest)) {
763 dev_dbg(dev->class_dev,
764 "%s: unhandled rtsi destination (%d) queried\n",
765 __func__, dest);
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784 } else if (channel_is_ctr(dest)) {
785 reg = ni_tio_get_routing(devpriv->counter_dev, dest);
786 } else {
787 dev_dbg(dev->class_dev,
788 "%s: unhandled destination (%d) queried\n",
789 __func__, dest);
790 }
791
792 if (reg >= 0)
793 return ni_find_route_source(CR_CHAN(reg), dest,
794 &devpriv->routing_tables);
795 return -EINVAL;
796}
797
798
799
800
801
802
803
804
805static inline int test_route(unsigned int src, unsigned int dest,
806 struct comedi_device *dev)
807{
808 struct ni_660x_private *devpriv = dev->private;
809 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
810 &devpriv->routing_tables);
811
812 if (reg < 0)
813 return -1;
814 if (get_output_select_source(dest, dev) != CR_CHAN(src))
815 return 0;
816 return 1;
817}
818
819
820static inline int connect_route(unsigned int src, unsigned int dest,
821 struct comedi_device *dev)
822{
823 struct ni_660x_private *devpriv = dev->private;
824 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
825 &devpriv->routing_tables);
826 s8 current_src;
827
828 if (reg < 0)
829
830 return -EINVAL;
831
832 current_src = get_output_select_source(dest, dev);
833 if (current_src == CR_CHAN(src))
834 return -EALREADY;
835 if (current_src >= 0)
836
837 return -EBUSY;
838
839
840 if (channel_is_pfi(CR_CHAN(dest))) {
841
842
843
844
845 ni_660x_set_pfi_routing(dev, dest, reg);
846 ni_660x_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
847 } else if (channel_is_rtsi(CR_CHAN(dest))) {
848 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
849 __func__, dest);
850 return -EINVAL;
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874 } else if (channel_is_ctr(CR_CHAN(dest))) {
875
876
877
878
879 ni_tio_set_routing(devpriv->counter_dev, dest,
880 reg | (src & ~CR_CHAN(-1)));
881 } else {
882 return -EINVAL;
883 }
884 return 0;
885}
886
887static inline int disconnect_route(unsigned int src, unsigned int dest,
888 struct comedi_device *dev)
889{
890 struct ni_660x_private *devpriv = dev->private;
891 s8 reg = ni_route_to_register(CR_CHAN(src), CR_CHAN(dest),
892 &devpriv->routing_tables);
893
894 if (reg < 0)
895
896 return -EINVAL;
897 if (get_output_select_source(dest, dev) != CR_CHAN(src))
898
899 return -EINVAL;
900
901
902 if (channel_is_pfi(CR_CHAN(dest))) {
903 unsigned int source = ((CR_CHAN(dest) - NI_PFI(0)) < 8)
904 ? NI_660X_PFI_OUTPUT_DIO
905 : NI_660X_PFI_OUTPUT_COUNTER;
906
907
908 ni_660x_set_pfi_direction(dev, dest, COMEDI_INPUT);
909 ni_660x_set_pfi_routing(dev, dest, source);
910 } else if (channel_is_rtsi(CR_CHAN(dest))) {
911 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
912 __func__, dest);
913 return -EINVAL;
914
915
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 } else if (channel_is_ctr(CR_CHAN(dest))) {
941 ni_tio_unset_routing(devpriv->counter_dev, dest);
942 } else {
943 return -EINVAL;
944 }
945 return 0;
946}
947
948static int ni_global_insn_config(struct comedi_device *dev,
949 struct comedi_insn *insn,
950 unsigned int *data)
951{
952 switch (data[0]) {
953 case INSN_DEVICE_CONFIG_TEST_ROUTE:
954 data[0] = test_route(data[1], data[2], dev);
955 return 2;
956 case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
957 return connect_route(data[1], data[2], dev);
958 case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
959 return disconnect_route(data[1], data[2], dev);
960
961
962
963
964 default:
965 return -EINVAL;
966 }
967 return 1;
968}
969
970static void ni_660x_init_tio_chips(struct comedi_device *dev,
971 unsigned int n_chips)
972{
973 struct ni_660x_private *devpriv = dev->private;
974 unsigned int chip;
975 unsigned int chan;
976
977
978
979
980
981 ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL);
982
983 for (chip = 0; chip < n_chips; ++chip) {
984
985 devpriv->dma_cfg[chip] = 0;
986 for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
987 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
988 ni_660x_write(dev, chip, devpriv->dma_cfg[chip],
989 NI660X_DMA_CFG);
990
991
992 for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
993 ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan));
994 }
995}
996
997static int ni_660x_auto_attach(struct comedi_device *dev,
998 unsigned long context)
999{
1000 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1001 const struct ni_660x_board *board = NULL;
1002 struct ni_660x_private *devpriv;
1003 struct comedi_subdevice *s;
1004 struct ni_gpct_device *gpct_dev;
1005 unsigned int n_counters;
1006 int subdev;
1007 int ret;
1008 unsigned int i;
1009 unsigned int global_interrupt_config_bits;
1010
1011 if (context < ARRAY_SIZE(ni_660x_boards))
1012 board = &ni_660x_boards[context];
1013 if (!board)
1014 return -ENODEV;
1015 dev->board_ptr = board;
1016 dev->board_name = board->name;
1017
1018 ret = comedi_pci_enable(dev);
1019 if (ret)
1020 return ret;
1021
1022 ret = ni_660x_allocate_private(dev);
1023 if (ret < 0)
1024 return ret;
1025 devpriv = dev->private;
1026
1027 devpriv->mite = mite_attach(dev, true);
1028 if (!devpriv->mite)
1029 return -ENOMEM;
1030
1031 ret = ni_660x_alloc_mite_rings(dev);
1032 if (ret < 0)
1033 return ret;
1034
1035 ni_660x_init_tio_chips(dev, board->n_chips);
1036
1037
1038 if (ni_assign_device_routes("ni_660x", board->name,
1039 &devpriv->routing_tables) < 0) {
1040 dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
1041 __func__, board->name);
1042 dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
1043 __func__, board->name);
1044 } else {
1045
1046
1047
1048
1049 dev->insn_device_config = ni_global_insn_config;
1050 dev->get_valid_routes = _ni_get_valid_routes;
1051 }
1052
1053 n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
1054 gpct_dev = ni_gpct_device_construct(dev,
1055 ni_660x_gpct_write,
1056 ni_660x_gpct_read,
1057 ni_gpct_variant_660x,
1058 n_counters,
1059 NI660X_COUNTERS_PER_CHIP,
1060 &devpriv->routing_tables);
1061 if (!gpct_dev)
1062 return -ENOMEM;
1063 devpriv->counter_dev = gpct_dev;
1064
1065 ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS);
1066 if (ret)
1067 return ret;
1068
1069 subdev = 0;
1070
1071 s = &dev->subdevices[subdev++];
1072
1073 s->type = COMEDI_SUBD_UNUSED;
1074
1075
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 s = &dev->subdevices[subdev++];
1129 s->type = COMEDI_SUBD_DIO;
1130 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1131 s->n_chan = NI660X_NUM_PFI_CHANNELS;
1132 s->maxdata = 1;
1133 s->range_table = &range_digital;
1134 s->insn_bits = ni_660x_dio_insn_bits;
1135 s->insn_config = ni_660x_dio_insn_config;
1136
1137
1138
1139
1140
1141
1142 for (i = 0; i < s->n_chan; ++i) {
1143 unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
1144 : NI_660X_PFI_OUTPUT_COUNTER;
1145
1146 ni_660x_set_pfi_routing(dev, i, source);
1147 ni_660x_set_pfi_direction(dev, i, COMEDI_INPUT);
1148 }
1149
1150
1151 for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
1152 s = &dev->subdevices[subdev++];
1153 if (i < n_counters) {
1154 struct ni_gpct *counter = &gpct_dev->counters[i];
1155
1156 s->type = COMEDI_SUBD_COUNTER;
1157 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
1158 SDF_LSAMPL | SDF_CMD_READ;
1159 s->n_chan = 3;
1160 s->maxdata = 0xffffffff;
1161 s->insn_read = ni_tio_insn_read;
1162 s->insn_write = ni_tio_insn_write;
1163 s->insn_config = ni_tio_insn_config;
1164 s->len_chanlist = 1;
1165 s->do_cmd = ni_660x_cmd;
1166 s->do_cmdtest = ni_tio_cmdtest;
1167 s->cancel = ni_660x_cancel;
1168 s->poll = ni_660x_input_poll;
1169 s->buf_change = ni_660x_buf_change;
1170 s->async_dma_dir = DMA_BIDIRECTIONAL;
1171 s->private = counter;
1172
1173 ni_tio_init_counter(counter);
1174 } else {
1175 s->type = COMEDI_SUBD_UNUSED;
1176 }
1177 }
1178
1179
1180
1181
1182
1183 for (i = 0; i < board->n_chips; ++i)
1184 set_tio_counterswap(dev, i);
1185
1186 ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
1187 dev->board_name, dev);
1188 if (ret < 0) {
1189 dev_warn(dev->class_dev, " irq not available\n");
1190 return ret;
1191 }
1192 dev->irq = pcidev->irq;
1193 global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
1194 if (board->n_chips > 1)
1195 global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
1196 ni_660x_write(dev, 0, global_interrupt_config_bits,
1197 NI660X_GLOBAL_INT_CFG);
1198
1199 return 0;
1200}
1201
1202static void ni_660x_detach(struct comedi_device *dev)
1203{
1204 struct ni_660x_private *devpriv = dev->private;
1205
1206 if (dev->irq) {
1207 ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG);
1208 free_irq(dev->irq, dev);
1209 }
1210 if (devpriv) {
1211 ni_gpct_device_destroy(devpriv->counter_dev);
1212 ni_660x_free_mite_rings(dev);
1213 mite_detach(devpriv->mite);
1214 }
1215 if (dev->mmio)
1216 iounmap(dev->mmio);
1217 comedi_pci_disable(dev);
1218}
1219
1220static struct comedi_driver ni_660x_driver = {
1221 .driver_name = "ni_660x",
1222 .module = THIS_MODULE,
1223 .auto_attach = ni_660x_auto_attach,
1224 .detach = ni_660x_detach,
1225};
1226
1227static int ni_660x_pci_probe(struct pci_dev *dev,
1228 const struct pci_device_id *id)
1229{
1230 return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
1231}
1232
1233static const struct pci_device_id ni_660x_pci_table[] = {
1234 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
1235 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
1236 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
1237 { PCI_VDEVICE(NI, 0x2db0), BOARD_PCI6608 },
1238 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
1239 { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
1240 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
1241 { 0 }
1242};
1243MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
1244
1245static struct pci_driver ni_660x_pci_driver = {
1246 .name = "ni_660x",
1247 .id_table = ni_660x_pci_table,
1248 .probe = ni_660x_pci_probe,
1249 .remove = comedi_pci_auto_unconfig,
1250};
1251module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
1252
1253MODULE_AUTHOR("Comedi http://www.comedi.org");
1254MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
1255MODULE_LICENSE("GPL");
1256