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
28
29
30
31
32
33
34
35
36#include <linux/module.h>
37#include <linux/interrupt.h>
38
39#include "../comedi_pci.h"
40
41#include "mite.h"
42#include "ni_tio.h"
43
44
45enum ni_660x_register {
46
47 NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS,
48 NI660X_STC_DIO_OUTPUT,
49 NI660X_STC_DIO_CONTROL,
50 NI660X_STC_DIO_SERIAL_INPUT,
51 NI660X_DIO32_INPUT,
52 NI660X_DIO32_OUTPUT,
53 NI660X_CLK_CFG,
54 NI660X_GLOBAL_INT_STATUS,
55 NI660X_DMA_CFG,
56 NI660X_GLOBAL_INT_CFG,
57 NI660X_IO_CFG_0_1,
58 NI660X_IO_CFG_2_3,
59 NI660X_IO_CFG_4_5,
60 NI660X_IO_CFG_6_7,
61 NI660X_IO_CFG_8_9,
62 NI660X_IO_CFG_10_11,
63 NI660X_IO_CFG_12_13,
64 NI660X_IO_CFG_14_15,
65 NI660X_IO_CFG_16_17,
66 NI660X_IO_CFG_18_19,
67 NI660X_IO_CFG_20_21,
68 NI660X_IO_CFG_22_23,
69 NI660X_IO_CFG_24_25,
70 NI660X_IO_CFG_26_27,
71 NI660X_IO_CFG_28_29,
72 NI660X_IO_CFG_30_31,
73 NI660X_IO_CFG_32_33,
74 NI660X_IO_CFG_34_35,
75 NI660X_IO_CFG_36_37,
76 NI660X_IO_CFG_38_39,
77 NI660X_NUM_REGS,
78};
79
80#define NI660X_CLK_CFG_COUNTER_SWAP BIT(21)
81
82#define NI660X_GLOBAL_INT_COUNTER0 BIT(8)
83#define NI660X_GLOBAL_INT_COUNTER1 BIT(9)
84#define NI660X_GLOBAL_INT_COUNTER2 BIT(10)
85#define NI660X_GLOBAL_INT_COUNTER3 BIT(11)
86#define NI660X_GLOBAL_INT_CASCADE BIT(29)
87#define NI660X_GLOBAL_INT_GLOBAL_POL BIT(30)
88#define NI660X_GLOBAL_INT_GLOBAL BIT(31)
89
90#define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c)))
91#define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
92#define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
93#define NI660X_DMA_CFG_RESET(_c) NI660X_DMA_CFG_SEL((_c), 0x80)
94
95#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2))
96#define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8))
97#define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3)
98#define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12))
99#define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7)
100
101struct ni_660x_register_data {
102 int offset;
103 char size;
104};
105
106static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = {
107 [NITIO_G0_INT_ACK] = { 0x004, 2 },
108 [NITIO_G0_STATUS] = { 0x004, 2 },
109 [NITIO_G1_INT_ACK] = { 0x006, 2 },
110 [NITIO_G1_STATUS] = { 0x006, 2 },
111 [NITIO_G01_STATUS] = { 0x008, 2 },
112 [NITIO_G0_CMD] = { 0x00c, 2 },
113 [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 },
114 [NITIO_G1_CMD] = { 0x00e, 2 },
115 [NITIO_G0_HW_SAVE] = { 0x010, 4 },
116 [NITIO_G1_HW_SAVE] = { 0x014, 4 },
117 [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 },
118 [NI660X_STC_DIO_CONTROL] = { 0x016, 2 },
119 [NITIO_G0_SW_SAVE] = { 0x018, 4 },
120 [NITIO_G1_SW_SAVE] = { 0x01c, 4 },
121 [NITIO_G0_MODE] = { 0x034, 2 },
122 [NITIO_G01_STATUS1] = { 0x036, 2 },
123 [NITIO_G1_MODE] = { 0x036, 2 },
124 [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 },
125 [NITIO_G0_LOADA] = { 0x038, 4 },
126 [NITIO_G01_STATUS2] = { 0x03a, 2 },
127 [NITIO_G0_LOADB] = { 0x03c, 4 },
128 [NITIO_G1_LOADA] = { 0x040, 4 },
129 [NITIO_G1_LOADB] = { 0x044, 4 },
130 [NITIO_G0_INPUT_SEL] = { 0x048, 2 },
131 [NITIO_G1_INPUT_SEL] = { 0x04a, 2 },
132 [NITIO_G0_AUTO_INC] = { 0x088, 2 },
133 [NITIO_G1_AUTO_INC] = { 0x08a, 2 },
134 [NITIO_G01_RESET] = { 0x090, 2 },
135 [NITIO_G0_INT_ENA] = { 0x092, 2 },
136 [NITIO_G1_INT_ENA] = { 0x096, 2 },
137 [NITIO_G0_CNT_MODE] = { 0x0b0, 2 },
138 [NITIO_G1_CNT_MODE] = { 0x0b2, 2 },
139 [NITIO_G0_GATE2] = { 0x0b4, 2 },
140 [NITIO_G1_GATE2] = { 0x0b6, 2 },
141 [NITIO_G0_DMA_CFG] = { 0x0b8, 2 },
142 [NITIO_G0_DMA_STATUS] = { 0x0b8, 2 },
143 [NITIO_G1_DMA_CFG] = { 0x0ba, 2 },
144 [NITIO_G1_DMA_STATUS] = { 0x0ba, 2 },
145 [NITIO_G2_INT_ACK] = { 0x104, 2 },
146 [NITIO_G2_STATUS] = { 0x104, 2 },
147 [NITIO_G3_INT_ACK] = { 0x106, 2 },
148 [NITIO_G3_STATUS] = { 0x106, 2 },
149 [NITIO_G23_STATUS] = { 0x108, 2 },
150 [NITIO_G2_CMD] = { 0x10c, 2 },
151 [NITIO_G3_CMD] = { 0x10e, 2 },
152 [NITIO_G2_HW_SAVE] = { 0x110, 4 },
153 [NITIO_G3_HW_SAVE] = { 0x114, 4 },
154 [NITIO_G2_SW_SAVE] = { 0x118, 4 },
155 [NITIO_G3_SW_SAVE] = { 0x11c, 4 },
156 [NITIO_G2_MODE] = { 0x134, 2 },
157 [NITIO_G23_STATUS1] = { 0x136, 2 },
158 [NITIO_G3_MODE] = { 0x136, 2 },
159 [NITIO_G2_LOADA] = { 0x138, 4 },
160 [NITIO_G23_STATUS2] = { 0x13a, 2 },
161 [NITIO_G2_LOADB] = { 0x13c, 4 },
162 [NITIO_G3_LOADA] = { 0x140, 4 },
163 [NITIO_G3_LOADB] = { 0x144, 4 },
164 [NITIO_G2_INPUT_SEL] = { 0x148, 2 },
165 [NITIO_G3_INPUT_SEL] = { 0x14a, 2 },
166 [NITIO_G2_AUTO_INC] = { 0x188, 2 },
167 [NITIO_G3_AUTO_INC] = { 0x18a, 2 },
168 [NITIO_G23_RESET] = { 0x190, 2 },
169 [NITIO_G2_INT_ENA] = { 0x192, 2 },
170 [NITIO_G3_INT_ENA] = { 0x196, 2 },
171 [NITIO_G2_CNT_MODE] = { 0x1b0, 2 },
172 [NITIO_G3_CNT_MODE] = { 0x1b2, 2 },
173 [NITIO_G2_GATE2] = { 0x1b4, 2 },
174 [NITIO_G3_GATE2] = { 0x1b6, 2 },
175 [NITIO_G2_DMA_CFG] = { 0x1b8, 2 },
176 [NITIO_G2_DMA_STATUS] = { 0x1b8, 2 },
177 [NITIO_G3_DMA_CFG] = { 0x1ba, 2 },
178 [NITIO_G3_DMA_STATUS] = { 0x1ba, 2 },
179 [NI660X_DIO32_INPUT] = { 0x414, 4 },
180 [NI660X_DIO32_OUTPUT] = { 0x510, 4 },
181 [NI660X_CLK_CFG] = { 0x73c, 4 },
182 [NI660X_GLOBAL_INT_STATUS] = { 0x754, 4 },
183 [NI660X_DMA_CFG] = { 0x76c, 4 },
184 [NI660X_GLOBAL_INT_CFG] = { 0x770, 4 },
185 [NI660X_IO_CFG_0_1] = { 0x77c, 2 },
186 [NI660X_IO_CFG_2_3] = { 0x77e, 2 },
187 [NI660X_IO_CFG_4_5] = { 0x780, 2 },
188 [NI660X_IO_CFG_6_7] = { 0x782, 2 },
189 [NI660X_IO_CFG_8_9] = { 0x784, 2 },
190 [NI660X_IO_CFG_10_11] = { 0x786, 2 },
191 [NI660X_IO_CFG_12_13] = { 0x788, 2 },
192 [NI660X_IO_CFG_14_15] = { 0x78a, 2 },
193 [NI660X_IO_CFG_16_17] = { 0x78c, 2 },
194 [NI660X_IO_CFG_18_19] = { 0x78e, 2 },
195 [NI660X_IO_CFG_20_21] = { 0x790, 2 },
196 [NI660X_IO_CFG_22_23] = { 0x792, 2 },
197 [NI660X_IO_CFG_24_25] = { 0x794, 2 },
198 [NI660X_IO_CFG_26_27] = { 0x796, 2 },
199 [NI660X_IO_CFG_28_29] = { 0x798, 2 },
200 [NI660X_IO_CFG_30_31] = { 0x79a, 2 },
201 [NI660X_IO_CFG_32_33] = { 0x79c, 2 },
202 [NI660X_IO_CFG_34_35] = { 0x79e, 2 },
203 [NI660X_IO_CFG_36_37] = { 0x7a0, 2 },
204 [NI660X_IO_CFG_38_39] = { 0x7a2, 2 }
205};
206
207#define NI660X_CHIP_OFFSET 0x800
208
209enum ni_660x_boardid {
210 BOARD_PCI6601,
211 BOARD_PCI6602,
212 BOARD_PXI6602,
213 BOARD_PXI6608,
214 BOARD_PXI6624
215};
216
217struct ni_660x_board {
218 const char *name;
219 unsigned int n_chips;
220};
221
222static const struct ni_660x_board ni_660x_boards[] = {
223 [BOARD_PCI6601] = {
224 .name = "PCI-6601",
225 .n_chips = 1,
226 },
227 [BOARD_PCI6602] = {
228 .name = "PCI-6602",
229 .n_chips = 2,
230 },
231 [BOARD_PXI6602] = {
232 .name = "PXI-6602",
233 .n_chips = 2,
234 },
235 [BOARD_PXI6608] = {
236 .name = "PXI-6608",
237 .n_chips = 2,
238 },
239 [BOARD_PXI6624] = {
240 .name = "PXI-6624",
241 .n_chips = 2,
242 },
243};
244
245#define NI660X_NUM_PFI_CHANNELS 40
246
247
248#define NI660X_MAX_DMA_CHANNEL 4
249
250#define NI660X_COUNTERS_PER_CHIP 4
251#define NI660X_MAX_CHIPS 2
252#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \
253 NI660X_COUNTERS_PER_CHIP)
254
255struct ni_660x_private {
256 struct mite *mite;
257 struct ni_gpct_device *counter_dev;
258 struct mite_ring *ring[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP];
259
260 spinlock_t mite_channel_lock;
261
262 spinlock_t interrupt_lock;
263 unsigned int dma_cfg[NI660X_MAX_CHIPS];
264 unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
265 u64 io_dir;
266};
267
268static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
269 unsigned int bits, unsigned int reg)
270{
271 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
272 ni_660x_reg_data[reg].offset;
273
274 if (ni_660x_reg_data[reg].size == 2)
275 writew(bits, dev->mmio + addr);
276 else
277 writel(bits, dev->mmio + addr);
278}
279
280static unsigned int ni_660x_read(struct comedi_device *dev,
281 unsigned int chip, unsigned int reg)
282{
283 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
284 ni_660x_reg_data[reg].offset;
285
286 if (ni_660x_reg_data[reg].size == 2)
287 return readw(dev->mmio + addr);
288 return readl(dev->mmio + addr);
289}
290
291static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits,
292 enum ni_gpct_register reg)
293{
294 struct comedi_device *dev = counter->counter_dev->dev;
295
296 ni_660x_write(dev, counter->chip_index, bits, reg);
297}
298
299static unsigned int ni_660x_gpct_read(struct ni_gpct *counter,
300 enum ni_gpct_register reg)
301{
302 struct comedi_device *dev = counter->counter_dev->dev;
303
304 return ni_660x_read(dev, counter->chip_index, reg);
305}
306
307static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
308 unsigned int mite_channel,
309 struct ni_gpct *counter)
310{
311 struct ni_660x_private *devpriv = dev->private;
312 unsigned int chip = counter->chip_index;
313
314 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
315 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel,
316 counter->counter_index);
317 ni_660x_write(dev, chip, devpriv->dma_cfg[chip] |
318 NI660X_DMA_CFG_RESET(mite_channel),
319 NI660X_DMA_CFG);
320 mmiowb();
321}
322
323static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
324 unsigned int mite_channel,
325 struct ni_gpct *counter)
326{
327 struct ni_660x_private *devpriv = dev->private;
328 unsigned int chip = counter->chip_index;
329
330 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
331 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
332 ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG);
333 mmiowb();
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(devpriv->mite, ring);
348 if (!mite_chan) {
349 spin_unlock_irqrestore(&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_chan->channel, counter);
357 spin_unlock_irqrestore(&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_chan->channel, counter);
372 ni_tio_set_mite_channel(counter, NULL);
373 mite_release_channel(mite_chan);
374 }
375 spin_unlock_irqrestore(&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, 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
410
411
412
413
414 if (chip)
415 bits = NI660X_CLK_CFG_COUNTER_SWAP;
416
417 ni_660x_write(dev, chip, bits, 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
440 smp_mb();
441
442
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(&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
461 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
462 mite_sync_dma(counter->mite_chan, s);
463 spin_unlock_irqrestore(&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, 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(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(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
541
542
543
544
545 if (mask) {
546 s->state &= ~mask;
547 s->state |= (bits & mask);
548 ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT);
549 }
550
551
552
553
554
555 data[1] = ni_660x_read(dev, 0, 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 (board->n_chips > 1) {
569 if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
570 chan >= 8 && chan <= 23) {
571
572 active_chip = 1;
573 idle_chip = 0;
574 } else {
575
576 active_chip = 0;
577 idle_chip = 1;
578 }
579 }
580
581 if (idle_chip != active_chip) {
582
583 bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan));
584 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
585 bits |= NI660X_IO_CFG_OUT_SEL(chan, 0);
586 ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan));
587 }
588
589
590 bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan));
591 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
592 bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
593 ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
594}
595
596static int ni_660x_set_pfi_routing(struct comedi_device *dev,
597 unsigned int chan, unsigned int source)
598{
599 struct ni_660x_private *devpriv = dev->private;
600
601 switch (source) {
602 case NI_660X_PFI_OUTPUT_COUNTER:
603 if (chan < 8)
604 return -EINVAL;
605 break;
606 case NI_660X_PFI_OUTPUT_DIO:
607 if (chan > 31)
608 return -EINVAL;
609 default:
610 return -EINVAL;
611 }
612
613 devpriv->io_cfg[chan] = source;
614 if (devpriv->io_dir & (1ULL << chan))
615 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
616 return 0;
617}
618
619static int ni_660x_dio_insn_config(struct comedi_device *dev,
620 struct comedi_subdevice *s,
621 struct comedi_insn *insn,
622 unsigned int *data)
623{
624 struct ni_660x_private *devpriv = dev->private;
625 unsigned int chan = CR_CHAN(insn->chanspec);
626 u64 bit = 1ULL << chan;
627 unsigned int val;
628 int ret;
629
630 switch (data[0]) {
631 case INSN_CONFIG_DIO_OUTPUT:
632 devpriv->io_dir |= bit;
633 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
634 break;
635
636 case INSN_CONFIG_DIO_INPUT:
637 devpriv->io_dir &= ~bit;
638 ni_660x_select_pfi_output(dev, chan, 0);
639 break;
640
641 case INSN_CONFIG_DIO_QUERY:
642 data[1] = (devpriv->io_dir & bit) ? COMEDI_OUTPUT
643 : COMEDI_INPUT;
644 break;
645
646 case INSN_CONFIG_SET_ROUTING:
647 ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
648 if (ret)
649 return ret;
650 break;
651
652 case INSN_CONFIG_GET_ROUTING:
653 data[1] = devpriv->io_cfg[chan];
654 break;
655
656 case INSN_CONFIG_FILTER:
657 val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
658 val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
659 val |= NI660X_IO_CFG_IN_SEL(chan, data[1]);
660 ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
661 break;
662
663 default:
664 return -EINVAL;
665 }
666
667 return insn->n;
668}
669
670static void ni_660x_init_tio_chips(struct comedi_device *dev,
671 unsigned int n_chips)
672{
673 struct ni_660x_private *devpriv = dev->private;
674 unsigned int chip;
675 unsigned int chan;
676
677
678
679
680
681 ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL);
682
683 for (chip = 0; chip < n_chips; ++chip) {
684
685 devpriv->dma_cfg[chip] = 0;
686 for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
687 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
688 ni_660x_write(dev, chip, devpriv->dma_cfg[chip],
689 NI660X_DMA_CFG);
690
691
692 for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
693 ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan));
694 }
695}
696
697static int ni_660x_auto_attach(struct comedi_device *dev,
698 unsigned long context)
699{
700 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
701 const struct ni_660x_board *board = NULL;
702 struct ni_660x_private *devpriv;
703 struct comedi_subdevice *s;
704 struct ni_gpct_device *gpct_dev;
705 unsigned int n_counters;
706 int subdev;
707 int ret;
708 unsigned int i;
709 unsigned int global_interrupt_config_bits;
710
711 if (context < ARRAY_SIZE(ni_660x_boards))
712 board = &ni_660x_boards[context];
713 if (!board)
714 return -ENODEV;
715 dev->board_ptr = board;
716 dev->board_name = board->name;
717
718 ret = comedi_pci_enable(dev);
719 if (ret)
720 return ret;
721
722 ret = ni_660x_allocate_private(dev);
723 if (ret < 0)
724 return ret;
725 devpriv = dev->private;
726
727 devpriv->mite = mite_attach(dev, true);
728 if (!devpriv->mite)
729 return -ENOMEM;
730
731 ret = ni_660x_alloc_mite_rings(dev);
732 if (ret < 0)
733 return ret;
734
735 ni_660x_init_tio_chips(dev, board->n_chips);
736
737 n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
738 gpct_dev = ni_gpct_device_construct(dev,
739 ni_660x_gpct_write,
740 ni_660x_gpct_read,
741 ni_gpct_variant_660x,
742 n_counters);
743 if (!gpct_dev)
744 return -ENOMEM;
745 devpriv->counter_dev = gpct_dev;
746
747 ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS);
748 if (ret)
749 return ret;
750
751 subdev = 0;
752
753 s = &dev->subdevices[subdev++];
754
755 s->type = COMEDI_SUBD_UNUSED;
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810 s = &dev->subdevices[subdev++];
811 s->type = COMEDI_SUBD_DIO;
812 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
813 s->n_chan = NI660X_NUM_PFI_CHANNELS;
814 s->maxdata = 1;
815 s->range_table = &range_digital;
816 s->insn_bits = ni_660x_dio_insn_bits;
817 s->insn_config = ni_660x_dio_insn_config;
818
819
820
821
822
823
824 for (i = 0; i < s->n_chan; ++i) {
825 unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
826 : NI_660X_PFI_OUTPUT_COUNTER;
827
828 ni_660x_set_pfi_routing(dev, i, source);
829 ni_660x_select_pfi_output(dev, i, 0);
830 }
831
832
833 for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
834 s = &dev->subdevices[subdev++];
835 if (i < n_counters) {
836 struct ni_gpct *counter = &gpct_dev->counters[i];
837
838 counter->chip_index = i / NI660X_COUNTERS_PER_CHIP;
839 counter->counter_index = i % NI660X_COUNTERS_PER_CHIP;
840
841 s->type = COMEDI_SUBD_COUNTER;
842 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
843 SDF_LSAMPL | SDF_CMD_READ;
844 s->n_chan = 3;
845 s->maxdata = 0xffffffff;
846 s->insn_read = ni_tio_insn_read;
847 s->insn_write = ni_tio_insn_write;
848 s->insn_config = ni_tio_insn_config;
849 s->len_chanlist = 1;
850 s->do_cmd = ni_660x_cmd;
851 s->do_cmdtest = ni_tio_cmdtest;
852 s->cancel = ni_660x_cancel;
853 s->poll = ni_660x_input_poll;
854 s->buf_change = ni_660x_buf_change;
855 s->async_dma_dir = DMA_BIDIRECTIONAL;
856 s->private = counter;
857
858 ni_tio_init_counter(counter);
859 } else {
860 s->type = COMEDI_SUBD_UNUSED;
861 }
862 }
863
864
865
866
867
868 for (i = 0; i < board->n_chips; ++i)
869 set_tio_counterswap(dev, i);
870
871 ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
872 dev->board_name, dev);
873 if (ret < 0) {
874 dev_warn(dev->class_dev, " irq not available\n");
875 return ret;
876 }
877 dev->irq = pcidev->irq;
878 global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
879 if (board->n_chips > 1)
880 global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
881 ni_660x_write(dev, 0, global_interrupt_config_bits,
882 NI660X_GLOBAL_INT_CFG);
883
884 return 0;
885}
886
887static void ni_660x_detach(struct comedi_device *dev)
888{
889 struct ni_660x_private *devpriv = dev->private;
890
891 if (dev->irq) {
892 ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG);
893 free_irq(dev->irq, dev);
894 }
895 if (devpriv) {
896 ni_gpct_device_destroy(devpriv->counter_dev);
897 ni_660x_free_mite_rings(dev);
898 mite_detach(devpriv->mite);
899 }
900 if (dev->mmio)
901 iounmap(dev->mmio);
902 comedi_pci_disable(dev);
903}
904
905static struct comedi_driver ni_660x_driver = {
906 .driver_name = "ni_660x",
907 .module = THIS_MODULE,
908 .auto_attach = ni_660x_auto_attach,
909 .detach = ni_660x_detach,
910};
911
912static int ni_660x_pci_probe(struct pci_dev *dev,
913 const struct pci_device_id *id)
914{
915 return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
916}
917
918static const struct pci_device_id ni_660x_pci_table[] = {
919 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
920 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
921 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
922 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
923 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
924 { 0 }
925};
926MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
927
928static struct pci_driver ni_660x_pci_driver = {
929 .name = "ni_660x",
930 .id_table = ni_660x_pci_table,
931 .probe = ni_660x_pci_probe,
932 .remove = comedi_pci_auto_unconfig,
933};
934module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
935
936MODULE_AUTHOR("Comedi http://www.comedi.org");
937MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
938MODULE_LICENSE("GPL");
939