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
35
36enum ni_660x_register {
37
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;
94 char size;
95};
96
97static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = {
98 [NITIO_G0_INT_ACK] = { 0x004, 2 },
99 [NITIO_G0_STATUS] = { 0x004, 2 },
100 [NITIO_G1_INT_ACK] = { 0x006, 2 },
101 [NITIO_G1_STATUS] = { 0x006, 2 },
102 [NITIO_G01_STATUS] = { 0x008, 2 },
103 [NITIO_G0_CMD] = { 0x00c, 2 },
104 [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 },
105 [NITIO_G1_CMD] = { 0x00e, 2 },
106 [NITIO_G0_HW_SAVE] = { 0x010, 4 },
107 [NITIO_G1_HW_SAVE] = { 0x014, 4 },
108 [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 },
109 [NI660X_STC_DIO_CONTROL] = { 0x016, 2 },
110 [NITIO_G0_SW_SAVE] = { 0x018, 4 },
111 [NITIO_G1_SW_SAVE] = { 0x01c, 4 },
112 [NITIO_G0_MODE] = { 0x034, 2 },
113 [NITIO_G01_STATUS1] = { 0x036, 2 },
114 [NITIO_G1_MODE] = { 0x036, 2 },
115 [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 },
116 [NITIO_G0_LOADA] = { 0x038, 4 },
117 [NITIO_G01_STATUS2] = { 0x03a, 2 },
118 [NITIO_G0_LOADB] = { 0x03c, 4 },
119 [NITIO_G1_LOADA] = { 0x040, 4 },
120 [NITIO_G1_LOADB] = { 0x044, 4 },
121 [NITIO_G0_INPUT_SEL] = { 0x048, 2 },
122 [NITIO_G1_INPUT_SEL] = { 0x04a, 2 },
123 [NITIO_G0_AUTO_INC] = { 0x088, 2 },
124 [NITIO_G1_AUTO_INC] = { 0x08a, 2 },
125 [NITIO_G01_RESET] = { 0x090, 2 },
126 [NITIO_G0_INT_ENA] = { 0x092, 2 },
127 [NITIO_G1_INT_ENA] = { 0x096, 2 },
128 [NITIO_G0_CNT_MODE] = { 0x0b0, 2 },
129 [NITIO_G1_CNT_MODE] = { 0x0b2, 2 },
130 [NITIO_G0_GATE2] = { 0x0b4, 2 },
131 [NITIO_G1_GATE2] = { 0x0b6, 2 },
132 [NITIO_G0_DMA_CFG] = { 0x0b8, 2 },
133 [NITIO_G0_DMA_STATUS] = { 0x0b8, 2 },
134 [NITIO_G1_DMA_CFG] = { 0x0ba, 2 },
135 [NITIO_G1_DMA_STATUS] = { 0x0ba, 2 },
136 [NITIO_G2_INT_ACK] = { 0x104, 2 },
137 [NITIO_G2_STATUS] = { 0x104, 2 },
138 [NITIO_G3_INT_ACK] = { 0x106, 2 },
139 [NITIO_G3_STATUS] = { 0x106, 2 },
140 [NITIO_G23_STATUS] = { 0x108, 2 },
141 [NITIO_G2_CMD] = { 0x10c, 2 },
142 [NITIO_G3_CMD] = { 0x10e, 2 },
143 [NITIO_G2_HW_SAVE] = { 0x110, 4 },
144 [NITIO_G3_HW_SAVE] = { 0x114, 4 },
145 [NITIO_G2_SW_SAVE] = { 0x118, 4 },
146 [NITIO_G3_SW_SAVE] = { 0x11c, 4 },
147 [NITIO_G2_MODE] = { 0x134, 2 },
148 [NITIO_G23_STATUS1] = { 0x136, 2 },
149 [NITIO_G3_MODE] = { 0x136, 2 },
150 [NITIO_G2_LOADA] = { 0x138, 4 },
151 [NITIO_G23_STATUS2] = { 0x13a, 2 },
152 [NITIO_G2_LOADB] = { 0x13c, 4 },
153 [NITIO_G3_LOADA] = { 0x140, 4 },
154 [NITIO_G3_LOADB] = { 0x144, 4 },
155 [NITIO_G2_INPUT_SEL] = { 0x148, 2 },
156 [NITIO_G3_INPUT_SEL] = { 0x14a, 2 },
157 [NITIO_G2_AUTO_INC] = { 0x188, 2 },
158 [NITIO_G3_AUTO_INC] = { 0x18a, 2 },
159 [NITIO_G23_RESET] = { 0x190, 2 },
160 [NITIO_G2_INT_ENA] = { 0x192, 2 },
161 [NITIO_G3_INT_ENA] = { 0x196, 2 },
162 [NITIO_G2_CNT_MODE] = { 0x1b0, 2 },
163 [NITIO_G3_CNT_MODE] = { 0x1b2, 2 },
164 [NITIO_G2_GATE2] = { 0x1b4, 2 },
165 [NITIO_G3_GATE2] = { 0x1b6, 2 },
166 [NITIO_G2_DMA_CFG] = { 0x1b8, 2 },
167 [NITIO_G2_DMA_STATUS] = { 0x1b8, 2 },
168 [NITIO_G3_DMA_CFG] = { 0x1ba, 2 },
169 [NITIO_G3_DMA_STATUS] = { 0x1ba, 2 },
170 [NI660X_DIO32_INPUT] = { 0x414, 4 },
171 [NI660X_DIO32_OUTPUT] = { 0x510, 4 },
172 [NI660X_CLK_CFG] = { 0x73c, 4 },
173 [NI660X_GLOBAL_INT_STATUS] = { 0x754, 4 },
174 [NI660X_DMA_CFG] = { 0x76c, 4 },
175 [NI660X_GLOBAL_INT_CFG] = { 0x770, 4 },
176 [NI660X_IO_CFG_0_1] = { 0x77c, 2 },
177 [NI660X_IO_CFG_2_3] = { 0x77e, 2 },
178 [NI660X_IO_CFG_4_5] = { 0x780, 2 },
179 [NI660X_IO_CFG_6_7] = { 0x782, 2 },
180 [NI660X_IO_CFG_8_9] = { 0x784, 2 },
181 [NI660X_IO_CFG_10_11] = { 0x786, 2 },
182 [NI660X_IO_CFG_12_13] = { 0x788, 2 },
183 [NI660X_IO_CFG_14_15] = { 0x78a, 2 },
184 [NI660X_IO_CFG_16_17] = { 0x78c, 2 },
185 [NI660X_IO_CFG_18_19] = { 0x78e, 2 },
186 [NI660X_IO_CFG_20_21] = { 0x790, 2 },
187 [NI660X_IO_CFG_22_23] = { 0x792, 2 },
188 [NI660X_IO_CFG_24_25] = { 0x794, 2 },
189 [NI660X_IO_CFG_26_27] = { 0x796, 2 },
190 [NI660X_IO_CFG_28_29] = { 0x798, 2 },
191 [NI660X_IO_CFG_30_31] = { 0x79a, 2 },
192 [NI660X_IO_CFG_32_33] = { 0x79c, 2 },
193 [NI660X_IO_CFG_34_35] = { 0x79e, 2 },
194 [NI660X_IO_CFG_36_37] = { 0x7a0, 2 },
195 [NI660X_IO_CFG_38_39] = { 0x7a2, 2 }
196};
197
198#define NI660X_CHIP_OFFSET 0x800
199
200enum ni_660x_boardid {
201 BOARD_PCI6601,
202 BOARD_PCI6602,
203 BOARD_PXI6602,
204 BOARD_PXI6608,
205 BOARD_PCI6624,
206 BOARD_PXI6624
207};
208
209struct ni_660x_board {
210 const char *name;
211 unsigned int n_chips;
212};
213
214static const struct ni_660x_board ni_660x_boards[] = {
215 [BOARD_PCI6601] = {
216 .name = "PCI-6601",
217 .n_chips = 1,
218 },
219 [BOARD_PCI6602] = {
220 .name = "PCI-6602",
221 .n_chips = 2,
222 },
223 [BOARD_PXI6602] = {
224 .name = "PXI-6602",
225 .n_chips = 2,
226 },
227 [BOARD_PXI6608] = {
228 .name = "PXI-6608",
229 .n_chips = 2,
230 },
231 [BOARD_PCI6624] = {
232 .name = "PCI-6624",
233 .n_chips = 2,
234 },
235 [BOARD_PXI6624] = {
236 .name = "PXI-6624",
237 .n_chips = 2,
238 },
239};
240
241#define NI660X_NUM_PFI_CHANNELS 40
242
243
244#define NI660X_MAX_DMA_CHANNEL 4
245
246#define NI660X_COUNTERS_PER_CHIP 4
247#define NI660X_MAX_CHIPS 2
248#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \
249 NI660X_COUNTERS_PER_CHIP)
250
251struct ni_660x_private {
252 struct mite *mite;
253 struct ni_gpct_device *counter_dev;
254 struct mite_ring *ring[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP];
255
256 spinlock_t mite_channel_lock;
257
258 spinlock_t interrupt_lock;
259 unsigned int dma_cfg[NI660X_MAX_CHIPS];
260 unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
261 u64 io_dir;
262};
263
264static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
265 unsigned int bits, unsigned int reg)
266{
267 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
268 ni_660x_reg_data[reg].offset;
269
270 if (ni_660x_reg_data[reg].size == 2)
271 writew(bits, dev->mmio + addr);
272 else
273 writel(bits, dev->mmio + addr);
274}
275
276static unsigned int ni_660x_read(struct comedi_device *dev,
277 unsigned int chip, unsigned int reg)
278{
279 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
280 ni_660x_reg_data[reg].offset;
281
282 if (ni_660x_reg_data[reg].size == 2)
283 return readw(dev->mmio + addr);
284 return readl(dev->mmio + addr);
285}
286
287static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits,
288 enum ni_gpct_register reg)
289{
290 struct comedi_device *dev = counter->counter_dev->dev;
291
292 ni_660x_write(dev, counter->chip_index, bits, reg);
293}
294
295static unsigned int ni_660x_gpct_read(struct ni_gpct *counter,
296 enum ni_gpct_register reg)
297{
298 struct comedi_device *dev = counter->counter_dev->dev;
299
300 return ni_660x_read(dev, counter->chip_index, reg);
301}
302
303static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
304 unsigned int mite_channel,
305 struct ni_gpct *counter)
306{
307 struct ni_660x_private *devpriv = dev->private;
308 unsigned int chip = counter->chip_index;
309
310 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
311 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel,
312 counter->counter_index);
313 ni_660x_write(dev, chip, devpriv->dma_cfg[chip] |
314 NI660X_DMA_CFG_RESET(mite_channel),
315 NI660X_DMA_CFG);
316 mmiowb();
317}
318
319static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
320 unsigned int mite_channel,
321 struct ni_gpct *counter)
322{
323 struct ni_660x_private *devpriv = dev->private;
324 unsigned int chip = counter->chip_index;
325
326 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
327 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
328 ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG);
329 mmiowb();
330}
331
332static int ni_660x_request_mite_channel(struct comedi_device *dev,
333 struct ni_gpct *counter,
334 enum comedi_io_direction direction)
335{
336 struct ni_660x_private *devpriv = dev->private;
337 struct mite_ring *ring;
338 struct mite_channel *mite_chan;
339 unsigned long flags;
340
341 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
342 ring = devpriv->ring[counter->chip_index][counter->counter_index];
343 mite_chan = mite_request_channel(devpriv->mite, ring);
344 if (!mite_chan) {
345 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
346 dev_err(dev->class_dev,
347 "failed to reserve mite dma channel for counter\n");
348 return -EBUSY;
349 }
350 mite_chan->dir = direction;
351 ni_tio_set_mite_channel(counter, mite_chan);
352 ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
353 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
354 return 0;
355}
356
357static void ni_660x_release_mite_channel(struct comedi_device *dev,
358 struct ni_gpct *counter)
359{
360 struct ni_660x_private *devpriv = dev->private;
361 unsigned long flags;
362
363 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
364 if (counter->mite_chan) {
365 struct mite_channel *mite_chan = counter->mite_chan;
366
367 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
368 ni_tio_set_mite_channel(counter, NULL);
369 mite_release_channel(mite_chan);
370 }
371 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
372}
373
374static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
375{
376 struct ni_gpct *counter = s->private;
377 int retval;
378
379 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
380 if (retval) {
381 dev_err(dev->class_dev,
382 "no dma channel available for use by counter\n");
383 return retval;
384 }
385 ni_tio_acknowledge(counter);
386
387 return ni_tio_cmd(dev, s);
388}
389
390static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
391{
392 struct ni_gpct *counter = s->private;
393 int retval;
394
395 retval = ni_tio_cancel(counter);
396 ni_660x_release_mite_channel(dev, counter);
397 return retval;
398}
399
400static void set_tio_counterswap(struct comedi_device *dev, int chip)
401{
402 unsigned int bits = 0;
403
404
405
406
407
408
409
410 if (chip)
411 bits = NI660X_CLK_CFG_COUNTER_SWAP;
412
413 ni_660x_write(dev, chip, bits, NI660X_CLK_CFG);
414}
415
416static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
417 struct comedi_subdevice *s)
418{
419 struct ni_gpct *counter = s->private;
420
421 ni_tio_handle_interrupt(counter, s);
422 comedi_handle_events(dev, s);
423}
424
425static irqreturn_t ni_660x_interrupt(int irq, void *d)
426{
427 struct comedi_device *dev = d;
428 struct ni_660x_private *devpriv = dev->private;
429 struct comedi_subdevice *s;
430 unsigned int i;
431 unsigned long flags;
432
433 if (!dev->attached)
434 return IRQ_NONE;
435
436 smp_mb();
437
438
439 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
440 for (i = 0; i < dev->n_subdevices; ++i) {
441 s = &dev->subdevices[i];
442 if (s->type == COMEDI_SUBD_COUNTER)
443 ni_660x_handle_gpct_interrupt(dev, s);
444 }
445 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
446 return IRQ_HANDLED;
447}
448
449static int ni_660x_input_poll(struct comedi_device *dev,
450 struct comedi_subdevice *s)
451{
452 struct ni_660x_private *devpriv = dev->private;
453 struct ni_gpct *counter = s->private;
454 unsigned long flags;
455
456
457 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
458 mite_sync_dma(counter->mite_chan, s);
459 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
460 return comedi_buf_read_n_available(s);
461}
462
463static int ni_660x_buf_change(struct comedi_device *dev,
464 struct comedi_subdevice *s)
465{
466 struct ni_660x_private *devpriv = dev->private;
467 struct ni_gpct *counter = s->private;
468 struct mite_ring *ring;
469 int ret;
470
471 ring = devpriv->ring[counter->chip_index][counter->counter_index];
472 ret = mite_buf_change(ring, s);
473 if (ret < 0)
474 return ret;
475
476 return 0;
477}
478
479static int ni_660x_allocate_private(struct comedi_device *dev)
480{
481 struct ni_660x_private *devpriv;
482 unsigned int i;
483
484 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
485 if (!devpriv)
486 return -ENOMEM;
487
488 spin_lock_init(&devpriv->mite_channel_lock);
489 spin_lock_init(&devpriv->interrupt_lock);
490 for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i)
491 devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER;
492
493 return 0;
494}
495
496static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
497{
498 const struct ni_660x_board *board = dev->board_ptr;
499 struct ni_660x_private *devpriv = dev->private;
500 unsigned int i;
501 unsigned int j;
502
503 for (i = 0; i < board->n_chips; ++i) {
504 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) {
505 devpriv->ring[i][j] = mite_alloc_ring(devpriv->mite);
506 if (!devpriv->ring[i][j])
507 return -ENOMEM;
508 }
509 }
510 return 0;
511}
512
513static void ni_660x_free_mite_rings(struct comedi_device *dev)
514{
515 const struct ni_660x_board *board = dev->board_ptr;
516 struct ni_660x_private *devpriv = dev->private;
517 unsigned int i;
518 unsigned int j;
519
520 for (i = 0; i < board->n_chips; ++i) {
521 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j)
522 mite_free_ring(devpriv->ring[i][j]);
523 }
524}
525
526static int ni_660x_dio_insn_bits(struct comedi_device *dev,
527 struct comedi_subdevice *s,
528 struct comedi_insn *insn,
529 unsigned int *data)
530{
531 unsigned int shift = CR_CHAN(insn->chanspec);
532 unsigned int mask = data[0] << shift;
533 unsigned int bits = data[1] << shift;
534
535
536
537
538
539
540
541 if (mask) {
542 s->state &= ~mask;
543 s->state |= (bits & mask);
544 ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT);
545 }
546
547
548
549
550
551 data[1] = ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> shift;
552
553 return insn->n;
554}
555
556static void ni_660x_select_pfi_output(struct comedi_device *dev,
557 unsigned int chan, unsigned int out_sel)
558{
559 const struct ni_660x_board *board = dev->board_ptr;
560 unsigned int active_chip = 0;
561 unsigned int idle_chip = 0;
562 unsigned int bits;
563
564 if (board->n_chips > 1) {
565 if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
566 chan >= 8 && chan <= 23) {
567
568 active_chip = 1;
569 idle_chip = 0;
570 } else {
571
572 active_chip = 0;
573 idle_chip = 1;
574 }
575 }
576
577 if (idle_chip != active_chip) {
578
579 bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan));
580 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
581 bits |= NI660X_IO_CFG_OUT_SEL(chan, 0);
582 ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan));
583 }
584
585
586 bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan));
587 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
588 bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
589 ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
590}
591
592static int ni_660x_set_pfi_routing(struct comedi_device *dev,
593 unsigned int chan, unsigned int source)
594{
595 struct ni_660x_private *devpriv = dev->private;
596
597 switch (source) {
598 case NI_660X_PFI_OUTPUT_COUNTER:
599 if (chan < 8)
600 return -EINVAL;
601 break;
602 case NI_660X_PFI_OUTPUT_DIO:
603 if (chan > 31)
604 return -EINVAL;
605 default:
606 return -EINVAL;
607 }
608
609 devpriv->io_cfg[chan] = source;
610 if (devpriv->io_dir & (1ULL << chan))
611 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
612 return 0;
613}
614
615static int ni_660x_dio_insn_config(struct comedi_device *dev,
616 struct comedi_subdevice *s,
617 struct comedi_insn *insn,
618 unsigned int *data)
619{
620 struct ni_660x_private *devpriv = dev->private;
621 unsigned int chan = CR_CHAN(insn->chanspec);
622 u64 bit = 1ULL << chan;
623 unsigned int val;
624 int ret;
625
626 switch (data[0]) {
627 case INSN_CONFIG_DIO_OUTPUT:
628 devpriv->io_dir |= bit;
629 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
630 break;
631
632 case INSN_CONFIG_DIO_INPUT:
633 devpriv->io_dir &= ~bit;
634 ni_660x_select_pfi_output(dev, chan, 0);
635 break;
636
637 case INSN_CONFIG_DIO_QUERY:
638 data[1] = (devpriv->io_dir & bit) ? COMEDI_OUTPUT
639 : COMEDI_INPUT;
640 break;
641
642 case INSN_CONFIG_SET_ROUTING:
643 ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
644 if (ret)
645 return ret;
646 break;
647
648 case INSN_CONFIG_GET_ROUTING:
649 data[1] = devpriv->io_cfg[chan];
650 break;
651
652 case INSN_CONFIG_FILTER:
653 val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
654 val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
655 val |= NI660X_IO_CFG_IN_SEL(chan, data[1]);
656 ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
657 break;
658
659 default:
660 return -EINVAL;
661 }
662
663 return insn->n;
664}
665
666static void ni_660x_init_tio_chips(struct comedi_device *dev,
667 unsigned int n_chips)
668{
669 struct ni_660x_private *devpriv = dev->private;
670 unsigned int chip;
671 unsigned int chan;
672
673
674
675
676
677 ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL);
678
679 for (chip = 0; chip < n_chips; ++chip) {
680
681 devpriv->dma_cfg[chip] = 0;
682 for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
683 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
684 ni_660x_write(dev, chip, devpriv->dma_cfg[chip],
685 NI660X_DMA_CFG);
686
687
688 for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
689 ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan));
690 }
691}
692
693static int ni_660x_auto_attach(struct comedi_device *dev,
694 unsigned long context)
695{
696 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
697 const struct ni_660x_board *board = NULL;
698 struct ni_660x_private *devpriv;
699 struct comedi_subdevice *s;
700 struct ni_gpct_device *gpct_dev;
701 unsigned int n_counters;
702 int subdev;
703 int ret;
704 unsigned int i;
705 unsigned int global_interrupt_config_bits;
706
707 if (context < ARRAY_SIZE(ni_660x_boards))
708 board = &ni_660x_boards[context];
709 if (!board)
710 return -ENODEV;
711 dev->board_ptr = board;
712 dev->board_name = board->name;
713
714 ret = comedi_pci_enable(dev);
715 if (ret)
716 return ret;
717
718 ret = ni_660x_allocate_private(dev);
719 if (ret < 0)
720 return ret;
721 devpriv = dev->private;
722
723 devpriv->mite = mite_attach(dev, true);
724 if (!devpriv->mite)
725 return -ENOMEM;
726
727 ret = ni_660x_alloc_mite_rings(dev);
728 if (ret < 0)
729 return ret;
730
731 ni_660x_init_tio_chips(dev, board->n_chips);
732
733 n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
734 gpct_dev = ni_gpct_device_construct(dev,
735 ni_660x_gpct_write,
736 ni_660x_gpct_read,
737 ni_gpct_variant_660x,
738 n_counters);
739 if (!gpct_dev)
740 return -ENOMEM;
741 devpriv->counter_dev = gpct_dev;
742
743 ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS);
744 if (ret)
745 return ret;
746
747 subdev = 0;
748
749 s = &dev->subdevices[subdev++];
750
751 s->type = COMEDI_SUBD_UNUSED;
752
753
754
755
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 s = &dev->subdevices[subdev++];
807 s->type = COMEDI_SUBD_DIO;
808 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
809 s->n_chan = NI660X_NUM_PFI_CHANNELS;
810 s->maxdata = 1;
811 s->range_table = &range_digital;
812 s->insn_bits = ni_660x_dio_insn_bits;
813 s->insn_config = ni_660x_dio_insn_config;
814
815
816
817
818
819
820 for (i = 0; i < s->n_chan; ++i) {
821 unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
822 : NI_660X_PFI_OUTPUT_COUNTER;
823
824 ni_660x_set_pfi_routing(dev, i, source);
825 ni_660x_select_pfi_output(dev, i, 0);
826 }
827
828
829 for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
830 s = &dev->subdevices[subdev++];
831 if (i < n_counters) {
832 struct ni_gpct *counter = &gpct_dev->counters[i];
833
834 counter->chip_index = i / NI660X_COUNTERS_PER_CHIP;
835 counter->counter_index = i % NI660X_COUNTERS_PER_CHIP;
836
837 s->type = COMEDI_SUBD_COUNTER;
838 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
839 SDF_LSAMPL | SDF_CMD_READ;
840 s->n_chan = 3;
841 s->maxdata = 0xffffffff;
842 s->insn_read = ni_tio_insn_read;
843 s->insn_write = ni_tio_insn_write;
844 s->insn_config = ni_tio_insn_config;
845 s->len_chanlist = 1;
846 s->do_cmd = ni_660x_cmd;
847 s->do_cmdtest = ni_tio_cmdtest;
848 s->cancel = ni_660x_cancel;
849 s->poll = ni_660x_input_poll;
850 s->buf_change = ni_660x_buf_change;
851 s->async_dma_dir = DMA_BIDIRECTIONAL;
852 s->private = counter;
853
854 ni_tio_init_counter(counter);
855 } else {
856 s->type = COMEDI_SUBD_UNUSED;
857 }
858 }
859
860
861
862
863
864 for (i = 0; i < board->n_chips; ++i)
865 set_tio_counterswap(dev, i);
866
867 ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
868 dev->board_name, dev);
869 if (ret < 0) {
870 dev_warn(dev->class_dev, " irq not available\n");
871 return ret;
872 }
873 dev->irq = pcidev->irq;
874 global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
875 if (board->n_chips > 1)
876 global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
877 ni_660x_write(dev, 0, global_interrupt_config_bits,
878 NI660X_GLOBAL_INT_CFG);
879
880 return 0;
881}
882
883static void ni_660x_detach(struct comedi_device *dev)
884{
885 struct ni_660x_private *devpriv = dev->private;
886
887 if (dev->irq) {
888 ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG);
889 free_irq(dev->irq, dev);
890 }
891 if (devpriv) {
892 ni_gpct_device_destroy(devpriv->counter_dev);
893 ni_660x_free_mite_rings(dev);
894 mite_detach(devpriv->mite);
895 }
896 if (dev->mmio)
897 iounmap(dev->mmio);
898 comedi_pci_disable(dev);
899}
900
901static struct comedi_driver ni_660x_driver = {
902 .driver_name = "ni_660x",
903 .module = THIS_MODULE,
904 .auto_attach = ni_660x_auto_attach,
905 .detach = ni_660x_detach,
906};
907
908static int ni_660x_pci_probe(struct pci_dev *dev,
909 const struct pci_device_id *id)
910{
911 return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
912}
913
914static const struct pci_device_id ni_660x_pci_table[] = {
915 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
916 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
917 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
918 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
919 { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
920 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
921 { 0 }
922};
923MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
924
925static struct pci_driver ni_660x_pci_driver = {
926 .name = "ni_660x",
927 .id_table = ni_660x_pci_table,
928 .probe = ni_660x_pci_probe,
929 .remove = comedi_pci_auto_unconfig,
930};
931module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
932
933MODULE_AUTHOR("Comedi http://www.comedi.org");
934MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
935MODULE_LICENSE("GPL");
936