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