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