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