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