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