staging: comedi: comedi_test: rename waveform members
[deliverable/linux.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.
58dd7c0a
M
14*/
15
16/*
71d92fac
IA
17 * Driver: ni_660x
18 * Description: National Instruments 660x counter/timer boards
19 * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
8bdfefb7 20 * PXI-6608, PXI-6624
71d92fac
IA
21 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
22 * Herman.Bruyninckx@mech.kuleuven.ac.be,
23 * Wim.Meeussen@mech.kuleuven.ac.be,
24 * Klaas.Gadeyne@mech.kuleuven.ac.be,
25 * Frank Mori Hess <fmhess@users.sourceforge.net>
8bdfefb7 26 * Updated: Fri, 15 Mar 2013 10:47:56 +0000
71d92fac
IA
27 * Status: experimental
28 *
29 * Encoders work. PulseGeneration (both single pulse and pulse train)
30 * works. Buffered commands work for input but not output.
c8c8ff88 31 *
71d92fac
IA
32 * References:
33 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
34 * DAQ 6601/6602 User Manual (NI 322137B-01)
35 */
58dd7c0a 36
ce157f80 37#include <linux/module.h>
25436dc9 38#include <linux/interrupt.h>
33782dd5 39
a6c760b1 40#include "../comedi_pci.h"
33782dd5 41
58dd7c0a
M
42#include "mite.h"
43#include "ni_tio.h"
44
45enum ni_660x_constants {
46 min_counter_pfi_chan = 8,
47 max_dio_pfi_chan = 31,
48 counters_per_chip = 4
49};
50
51#define NUM_PFI_CHANNELS 40
900b7808
BA
52/* really there are only up to 3 dma channels, but the register layout allows
53for 4 */
58dd7c0a
M
54#define MAX_DMA_CHANNEL 4
55
56/* See Register-Level Programmer Manual page 3.1 */
1246f05b
HS
57enum ni_660x_register {
58 NI660X_G0_INT_ACK,
59 NI660X_G0_STATUS,
60 NI660X_G1_INT_ACK,
61 NI660X_G1_STATUS,
62 NI660X_G01_STATUS,
63 NI660X_G0_CMD,
64 NI660X_STC_DIO_PARALLEL_INPUT,
65 NI660X_G1_CMD,
66 NI660X_G0_HW_SAVE,
67 NI660X_G1_HW_SAVE,
68 NI660X_STC_DIO_OUTPUT,
69 NI660X_STC_DIO_CONTROL,
70 NI660X_G0_SW_SAVE,
71 NI660X_G1_SW_SAVE,
72 NI660X_G0_MODE,
73 NI660X_G01_STATUS1,
74 NI660X_G1_MODE,
75 NI660X_STC_DIO_SERIAL_INPUT,
76 NI660X_G0_LOADA,
77 NI660X_G01_STATUS2,
78 NI660X_G0_LOADB,
79 NI660X_G1_LOADA,
80 NI660X_G1_LOADB,
81 NI660X_G0_INPUT_SEL,
82 NI660X_G1_INPUT_SEL,
83 NI660X_G0_AUTO_INC,
84 NI660X_G1_AUTO_INC,
85 NI660X_G01_RESET,
86 NI660X_G0_INT_ENA,
87 NI660X_G1_INT_ENA,
88 NI660X_G0_CNT_MODE,
89 NI660X_G1_CNT_MODE,
90 NI660X_G0_GATE2,
91 NI660X_G1_GATE2,
92 NI660X_G0_DMA_CFG,
93 NI660X_G0_DMA_STATUS,
94 NI660X_G1_DMA_CFG,
95 NI660X_G1_DMA_STATUS,
96 NI660X_G2_INT_ACK,
97 NI660X_G2_STATUS,
98 NI660X_G3_INT_ACK,
99 NI660X_G3_STATUS,
100 NI660X_G23_STATUS,
101 NI660X_G2_CMD,
102 NI660X_G3_CMD,
103 NI660X_G2_HW_SAVE,
104 NI660X_G3_HW_SAVE,
105 NI660X_G2_SW_SAVE,
106 NI660X_G3_SW_SAVE,
107 NI660X_G2_MODE,
108 NI660X_G23_STATUS1,
109 NI660X_G3_MODE,
110 NI660X_G2_LOADA,
111 NI660X_G23_STATUS2,
112 NI660X_G2_LOADB,
113 NI660X_G3_LOADA,
114 NI660X_G3_LOADB,
115 NI660X_G2_INPUT_SEL,
116 NI660X_G3_INPUT_SEL,
117 NI660X_G2_AUTO_INC,
118 NI660X_G3_AUTO_INC,
119 NI660X_G23_RESET,
120 NI660X_G2_INT_ENA,
121 NI660X_G3_INT_ENA,
122 NI660X_G2_CNT_MODE,
123 NI660X_G3_CNT_MODE,
124 NI660X_G3_GATE2,
125 NI660X_G2_GATE2,
126 NI660X_G2_DMA_CFG,
127 NI660X_G2_DMA_STATUS,
128 NI660X_G3_DMA_CFG,
129 NI660X_G3_DMA_STATUS,
130 NI660X_DIO32_INPUT,
131 NI660X_DIO32_OUTPUT,
132 NI660X_CLK_CFG,
133 NI660X_GLOBAL_INT_STATUS,
134 NI660X_DMA_CFG,
135 NI660X_GLOBAL_INT_CFG,
136 NI660X_IO_CFG_0_1,
137 NI660X_IO_CFG_2_3,
138 NI660X_IO_CFG_4_5,
139 NI660X_IO_CFG_6_7,
140 NI660X_IO_CFG_8_9,
141 NI660X_IO_CFG_10_11,
142 NI660X_IO_CFG_12_13,
143 NI660X_IO_CFG_14_15,
144 NI660X_IO_CFG_16_17,
145 NI660X_IO_CFG_18_19,
146 NI660X_IO_CFG_20_21,
147 NI660X_IO_CFG_22_23,
148 NI660X_IO_CFG_24_25,
149 NI660X_IO_CFG_26_27,
150 NI660X_IO_CFG_28_29,
151 NI660X_IO_CFG_30_31,
152 NI660X_IO_CFG_32_33,
153 NI660X_IO_CFG_34_35,
154 NI660X_IO_CFG_36_37,
155 NI660X_IO_CFG_38_39,
156 NI660X_NUM_REGS,
251411cf 157};
58dd7c0a
M
158
159static inline unsigned IOConfigReg(unsigned pfi_channel)
160{
1246f05b 161 unsigned reg = NI660X_IO_CFG_0_1 + pfi_channel / 2;
c4c2c67a 162
1246f05b 163 BUG_ON(reg > NI660X_IO_CFG_38_39);
58dd7c0a
M
164 return reg;
165}
166
167enum ni_660x_register_width {
168 DATA_1B,
169 DATA_2B,
170 DATA_4B
171};
172
173enum ni_660x_register_direction {
174 NI_660x_READ,
175 NI_660x_WRITE,
176 NI_660x_READ_WRITE
177};
178
179enum ni_660x_pfi_output_select {
180 pfi_output_select_high_Z = 0,
181 pfi_output_select_counter = 1,
182 pfi_output_select_do = 2,
183 num_pfi_output_selects
184};
185
186enum ni_660x_subdevices {
187 NI_660X_DIO_SUBDEV = 1,
188 NI_660X_GPCT_SUBDEV_0 = 2
189};
190static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
191{
192 return NI_660X_GPCT_SUBDEV_0 + index;
193}
194
0cb5e8ff 195struct NI_660xRegisterData {
2696fb57
BP
196 const char *name; /* Register Name */
197 int offset; /* Offset from base address from GPCT chip */
58dd7c0a 198 enum ni_660x_register_direction direction;
b02957d5 199 enum ni_660x_register_width size; /* 1 byte, 2 bytes, or 4 bytes */
0cb5e8ff
BP
200};
201
1246f05b 202static const struct NI_660xRegisterData registerData[NI660X_NUM_REGS] = {
58dd7c0a
M
203 {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
204 {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
205 {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
206 {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
207 {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
208 {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
209 {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
210 {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
211 {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
212 {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
213 {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
214 {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
215 {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
216 {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
217 {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
218 {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
219 {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
220 {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
221 {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
222 {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
223 {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
224 {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
225 {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
226 {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
227 {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
228 {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
229 {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
230 {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
231 {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
232 {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
233 {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
234 {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
235 {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
236 {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
237 {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
238 {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
239 {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
240 {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
241 {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
242 {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
243 {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
244 {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
245 {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
246 {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
247 {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
248 {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
249 {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
250 {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
251 {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
252 {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
253 {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
254 {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
255 {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
256 {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
257 {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
258 {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
259 {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
260 {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
261 {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
262 {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
263 {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
264 {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
265 {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
266 {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
267 {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
268 {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
269 {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
270 {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
271 {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
272 {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
273 {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
274 {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
275 {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
276 {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
277 {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
278 {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
279 {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
280 {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
281 {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
282 {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
283 {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
284 {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
285 {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
286 {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
287 {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
288 {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
289 {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
290 {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
291 {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
292 {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
293 {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
294 {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
295 {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
296 {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
297 {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
298 {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
299 {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
300 {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
301};
302
2696fb57 303/* kind of ENABLE for the second counter */
58dd7c0a
M
304enum clock_config_register_bits {
305 CounterSwap = 0x1 << 21
306};
307
2696fb57 308/* ioconfigreg */
58dd7c0a
M
309static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
310{
f9558b49 311 return (pfi_channel % 2) ? 0 : 8;
58dd7c0a 312}
0a85b6f0 313
58dd7c0a
M
314static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
315{
316 return 0x3 << ioconfig_bitshift(pfi_channel);
317}
0a85b6f0 318
58dd7c0a 319static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
0a85b6f0 320 unsigned output_select)
58dd7c0a
M
321{
322 return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
323}
0a85b6f0 324
58dd7c0a
M
325static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
326{
327 return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
328}
0a85b6f0 329
58dd7c0a 330static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
0a85b6f0 331 unsigned input_select)
58dd7c0a
M
332{
333 return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
334}
335
2696fb57 336/* dma configuration register bits */
58dd7c0a
M
337static inline unsigned dma_select_mask(unsigned dma_channel)
338{
339 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
340 return 0x1f << (8 * dma_channel);
341}
0a85b6f0 342
58dd7c0a
M
343enum dma_selection {
344 dma_selection_none = 0x1f,
345};
0a85b6f0 346
58dd7c0a
M
347static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
348{
349 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
350 return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
351}
0a85b6f0 352
58dd7c0a
M
353static inline unsigned dma_reset_bit(unsigned dma_channel)
354{
355 BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
356 return 0x80 << (8 * dma_channel);
357}
358
359enum global_interrupt_status_register_bits {
360 Counter_0_Int_Bit = 0x100,
361 Counter_1_Int_Bit = 0x200,
362 Counter_2_Int_Bit = 0x400,
363 Counter_3_Int_Bit = 0x800,
364 Cascade_Int_Bit = 0x20000000,
365 Global_Int_Bit = 0x80000000
366};
367
368enum global_interrupt_config_register_bits {
369 Cascade_Int_Enable_Bit = 0x20000000,
370 Global_Int_Polarity_Bit = 0x40000000,
371 Global_Int_Enable_Bit = 0x80000000
372};
373
f69b0d64 374/* Offset of the GPCT chips from the base-address of the card */
900b7808
BA
375/* First chip is at base-address + 0x00, etc. */
376static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 };
58dd7c0a 377
97bcce5a
HS
378enum ni_660x_boardid {
379 BOARD_PCI6601,
380 BOARD_PCI6602,
381 BOARD_PXI6602,
382 BOARD_PXI6608,
8bdfefb7 383 BOARD_PXI6624
97bcce5a
HS
384};
385
50792813 386struct ni_660x_board {
58dd7c0a
M
387 const char *name;
388 unsigned n_chips; /* total number of TIO chips */
50792813 389};
58dd7c0a 390
50792813 391static const struct ni_660x_board ni_660x_boards[] = {
97bcce5a 392 [BOARD_PCI6601] = {
e2b8360f
HS
393 .name = "PCI-6601",
394 .n_chips = 1,
395 },
97bcce5a 396 [BOARD_PCI6602] = {
e2b8360f
HS
397 .name = "PCI-6602",
398 .n_chips = 2,
399 },
97bcce5a 400 [BOARD_PXI6602] = {
e2b8360f
HS
401 .name = "PXI-6602",
402 .n_chips = 2,
403 },
97bcce5a 404 [BOARD_PXI6608] = {
e2b8360f
HS
405 .name = "PXI-6608",
406 .n_chips = 2,
407 },
8bdfefb7
IA
408 [BOARD_PXI6624] = {
409 .name = "PXI-6624",
410 .n_chips = 2,
411 },
58dd7c0a
M
412};
413
414#define NI_660X_MAX_NUM_CHIPS 2
415#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
416
b3be94ea 417struct ni_660x_private {
58dd7c0a
M
418 struct mite_struct *mite;
419 struct ni_gpct_device *counter_dev;
420 uint64_t pfi_direction_bits;
421 struct mite_dma_descriptor_ring
422 *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
423 spinlock_t mite_channel_lock;
894db119
FMH
424 /* interrupt_lock prevents races between interrupt and comedi_poll */
425 spinlock_t interrupt_lock;
58dd7c0a
M
426 unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
427 spinlock_t soft_reg_copy_lock;
428 unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
b3be94ea 429};
58dd7c0a 430
da91b269 431static inline unsigned ni_660x_num_counters(struct comedi_device *dev)
58dd7c0a 432{
da8e2a52 433 const struct ni_660x_board *board = dev->board_ptr;
9186ccde
HS
434
435 return board->n_chips * counters_per_chip;
58dd7c0a
M
436}
437
1246f05b 438static enum ni_660x_register ni_gpct_to_660x_register(enum ni_gpct_register reg)
58dd7c0a 439{
58dd7c0a 440 switch (reg) {
12375292 441 case NITIO_G0_AUTO_INC:
1246f05b 442 return NI660X_G0_AUTO_INC;
12375292 443 case NITIO_G1_AUTO_INC:
1246f05b 444 return NI660X_G1_AUTO_INC;
12375292 445 case NITIO_G2_AUTO_INC:
1246f05b 446 return NI660X_G2_AUTO_INC;
12375292 447 case NITIO_G3_AUTO_INC:
1246f05b 448 return NI660X_G3_AUTO_INC;
12375292 449 case NITIO_G0_CMD:
1246f05b 450 return NI660X_G0_CMD;
12375292 451 case NITIO_G1_CMD:
1246f05b 452 return NI660X_G1_CMD;
12375292 453 case NITIO_G2_CMD:
1246f05b 454 return NI660X_G2_CMD;
12375292 455 case NITIO_G3_CMD:
1246f05b 456 return NI660X_G3_CMD;
12375292 457 case NITIO_G0_HW_SAVE:
1246f05b 458 return NI660X_G0_HW_SAVE;
12375292 459 case NITIO_G1_HW_SAVE:
1246f05b 460 return NI660X_G1_HW_SAVE;
12375292 461 case NITIO_G2_HW_SAVE:
1246f05b 462 return NI660X_G2_HW_SAVE;
12375292 463 case NITIO_G3_HW_SAVE:
1246f05b 464 return NI660X_G3_HW_SAVE;
12375292 465 case NITIO_G0_SW_SAVE:
1246f05b 466 return NI660X_G0_SW_SAVE;
12375292 467 case NITIO_G1_SW_SAVE:
1246f05b 468 return NI660X_G1_SW_SAVE;
12375292 469 case NITIO_G2_SW_SAVE:
1246f05b 470 return NI660X_G2_SW_SAVE;
12375292 471 case NITIO_G3_SW_SAVE:
1246f05b 472 return NI660X_G3_SW_SAVE;
12375292 473 case NITIO_G0_MODE:
1246f05b 474 return NI660X_G0_MODE;
12375292 475 case NITIO_G1_MODE:
1246f05b 476 return NI660X_G1_MODE;
12375292 477 case NITIO_G2_MODE:
1246f05b 478 return NI660X_G2_MODE;
12375292 479 case NITIO_G3_MODE:
1246f05b 480 return NI660X_G3_MODE;
12375292 481 case NITIO_G0_LOADA:
1246f05b 482 return NI660X_G0_LOADA;
12375292 483 case NITIO_G1_LOADA:
1246f05b 484 return NI660X_G1_LOADA;
12375292 485 case NITIO_G2_LOADA:
1246f05b 486 return NI660X_G2_LOADA;
12375292 487 case NITIO_G3_LOADA:
1246f05b 488 return NI660X_G3_LOADA;
12375292 489 case NITIO_G0_LOADB:
1246f05b 490 return NI660X_G0_LOADB;
12375292 491 case NITIO_G1_LOADB:
1246f05b 492 return NI660X_G1_LOADB;
12375292 493 case NITIO_G2_LOADB:
1246f05b 494 return NI660X_G2_LOADB;
12375292 495 case NITIO_G3_LOADB:
1246f05b 496 return NI660X_G3_LOADB;
12375292 497 case NITIO_G0_INPUT_SEL:
1246f05b 498 return NI660X_G0_INPUT_SEL;
12375292 499 case NITIO_G1_INPUT_SEL:
1246f05b 500 return NI660X_G1_INPUT_SEL;
12375292 501 case NITIO_G2_INPUT_SEL:
1246f05b 502 return NI660X_G2_INPUT_SEL;
12375292 503 case NITIO_G3_INPUT_SEL:
1246f05b 504 return NI660X_G3_INPUT_SEL;
12375292 505 case NITIO_G01_STATUS:
1246f05b 506 return NI660X_G01_STATUS;
12375292 507 case NITIO_G23_STATUS:
1246f05b 508 return NI660X_G23_STATUS;
12375292 509 case NITIO_G01_RESET:
1246f05b 510 return NI660X_G01_RESET;
12375292 511 case NITIO_G23_RESET:
1246f05b 512 return NI660X_G23_RESET;
12375292 513 case NITIO_G01_STATUS1:
1246f05b 514 return NI660X_G01_STATUS1;
12375292 515 case NITIO_G23_STATUS1:
1246f05b 516 return NI660X_G23_STATUS1;
12375292 517 case NITIO_G01_STATUS2:
1246f05b 518 return NI660X_G01_STATUS2;
12375292 519 case NITIO_G23_STATUS2:
1246f05b 520 return NI660X_G23_STATUS2;
12375292 521 case NITIO_G0_CNT_MODE:
1246f05b 522 return NI660X_G0_CNT_MODE;
12375292 523 case NITIO_G1_CNT_MODE:
1246f05b 524 return NI660X_G1_CNT_MODE;
12375292 525 case NITIO_G2_CNT_MODE:
1246f05b 526 return NI660X_G2_CNT_MODE;
12375292 527 case NITIO_G3_CNT_MODE:
1246f05b 528 return NI660X_G3_CNT_MODE;
12375292 529 case NITIO_G0_GATE2:
1246f05b 530 return NI660X_G0_GATE2;
12375292 531 case NITIO_G1_GATE2:
1246f05b 532 return NI660X_G1_GATE2;
12375292 533 case NITIO_G2_GATE2:
1246f05b 534 return NI660X_G2_GATE2;
12375292 535 case NITIO_G3_GATE2:
1246f05b 536 return NI660X_G3_GATE2;
12375292 537 case NITIO_G0_DMA_CFG:
1246f05b 538 return NI660X_G0_DMA_CFG;
12375292 539 case NITIO_G0_DMA_STATUS:
1246f05b 540 return NI660X_G0_DMA_STATUS;
12375292 541 case NITIO_G1_DMA_CFG:
1246f05b 542 return NI660X_G1_DMA_CFG;
12375292 543 case NITIO_G1_DMA_STATUS:
1246f05b 544 return NI660X_G1_DMA_STATUS;
12375292 545 case NITIO_G2_DMA_CFG:
1246f05b 546 return NI660X_G2_DMA_CFG;
12375292 547 case NITIO_G2_DMA_STATUS:
1246f05b 548 return NI660X_G2_DMA_STATUS;
12375292 549 case NITIO_G3_DMA_CFG:
1246f05b 550 return NI660X_G3_DMA_CFG;
12375292 551 case NITIO_G3_DMA_STATUS:
1246f05b 552 return NI660X_G3_DMA_STATUS;
12375292 553 case NITIO_G0_INT_ACK:
1246f05b 554 return NI660X_G0_INT_ACK;
12375292 555 case NITIO_G1_INT_ACK:
1246f05b 556 return NI660X_G1_INT_ACK;
12375292 557 case NITIO_G2_INT_ACK:
1246f05b 558 return NI660X_G2_INT_ACK;
12375292 559 case NITIO_G3_INT_ACK:
1246f05b 560 return NI660X_G3_INT_ACK;
12375292 561 case NITIO_G0_STATUS:
1246f05b 562 return NI660X_G0_STATUS;
12375292 563 case NITIO_G1_STATUS:
1246f05b 564 return NI660X_G1_STATUS;
12375292 565 case NITIO_G2_STATUS:
1246f05b 566 return NI660X_G2_STATUS;
12375292 567 case NITIO_G3_STATUS:
1246f05b 568 return NI660X_G3_STATUS;
12375292 569 case NITIO_G0_INT_ENA:
1246f05b 570 return NI660X_G0_INT_ENA;
12375292 571 case NITIO_G1_INT_ENA:
1246f05b 572 return NI660X_G1_INT_ENA;
12375292 573 case NITIO_G2_INT_ENA:
1246f05b 574 return NI660X_G2_INT_ENA;
12375292 575 case NITIO_G3_INT_ENA:
1246f05b 576 return NI660X_G3_INT_ENA;
58dd7c0a 577 default:
58dd7c0a
M
578 BUG();
579 return 0;
58dd7c0a 580 }
58dd7c0a
M
581}
582
da91b269 583static inline void ni_660x_write_register(struct comedi_device *dev,
0c26c7ed 584 unsigned chip, unsigned bits,
1246f05b 585 enum ni_660x_register reg)
58dd7c0a 586{
5f8a5f4f 587 unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
58dd7c0a
M
588
589 switch (registerData[reg].size) {
590 case DATA_2B:
5f8a5f4f 591 writew(bits, dev->mmio + addr);
58dd7c0a
M
592 break;
593 case DATA_4B:
5f8a5f4f 594 writel(bits, dev->mmio + addr);
58dd7c0a
M
595 break;
596 default:
58dd7c0a
M
597 BUG();
598 break;
599 }
600}
601
da91b269 602static inline unsigned ni_660x_read_register(struct comedi_device *dev,
0c26c7ed 603 unsigned chip,
1246f05b 604 enum ni_660x_register reg)
58dd7c0a 605{
5f8a5f4f 606 unsigned int addr = GPCT_OFFSET[chip] + registerData[reg].offset;
58dd7c0a
M
607
608 switch (registerData[reg].size) {
609 case DATA_2B:
5f8a5f4f 610 return readw(dev->mmio + addr);
58dd7c0a 611 case DATA_4B:
5f8a5f4f 612 return readl(dev->mmio + addr);
58dd7c0a 613 default:
58dd7c0a
M
614 BUG();
615 break;
616 }
617 return 0;
618}
619
620static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
0a85b6f0 621 enum ni_gpct_register reg)
58dd7c0a 622{
71b5f4f1 623 struct comedi_device *dev = counter->counter_dev->dev;
1246f05b 624 enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg);
0c26c7ed
HS
625 unsigned chip = counter->chip_index;
626
627 ni_660x_write_register(dev, chip, bits, ni_660x_register);
58dd7c0a
M
628}
629
630static unsigned ni_gpct_read_register(struct ni_gpct *counter,
0a85b6f0 631 enum ni_gpct_register reg)
58dd7c0a 632{
71b5f4f1 633 struct comedi_device *dev = counter->counter_dev->dev;
1246f05b 634 enum ni_660x_register ni_660x_register = ni_gpct_to_660x_register(reg);
0c26c7ed
HS
635 unsigned chip = counter->chip_index;
636
637 return ni_660x_read_register(dev, chip, ni_660x_register);
58dd7c0a
M
638}
639
0a85b6f0
MT
640static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private
641 *priv,
642 struct ni_gpct
643 *counter)
58dd7c0a 644{
0c26c7ed
HS
645 unsigned chip = counter->chip_index;
646
647 return priv->mite_rings[chip][counter->counter_index];
58dd7c0a
M
648}
649
da91b269 650static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
0a85b6f0
MT
651 unsigned mite_channel,
652 struct ni_gpct *counter)
58dd7c0a 653{
8c12ec26 654 struct ni_660x_private *devpriv = dev->private;
0c26c7ed 655 unsigned chip = counter->chip_index;
58dd7c0a 656 unsigned long flags;
8c12ec26
HS
657
658 spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
0c26c7ed 659 devpriv->dma_configuration_soft_copies[chip] &=
d783a20e 660 ~dma_select_mask(mite_channel);
0c26c7ed 661 devpriv->dma_configuration_soft_copies[chip] |=
d783a20e 662 dma_select_bits(mite_channel, counter->counter_index);
0c26c7ed
HS
663 ni_660x_write_register(dev, chip,
664 devpriv->dma_configuration_soft_copies[chip] |
1246f05b 665 dma_reset_bit(mite_channel), NI660X_DMA_CFG);
58dd7c0a 666 mmiowb();
8c12ec26 667 spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
58dd7c0a
M
668}
669
da91b269 670static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
0a85b6f0
MT
671 unsigned mite_channel,
672 struct ni_gpct *counter)
58dd7c0a 673{
8c12ec26 674 struct ni_660x_private *devpriv = dev->private;
0c26c7ed 675 unsigned chip = counter->chip_index;
58dd7c0a 676 unsigned long flags;
8c12ec26
HS
677
678 spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
0c26c7ed 679 devpriv->dma_configuration_soft_copies[chip] &=
0a85b6f0 680 ~dma_select_mask(mite_channel);
0c26c7ed 681 devpriv->dma_configuration_soft_copies[chip] |=
0a85b6f0 682 dma_select_bits(mite_channel, dma_selection_none);
0c26c7ed
HS
683 ni_660x_write_register(dev, chip,
684 devpriv->dma_configuration_soft_copies[chip],
685 NI660X_DMA_CFG);
58dd7c0a 686 mmiowb();
8c12ec26 687 spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
58dd7c0a
M
688}
689
da91b269 690static int ni_660x_request_mite_channel(struct comedi_device *dev,
0a85b6f0
MT
691 struct ni_gpct *counter,
692 enum comedi_io_direction direction)
58dd7c0a 693{
8c12ec26 694 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
695 unsigned long flags;
696 struct mite_channel *mite_chan;
697
8c12ec26 698 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
58dd7c0a 699 BUG_ON(counter->mite_chan);
8c12ec26
HS
700 mite_chan = mite_request_channel(devpriv->mite,
701 mite_ring(devpriv, counter));
307da4b2 702 if (!mite_chan) {
8c12ec26 703 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
22bc059e
HS
704 dev_err(dev->class_dev,
705 "failed to reserve mite dma channel for counter\n");
58dd7c0a
M
706 return -EBUSY;
707 }
708 mite_chan->dir = direction;
709 ni_tio_set_mite_channel(counter, mite_chan);
710 ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
8c12ec26 711 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
712 return 0;
713}
714
ce48a911
HS
715static void ni_660x_release_mite_channel(struct comedi_device *dev,
716 struct ni_gpct *counter)
58dd7c0a 717{
8c12ec26 718 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
719 unsigned long flags;
720
8c12ec26 721 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
722 if (counter->mite_chan) {
723 struct mite_channel *mite_chan = counter->mite_chan;
724
725 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
726 ni_tio_set_mite_channel(counter, NULL);
727 mite_release_channel(mite_chan);
728 }
8c12ec26 729 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
730}
731
da91b269 732static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
58dd7c0a 733{
00edbc31 734 struct ni_gpct *counter = s->private;
58dd7c0a
M
735 int retval;
736
58dd7c0a
M
737 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
738 if (retval) {
22bc059e
HS
739 dev_err(dev->class_dev,
740 "no dma channel available for use by counter\n");
58dd7c0a
M
741 return retval;
742 }
f8cfd0eb 743 ni_tio_acknowledge(counter);
58dd7c0a 744
16cc181d 745 return ni_tio_cmd(dev, s);
58dd7c0a
M
746}
747
da91b269 748static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
58dd7c0a 749{
00edbc31 750 struct ni_gpct *counter = s->private;
58dd7c0a
M
751 int retval;
752
753 retval = ni_tio_cancel(counter);
754 ni_660x_release_mite_channel(dev, counter);
755 return retval;
756}
757
01b6442b 758static void set_tio_counterswap(struct comedi_device *dev, int chip)
58dd7c0a 759{
01b6442b
HS
760 unsigned bits = 0;
761
762 /*
763 * See P. 3.5 of the Register-Level Programming manual.
764 * The CounterSwap bit has to be set on the second chip,
765 * otherwise it will try to use the same pins as the
766 * first chip.
58dd7c0a 767 */
01b6442b
HS
768 if (chip)
769 bits = CounterSwap;
770
771 ni_660x_write_register(dev, chip, bits, NI660X_CLK_CFG);
58dd7c0a
M
772}
773
da91b269 774static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
0a85b6f0 775 struct comedi_subdevice *s)
58dd7c0a 776{
00edbc31
HS
777 struct ni_gpct *counter = s->private;
778
779 ni_tio_handle_interrupt(counter, s);
9e1a0824 780 comedi_handle_events(dev, s);
58dd7c0a
M
781}
782
70265d24 783static irqreturn_t ni_660x_interrupt(int irq, void *d)
58dd7c0a 784{
71b5f4f1 785 struct comedi_device *dev = d;
8c12ec26 786 struct ni_660x_private *devpriv = dev->private;
34c43922 787 struct comedi_subdevice *s;
58dd7c0a 788 unsigned i;
894db119 789 unsigned long flags;
58dd7c0a 790
a7401cdd 791 if (!dev->attached)
58dd7c0a 792 return IRQ_NONE;
894db119 793 /* lock to avoid race with comedi_poll */
8c12ec26 794 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
58dd7c0a
M
795 smp_mb();
796 for (i = 0; i < ni_660x_num_counters(dev); ++i) {
41e862f3 797 s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
58dd7c0a
M
798 ni_660x_handle_gpct_interrupt(dev, s);
799 }
8c12ec26 800 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
58dd7c0a
M
801 return IRQ_HANDLED;
802}
803
894db119
FMH
804static int ni_660x_input_poll(struct comedi_device *dev,
805 struct comedi_subdevice *s)
806{
8c12ec26 807 struct ni_660x_private *devpriv = dev->private;
00edbc31 808 struct ni_gpct *counter = s->private;
894db119 809 unsigned long flags;
8c12ec26 810
894db119 811 /* lock to avoid race with comedi_poll */
8c12ec26 812 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
74f63db7 813 mite_sync_input_dma(counter->mite_chan, s);
8c12ec26 814 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
e9edef3a 815 return comedi_buf_read_n_available(s);
894db119
FMH
816}
817
0a85b6f0 818static int ni_660x_buf_change(struct comedi_device *dev,
d546b896 819 struct comedi_subdevice *s)
58dd7c0a 820{
8c12ec26 821 struct ni_660x_private *devpriv = dev->private;
00edbc31 822 struct ni_gpct *counter = s->private;
58dd7c0a
M
823 int ret;
824
b74e635d 825 ret = mite_buf_change(mite_ring(devpriv, counter), s);
58dd7c0a
M
826 if (ret < 0)
827 return ret;
828
829 return 0;
830}
831
da91b269 832static int ni_660x_allocate_private(struct comedi_device *dev)
58dd7c0a 833{
8c12ec26 834 struct ni_660x_private *devpriv;
58dd7c0a
M
835 unsigned i;
836
0bdab509 837 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
c34fa261
HS
838 if (!devpriv)
839 return -ENOMEM;
c3744138 840
8c12ec26
HS
841 spin_lock_init(&devpriv->mite_channel_lock);
842 spin_lock_init(&devpriv->interrupt_lock);
843 spin_lock_init(&devpriv->soft_reg_copy_lock);
900b7808 844 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
8c12ec26 845 devpriv->pfi_output_selects[i] = pfi_output_select_counter;
900b7808 846
58dd7c0a
M
847 return 0;
848}
849
da91b269 850static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
58dd7c0a 851{
da8e2a52 852 const struct ni_660x_board *board = dev->board_ptr;
8c12ec26 853 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
854 unsigned i;
855 unsigned j;
856
9186ccde 857 for (i = 0; i < board->n_chips; ++i) {
58dd7c0a 858 for (j = 0; j < counters_per_chip; ++j) {
8c12ec26
HS
859 devpriv->mite_rings[i][j] =
860 mite_alloc_ring(devpriv->mite);
307da4b2 861 if (!devpriv->mite_rings[i][j])
58dd7c0a 862 return -ENOMEM;
58dd7c0a
M
863 }
864 }
865 return 0;
866}
867
da91b269 868static void ni_660x_free_mite_rings(struct comedi_device *dev)
58dd7c0a 869{
da8e2a52 870 const struct ni_660x_board *board = dev->board_ptr;
8c12ec26 871 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
872 unsigned i;
873 unsigned j;
874
9186ccde 875 for (i = 0; i < board->n_chips; ++i) {
900b7808 876 for (j = 0; j < counters_per_chip; ++j)
8c12ec26 877 mite_free_ring(devpriv->mite_rings[i][j]);
58dd7c0a
M
878 }
879}
880
da91b269 881static void init_tio_chip(struct comedi_device *dev, int chipset)
58dd7c0a 882{
8c12ec26 883 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
884 unsigned i;
885
2696fb57 886 /* init dma configuration register */
8c12ec26 887 devpriv->dma_configuration_soft_copies[chipset] = 0;
58dd7c0a 888 for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
8c12ec26 889 devpriv->dma_configuration_soft_copies[chipset] |=
0a85b6f0 890 dma_select_bits(i, dma_selection_none) & dma_select_mask(i);
58dd7c0a
M
891 }
892 ni_660x_write_register(dev, chipset,
8c12ec26 893 devpriv->dma_configuration_soft_copies[chipset],
1246f05b 894 NI660X_DMA_CFG);
900b7808 895 for (i = 0; i < NUM_PFI_CHANNELS; ++i)
58dd7c0a 896 ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
58dd7c0a
M
897}
898
da91b269 899static int ni_660x_dio_insn_bits(struct comedi_device *dev,
0a85b6f0
MT
900 struct comedi_subdevice *s,
901 struct comedi_insn *insn, unsigned int *data)
58dd7c0a
M
902{
903 unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
904
2696fb57 905 /* Check if we have to write some bits */
58dd7c0a
M
906 if (data[0]) {
907 s->state &= ~(data[0] << base_bitfield_channel);
908 s->state |= (data[0] & data[1]) << base_bitfield_channel;
909 /* Write out the new digital output lines */
1246f05b 910 ni_660x_write_register(dev, 0, s->state, NI660X_DIO32_OUTPUT);
58dd7c0a
M
911 }
912 /* on return, data[1] contains the value of the digital
913 * input and output lines. */
1246f05b
HS
914 data[1] = (ni_660x_read_register(dev, 0, NI660X_DIO32_INPUT) >>
915 base_bitfield_channel);
916
a2714e3e 917 return insn->n;
58dd7c0a
M
918}
919
0a85b6f0
MT
920static void ni_660x_select_pfi_output(struct comedi_device *dev,
921 unsigned pfi_channel,
922 unsigned output_select)
58dd7c0a 923{
da8e2a52 924 const struct ni_660x_board *board = dev->board_ptr;
58dd7c0a
M
925 static const unsigned counter_4_7_first_pfi = 8;
926 static const unsigned counter_4_7_last_pfi = 23;
927 unsigned active_chipset = 0;
928 unsigned idle_chipset = 0;
929 unsigned active_bits;
930 unsigned idle_bits;
931
9186ccde 932 if (board->n_chips > 1) {
53106ae6 933 if (output_select == pfi_output_select_counter &&
0a85b6f0
MT
934 pfi_channel >= counter_4_7_first_pfi &&
935 pfi_channel <= counter_4_7_last_pfi) {
58dd7c0a
M
936 active_chipset = 1;
937 idle_chipset = 0;
0a85b6f0 938 } else {
58dd7c0a
M
939 active_chipset = 0;
940 idle_chipset = 1;
941 }
942 }
943
53106ae6 944 if (idle_chipset != active_chipset) {
0a85b6f0
MT
945 idle_bits =
946 ni_660x_read_register(dev, idle_chipset,
947 IOConfigReg(pfi_channel));
58dd7c0a 948 idle_bits &= ~pfi_output_select_mask(pfi_channel);
0a85b6f0
MT
949 idle_bits |=
950 pfi_output_select_bits(pfi_channel,
951 pfi_output_select_high_Z);
952 ni_660x_write_register(dev, idle_chipset, idle_bits,
953 IOConfigReg(pfi_channel));
58dd7c0a
M
954 }
955
0a85b6f0
MT
956 active_bits =
957 ni_660x_read_register(dev, active_chipset,
958 IOConfigReg(pfi_channel));
58dd7c0a
M
959 active_bits &= ~pfi_output_select_mask(pfi_channel);
960 active_bits |= pfi_output_select_bits(pfi_channel, output_select);
0a85b6f0
MT
961 ni_660x_write_register(dev, active_chipset, active_bits,
962 IOConfigReg(pfi_channel));
58dd7c0a
M
963}
964
da91b269 965static int ni_660x_set_pfi_routing(struct comedi_device *dev, unsigned chan,
0a85b6f0 966 unsigned source)
58dd7c0a 967{
8c12ec26
HS
968 struct ni_660x_private *devpriv = dev->private;
969
58dd7c0a
M
970 if (source > num_pfi_output_selects)
971 return -EINVAL;
972 if (source == pfi_output_select_high_Z)
973 return -EINVAL;
974 if (chan < min_counter_pfi_chan) {
975 if (source == pfi_output_select_counter)
976 return -EINVAL;
977 } else if (chan > max_dio_pfi_chan) {
978 if (source == pfi_output_select_do)
979 return -EINVAL;
980 }
58dd7c0a 981
8c12ec26
HS
982 devpriv->pfi_output_selects[chan] = source;
983 if (devpriv->pfi_direction_bits & (((uint64_t) 1) << chan))
58dd7c0a 984 ni_660x_select_pfi_output(dev, chan,
8c12ec26 985 devpriv->pfi_output_selects[chan]);
58dd7c0a
M
986 return 0;
987}
988
da91b269 989static int ni_660x_dio_insn_config(struct comedi_device *dev,
0a85b6f0 990 struct comedi_subdevice *s,
56c645ff
HS
991 struct comedi_insn *insn,
992 unsigned int *data)
58dd7c0a 993{
8c12ec26 994 struct ni_660x_private *devpriv = dev->private;
56c645ff
HS
995 unsigned int chan = CR_CHAN(insn->chanspec);
996 uint64_t bit = 1ULL << chan;
82327aaf 997 unsigned int val;
56c645ff 998 int ret;
58dd7c0a
M
999
1000 switch (data[0]) {
1001 case INSN_CONFIG_DIO_OUTPUT:
56c645ff 1002 devpriv->pfi_direction_bits |= bit;
58dd7c0a 1003 ni_660x_select_pfi_output(dev, chan,
8c12ec26 1004 devpriv->pfi_output_selects[chan]);
58dd7c0a 1005 break;
56c645ff 1006
58dd7c0a 1007 case INSN_CONFIG_DIO_INPUT:
56c645ff 1008 devpriv->pfi_direction_bits &= ~bit;
58dd7c0a
M
1009 ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
1010 break;
56c645ff 1011
58dd7c0a 1012 case INSN_CONFIG_DIO_QUERY:
56c645ff
HS
1013 data[1] = (devpriv->pfi_direction_bits & bit) ? COMEDI_OUTPUT
1014 : COMEDI_INPUT;
1015 break;
1016
58dd7c0a 1017 case INSN_CONFIG_SET_ROUTING:
56c645ff
HS
1018 ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
1019 if (ret)
1020 return ret;
58dd7c0a 1021 break;
56c645ff 1022
58dd7c0a 1023 case INSN_CONFIG_GET_ROUTING:
32bd027d 1024 data[1] = devpriv->pfi_output_selects[chan];
58dd7c0a 1025 break;
56c645ff 1026
58dd7c0a 1027 case INSN_CONFIG_FILTER:
82327aaf
HS
1028 val = ni_660x_read_register(dev, 0, IOConfigReg(chan));
1029 val &= ~pfi_input_select_mask(chan);
1030 val |= pfi_input_select_bits(chan, data[1]);
1031 ni_660x_write_register(dev, 0, val, IOConfigReg(chan));
58dd7c0a 1032 break;
56c645ff 1033
58dd7c0a
M
1034 default:
1035 return -EINVAL;
95cd17c9 1036 }
56c645ff
HS
1037
1038 return insn->n;
58dd7c0a 1039}
3c323c01 1040
a690b7e5 1041static int ni_660x_auto_attach(struct comedi_device *dev,
97bcce5a 1042 unsigned long context)
990b9eed 1043{
750af5e5 1044 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
97bcce5a 1045 const struct ni_660x_board *board = NULL;
990b9eed
HS
1046 struct ni_660x_private *devpriv;
1047 struct comedi_subdevice *s;
1048 int ret;
1049 unsigned i;
1050 unsigned global_interrupt_config_bits;
1051
97bcce5a
HS
1052 if (context < ARRAY_SIZE(ni_660x_boards))
1053 board = &ni_660x_boards[context];
1054 if (!board)
1055 return -ENODEV;
1056 dev->board_ptr = board;
1057 dev->board_name = board->name;
1058
818f569f
HS
1059 ret = comedi_pci_enable(dev);
1060 if (ret)
1061 return ret;
818f569f 1062
990b9eed
HS
1063 ret = ni_660x_allocate_private(dev);
1064 if (ret < 0)
1065 return ret;
1066 devpriv = dev->private;
1067
990b9eed
HS
1068 devpriv->mite = mite_alloc(pcidev);
1069 if (!devpriv->mite)
1070 return -ENOMEM;
1071
3bb7c3ab
HS
1072 ret = mite_setup2(dev, devpriv->mite, true);
1073 if (ret < 0)
990b9eed 1074 return ret;
990b9eed
HS
1075
1076 ret = ni_660x_alloc_mite_rings(dev);
1077 if (ret < 0)
1078 return ret;
1079
1080 ret = comedi_alloc_subdevices(dev, 2 + NI_660X_MAX_NUM_COUNTERS);
1081 if (ret)
1082 return ret;
1083
1084 s = &dev->subdevices[0];
1085 /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
1086 s->type = COMEDI_SUBD_UNUSED;
1087
1088 s = &dev->subdevices[NI_660X_DIO_SUBDEV];
1089 /* DIGITAL I/O SUBDEVICE */
1090 s->type = COMEDI_SUBD_DIO;
1091 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1092 s->n_chan = NUM_PFI_CHANNELS;
1093 s->maxdata = 1;
1094 s->range_table = &range_digital;
1095 s->insn_bits = ni_660x_dio_insn_bits;
1096 s->insn_config = ni_660x_dio_insn_config;
990b9eed
HS
1097 /* we use the ioconfig registers to control dio direction, so zero
1098 output enables in stc dio control reg */
1246f05b 1099 ni_660x_write_register(dev, 0, 0, NI660X_STC_DIO_CONTROL);
990b9eed
HS
1100
1101 devpriv->counter_dev = ni_gpct_device_construct(dev,
1102 &ni_gpct_write_register,
1103 &ni_gpct_read_register,
1104 ni_gpct_variant_660x,
1105 ni_660x_num_counters
1106 (dev));
307da4b2 1107 if (!devpriv->counter_dev)
990b9eed
HS
1108 return -ENOMEM;
1109 for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
1110 s = &dev->subdevices[NI_660X_GPCT_SUBDEV(i)];
1111 if (i < ni_660x_num_counters(dev)) {
1112 s->type = COMEDI_SUBD_COUNTER;
56e9bef5
HS
1113 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
1114 SDF_LSAMPL | SDF_CMD_READ;
990b9eed
HS
1115 s->n_chan = 3;
1116 s->maxdata = 0xffffffff;
9014d816 1117 s->insn_read = ni_tio_insn_read;
10f74377 1118 s->insn_write = ni_tio_insn_write;
cac04c0f 1119 s->insn_config = ni_tio_insn_config;
990b9eed
HS
1120 s->do_cmd = &ni_660x_cmd;
1121 s->len_chanlist = 1;
c3f3b431 1122 s->do_cmdtest = ni_tio_cmdtest;
990b9eed
HS
1123 s->cancel = &ni_660x_cancel;
1124 s->poll = &ni_660x_input_poll;
1125 s->async_dma_dir = DMA_BIDIRECTIONAL;
1126 s->buf_change = &ni_660x_buf_change;
1127 s->private = &devpriv->counter_dev->counters[i];
1128
1129 devpriv->counter_dev->counters[i].chip_index =
1130 i / counters_per_chip;
1131 devpriv->counter_dev->counters[i].counter_index =
1132 i % counters_per_chip;
1133 } else {
1134 s->type = COMEDI_SUBD_UNUSED;
1135 }
1136 }
9186ccde 1137 for (i = 0; i < board->n_chips; ++i)
990b9eed
HS
1138 init_tio_chip(dev, i);
1139
1140 for (i = 0; i < ni_660x_num_counters(dev); ++i)
1141 ni_tio_init_counter(&devpriv->counter_dev->counters[i]);
1142
1143 for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
1144 if (i < min_counter_pfi_chan)
1145 ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
1146 else
1147 ni_660x_set_pfi_routing(dev, i,
1148 pfi_output_select_counter);
1149 ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
1150 }
1151 /* to be safe, set counterswap bits on tio chips after all the counter
1152 outputs have been set to high impedance mode */
9186ccde 1153 for (i = 0; i < board->n_chips; ++i)
990b9eed
HS
1154 set_tio_counterswap(dev, i);
1155
71e06874
HS
1156 ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
1157 dev->board_name, dev);
990b9eed
HS
1158 if (ret < 0) {
1159 dev_warn(dev->class_dev, " irq not available\n");
1160 return ret;
1161 }
ba9d29fe 1162 dev->irq = pcidev->irq;
990b9eed 1163 global_interrupt_config_bits = Global_Int_Enable_Bit;
9186ccde 1164 if (board->n_chips > 1)
990b9eed
HS
1165 global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
1166 ni_660x_write_register(dev, 0, global_interrupt_config_bits,
1246f05b 1167 NI660X_GLOBAL_INT_CFG);
c93999c2 1168
990b9eed
HS
1169 return 0;
1170}
1171
1172static void ni_660x_detach(struct comedi_device *dev)
1173{
1174 struct ni_660x_private *devpriv = dev->private;
1175
1176 if (dev->irq)
1177 free_irq(dev->irq, dev);
1178 if (devpriv) {
1179 if (devpriv->counter_dev)
1180 ni_gpct_device_destroy(devpriv->counter_dev);
b876e985
HS
1181 ni_660x_free_mite_rings(dev);
1182 mite_detach(devpriv->mite);
990b9eed 1183 }
5f8a5f4f
HS
1184 if (dev->mmio)
1185 iounmap(dev->mmio);
7f072f54 1186 comedi_pci_disable(dev);
990b9eed
HS
1187}
1188
1189static struct comedi_driver ni_660x_driver = {
1190 .driver_name = "ni_660x",
1191 .module = THIS_MODULE,
750af5e5 1192 .auto_attach = ni_660x_auto_attach,
990b9eed
HS
1193 .detach = ni_660x_detach,
1194};
1195
a690b7e5 1196static int ni_660x_pci_probe(struct pci_dev *dev,
b8f4ac23 1197 const struct pci_device_id *id)
990b9eed 1198{
b8f4ac23 1199 return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
990b9eed
HS
1200}
1201
41e043fc 1202static const struct pci_device_id ni_660x_pci_table[] = {
97bcce5a
HS
1203 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
1204 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
1205 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
1206 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
8bdfefb7 1207 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
97bcce5a 1208 { 0 }
990b9eed
HS
1209};
1210MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
1211
1212static struct pci_driver ni_660x_pci_driver = {
1213 .name = "ni_660x",
1214 .id_table = ni_660x_pci_table,
1215 .probe = ni_660x_pci_probe,
9901a4d7 1216 .remove = comedi_pci_auto_unconfig,
990b9eed
HS
1217};
1218module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
1219
3c323c01
IA
1220MODULE_AUTHOR("Comedi http://www.comedi.org");
1221MODULE_DESCRIPTION("Comedi low-level driver");
1222MODULE_LICENSE("GPL");
This page took 1.175662 seconds and 5 git commands to generate.