2 comedi/drivers/ni_660x.c
3 Hardware driver for NI 660x devices
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 Description: National Instruments 660x counter/timer boards
24 [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
26 Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
27 Herman.Bruyninckx@mech.kuleuven.ac.be,
28 Wim.Meeussen@mech.kuleuven.ac.be,
29 Klaas.Gadeyne@mech.kuleuven.ac.be,
30 Frank Mori Hess <fmhess@users.sourceforge.net>
31 Updated: Thu Oct 18 12:56:06 EDT 2007
34 Encoders work. PulseGeneration (both single pulse and pulse train)
35 works. Buffered commands work for input but not output.
38 DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
39 DAQ 6601/6602 User Manual (NI 322137B-01)
43 #include <linux/interrupt.h>
44 #include "../comedidev.h"
48 enum ni_660x_constants {
49 min_counter_pfi_chan = 8,
50 max_dio_pfi_chan = 31,
54 #define NUM_PFI_CHANNELS 40
55 /* really there are only up to 3 dma channels, but the register layout allows
57 #define MAX_DMA_CHANNEL 4
59 /* See Register-Level Programmer Manual page 3.1 */
60 enum NI_660x_Register {
61 G0InterruptAcknowledge,
63 G1InterruptAcknowledge,
76 G01JointStatus1Register,
80 G01JointStatus2Register,
84 G0InputSelectRegister,
85 G1InputSelectRegister,
86 G0AutoincrementRegister,
87 G1AutoincrementRegister,
88 G01JointResetRegister,
91 G0CountingModeRegister,
92 G1CountingModeRegister,
99 G2InterruptAcknowledge,
101 G3InterruptAcknowledge,
111 G23JointStatus1Register,
114 G23JointStatus2Register,
118 G2InputSelectRegister,
119 G3InputSelectRegister,
120 G2AutoincrementRegister,
121 G3AutoincrementRegister,
122 G23JointResetRegister,
125 G2CountingModeRegister,
126 G3CountingModeRegister,
127 G3SecondGateRegister,
128 G2SecondGateRegister,
136 GlobalInterruptStatusRegister,
138 GlobalInterruptConfigRegister,
162 static inline unsigned IOConfigReg(unsigned pfi_channel)
164 unsigned reg = IOConfigReg0_1 + pfi_channel / 2;
165 BUG_ON(reg > IOConfigReg38_39);
169 enum ni_660x_register_width {
175 enum ni_660x_register_direction {
181 enum ni_660x_pfi_output_select {
182 pfi_output_select_high_Z = 0,
183 pfi_output_select_counter = 1,
184 pfi_output_select_do = 2,
185 num_pfi_output_selects
188 enum ni_660x_subdevices {
189 NI_660X_DIO_SUBDEV = 1,
190 NI_660X_GPCT_SUBDEV_0 = 2
192 static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
194 return NI_660X_GPCT_SUBDEV_0 + index;
197 struct NI_660xRegisterData {
199 const char *name; /* Register Name */
200 int offset; /* Offset from base address from GPCT chip */
201 enum ni_660x_register_direction direction;
202 enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
205 static const struct NI_660xRegisterData registerData[NumRegisters] = {
206 {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
207 {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
208 {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
209 {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
210 {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
211 {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
212 {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
213 {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
214 {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
215 {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
216 {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
217 {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
218 {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
219 {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
220 {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
221 {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
222 {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
223 {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
224 {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
225 {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
226 {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
227 {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
228 {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
229 {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
230 {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
231 {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
232 {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
233 {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
234 {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
235 {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
236 {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
237 {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
238 {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
239 {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
240 {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
241 {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
242 {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
243 {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
244 {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
245 {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
246 {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
247 {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
248 {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
249 {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
250 {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
251 {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
252 {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
253 {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
254 {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
255 {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
256 {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
257 {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
258 {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
259 {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
260 {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
261 {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
262 {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
263 {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
264 {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
265 {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
266 {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
267 {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
268 {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
269 {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
270 {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
271 {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
272 {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
273 {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
274 {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
275 {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
276 {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
277 {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
278 {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
279 {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
280 {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
281 {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
282 {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
283 {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
284 {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
285 {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
286 {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
287 {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
288 {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
289 {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
290 {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
291 {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
292 {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
293 {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
294 {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
295 {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
296 {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
297 {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
298 {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
299 {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
300 {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
301 {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
302 {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
303 {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
306 /* kind of ENABLE for the second counter */
307 enum clock_config_register_bits {
308 CounterSwap = 0x1 << 21
312 static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
320 static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
322 return 0x3 << ioconfig_bitshift(pfi_channel);
325 static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
326 unsigned output_select)
328 return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
331 static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
333 return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
336 static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
337 unsigned input_select)
339 return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
342 /* dma configuration register bits */
343 static inline unsigned dma_select_mask(unsigned dma_channel)
345 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
346 return 0x1f << (8 * dma_channel);
350 dma_selection_none = 0x1f,
352 static inline unsigned dma_selection_counter(unsigned counter_index)
354 BUG_ON(counter_index >= counters_per_chip);
355 return counter_index;
358 static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
360 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
361 return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
364 static inline unsigned dma_reset_bit(unsigned dma_channel)
366 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
367 return 0x80 << (8 * dma_channel);
370 enum global_interrupt_status_register_bits {
371 Counter_0_Int_Bit = 0x100,
372 Counter_1_Int_Bit = 0x200,
373 Counter_2_Int_Bit = 0x400,
374 Counter_3_Int_Bit = 0x800,
375 Cascade_Int_Bit = 0x20000000,
376 Global_Int_Bit = 0x80000000
379 enum global_interrupt_config_register_bits {
380 Cascade_Int_Enable_Bit = 0x20000000,
381 Global_Int_Polarity_Bit = 0x40000000,
382 Global_Int_Enable_Bit = 0x80000000
385 /* Offset of the GPCT chips from the base-adress of the card */
386 /* First chip is at base-address + 0x00, etc. */
387 static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
389 /* Board description*/
390 struct ni_660x_board {
391 unsigned short dev_id; /* `lspci` will show you this */
393 unsigned n_chips; /* total number of TIO chips */
396 static const struct ni_660x_board ni_660x_boards[] = {
419 #define NI_660X_MAX_NUM_CHIPS 2
420 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
422 static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
424 PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
425 PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
426 PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
427 PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
431 MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
433 struct ni_660x_private {
434 struct mite_struct *mite;
435 struct ni_gpct_device *counter_dev;
436 uint64_t pfi_direction_bits;
437 struct mite_dma_descriptor_ring
438 *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
439 spinlock_t mite_channel_lock;
440 /* interrupt_lock prevents races between interrupt and comedi_poll */
441 spinlock_t interrupt_lock;
442 unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
443 spinlock_t soft_reg_copy_lock;
444 unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
447 static inline struct ni_660x_private *private(struct comedi_device *dev)
452 /* initialized in ni_660x_find_device() */
453 static inline const struct ni_660x_board *board(struct comedi_device *dev)
455 return dev->board_ptr;
458 #define n_ni_660x_boards ARRAY_SIZE(ni_660x_boards)
460 static int ni_660x_attach(struct comedi_device *dev,
461 struct comedi_devconfig *it);
462 static int ni_660x_detach(struct comedi_device *dev);
463 static void init_tio_chip(struct comedi_device *dev, int chipset);
464 static void ni_660x_select_pfi_output(struct comedi_device *dev,
465 unsigned pfi_channel,
466 unsigned output_select);
468 static struct comedi_driver driver_ni_660x = {
469 .driver_name = "ni_660x",
470 .module = THIS_MODULE,
471 .attach = ni_660x_attach,
472 .detach = ni_660x_detach,
475 COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
477 static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot);
478 static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
481 /* Possible instructions for a GPCT */
482 static int ni_660x_GPCT_rinsn(struct comedi_device *dev,
483 struct comedi_subdevice *s,
484 struct comedi_insn *insn, unsigned int *data);
485 static int ni_660x_GPCT_insn_config(struct comedi_device *dev,
486 struct comedi_subdevice *s,
487 struct comedi_insn *insn,
489 static int ni_660x_GPCT_winsn(struct comedi_device *dev,
490 struct comedi_subdevice *s,
491 struct comedi_insn *insn, unsigned int *data);
493 /* Possible instructions for Digital IO */
494 static int ni_660x_dio_insn_config(struct comedi_device *dev,
495 struct comedi_subdevice *s,
496 struct comedi_insn *insn,
498 static int ni_660x_dio_insn_bits(struct comedi_device *dev,
499 struct comedi_subdevice *s,
500 struct comedi_insn *insn, unsigned int *data);
502 static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
504 return board(dev)->n_chips * counters_per_chip;
507 static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
509 enum NI_660x_Register ni_660x_register;
511 case NITIO_G0_Autoincrement_Reg:
512 ni_660x_register = G0AutoincrementRegister;
514 case NITIO_G1_Autoincrement_Reg:
515 ni_660x_register = G1AutoincrementRegister;
517 case NITIO_G2_Autoincrement_Reg:
518 ni_660x_register = G2AutoincrementRegister;
520 case NITIO_G3_Autoincrement_Reg:
521 ni_660x_register = G3AutoincrementRegister;
523 case NITIO_G0_Command_Reg:
524 ni_660x_register = G0CommandRegister;
526 case NITIO_G1_Command_Reg:
527 ni_660x_register = G1CommandRegister;
529 case NITIO_G2_Command_Reg:
530 ni_660x_register = G2CommandRegister;
532 case NITIO_G3_Command_Reg:
533 ni_660x_register = G3CommandRegister;
535 case NITIO_G0_HW_Save_Reg:
536 ni_660x_register = G0HWSaveRegister;
538 case NITIO_G1_HW_Save_Reg:
539 ni_660x_register = G1HWSaveRegister;
541 case NITIO_G2_HW_Save_Reg:
542 ni_660x_register = G2HWSaveRegister;
544 case NITIO_G3_HW_Save_Reg:
545 ni_660x_register = G3HWSaveRegister;
547 case NITIO_G0_SW_Save_Reg:
548 ni_660x_register = G0SWSaveRegister;
550 case NITIO_G1_SW_Save_Reg:
551 ni_660x_register = G1SWSaveRegister;
553 case NITIO_G2_SW_Save_Reg:
554 ni_660x_register = G2SWSaveRegister;
556 case NITIO_G3_SW_Save_Reg:
557 ni_660x_register = G3SWSaveRegister;
559 case NITIO_G0_Mode_Reg:
560 ni_660x_register = G0ModeRegister;
562 case NITIO_G1_Mode_Reg:
563 ni_660x_register = G1ModeRegister;
565 case NITIO_G2_Mode_Reg:
566 ni_660x_register = G2ModeRegister;
568 case NITIO_G3_Mode_Reg:
569 ni_660x_register = G3ModeRegister;
571 case NITIO_G0_LoadA_Reg:
572 ni_660x_register = G0LoadARegister;
574 case NITIO_G1_LoadA_Reg:
575 ni_660x_register = G1LoadARegister;
577 case NITIO_G2_LoadA_Reg:
578 ni_660x_register = G2LoadARegister;
580 case NITIO_G3_LoadA_Reg:
581 ni_660x_register = G3LoadARegister;
583 case NITIO_G0_LoadB_Reg:
584 ni_660x_register = G0LoadBRegister;
586 case NITIO_G1_LoadB_Reg:
587 ni_660x_register = G1LoadBRegister;
589 case NITIO_G2_LoadB_Reg:
590 ni_660x_register = G2LoadBRegister;
592 case NITIO_G3_LoadB_Reg:
593 ni_660x_register = G3LoadBRegister;
595 case NITIO_G0_Input_Select_Reg:
596 ni_660x_register = G0InputSelectRegister;
598 case NITIO_G1_Input_Select_Reg:
599 ni_660x_register = G1InputSelectRegister;
601 case NITIO_G2_Input_Select_Reg:
602 ni_660x_register = G2InputSelectRegister;
604 case NITIO_G3_Input_Select_Reg:
605 ni_660x_register = G3InputSelectRegister;
607 case NITIO_G01_Status_Reg:
608 ni_660x_register = G01StatusRegister;
610 case NITIO_G23_Status_Reg:
611 ni_660x_register = G23StatusRegister;
613 case NITIO_G01_Joint_Reset_Reg:
614 ni_660x_register = G01JointResetRegister;
616 case NITIO_G23_Joint_Reset_Reg:
617 ni_660x_register = G23JointResetRegister;
619 case NITIO_G01_Joint_Status1_Reg:
620 ni_660x_register = G01JointStatus1Register;
622 case NITIO_G23_Joint_Status1_Reg:
623 ni_660x_register = G23JointStatus1Register;
625 case NITIO_G01_Joint_Status2_Reg:
626 ni_660x_register = G01JointStatus2Register;
628 case NITIO_G23_Joint_Status2_Reg:
629 ni_660x_register = G23JointStatus2Register;
631 case NITIO_G0_Counting_Mode_Reg:
632 ni_660x_register = G0CountingModeRegister;
634 case NITIO_G1_Counting_Mode_Reg:
635 ni_660x_register = G1CountingModeRegister;
637 case NITIO_G2_Counting_Mode_Reg:
638 ni_660x_register = G2CountingModeRegister;
640 case NITIO_G3_Counting_Mode_Reg:
641 ni_660x_register = G3CountingModeRegister;
643 case NITIO_G0_Second_Gate_Reg:
644 ni_660x_register = G0SecondGateRegister;
646 case NITIO_G1_Second_Gate_Reg:
647 ni_660x_register = G1SecondGateRegister;
649 case NITIO_G2_Second_Gate_Reg:
650 ni_660x_register = G2SecondGateRegister;
652 case NITIO_G3_Second_Gate_Reg:
653 ni_660x_register = G3SecondGateRegister;
655 case NITIO_G0_DMA_Config_Reg:
656 ni_660x_register = G0DMAConfigRegister;
658 case NITIO_G0_DMA_Status_Reg:
659 ni_660x_register = G0DMAStatusRegister;
661 case NITIO_G1_DMA_Config_Reg:
662 ni_660x_register = G1DMAConfigRegister;
664 case NITIO_G1_DMA_Status_Reg:
665 ni_660x_register = G1DMAStatusRegister;
667 case NITIO_G2_DMA_Config_Reg:
668 ni_660x_register = G2DMAConfigRegister;
670 case NITIO_G2_DMA_Status_Reg:
671 ni_660x_register = G2DMAStatusRegister;
673 case NITIO_G3_DMA_Config_Reg:
674 ni_660x_register = G3DMAConfigRegister;
676 case NITIO_G3_DMA_Status_Reg:
677 ni_660x_register = G3DMAStatusRegister;
679 case NITIO_G0_Interrupt_Acknowledge_Reg:
680 ni_660x_register = G0InterruptAcknowledge;
682 case NITIO_G1_Interrupt_Acknowledge_Reg:
683 ni_660x_register = G1InterruptAcknowledge;
685 case NITIO_G2_Interrupt_Acknowledge_Reg:
686 ni_660x_register = G2InterruptAcknowledge;
688 case NITIO_G3_Interrupt_Acknowledge_Reg:
689 ni_660x_register = G3InterruptAcknowledge;
691 case NITIO_G0_Status_Reg:
692 ni_660x_register = G0StatusRegister;
694 case NITIO_G1_Status_Reg:
695 ni_660x_register = G1StatusRegister;
697 case NITIO_G2_Status_Reg:
698 ni_660x_register = G2StatusRegister;
700 case NITIO_G3_Status_Reg:
701 ni_660x_register = G3StatusRegister;
703 case NITIO_G0_Interrupt_Enable_Reg:
704 ni_660x_register = G0InterruptEnable;
706 case NITIO_G1_Interrupt_Enable_Reg:
707 ni_660x_register = G1InterruptEnable;
709 case NITIO_G2_Interrupt_Enable_Reg:
710 ni_660x_register = G2InterruptEnable;
712 case NITIO_G3_Interrupt_Enable_Reg:
713 ni_660x_register = G3InterruptEnable;
716 printk(KERN_WARNING "%s: unhandled register 0x%x in switch.\n",
722 return ni_660x_register;
725 static inline void ni_660x_write_register(struct comedi_device *dev,
726 unsigned chip_index, unsigned bits,
727 enum NI_660x_Register reg)
729 void *const write_address =
730 private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
731 registerData[reg].offset;
733 switch (registerData[reg].size) {
735 writew(bits, write_address);
738 writel(bits, write_address);
741 printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
742 __FILE__, __func__, reg);
748 static inline unsigned ni_660x_read_register(struct comedi_device *dev,
750 enum NI_660x_Register reg)
752 void *const read_address =
753 private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
754 registerData[reg].offset;
756 switch (registerData[reg].size) {
758 return readw(read_address);
761 return readl(read_address);
764 printk(KERN_WARNING "%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
765 __FILE__, __func__, reg);
772 static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
773 enum ni_gpct_register reg)
775 struct comedi_device *dev = counter->counter_dev->dev;
776 enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
777 ni_660x_write_register(dev, counter->chip_index, bits,
781 static unsigned ni_gpct_read_register(struct ni_gpct *counter,
782 enum ni_gpct_register reg)
784 struct comedi_device *dev = counter->counter_dev->dev;
785 enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
786 return ni_660x_read_register(dev, counter->chip_index,
790 static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private
795 return priv->mite_rings[counter->chip_index][counter->counter_index];
798 static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
799 unsigned mite_channel,
800 struct ni_gpct *counter)
803 spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
804 private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
805 ~dma_select_mask(mite_channel);
806 private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
807 dma_select_bits(mite_channel,
808 dma_selection_counter(counter->counter_index));
809 ni_660x_write_register(dev, counter->chip_index,
811 dma_configuration_soft_copies
812 [counter->chip_index] |
813 dma_reset_bit(mite_channel), DMAConfigRegister);
815 spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
818 static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
819 unsigned mite_channel,
820 struct ni_gpct *counter)
823 spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
824 private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
825 ~dma_select_mask(mite_channel);
826 private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
827 dma_select_bits(mite_channel, dma_selection_none);
828 ni_660x_write_register(dev, counter->chip_index,
830 dma_configuration_soft_copies
831 [counter->chip_index], DMAConfigRegister);
833 spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
836 static int ni_660x_request_mite_channel(struct comedi_device *dev,
837 struct ni_gpct *counter,
838 enum comedi_io_direction direction)
841 struct mite_channel *mite_chan;
843 spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
844 BUG_ON(counter->mite_chan);
846 mite_request_channel(private(dev)->mite, mite_ring(private(dev),
848 if (mite_chan == NULL) {
849 spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
851 "failed to reserve mite dma channel for counter.");
854 mite_chan->dir = direction;
855 ni_tio_set_mite_channel(counter, mite_chan);
856 ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
857 spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
861 void ni_660x_release_mite_channel(struct comedi_device *dev,
862 struct ni_gpct *counter)
866 spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
867 if (counter->mite_chan) {
868 struct mite_channel *mite_chan = counter->mite_chan;
870 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
871 ni_tio_set_mite_channel(counter, NULL);
872 mite_release_channel(mite_chan);
874 spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
877 static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
881 struct ni_gpct *counter = subdev_to_counter(s);
882 /* const struct comedi_cmd *cmd = &s->async->cmd; */
884 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
887 "no dma channel available for use by counter");
890 ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
891 retval = ni_tio_cmd(counter, s->async);
896 static int ni_660x_cmdtest(struct comedi_device *dev,
897 struct comedi_subdevice *s, struct comedi_cmd *cmd)
899 struct ni_gpct *counter = subdev_to_counter(s);
901 return ni_tio_cmdtest(counter, cmd);
904 static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
906 struct ni_gpct *counter = subdev_to_counter(s);
909 retval = ni_tio_cancel(counter);
910 ni_660x_release_mite_channel(dev, counter);
914 static void set_tio_counterswap(struct comedi_device *dev, int chipset)
916 /* See P. 3.5 of the Register-Level Programming manual. The
917 CounterSwap bit has to be set on the second chip, otherwise
918 it will try to use the same pins as the first chip.
921 ni_660x_write_register(dev, chipset, CounterSwap,
922 ClockConfigRegister);
924 ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
927 static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
928 struct comedi_subdevice *s)
930 ni_tio_handle_interrupt(subdev_to_counter(s), s);
931 if (s->async->events) {
932 if (s->async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
933 COMEDI_CB_OVERFLOW)) {
934 ni_660x_cancel(dev, s);
936 comedi_event(dev, s);
940 static irqreturn_t ni_660x_interrupt(int irq, void *d)
942 struct comedi_device *dev = d;
943 struct comedi_subdevice *s;
947 if (dev->attached == 0)
949 /* lock to avoid race with comedi_poll */
950 spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
952 for (i = 0; i < ni_660x_num_counters(dev); ++i) {
953 s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
954 ni_660x_handle_gpct_interrupt(dev, s);
956 spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
960 static int ni_660x_input_poll(struct comedi_device *dev,
961 struct comedi_subdevice *s)
964 /* lock to avoid race with comedi_poll */
965 spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
966 mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async);
967 spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
968 return comedi_buf_read_n_available(s->async);
971 static int ni_660x_buf_change(struct comedi_device *dev,
972 struct comedi_subdevice *s,
973 unsigned long new_size)
977 ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
985 static int ni_660x_allocate_private(struct comedi_device *dev)
990 retval = alloc_private(dev, sizeof(struct ni_660x_private));
994 spin_lock_init(&private(dev)->mite_channel_lock);
995 spin_lock_init(&private(dev)->interrupt_lock);
996 spin_lock_init(&private(dev)->soft_reg_copy_lock);
997 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
998 private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
1003 static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
1008 for (i = 0; i < board(dev)->n_chips; ++i) {
1009 for (j = 0; j < counters_per_chip; ++j) {
1010 private(dev)->mite_rings[i][j] =
1011 mite_alloc_ring(private(dev)->mite);
1012 if (private(dev)->mite_rings[i][j] == NULL)
1019 static void ni_660x_free_mite_rings(struct comedi_device *dev)
1024 for (i = 0; i < board(dev)->n_chips; ++i) {
1025 for (j = 0; j < counters_per_chip; ++j)
1026 mite_free_ring(private(dev)->mite_rings[i][j]);
1030 static int ni_660x_attach(struct comedi_device *dev,
1031 struct comedi_devconfig *it)
1033 struct comedi_subdevice *s;
1036 unsigned global_interrupt_config_bits;
1038 printk(KERN_INFO "comedi%d: ni_660x: ", dev->minor);
1040 ret = ni_660x_allocate_private(dev);
1043 ret = ni_660x_find_device(dev, it->options[0], it->options[1]);
1047 dev->board_name = board(dev)->name;
1049 ret = mite_setup2(private(dev)->mite, 1);
1051 printk(KERN_WARNING "error setting up mite\n");
1054 comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
1055 ret = ni_660x_alloc_mite_rings(dev);
1059 printk(KERN_INFO " %s ", dev->board_name);
1061 dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
1063 if (alloc_subdevices(dev, dev->n_subdevices) < 0)
1066 s = dev->subdevices + 0;
1067 /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
1068 s->type = COMEDI_SUBD_UNUSED;
1070 s = dev->subdevices + NI_660X_DIO_SUBDEV;
1071 /* DIGITAL I/O SUBDEVICE */
1072 s->type = COMEDI_SUBD_DIO;
1073 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1074 s->n_chan = NUM_PFI_CHANNELS;
1076 s->range_table = &range_digital;
1077 s->insn_bits = ni_660x_dio_insn_bits;
1078 s->insn_config = ni_660x_dio_insn_config;
1079 s->io_bits = 0; /* all bits default to input */
1080 /* we use the ioconfig registers to control dio direction, so zero
1081 output enables in stc dio control reg */
1082 ni_660x_write_register(dev, 0, 0, STCDIOControl);
1084 private(dev)->counter_dev = ni_gpct_device_construct(dev,
1085 &ni_gpct_write_register,
1086 &ni_gpct_read_register,
1087 ni_gpct_variant_660x,
1088 ni_660x_num_counters
1090 if (private(dev)->counter_dev == NULL)
1092 for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
1093 s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
1094 if (i < ni_660x_num_counters(dev)) {
1095 s->type = COMEDI_SUBD_COUNTER;
1097 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
1098 SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
1100 s->maxdata = 0xffffffff;
1101 s->insn_read = ni_660x_GPCT_rinsn;
1102 s->insn_write = ni_660x_GPCT_winsn;
1103 s->insn_config = ni_660x_GPCT_insn_config;
1104 s->do_cmd = &ni_660x_cmd;
1105 s->len_chanlist = 1;
1106 s->do_cmdtest = &ni_660x_cmdtest;
1107 s->cancel = &ni_660x_cancel;
1108 s->poll = &ni_660x_input_poll;
1109 s->async_dma_dir = DMA_BIDIRECTIONAL;
1110 s->buf_change = &ni_660x_buf_change;
1111 s->private = &private(dev)->counter_dev->counters[i];
1113 private(dev)->counter_dev->counters[i].chip_index =
1114 i / counters_per_chip;
1115 private(dev)->counter_dev->counters[i].counter_index =
1116 i % counters_per_chip;
1118 s->type = COMEDI_SUBD_UNUSED;
1121 for (i = 0; i < board(dev)->n_chips; ++i)
1122 init_tio_chip(dev, i);
1124 for (i = 0; i < ni_660x_num_counters(dev); ++i)
1125 ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
1127 for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
1128 if (i < min_counter_pfi_chan)
1129 ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
1131 ni_660x_set_pfi_routing(dev, i,
1132 pfi_output_select_counter);
1133 ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
1135 /* to be safe, set counterswap bits on tio chips after all the counter
1136 outputs have been set to high impedance mode */
1137 for (i = 0; i < board(dev)->n_chips; ++i)
1138 set_tio_counterswap(dev, i);
1140 ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
1141 IRQF_SHARED, "ni_660x", dev);
1143 printk(KERN_WARNING " irq not available\n");
1146 dev->irq = mite_irq(private(dev)->mite);
1147 global_interrupt_config_bits = Global_Int_Enable_Bit;
1148 if (board(dev)->n_chips > 1)
1149 global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
1150 ni_660x_write_register(dev, 0, global_interrupt_config_bits,
1151 GlobalInterruptConfigRegister);
1152 printk(KERN_INFO "attached\n");
1156 static int ni_660x_detach(struct comedi_device *dev)
1158 printk(KERN_INFO "comedi%d: ni_660x: remove\n", dev->minor);
1162 free_irq(dev->irq, dev);
1165 if (private(dev)->counter_dev)
1166 ni_gpct_device_destroy(private(dev)->counter_dev);
1167 if (private(dev)->mite) {
1168 ni_660x_free_mite_rings(dev);
1169 mite_unsetup(private(dev)->mite);
1176 ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1177 struct comedi_insn *insn, unsigned int *data)
1179 return ni_tio_rinsn(subdev_to_counter(s), insn, data);
1182 static void init_tio_chip(struct comedi_device *dev, int chipset)
1186 /* init dma configuration register */
1187 private(dev)->dma_configuration_soft_copies[chipset] = 0;
1188 for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
1189 private(dev)->dma_configuration_soft_copies[chipset] |=
1190 dma_select_bits(i, dma_selection_none) & dma_select_mask(i);
1192 ni_660x_write_register(dev, chipset,
1194 dma_configuration_soft_copies[chipset],
1196 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
1197 ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
1201 ni_660x_GPCT_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
1202 struct comedi_insn *insn, unsigned int *data)
1204 return ni_tio_insn_config(subdev_to_counter(s), insn, data);
1207 static int ni_660x_GPCT_winsn(struct comedi_device *dev,
1208 struct comedi_subdevice *s,
1209 struct comedi_insn *insn, unsigned int *data)
1211 return ni_tio_winsn(subdev_to_counter(s), insn, data);
1214 static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
1216 struct mite_struct *mite;
1219 for (mite = mite_devices; mite; mite = mite->next) {
1223 if (bus != mite->pcidev->bus->number ||
1224 slot != PCI_SLOT(mite->pcidev->devfn))
1228 for (i = 0; i < n_ni_660x_boards; i++) {
1229 if (mite_device_id(mite) == ni_660x_boards[i].dev_id) {
1230 dev->board_ptr = ni_660x_boards + i;
1231 private(dev)->mite = mite;
1236 printk(KERN_WARNING "no device found\n");
1237 mite_list_devices();
1241 static int ni_660x_dio_insn_bits(struct comedi_device *dev,
1242 struct comedi_subdevice *s,
1243 struct comedi_insn *insn, unsigned int *data)
1245 unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
1247 /* Check if we have to write some bits */
1249 s->state &= ~(data[0] << base_bitfield_channel);
1250 s->state |= (data[0] & data[1]) << base_bitfield_channel;
1251 /* Write out the new digital output lines */
1252 ni_660x_write_register(dev, 0, s->state, DIO32Output);
1254 /* on return, data[1] contains the value of the digital
1255 * input and output lines. */
1257 (ni_660x_read_register(dev, 0,
1258 DIO32Input) >> base_bitfield_channel);
1262 static void ni_660x_select_pfi_output(struct comedi_device *dev,
1263 unsigned pfi_channel,
1264 unsigned output_select)
1266 static const unsigned counter_4_7_first_pfi = 8;
1267 static const unsigned counter_4_7_last_pfi = 23;
1268 unsigned active_chipset = 0;
1269 unsigned idle_chipset = 0;
1270 unsigned active_bits;
1273 if (board(dev)->n_chips > 1) {
1274 if (output_select == pfi_output_select_counter &&
1275 pfi_channel >= counter_4_7_first_pfi &&
1276 pfi_channel <= counter_4_7_last_pfi) {
1285 if (idle_chipset != active_chipset) {
1287 ni_660x_read_register(dev, idle_chipset,
1288 IOConfigReg(pfi_channel));
1289 idle_bits &= ~pfi_output_select_mask(pfi_channel);
1291 pfi_output_select_bits(pfi_channel,
1292 pfi_output_select_high_Z);
1293 ni_660x_write_register(dev, idle_chipset, idle_bits,
1294 IOConfigReg(pfi_channel));
1298 ni_660x_read_register(dev, active_chipset,
1299 IOConfigReg(pfi_channel));
1300 active_bits &= ~pfi_output_select_mask(pfi_channel);
1301 active_bits |= pfi_output_select_bits(pfi_channel, output_select);
1302 ni_660x_write_register(dev, active_chipset, active_bits,
1303 IOConfigReg(pfi_channel));
1306 static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
1309 if (source > num_pfi_output_selects)
1311 if (source == pfi_output_select_high_Z)
1313 if (chan < min_counter_pfi_chan) {
1314 if (source == pfi_output_select_counter)
1316 } else if (chan > max_dio_pfi_chan) {
1317 if (source == pfi_output_select_do)
1320 BUG_ON(chan >= NUM_PFI_CHANNELS);
1322 private(dev)->pfi_output_selects[chan] = source;
1323 if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
1324 ni_660x_select_pfi_output(dev, chan,
1326 pfi_output_selects[chan]);
1330 static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev,
1333 BUG_ON(chan >= NUM_PFI_CHANNELS);
1334 return private(dev)->pfi_output_selects[chan];
1337 static void ni660x_config_filter(struct comedi_device *dev,
1338 unsigned pfi_channel,
1339 enum ni_gpct_filter_select filter)
1341 unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
1342 bits &= ~pfi_input_select_mask(pfi_channel);
1343 bits |= pfi_input_select_bits(pfi_channel, filter);
1344 ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
1347 static int ni_660x_dio_insn_config(struct comedi_device *dev,
1348 struct comedi_subdevice *s,
1349 struct comedi_insn *insn, unsigned int *data)
1351 int chan = CR_CHAN(insn->chanspec);
1353 /* The input or output configuration of each digital line is
1354 * configured by a special insn_config instruction. chanspec
1355 * contains the channel to be changed, and data[0] contains the
1356 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1359 case INSN_CONFIG_DIO_OUTPUT:
1360 private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
1361 ni_660x_select_pfi_output(dev, chan,
1363 pfi_output_selects[chan]);
1365 case INSN_CONFIG_DIO_INPUT:
1366 private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
1367 ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
1369 case INSN_CONFIG_DIO_QUERY:
1371 (private(dev)->pfi_direction_bits &
1372 (((uint64_t) 1) << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
1374 case INSN_CONFIG_SET_ROUTING:
1375 return ni_660x_set_pfi_routing(dev, chan, data[1]);
1377 case INSN_CONFIG_GET_ROUTING:
1378 data[1] = ni_660x_get_pfi_routing(dev, chan);
1380 case INSN_CONFIG_FILTER:
1381 ni660x_config_filter(dev, chan, data[1]);