ni_660x.c revision 5f74ea14c07fee91d3bdbaad88bff6264c6200e6
1/*
2  comedi/drivers/ni_660x.c
3  Hardware driver for NI 660x devices
4
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.
9
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.
14
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.
18*/
19
20/*
21Driver: ni_660x
22Description: National Instruments 660x counter/timer boards
23Devices:
24[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
25	PXI-6608
26Author: 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>
31Updated: Thu Oct 18 12:56:06 EDT 2007
32Status: experimental
33
34Encoders work.  PulseGeneration (both single pulse and pulse train)
35works. Buffered commands work for input but not output.
36
37References:
38DAQ 660x Register-Level Programmer Manual  (NI 370505A-01)
39DAQ 6601/6602 User Manual (NI 322137B-01)
40
41*/
42
43#include "../comedidev.h"
44#include "mite.h"
45#include "ni_tio.h"
46
47enum ni_660x_constants {
48	min_counter_pfi_chan = 8,
49	max_dio_pfi_chan = 31,
50	counters_per_chip = 4
51};
52
53#define NUM_PFI_CHANNELS 40
54/* really there are only up to 3 dma channels, but the register layout allows for 4 */
55#define MAX_DMA_CHANNEL 4
56
57/* See Register-Level Programmer Manual page 3.1 */
58enum NI_660x_Register {
59	G0InterruptAcknowledge,
60	G0StatusRegister,
61	G1InterruptAcknowledge,
62	G1StatusRegister,
63	G01StatusRegister,
64	G0CommandRegister,
65	STCDIOParallelInput,
66	G1CommandRegister,
67	G0HWSaveRegister,
68	G1HWSaveRegister,
69	STCDIOOutput,
70	STCDIOControl,
71	G0SWSaveRegister,
72	G1SWSaveRegister,
73	G0ModeRegister,
74	G01JointStatus1Register,
75	G1ModeRegister,
76	STCDIOSerialInput,
77	G0LoadARegister,
78	G01JointStatus2Register,
79	G0LoadBRegister,
80	G1LoadARegister,
81	G1LoadBRegister,
82	G0InputSelectRegister,
83	G1InputSelectRegister,
84	G0AutoincrementRegister,
85	G1AutoincrementRegister,
86	G01JointResetRegister,
87	G0InterruptEnable,
88	G1InterruptEnable,
89	G0CountingModeRegister,
90	G1CountingModeRegister,
91	G0SecondGateRegister,
92	G1SecondGateRegister,
93	G0DMAConfigRegister,
94	G0DMAStatusRegister,
95	G1DMAConfigRegister,
96	G1DMAStatusRegister,
97	G2InterruptAcknowledge,
98	G2StatusRegister,
99	G3InterruptAcknowledge,
100	G3StatusRegister,
101	G23StatusRegister,
102	G2CommandRegister,
103	G3CommandRegister,
104	G2HWSaveRegister,
105	G3HWSaveRegister,
106	G2SWSaveRegister,
107	G3SWSaveRegister,
108	G2ModeRegister,
109	G23JointStatus1Register,
110	G3ModeRegister,
111	G2LoadARegister,
112	G23JointStatus2Register,
113	G2LoadBRegister,
114	G3LoadARegister,
115	G3LoadBRegister,
116	G2InputSelectRegister,
117	G3InputSelectRegister,
118	G2AutoincrementRegister,
119	G3AutoincrementRegister,
120	G23JointResetRegister,
121	G2InterruptEnable,
122	G3InterruptEnable,
123	G2CountingModeRegister,
124	G3CountingModeRegister,
125	G3SecondGateRegister,
126	G2SecondGateRegister,
127	G2DMAConfigRegister,
128	G2DMAStatusRegister,
129	G3DMAConfigRegister,
130	G3DMAStatusRegister,
131	DIO32Input,
132	DIO32Output,
133	ClockConfigRegister,
134	GlobalInterruptStatusRegister,
135	DMAConfigRegister,
136	GlobalInterruptConfigRegister,
137	IOConfigReg0_1,
138	IOConfigReg2_3,
139	IOConfigReg4_5,
140	IOConfigReg6_7,
141	IOConfigReg8_9,
142	IOConfigReg10_11,
143	IOConfigReg12_13,
144	IOConfigReg14_15,
145	IOConfigReg16_17,
146	IOConfigReg18_19,
147	IOConfigReg20_21,
148	IOConfigReg22_23,
149	IOConfigReg24_25,
150	IOConfigReg26_27,
151	IOConfigReg28_29,
152	IOConfigReg30_31,
153	IOConfigReg32_33,
154	IOConfigReg34_35,
155	IOConfigReg36_37,
156	IOConfigReg38_39,
157	NumRegisters,
158};
159
160static inline unsigned IOConfigReg(unsigned pfi_channel)
161{
162	unsigned reg = IOConfigReg0_1 + pfi_channel / 2;
163	BUG_ON(reg > IOConfigReg38_39);
164	return reg;
165}
166
167enum ni_660x_register_width {
168	DATA_1B,
169	DATA_2B,
170	DATA_4B
171};
172
173enum ni_660x_register_direction {
174	NI_660x_READ,
175	NI_660x_WRITE,
176	NI_660x_READ_WRITE
177};
178
179enum ni_660x_pfi_output_select {
180	pfi_output_select_high_Z = 0,
181	pfi_output_select_counter = 1,
182	pfi_output_select_do = 2,
183	num_pfi_output_selects
184};
185
186enum ni_660x_subdevices {
187	NI_660X_DIO_SUBDEV = 1,
188	NI_660X_GPCT_SUBDEV_0 = 2
189};
190static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
191{
192	return NI_660X_GPCT_SUBDEV_0 + index;
193}
194
195struct NI_660xRegisterData {
196
197	const char *name;	/*  Register Name */
198	int offset;		/*  Offset from base address from GPCT chip */
199	enum ni_660x_register_direction direction;
200	enum ni_660x_register_width size;	/*  1 byte, 2 bytes, or 4 bytes */
201};
202
203
204static const struct NI_660xRegisterData registerData[NumRegisters] = {
205	{"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
206	{"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
207	{"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
208	{"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
209	{"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
210	{"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
211	{"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
212	{"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
213	{"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
214	{"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
215	{"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
216	{"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
217	{"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
218	{"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
219	{"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
220	{"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
221	{"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
222	{"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
223	{"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
224	{"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
225	{"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
226	{"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
227	{"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
228	{"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
229	{"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
230	{"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
231	{"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
232	{"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
233	{"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
234	{"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
235	{"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
236	{"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
237	{"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
238	{"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
239	{"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
240	{"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
241	{"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
242	{"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
243	{"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
244	{"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
245	{"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
246	{"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
247	{"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
248	{"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
249	{"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
250	{"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
251	{"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
252	{"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
253	{"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
254	{"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
255	{"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
256	{"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
257	{"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
258	{"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
259	{"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
260	{"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
261	{"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
262	{"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
263	{"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
264	{"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
265	{"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
266	{"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
267	{"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
268	{"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
269	{"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
270	{"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
271	{"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
272	{"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
273	{"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
274	{"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
275	{"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
276	{"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
277	{"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
278	{"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
279	{"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
280	{"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
281	{"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
282	{"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
283	{"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
284	{"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
285	{"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
286	{"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
287	{"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
288	{"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
289	{"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
290	{"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
291	{"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
292	{"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
293	{"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
294	{"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
295	{"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
296	{"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
297	{"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
298	{"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
299	{"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
300	{"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
301	{"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
302	{"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
303};
304
305/* kind of ENABLE for the second counter */
306enum clock_config_register_bits {
307	CounterSwap = 0x1 << 21
308};
309
310/* ioconfigreg */
311static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
312{
313	if (pfi_channel % 2)
314		return 0;
315	else
316		return 8;
317}
318static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
319{
320	return 0x3 << ioconfig_bitshift(pfi_channel);
321}
322static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
323	unsigned output_select)
324{
325	return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
326}
327static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
328{
329	return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
330}
331static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
332	unsigned input_select)
333{
334	return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
335}
336
337/* dma configuration register bits */
338static inline unsigned dma_select_mask(unsigned dma_channel)
339{
340	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
341	return 0x1f << (8 * dma_channel);
342}
343enum dma_selection {
344	dma_selection_none = 0x1f,
345};
346static inline unsigned dma_selection_counter(unsigned counter_index)
347{
348	BUG_ON(counter_index >= counters_per_chip);
349	return counter_index;
350}
351static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
352{
353	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
354	return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
355}
356static inline unsigned dma_reset_bit(unsigned dma_channel)
357{
358	BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
359	return 0x80 << (8 * dma_channel);
360}
361
362enum global_interrupt_status_register_bits {
363	Counter_0_Int_Bit = 0x100,
364	Counter_1_Int_Bit = 0x200,
365	Counter_2_Int_Bit = 0x400,
366	Counter_3_Int_Bit = 0x800,
367	Cascade_Int_Bit = 0x20000000,
368	Global_Int_Bit = 0x80000000
369};
370
371enum global_interrupt_config_register_bits {
372	Cascade_Int_Enable_Bit = 0x20000000,
373	Global_Int_Polarity_Bit = 0x40000000,
374	Global_Int_Enable_Bit = 0x80000000
375};
376
377/* Offset of the GPCT chips from the base-adress of the card */
378static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };	/* First chip is at base-address +
379							   0x00, etc. */
380
381/* Board description*/
382struct ni_660x_board {
383	unsigned short dev_id;	/* `lspci` will show you this */
384	const char *name;
385	unsigned n_chips;	/* total number of TIO chips */
386};
387
388static const struct ni_660x_board ni_660x_boards[] = {
389	{
390	.dev_id = 0x2c60,
391	.name = "PCI-6601",
392	.n_chips = 1,
393		},
394	{
395	.dev_id = 0x1310,
396	.name = "PCI-6602",
397	.n_chips = 2,
398		},
399	{
400	.dev_id = 0x1360,
401	.name = "PXI-6602",
402	.n_chips = 2,
403		},
404	{
405	.dev_id = 0x2cc0,
406	.name = "PXI-6608",
407	.n_chips = 2,
408		},
409};
410
411#define NI_660X_MAX_NUM_CHIPS 2
412#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
413
414static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
415	{PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
416	{PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
417	{PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
418	{PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
419	{0}
420};
421
422MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
423
424struct ni_660x_private {
425	struct mite_struct *mite;
426	struct ni_gpct_device *counter_dev;
427	uint64_t pfi_direction_bits;
428	struct mite_dma_descriptor_ring
429	*mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
430	spinlock_t mite_channel_lock;
431	/* interrupt_lock prevents races between interrupt and comedi_poll */
432	spinlock_t interrupt_lock;
433	unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
434	spinlock_t soft_reg_copy_lock;
435	unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
436};
437
438static inline struct ni_660x_private *private(struct comedi_device * dev)
439{
440	return dev->private;
441}
442
443/* initialized in ni_660x_find_device() */
444static inline const struct ni_660x_board *board(struct comedi_device * dev)
445{
446	return dev->board_ptr;
447}
448
449#define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0]))
450
451static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it);
452static int ni_660x_detach(struct comedi_device *dev);
453static void init_tio_chip(struct comedi_device *dev, int chipset);
454static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel,
455	unsigned output_select);
456
457static struct comedi_driver driver_ni_660x = {
458	.driver_name = "ni_660x",
459	.module = THIS_MODULE,
460	.attach = ni_660x_attach,
461	.detach = ni_660x_detach,
462};
463
464COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
465
466static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot);
467static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
468	unsigned source);
469
470/* Possible instructions for a GPCT */
471static int ni_660x_GPCT_rinsn(struct comedi_device *dev,
472	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
473static int ni_660x_GPCT_insn_config(struct comedi_device *dev,
474	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
475static int ni_660x_GPCT_winsn(struct comedi_device *dev,
476	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
477
478/* Possible instructions for Digital IO */
479static int ni_660x_dio_insn_config(struct comedi_device *dev,
480	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
481static int ni_660x_dio_insn_bits(struct comedi_device *dev,
482	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
483
484static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
485{
486	return board(dev)->n_chips * counters_per_chip;
487}
488
489static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
490{
491	enum NI_660x_Register ni_660x_register;
492	switch (reg) {
493	case NITIO_G0_Autoincrement_Reg:
494		ni_660x_register = G0AutoincrementRegister;
495		break;
496	case NITIO_G1_Autoincrement_Reg:
497		ni_660x_register = G1AutoincrementRegister;
498		break;
499	case NITIO_G2_Autoincrement_Reg:
500		ni_660x_register = G2AutoincrementRegister;
501		break;
502	case NITIO_G3_Autoincrement_Reg:
503		ni_660x_register = G3AutoincrementRegister;
504		break;
505	case NITIO_G0_Command_Reg:
506		ni_660x_register = G0CommandRegister;
507		break;
508	case NITIO_G1_Command_Reg:
509		ni_660x_register = G1CommandRegister;
510		break;
511	case NITIO_G2_Command_Reg:
512		ni_660x_register = G2CommandRegister;
513		break;
514	case NITIO_G3_Command_Reg:
515		ni_660x_register = G3CommandRegister;
516		break;
517	case NITIO_G0_HW_Save_Reg:
518		ni_660x_register = G0HWSaveRegister;
519		break;
520	case NITIO_G1_HW_Save_Reg:
521		ni_660x_register = G1HWSaveRegister;
522		break;
523	case NITIO_G2_HW_Save_Reg:
524		ni_660x_register = G2HWSaveRegister;
525		break;
526	case NITIO_G3_HW_Save_Reg:
527		ni_660x_register = G3HWSaveRegister;
528		break;
529	case NITIO_G0_SW_Save_Reg:
530		ni_660x_register = G0SWSaveRegister;
531		break;
532	case NITIO_G1_SW_Save_Reg:
533		ni_660x_register = G1SWSaveRegister;
534		break;
535	case NITIO_G2_SW_Save_Reg:
536		ni_660x_register = G2SWSaveRegister;
537		break;
538	case NITIO_G3_SW_Save_Reg:
539		ni_660x_register = G3SWSaveRegister;
540		break;
541	case NITIO_G0_Mode_Reg:
542		ni_660x_register = G0ModeRegister;
543		break;
544	case NITIO_G1_Mode_Reg:
545		ni_660x_register = G1ModeRegister;
546		break;
547	case NITIO_G2_Mode_Reg:
548		ni_660x_register = G2ModeRegister;
549		break;
550	case NITIO_G3_Mode_Reg:
551		ni_660x_register = G3ModeRegister;
552		break;
553	case NITIO_G0_LoadA_Reg:
554		ni_660x_register = G0LoadARegister;
555		break;
556	case NITIO_G1_LoadA_Reg:
557		ni_660x_register = G1LoadARegister;
558		break;
559	case NITIO_G2_LoadA_Reg:
560		ni_660x_register = G2LoadARegister;
561		break;
562	case NITIO_G3_LoadA_Reg:
563		ni_660x_register = G3LoadARegister;
564		break;
565	case NITIO_G0_LoadB_Reg:
566		ni_660x_register = G0LoadBRegister;
567		break;
568	case NITIO_G1_LoadB_Reg:
569		ni_660x_register = G1LoadBRegister;
570		break;
571	case NITIO_G2_LoadB_Reg:
572		ni_660x_register = G2LoadBRegister;
573		break;
574	case NITIO_G3_LoadB_Reg:
575		ni_660x_register = G3LoadBRegister;
576		break;
577	case NITIO_G0_Input_Select_Reg:
578		ni_660x_register = G0InputSelectRegister;
579		break;
580	case NITIO_G1_Input_Select_Reg:
581		ni_660x_register = G1InputSelectRegister;
582		break;
583	case NITIO_G2_Input_Select_Reg:
584		ni_660x_register = G2InputSelectRegister;
585		break;
586	case NITIO_G3_Input_Select_Reg:
587		ni_660x_register = G3InputSelectRegister;
588		break;
589	case NITIO_G01_Status_Reg:
590		ni_660x_register = G01StatusRegister;
591		break;
592	case NITIO_G23_Status_Reg:
593		ni_660x_register = G23StatusRegister;
594		break;
595	case NITIO_G01_Joint_Reset_Reg:
596		ni_660x_register = G01JointResetRegister;
597		break;
598	case NITIO_G23_Joint_Reset_Reg:
599		ni_660x_register = G23JointResetRegister;
600		break;
601	case NITIO_G01_Joint_Status1_Reg:
602		ni_660x_register = G01JointStatus1Register;
603		break;
604	case NITIO_G23_Joint_Status1_Reg:
605		ni_660x_register = G23JointStatus1Register;
606		break;
607	case NITIO_G01_Joint_Status2_Reg:
608		ni_660x_register = G01JointStatus2Register;
609		break;
610	case NITIO_G23_Joint_Status2_Reg:
611		ni_660x_register = G23JointStatus2Register;
612		break;
613	case NITIO_G0_Counting_Mode_Reg:
614		ni_660x_register = G0CountingModeRegister;
615		break;
616	case NITIO_G1_Counting_Mode_Reg:
617		ni_660x_register = G1CountingModeRegister;
618		break;
619	case NITIO_G2_Counting_Mode_Reg:
620		ni_660x_register = G2CountingModeRegister;
621		break;
622	case NITIO_G3_Counting_Mode_Reg:
623		ni_660x_register = G3CountingModeRegister;
624		break;
625	case NITIO_G0_Second_Gate_Reg:
626		ni_660x_register = G0SecondGateRegister;
627		break;
628	case NITIO_G1_Second_Gate_Reg:
629		ni_660x_register = G1SecondGateRegister;
630		break;
631	case NITIO_G2_Second_Gate_Reg:
632		ni_660x_register = G2SecondGateRegister;
633		break;
634	case NITIO_G3_Second_Gate_Reg:
635		ni_660x_register = G3SecondGateRegister;
636		break;
637	case NITIO_G0_DMA_Config_Reg:
638		ni_660x_register = G0DMAConfigRegister;
639		break;
640	case NITIO_G0_DMA_Status_Reg:
641		ni_660x_register = G0DMAStatusRegister;
642		break;
643	case NITIO_G1_DMA_Config_Reg:
644		ni_660x_register = G1DMAConfigRegister;
645		break;
646	case NITIO_G1_DMA_Status_Reg:
647		ni_660x_register = G1DMAStatusRegister;
648		break;
649	case NITIO_G2_DMA_Config_Reg:
650		ni_660x_register = G2DMAConfigRegister;
651		break;
652	case NITIO_G2_DMA_Status_Reg:
653		ni_660x_register = G2DMAStatusRegister;
654		break;
655	case NITIO_G3_DMA_Config_Reg:
656		ni_660x_register = G3DMAConfigRegister;
657		break;
658	case NITIO_G3_DMA_Status_Reg:
659		ni_660x_register = G3DMAStatusRegister;
660		break;
661	case NITIO_G0_Interrupt_Acknowledge_Reg:
662		ni_660x_register = G0InterruptAcknowledge;
663		break;
664	case NITIO_G1_Interrupt_Acknowledge_Reg:
665		ni_660x_register = G1InterruptAcknowledge;
666		break;
667	case NITIO_G2_Interrupt_Acknowledge_Reg:
668		ni_660x_register = G2InterruptAcknowledge;
669		break;
670	case NITIO_G3_Interrupt_Acknowledge_Reg:
671		ni_660x_register = G3InterruptAcknowledge;
672		break;
673	case NITIO_G0_Status_Reg:
674		ni_660x_register = G0StatusRegister;
675		break;
676	case NITIO_G1_Status_Reg:
677		ni_660x_register = G0StatusRegister;
678		break;
679	case NITIO_G2_Status_Reg:
680		ni_660x_register = G0StatusRegister;
681		break;
682	case NITIO_G3_Status_Reg:
683		ni_660x_register = G0StatusRegister;
684		break;
685	case NITIO_G0_Interrupt_Enable_Reg:
686		ni_660x_register = G0InterruptEnable;
687		break;
688	case NITIO_G1_Interrupt_Enable_Reg:
689		ni_660x_register = G1InterruptEnable;
690		break;
691	case NITIO_G2_Interrupt_Enable_Reg:
692		ni_660x_register = G2InterruptEnable;
693		break;
694	case NITIO_G3_Interrupt_Enable_Reg:
695		ni_660x_register = G3InterruptEnable;
696		break;
697	default:
698		printk("%s: unhandled register 0x%x in switch.\n",
699			__func__, reg);
700		BUG();
701		return 0;
702		break;
703	}
704	return ni_660x_register;
705}
706
707static inline void ni_660x_write_register(struct comedi_device *dev,
708	unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
709{
710	void *const write_address =
711		private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
712		registerData[reg].offset;
713
714	switch (registerData[reg].size) {
715	case DATA_2B:
716		writew(bits, write_address);
717		break;
718	case DATA_4B:
719		writel(bits, write_address);
720		break;
721	default:
722		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
723			__FILE__, __func__, reg);
724		BUG();
725		break;
726	}
727}
728
729static inline unsigned ni_660x_read_register(struct comedi_device *dev,
730	unsigned chip_index, enum NI_660x_Register reg)
731{
732	void *const read_address =
733		private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
734		registerData[reg].offset;
735
736	switch (registerData[reg].size) {
737	case DATA_2B:
738		return readw(read_address);
739		break;
740	case DATA_4B:
741		return readl(read_address);
742		break;
743	default:
744		printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
745			__FILE__, __func__, reg);
746		BUG();
747		break;
748	}
749	return 0;
750}
751
752static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
753	enum ni_gpct_register reg)
754{
755	struct comedi_device *dev = counter->counter_dev->dev;
756	enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
757	ni_660x_write_register(dev, counter->chip_index, bits,
758		ni_660x_register);
759}
760
761static unsigned ni_gpct_read_register(struct ni_gpct *counter,
762	enum ni_gpct_register reg)
763{
764	struct comedi_device *dev = counter->counter_dev->dev;
765	enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
766	return ni_660x_read_register(dev, counter->chip_index,
767		ni_660x_register);
768}
769
770static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
771	struct ni_gpct *counter)
772{
773	return priv->mite_rings[counter->chip_index][counter->counter_index];
774}
775
776static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
777	unsigned mite_channel, struct ni_gpct *counter)
778{
779	unsigned long flags;
780	spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
781	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
782		~dma_select_mask(mite_channel);
783	private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
784		dma_select_bits(mite_channel,
785		dma_selection_counter(counter->counter_index));
786	ni_660x_write_register(dev, counter->chip_index,
787		private(dev)->dma_configuration_soft_copies[counter->
788			chip_index] | dma_reset_bit(mite_channel),
789		DMAConfigRegister);
790	mmiowb();
791	spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
792}
793
794static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
795	unsigned mite_channel, struct ni_gpct *counter)
796{
797	unsigned long flags;
798	spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
799	private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
800		~dma_select_mask(mite_channel);
801	private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
802		dma_select_bits(mite_channel, dma_selection_none);
803	ni_660x_write_register(dev, counter->chip_index,
804		private(dev)->dma_configuration_soft_copies[counter->
805			chip_index], DMAConfigRegister);
806	mmiowb();
807	spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
808}
809
810static int ni_660x_request_mite_channel(struct comedi_device *dev,
811	struct ni_gpct *counter, enum comedi_io_direction direction)
812{
813	unsigned long flags;
814	struct mite_channel *mite_chan;
815
816	spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
817	BUG_ON(counter->mite_chan);
818	mite_chan =
819		mite_request_channel(private(dev)->mite, mite_ring(private(dev),
820			counter));
821	if (mite_chan == NULL) {
822		spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
823			flags);
824		comedi_error(dev,
825			"failed to reserve mite dma channel for counter.");
826		return -EBUSY;
827	}
828	mite_chan->dir = direction;
829	ni_tio_set_mite_channel(counter, mite_chan);
830	ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
831	spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
832	return 0;
833}
834
835void ni_660x_release_mite_channel(struct comedi_device *dev, struct ni_gpct *counter)
836{
837	unsigned long flags;
838
839	spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
840	if (counter->mite_chan) {
841		struct mite_channel *mite_chan = counter->mite_chan;
842
843		ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
844		ni_tio_set_mite_channel(counter, NULL);
845		mite_release_channel(mite_chan);
846	}
847	spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
848}
849
850static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
851{
852	int retval;
853
854	struct ni_gpct *counter = subdev_to_counter(s);
855/* const struct comedi_cmd *cmd = &s->async->cmd; */
856
857	retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
858	if (retval) {
859		comedi_error(dev,
860			"no dma channel available for use by counter");
861		return retval;
862	}
863	ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
864	retval = ni_tio_cmd(counter, s->async);
865
866	return retval;
867}
868
869static int ni_660x_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
870	struct comedi_cmd *cmd)
871{
872	struct ni_gpct *counter = subdev_to_counter(s);
873
874	return ni_tio_cmdtest(counter, cmd);
875}
876
877static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
878{
879	struct ni_gpct *counter = subdev_to_counter(s);
880	int retval;
881
882	retval = ni_tio_cancel(counter);
883	ni_660x_release_mite_channel(dev, counter);
884	return retval;
885}
886
887static void set_tio_counterswap(struct comedi_device *dev, int chipset)
888{
889	/* See P. 3.5 of the Register-Level Programming manual.  The
890	   CounterSwap bit has to be set on the second chip, otherwise
891	   it will try to use the same pins as the first chip.
892	 */
893	if (chipset)
894		ni_660x_write_register(dev, chipset, CounterSwap,
895			ClockConfigRegister);
896	else
897		ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
898}
899
900static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
901	struct comedi_subdevice *s)
902{
903	ni_tio_handle_interrupt(subdev_to_counter(s), s);
904	if (s->async->events) {
905		if (s->async->
906			events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
907				COMEDI_CB_OVERFLOW)) {
908			ni_660x_cancel(dev, s);
909		}
910		comedi_event(dev, s);
911	}
912}
913
914static irqreturn_t ni_660x_interrupt(int irq, void *d)
915{
916	struct comedi_device *dev = d;
917	struct comedi_subdevice *s;
918	unsigned i;
919	unsigned long flags;
920
921	if (dev->attached == 0)
922		return IRQ_NONE;
923	/* lock to avoid race with comedi_poll */
924	spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
925	smp_mb();
926	for (i = 0; i < ni_660x_num_counters(dev); ++i) {
927		s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
928		ni_660x_handle_gpct_interrupt(dev, s);
929	}
930	spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
931	return IRQ_HANDLED;
932}
933
934static int ni_660x_input_poll(struct comedi_device *dev,
935			      struct comedi_subdevice *s)
936{
937	unsigned long flags;
938	/* lock to avoid race with comedi_poll */
939	spin_lock_irqsave(&private(dev)->interrupt_lock, flags);
940	mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async);
941	spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags);
942	return comedi_buf_read_n_available(s->async);
943}
944
945static int ni_660x_buf_change(struct comedi_device *dev, struct comedi_subdevice *s,
946	unsigned long new_size)
947{
948	int ret;
949
950	ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
951		s->async);
952	if (ret < 0)
953		return ret;
954
955	return 0;
956}
957
958static int ni_660x_allocate_private(struct comedi_device *dev)
959{
960	int retval;
961	unsigned i;
962
963	retval = alloc_private(dev, sizeof(struct ni_660x_private));
964	if (retval < 0)
965		return retval;
966
967	spin_lock_init(&private(dev)->mite_channel_lock);
968	spin_lock_init(&private(dev)->interrupt_lock);
969	spin_lock_init(&private(dev)->soft_reg_copy_lock);
970	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
971		private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
972	}
973	return 0;
974}
975
976static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
977{
978	unsigned i;
979	unsigned j;
980
981	for (i = 0; i < board(dev)->n_chips; ++i) {
982		for (j = 0; j < counters_per_chip; ++j) {
983			private(dev)->mite_rings[i][j] =
984				mite_alloc_ring(private(dev)->mite);
985			if (private(dev)->mite_rings[i][j] == NULL) {
986				return -ENOMEM;
987			}
988		}
989	}
990	return 0;
991}
992
993static void ni_660x_free_mite_rings(struct comedi_device *dev)
994{
995	unsigned i;
996	unsigned j;
997
998	for (i = 0; i < board(dev)->n_chips; ++i) {
999		for (j = 0; j < counters_per_chip; ++j) {
1000			mite_free_ring(private(dev)->mite_rings[i][j]);
1001		}
1002	}
1003}
1004
1005static int ni_660x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1006{
1007	struct comedi_subdevice *s;
1008	int ret;
1009	unsigned i;
1010	unsigned global_interrupt_config_bits;
1011
1012	printk("comedi%d: ni_660x: ", dev->minor);
1013
1014	ret = ni_660x_allocate_private(dev);
1015	if (ret < 0)
1016		return ret;
1017	ret = ni_660x_find_device(dev, it->options[0], it->options[1]);
1018	if (ret < 0)
1019		return ret;
1020
1021	dev->board_name = board(dev)->name;
1022
1023	ret = mite_setup2(private(dev)->mite, 1);
1024	if (ret < 0) {
1025		printk("error setting up mite\n");
1026		return ret;
1027	}
1028	comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
1029	ret = ni_660x_alloc_mite_rings(dev);
1030	if (ret < 0)
1031		return ret;
1032
1033	printk(" %s ", dev->board_name);
1034
1035	dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
1036
1037	if (alloc_subdevices(dev, dev->n_subdevices) < 0)
1038		return -ENOMEM;
1039
1040	s = dev->subdevices + 0;
1041	/* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
1042	s->type = COMEDI_SUBD_UNUSED;
1043
1044	s = dev->subdevices + NI_660X_DIO_SUBDEV;
1045	/* DIGITAL I/O SUBDEVICE */
1046	s->type = COMEDI_SUBD_DIO;
1047	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1048	s->n_chan = NUM_PFI_CHANNELS;
1049	s->maxdata = 1;
1050	s->range_table = &range_digital;
1051	s->insn_bits = ni_660x_dio_insn_bits;
1052	s->insn_config = ni_660x_dio_insn_config;
1053	s->io_bits = 0;		/* all bits default to input */
1054	/*  we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg */
1055	ni_660x_write_register(dev, 0, 0, STCDIOControl);
1056
1057	private(dev)->counter_dev = ni_gpct_device_construct(dev,
1058		&ni_gpct_write_register, &ni_gpct_read_register,
1059		ni_gpct_variant_660x, ni_660x_num_counters(dev));
1060	if (private(dev)->counter_dev == NULL)
1061		return -ENOMEM;
1062	for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
1063		s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
1064		if (i < ni_660x_num_counters(dev)) {
1065			s->type = COMEDI_SUBD_COUNTER;
1066			s->subdev_flags =
1067				SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
1068				SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
1069			s->n_chan = 3;
1070			s->maxdata = 0xffffffff;
1071			s->insn_read = ni_660x_GPCT_rinsn;
1072			s->insn_write = ni_660x_GPCT_winsn;
1073			s->insn_config = ni_660x_GPCT_insn_config;
1074			s->do_cmd = &ni_660x_cmd;
1075			s->len_chanlist = 1;
1076			s->do_cmdtest = &ni_660x_cmdtest;
1077			s->cancel = &ni_660x_cancel;
1078			s->poll = &ni_660x_input_poll;
1079			s->async_dma_dir = DMA_BIDIRECTIONAL;
1080			s->buf_change = &ni_660x_buf_change;
1081			s->private = &private(dev)->counter_dev->counters[i];
1082
1083			private(dev)->counter_dev->counters[i].chip_index =
1084				i / counters_per_chip;
1085			private(dev)->counter_dev->counters[i].counter_index =
1086				i % counters_per_chip;
1087		} else {
1088			s->type = COMEDI_SUBD_UNUSED;
1089		}
1090	}
1091	for (i = 0; i < board(dev)->n_chips; ++i) {
1092		init_tio_chip(dev, i);
1093	}
1094	for (i = 0; i < ni_660x_num_counters(dev); ++i) {
1095		ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
1096	}
1097	for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
1098		if (i < min_counter_pfi_chan)
1099			ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
1100		else
1101			ni_660x_set_pfi_routing(dev, i,
1102				pfi_output_select_counter);
1103		ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
1104	}
1105	/* to be safe, set counterswap bits on tio chips after all the counter
1106	   outputs have been set to high impedance mode */
1107	for (i = 0; i < board(dev)->n_chips; ++i) {
1108		set_tio_counterswap(dev, i);
1109	}
1110	ret = request_irq(mite_irq(private(dev)->mite), ni_660x_interrupt,
1111			  IRQF_SHARED, "ni_660x", dev);
1112	if (ret < 0) {
1113		printk(" irq not available\n");
1114		return ret;
1115	}
1116	dev->irq = mite_irq(private(dev)->mite);
1117	global_interrupt_config_bits = Global_Int_Enable_Bit;
1118	if (board(dev)->n_chips > 1)
1119		global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
1120	ni_660x_write_register(dev, 0, global_interrupt_config_bits,
1121		GlobalInterruptConfigRegister);
1122	printk("attached\n");
1123	return 0;
1124}
1125
1126static int ni_660x_detach(struct comedi_device *dev)
1127{
1128	printk("comedi%d: ni_660x: remove\n", dev->minor);
1129
1130	/* Free irq */
1131	if (dev->irq)
1132		free_irq(dev->irq, dev);
1133
1134	if (dev->private) {
1135		if (private(dev)->counter_dev)
1136			ni_gpct_device_destroy(private(dev)->counter_dev);
1137		if (private(dev)->mite) {
1138			ni_660x_free_mite_rings(dev);
1139			mite_unsetup(private(dev)->mite);
1140		}
1141	}
1142	return 0;
1143}
1144
1145static int
1146ni_660x_GPCT_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1147	struct comedi_insn *insn, unsigned int *data)
1148{
1149	return ni_tio_rinsn(subdev_to_counter(s), insn, data);
1150}
1151
1152static void init_tio_chip(struct comedi_device *dev, int chipset)
1153{
1154	unsigned i;
1155
1156	/*  init dma configuration register */
1157	private(dev)->dma_configuration_soft_copies[chipset] = 0;
1158	for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
1159		private(dev)->dma_configuration_soft_copies[chipset] |=
1160			dma_select_bits(i,
1161			dma_selection_none) & dma_select_mask(i);
1162	}
1163	ni_660x_write_register(dev, chipset,
1164		private(dev)->dma_configuration_soft_copies[chipset],
1165		DMAConfigRegister);
1166	for (i = 0; i < NUM_PFI_CHANNELS; ++i)
1167	{
1168		ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
1169	}
1170}
1171
1172static int
1173ni_660x_GPCT_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
1174	struct comedi_insn *insn, unsigned int *data)
1175{
1176	return ni_tio_insn_config(subdev_to_counter(s), insn, data);
1177}
1178
1179static int ni_660x_GPCT_winsn(struct comedi_device *dev,
1180	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1181{
1182	return ni_tio_winsn(subdev_to_counter(s), insn, data);
1183}
1184
1185static int ni_660x_find_device(struct comedi_device *dev, int bus, int slot)
1186{
1187	struct mite_struct *mite;
1188	int i;
1189
1190	for (mite = mite_devices; mite; mite = mite->next) {
1191		if (mite->used)
1192			continue;
1193		if (bus || slot) {
1194			if (bus != mite->pcidev->bus->number ||
1195				slot != PCI_SLOT(mite->pcidev->devfn))
1196				continue;
1197		}
1198
1199		for (i = 0; i < n_ni_660x_boards; i++) {
1200			if (mite_device_id(mite) == ni_660x_boards[i].dev_id) {
1201				dev->board_ptr = ni_660x_boards + i;
1202				private(dev)->mite = mite;
1203				return 0;
1204			}
1205		}
1206	}
1207	printk("no device found\n");
1208	mite_list_devices();
1209	return -EIO;
1210}
1211
1212static int ni_660x_dio_insn_bits(struct comedi_device *dev,
1213	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1214{
1215	unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
1216
1217	/*  Check if we have to write some bits */
1218	if (data[0]) {
1219		s->state &= ~(data[0] << base_bitfield_channel);
1220		s->state |= (data[0] & data[1]) << base_bitfield_channel;
1221		/* Write out the new digital output lines */
1222		ni_660x_write_register(dev, 0, s->state, DIO32Output);
1223	}
1224	/* on return, data[1] contains the value of the digital
1225	 * input and output lines. */
1226	data[1] =
1227		(ni_660x_read_register(dev, 0,
1228			DIO32Input) >> base_bitfield_channel);
1229	return 2;
1230}
1231
1232static void ni_660x_select_pfi_output(struct comedi_device *dev, unsigned pfi_channel,
1233	unsigned output_select)
1234{
1235	static const unsigned counter_4_7_first_pfi = 8;
1236	static const unsigned counter_4_7_last_pfi = 23;
1237	unsigned active_chipset = 0;
1238	unsigned idle_chipset = 0;
1239	unsigned active_bits;
1240	unsigned idle_bits;
1241
1242	if (board (dev)->n_chips > 1) {
1243		if (output_select == pfi_output_select_counter &&
1244			pfi_channel >= counter_4_7_first_pfi &&
1245			pfi_channel <= counter_4_7_last_pfi) {
1246			active_chipset = 1;
1247			idle_chipset = 0;
1248		}else {
1249			active_chipset = 0;
1250			idle_chipset = 1;
1251		}
1252	}
1253
1254	if (idle_chipset != active_chipset) {
1255		idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel));
1256		idle_bits &= ~pfi_output_select_mask(pfi_channel);
1257		idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z);
1258		ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel));
1259	}
1260
1261	active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel));
1262	active_bits &= ~pfi_output_select_mask(pfi_channel);
1263	active_bits |= pfi_output_select_bits(pfi_channel, output_select);
1264	ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel));
1265}
1266
1267static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
1268	unsigned source)
1269{
1270	if (source > num_pfi_output_selects)
1271		return -EINVAL;
1272	if (source == pfi_output_select_high_Z)
1273		return -EINVAL;
1274	if (chan < min_counter_pfi_chan) {
1275		if (source == pfi_output_select_counter)
1276			return -EINVAL;
1277	} else if (chan > max_dio_pfi_chan) {
1278		if (source == pfi_output_select_do)
1279			return -EINVAL;
1280	}
1281	BUG_ON(chan >= NUM_PFI_CHANNELS);
1282
1283	private(dev)->pfi_output_selects[chan] = source;
1284	if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
1285		ni_660x_select_pfi_output(dev, chan,
1286			private(dev)->pfi_output_selects[chan]);
1287	return 0;
1288}
1289
1290static unsigned ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned chan)
1291{
1292	BUG_ON(chan >= NUM_PFI_CHANNELS);
1293	return private(dev)->pfi_output_selects[chan];
1294}
1295
1296static void ni660x_config_filter(struct comedi_device *dev, unsigned pfi_channel,
1297	enum ni_gpct_filter_select filter)
1298{
1299	unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
1300	bits &= ~pfi_input_select_mask(pfi_channel);
1301	bits |= pfi_input_select_bits(pfi_channel, filter);
1302	ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
1303}
1304
1305static int ni_660x_dio_insn_config(struct comedi_device *dev,
1306	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1307{
1308	int chan = CR_CHAN(insn->chanspec);
1309
1310	/* The input or output configuration of each digital line is
1311	 * configured by a special insn_config instruction.  chanspec
1312	 * contains the channel to be changed, and data[0] contains the
1313	 * value COMEDI_INPUT or COMEDI_OUTPUT. */
1314
1315	switch (data[0]) {
1316	case INSN_CONFIG_DIO_OUTPUT:
1317		private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
1318		ni_660x_select_pfi_output(dev, chan,
1319			private(dev)->pfi_output_selects[chan]);
1320		break;
1321	case INSN_CONFIG_DIO_INPUT:
1322		private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
1323		ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
1324		break;
1325	case INSN_CONFIG_DIO_QUERY:
1326		data[1] =
1327			(private(dev)->
1328			pfi_direction_bits & (((uint64_t) 1) << chan)) ?
1329			COMEDI_OUTPUT : COMEDI_INPUT;
1330		return 0;
1331	case INSN_CONFIG_SET_ROUTING:
1332		return ni_660x_set_pfi_routing(dev, chan, data[1]);
1333		break;
1334	case INSN_CONFIG_GET_ROUTING:
1335		data[1] = ni_660x_get_pfi_routing(dev, chan);
1336		break;
1337	case INSN_CONFIG_FILTER:
1338		ni660x_config_filter(dev, chan, data[1]);
1339		break;
1340	default:
1341		return -EINVAL;
1342		break;
1343	};
1344	return 0;
1345}
1346