![]() |
RTXI 1.3
|
00001 /* 00002 comedi/drivers/ni_660x.c 00003 Hardware driver for NI 660x devices 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 /* 00021 Driver: ni_660x 00022 Description: National Instruments 660x counter/timer boards 00023 Devices: 00024 [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602, 00025 PXI-6608 00026 Author: J.P. Mellor <jpmellor@rose-hulman.edu>, 00027 Herman.Bruyninckx@mech.kuleuven.ac.be, 00028 Wim.Meeussen@mech.kuleuven.ac.be, 00029 Klaas.Gadeyne@mech.kuleuven.ac.be, 00030 Frank Mori Hess <fmhess@users.sourceforge.net> 00031 Updated: Thu Oct 18 12:56:06 EDT 2007 00032 Status: experimental 00033 00034 Encoders work. PulseGeneration (both single pulse and pulse train) 00035 works. Buffered commands work for input but not output. 00036 00037 References: 00038 DAQ 660x Register-Level Programmer Manual (NI 370505A-01) 00039 DAQ 6601/6602 User Manual (NI 322137B-01) 00040 00041 */ 00042 00043 #include <linux/comedidev.h> 00044 #include "mite.h" 00045 #include "ni_tio.h" 00046 00047 enum ni_660x_constants { 00048 min_counter_pfi_chan = 8, 00049 max_dio_pfi_chan = 31, 00050 counters_per_chip = 4 00051 }; 00052 00053 #define NUM_PFI_CHANNELS 40 00054 // really there are only up to 3 dma channels, but the register layout allows for 4 00055 #define MAX_DMA_CHANNEL 4 00056 00057 /* See Register-Level Programmer Manual page 3.1 */ 00058 typedef enum { 00059 G0InterruptAcknowledge, 00060 G0StatusRegister, 00061 G1InterruptAcknowledge, 00062 G1StatusRegister, 00063 G01StatusRegister, 00064 G0CommandRegister, 00065 STCDIOParallelInput, 00066 G1CommandRegister, 00067 G0HWSaveRegister, 00068 G1HWSaveRegister, 00069 STCDIOOutput, 00070 STCDIOControl, 00071 G0SWSaveRegister, 00072 G1SWSaveRegister, 00073 G0ModeRegister, 00074 G01JointStatus1Register, 00075 G1ModeRegister, 00076 STCDIOSerialInput, 00077 G0LoadARegister, 00078 G01JointStatus2Register, 00079 G0LoadBRegister, 00080 G1LoadARegister, 00081 G1LoadBRegister, 00082 G0InputSelectRegister, 00083 G1InputSelectRegister, 00084 G0AutoincrementRegister, 00085 G1AutoincrementRegister, 00086 G01JointResetRegister, 00087 G0InterruptEnable, 00088 G1InterruptEnable, 00089 G0CountingModeRegister, 00090 G1CountingModeRegister, 00091 G0SecondGateRegister, 00092 G1SecondGateRegister, 00093 G0DMAConfigRegister, 00094 G0DMAStatusRegister, 00095 G1DMAConfigRegister, 00096 G1DMAStatusRegister, 00097 G2InterruptAcknowledge, 00098 G2StatusRegister, 00099 G3InterruptAcknowledge, 00100 G3StatusRegister, 00101 G23StatusRegister, 00102 G2CommandRegister, 00103 G3CommandRegister, 00104 G2HWSaveRegister, 00105 G3HWSaveRegister, 00106 G2SWSaveRegister, 00107 G3SWSaveRegister, 00108 G2ModeRegister, 00109 G23JointStatus1Register, 00110 G3ModeRegister, 00111 G2LoadARegister, 00112 G23JointStatus2Register, 00113 G2LoadBRegister, 00114 G3LoadARegister, 00115 G3LoadBRegister, 00116 G2InputSelectRegister, 00117 G3InputSelectRegister, 00118 G2AutoincrementRegister, 00119 G3AutoincrementRegister, 00120 G23JointResetRegister, 00121 G2InterruptEnable, 00122 G3InterruptEnable, 00123 G2CountingModeRegister, 00124 G3CountingModeRegister, 00125 G3SecondGateRegister, 00126 G2SecondGateRegister, 00127 G2DMAConfigRegister, 00128 G2DMAStatusRegister, 00129 G3DMAConfigRegister, 00130 G3DMAStatusRegister, 00131 DIO32Input, 00132 DIO32Output, 00133 ClockConfigRegister, 00134 GlobalInterruptStatusRegister, 00135 DMAConfigRegister, 00136 GlobalInterruptConfigRegister, 00137 IOConfigReg0_1, 00138 IOConfigReg2_3, 00139 IOConfigReg4_5, 00140 IOConfigReg6_7, 00141 IOConfigReg8_9, 00142 IOConfigReg10_11, 00143 IOConfigReg12_13, 00144 IOConfigReg14_15, 00145 IOConfigReg16_17, 00146 IOConfigReg18_19, 00147 IOConfigReg20_21, 00148 IOConfigReg22_23, 00149 IOConfigReg24_25, 00150 IOConfigReg26_27, 00151 IOConfigReg28_29, 00152 IOConfigReg30_31, 00153 IOConfigReg32_33, 00154 IOConfigReg34_35, 00155 IOConfigReg36_37, 00156 IOConfigReg38_39, 00157 NumRegisters, 00158 } NI_660x_Register; 00159 00160 static inline unsigned IOConfigReg(unsigned pfi_channel) 00161 { 00162 unsigned reg = IOConfigReg0_1 + pfi_channel / 2; 00163 BUG_ON(reg > IOConfigReg38_39); 00164 return reg; 00165 } 00166 00167 enum ni_660x_register_width { 00168 DATA_1B, 00169 DATA_2B, 00170 DATA_4B 00171 }; 00172 00173 enum ni_660x_register_direction { 00174 NI_660x_READ, 00175 NI_660x_WRITE, 00176 NI_660x_READ_WRITE 00177 }; 00178 00179 enum ni_660x_pfi_output_select { 00180 pfi_output_select_high_Z = 0, 00181 pfi_output_select_counter = 1, 00182 pfi_output_select_do = 2, 00183 num_pfi_output_selects 00184 }; 00185 00186 enum ni_660x_subdevices { 00187 NI_660X_DIO_SUBDEV = 1, 00188 NI_660X_GPCT_SUBDEV_0 = 2 00189 }; 00190 static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index) 00191 { 00192 return NI_660X_GPCT_SUBDEV_0 + index; 00193 } 00194 00195 typedef struct { 00196 const char *name; // Register Name 00197 int offset; // Offset from base address from GPCT chip 00198 enum ni_660x_register_direction direction; 00199 enum ni_660x_register_width size; // 1 byte, 2 bytes, or 4 bytes 00200 } NI_660xRegisterData; 00201 00202 static const NI_660xRegisterData registerData[NumRegisters] = { 00203 {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B}, 00204 {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B}, 00205 {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B}, 00206 {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B}, 00207 {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B}, 00208 {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B}, 00209 {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B}, 00210 {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B}, 00211 {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B}, 00212 {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B}, 00213 {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B}, 00214 {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B}, 00215 {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B}, 00216 {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B}, 00217 {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B}, 00218 {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B}, 00219 {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B}, 00220 {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B}, 00221 {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B}, 00222 {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B}, 00223 {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B}, 00224 {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B}, 00225 {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B}, 00226 {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B}, 00227 {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B}, 00228 {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B}, 00229 {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B}, 00230 {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B}, 00231 {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B}, 00232 {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B}, 00233 {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B}, 00234 {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B}, 00235 {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B}, 00236 {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B}, 00237 {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B}, 00238 {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B}, 00239 {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B}, 00240 {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B}, 00241 {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B}, 00242 {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B}, 00243 {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B}, 00244 {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B}, 00245 {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B}, 00246 {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B}, 00247 {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B}, 00248 {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B}, 00249 {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B}, 00250 {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B}, 00251 {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B}, 00252 {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B}, 00253 {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B}, 00254 {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B}, 00255 {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B}, 00256 {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B}, 00257 {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B}, 00258 {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B}, 00259 {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B}, 00260 {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B}, 00261 {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B}, 00262 {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B}, 00263 {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B}, 00264 {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B}, 00265 {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B}, 00266 {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B}, 00267 {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B}, 00268 {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B}, 00269 {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B}, 00270 {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B}, 00271 {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B}, 00272 {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B}, 00273 {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B}, 00274 {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B}, 00275 {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B}, 00276 {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B}, 00277 {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B}, 00278 {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B}, 00279 {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B}, 00280 {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B}, 00281 {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B}, 00282 {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B}, 00283 {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B}, 00284 {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B}, 00285 {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B}, 00286 {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B}, 00287 {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B}, 00288 {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B}, 00289 {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B}, 00290 {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B}, 00291 {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B}, 00292 {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B}, 00293 {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B}, 00294 {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B}, 00295 {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B}, 00296 {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B}, 00297 {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B}, 00298 {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B}, 00299 {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B}, 00300 {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B} 00301 }; 00302 00303 // kind of ENABLE for the second counter 00304 enum clock_config_register_bits { 00305 CounterSwap = 0x1 << 21 00306 }; 00307 00308 // ioconfigreg 00309 static inline unsigned ioconfig_bitshift(unsigned pfi_channel) 00310 { 00311 if (pfi_channel % 2) 00312 return 0; 00313 else 00314 return 8; 00315 } 00316 static inline unsigned pfi_output_select_mask(unsigned pfi_channel) 00317 { 00318 return 0x3 << ioconfig_bitshift(pfi_channel); 00319 } 00320 static inline unsigned pfi_output_select_bits(unsigned pfi_channel, 00321 unsigned output_select) 00322 { 00323 return (output_select & 0x3) << ioconfig_bitshift(pfi_channel); 00324 } 00325 static inline unsigned pfi_input_select_mask(unsigned pfi_channel) 00326 { 00327 return 0x7 << (4 + ioconfig_bitshift(pfi_channel)); 00328 } 00329 static inline unsigned pfi_input_select_bits(unsigned pfi_channel, 00330 unsigned input_select) 00331 { 00332 return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel)); 00333 } 00334 00335 // dma configuration register bits 00336 static inline unsigned dma_select_mask(unsigned dma_channel) 00337 { 00338 BUG_ON(dma_channel >= MAX_DMA_CHANNEL); 00339 return 0x1f << (8 * dma_channel); 00340 } 00341 enum dma_selection { 00342 dma_selection_none = 0x1f, 00343 }; 00344 static inline unsigned dma_selection_counter(unsigned counter_index) 00345 { 00346 BUG_ON(counter_index >= counters_per_chip); 00347 return counter_index; 00348 } 00349 static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection) 00350 { 00351 BUG_ON(dma_channel >= MAX_DMA_CHANNEL); 00352 return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel); 00353 } 00354 static inline unsigned dma_reset_bit(unsigned dma_channel) 00355 { 00356 BUG_ON(dma_channel >= MAX_DMA_CHANNEL); 00357 return 0x80 << (8 * dma_channel); 00358 } 00359 00360 enum global_interrupt_status_register_bits { 00361 Counter_0_Int_Bit = 0x100, 00362 Counter_1_Int_Bit = 0x200, 00363 Counter_2_Int_Bit = 0x400, 00364 Counter_3_Int_Bit = 0x800, 00365 Cascade_Int_Bit = 0x20000000, 00366 Global_Int_Bit = 0x80000000 00367 }; 00368 00369 enum global_interrupt_config_register_bits { 00370 Cascade_Int_Enable_Bit = 0x20000000, 00371 Global_Int_Polarity_Bit = 0x40000000, 00372 Global_Int_Enable_Bit = 0x80000000 00373 }; 00374 00375 // Offset of the GPCT chips from the base-adress of the card 00376 static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address + 00377 0x00, etc. */ 00378 00379 /* Board description*/ 00380 typedef struct { 00381 unsigned short dev_id; /* `lspci` will show you this */ 00382 const char *name; 00383 unsigned n_chips; /* total number of TIO chips */ 00384 } ni_660x_board; 00385 00386 static const ni_660x_board ni_660x_boards[] = { 00387 { 00388 dev_id: 0x2c60, 00389 name: "PCI-6601", 00390 n_chips: 1, 00391 }, 00392 { 00393 dev_id: 0x1310, 00394 name: "PCI-6602", 00395 n_chips: 2, 00396 }, 00397 { 00398 dev_id: 0x1360, 00399 name: "PXI-6602", 00400 n_chips: 2, 00401 }, 00402 { 00403 dev_id: 0x2cc0, 00404 name: "PXI-6608", 00405 n_chips: 2, 00406 }, 00407 }; 00408 00409 #define NI_660X_MAX_NUM_CHIPS 2 00410 #define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip) 00411 00412 static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = { 00413 {PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 00414 {PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 00415 {PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 00416 {PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 00417 {0} 00418 }; 00419 00420 MODULE_DEVICE_TABLE(pci, ni_660x_pci_table); 00421 00422 typedef struct { 00423 struct mite_struct *mite; 00424 struct ni_gpct_device *counter_dev; 00425 uint64_t pfi_direction_bits; 00426 struct mite_dma_descriptor_ring 00427 *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip]; 00428 spinlock_t mite_channel_lock; 00429 // interrupt_lock prevents races between interrupt and comedi_poll 00430 spinlock_t interrupt_lock; 00431 unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS]; 00432 spinlock_t soft_reg_copy_lock; 00433 unsigned short pfi_output_selects[NUM_PFI_CHANNELS]; 00434 } ni_660x_private; 00435 00436 static inline ni_660x_private *private(comedi_device * dev) 00437 { 00438 return dev->private; 00439 } 00440 00441 /* initialized in ni_660x_find_device() */ 00442 static inline const ni_660x_board *board(comedi_device * dev) 00443 { 00444 return dev->board_ptr; 00445 } 00446 00447 #define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0])) 00448 00449 static int ni_660x_attach(comedi_device * dev, comedi_devconfig * it); 00450 static int ni_660x_detach(comedi_device * dev); 00451 static void init_tio_chip(comedi_device * dev, int chipset); 00452 static void ni_660x_select_pfi_output(comedi_device * dev, unsigned pfi_channel, 00453 unsigned output_select); 00454 00455 static comedi_driver driver_ni_660x = { 00456 driver_name:"ni_660x", 00457 module:THIS_MODULE, 00458 attach:ni_660x_attach, 00459 detach:ni_660x_detach, 00460 }; 00461 00462 COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table); 00463 00464 static int ni_660x_find_device(comedi_device * dev, int bus, int slot); 00465 static int ni_660x_set_pfi_routing(comedi_device * dev, unsigned chan, 00466 unsigned source); 00467 00468 /* Possible instructions for a GPCT */ 00469 static int ni_660x_GPCT_rinsn(comedi_device * dev, 00470 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00471 static int ni_660x_GPCT_insn_config(comedi_device * dev, 00472 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00473 static int ni_660x_GPCT_winsn(comedi_device * dev, 00474 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00475 00476 /* Possible instructions for Digital IO */ 00477 static int ni_660x_dio_insn_config(comedi_device * dev, 00478 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00479 static int ni_660x_dio_insn_bits(comedi_device * dev, 00480 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data); 00481 00482 static inline unsigned ni_660x_num_counters(comedi_device * dev) 00483 { 00484 return board(dev)->n_chips * counters_per_chip; 00485 } 00486 00487 static NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg) 00488 { 00489 NI_660x_Register ni_660x_register; 00490 switch (reg) { 00491 case NITIO_G0_Autoincrement_Reg: 00492 ni_660x_register = G0AutoincrementRegister; 00493 break; 00494 case NITIO_G1_Autoincrement_Reg: 00495 ni_660x_register = G1AutoincrementRegister; 00496 break; 00497 case NITIO_G2_Autoincrement_Reg: 00498 ni_660x_register = G2AutoincrementRegister; 00499 break; 00500 case NITIO_G3_Autoincrement_Reg: 00501 ni_660x_register = G3AutoincrementRegister; 00502 break; 00503 case NITIO_G0_Command_Reg: 00504 ni_660x_register = G0CommandRegister; 00505 break; 00506 case NITIO_G1_Command_Reg: 00507 ni_660x_register = G1CommandRegister; 00508 break; 00509 case NITIO_G2_Command_Reg: 00510 ni_660x_register = G2CommandRegister; 00511 break; 00512 case NITIO_G3_Command_Reg: 00513 ni_660x_register = G3CommandRegister; 00514 break; 00515 case NITIO_G0_HW_Save_Reg: 00516 ni_660x_register = G0HWSaveRegister; 00517 break; 00518 case NITIO_G1_HW_Save_Reg: 00519 ni_660x_register = G1HWSaveRegister; 00520 break; 00521 case NITIO_G2_HW_Save_Reg: 00522 ni_660x_register = G2HWSaveRegister; 00523 break; 00524 case NITIO_G3_HW_Save_Reg: 00525 ni_660x_register = G3HWSaveRegister; 00526 break; 00527 case NITIO_G0_SW_Save_Reg: 00528 ni_660x_register = G0SWSaveRegister; 00529 break; 00530 case NITIO_G1_SW_Save_Reg: 00531 ni_660x_register = G1SWSaveRegister; 00532 break; 00533 case NITIO_G2_SW_Save_Reg: 00534 ni_660x_register = G2SWSaveRegister; 00535 break; 00536 case NITIO_G3_SW_Save_Reg: 00537 ni_660x_register = G3SWSaveRegister; 00538 break; 00539 case NITIO_G0_Mode_Reg: 00540 ni_660x_register = G0ModeRegister; 00541 break; 00542 case NITIO_G1_Mode_Reg: 00543 ni_660x_register = G1ModeRegister; 00544 break; 00545 case NITIO_G2_Mode_Reg: 00546 ni_660x_register = G2ModeRegister; 00547 break; 00548 case NITIO_G3_Mode_Reg: 00549 ni_660x_register = G3ModeRegister; 00550 break; 00551 case NITIO_G0_LoadA_Reg: 00552 ni_660x_register = G0LoadARegister; 00553 break; 00554 case NITIO_G1_LoadA_Reg: 00555 ni_660x_register = G1LoadARegister; 00556 break; 00557 case NITIO_G2_LoadA_Reg: 00558 ni_660x_register = G2LoadARegister; 00559 break; 00560 case NITIO_G3_LoadA_Reg: 00561 ni_660x_register = G3LoadARegister; 00562 break; 00563 case NITIO_G0_LoadB_Reg: 00564 ni_660x_register = G0LoadBRegister; 00565 break; 00566 case NITIO_G1_LoadB_Reg: 00567 ni_660x_register = G1LoadBRegister; 00568 break; 00569 case NITIO_G2_LoadB_Reg: 00570 ni_660x_register = G2LoadBRegister; 00571 break; 00572 case NITIO_G3_LoadB_Reg: 00573 ni_660x_register = G3LoadBRegister; 00574 break; 00575 case NITIO_G0_Input_Select_Reg: 00576 ni_660x_register = G0InputSelectRegister; 00577 break; 00578 case NITIO_G1_Input_Select_Reg: 00579 ni_660x_register = G1InputSelectRegister; 00580 break; 00581 case NITIO_G2_Input_Select_Reg: 00582 ni_660x_register = G2InputSelectRegister; 00583 break; 00584 case NITIO_G3_Input_Select_Reg: 00585 ni_660x_register = G3InputSelectRegister; 00586 break; 00587 case NITIO_G01_Status_Reg: 00588 ni_660x_register = G01StatusRegister; 00589 break; 00590 case NITIO_G23_Status_Reg: 00591 ni_660x_register = G23StatusRegister; 00592 break; 00593 case NITIO_G01_Joint_Reset_Reg: 00594 ni_660x_register = G01JointResetRegister; 00595 break; 00596 case NITIO_G23_Joint_Reset_Reg: 00597 ni_660x_register = G23JointResetRegister; 00598 break; 00599 case NITIO_G01_Joint_Status1_Reg: 00600 ni_660x_register = G01JointStatus1Register; 00601 break; 00602 case NITIO_G23_Joint_Status1_Reg: 00603 ni_660x_register = G23JointStatus1Register; 00604 break; 00605 case NITIO_G01_Joint_Status2_Reg: 00606 ni_660x_register = G01JointStatus2Register; 00607 break; 00608 case NITIO_G23_Joint_Status2_Reg: 00609 ni_660x_register = G23JointStatus2Register; 00610 break; 00611 case NITIO_G0_Counting_Mode_Reg: 00612 ni_660x_register = G0CountingModeRegister; 00613 break; 00614 case NITIO_G1_Counting_Mode_Reg: 00615 ni_660x_register = G1CountingModeRegister; 00616 break; 00617 case NITIO_G2_Counting_Mode_Reg: 00618 ni_660x_register = G2CountingModeRegister; 00619 break; 00620 case NITIO_G3_Counting_Mode_Reg: 00621 ni_660x_register = G3CountingModeRegister; 00622 break; 00623 case NITIO_G0_Second_Gate_Reg: 00624 ni_660x_register = G0SecondGateRegister; 00625 break; 00626 case NITIO_G1_Second_Gate_Reg: 00627 ni_660x_register = G1SecondGateRegister; 00628 break; 00629 case NITIO_G2_Second_Gate_Reg: 00630 ni_660x_register = G2SecondGateRegister; 00631 break; 00632 case NITIO_G3_Second_Gate_Reg: 00633 ni_660x_register = G3SecondGateRegister; 00634 break; 00635 case NITIO_G0_DMA_Config_Reg: 00636 ni_660x_register = G0DMAConfigRegister; 00637 break; 00638 case NITIO_G0_DMA_Status_Reg: 00639 ni_660x_register = G0DMAStatusRegister; 00640 break; 00641 case NITIO_G1_DMA_Config_Reg: 00642 ni_660x_register = G1DMAConfigRegister; 00643 break; 00644 case NITIO_G1_DMA_Status_Reg: 00645 ni_660x_register = G1DMAStatusRegister; 00646 break; 00647 case NITIO_G2_DMA_Config_Reg: 00648 ni_660x_register = G2DMAConfigRegister; 00649 break; 00650 case NITIO_G2_DMA_Status_Reg: 00651 ni_660x_register = G2DMAStatusRegister; 00652 break; 00653 case NITIO_G3_DMA_Config_Reg: 00654 ni_660x_register = G3DMAConfigRegister; 00655 break; 00656 case NITIO_G3_DMA_Status_Reg: 00657 ni_660x_register = G3DMAStatusRegister; 00658 break; 00659 case NITIO_G0_Interrupt_Acknowledge_Reg: 00660 ni_660x_register = G0InterruptAcknowledge; 00661 break; 00662 case NITIO_G1_Interrupt_Acknowledge_Reg: 00663 ni_660x_register = G1InterruptAcknowledge; 00664 break; 00665 case NITIO_G2_Interrupt_Acknowledge_Reg: 00666 ni_660x_register = G2InterruptAcknowledge; 00667 break; 00668 case NITIO_G3_Interrupt_Acknowledge_Reg: 00669 ni_660x_register = G3InterruptAcknowledge; 00670 break; 00671 case NITIO_G0_Status_Reg: 00672 ni_660x_register = G0StatusRegister; 00673 break; 00674 case NITIO_G1_Status_Reg: 00675 ni_660x_register = G0StatusRegister; 00676 break; 00677 case NITIO_G2_Status_Reg: 00678 ni_660x_register = G0StatusRegister; 00679 break; 00680 case NITIO_G3_Status_Reg: 00681 ni_660x_register = G0StatusRegister; 00682 break; 00683 case NITIO_G0_Interrupt_Enable_Reg: 00684 ni_660x_register = G0InterruptEnable; 00685 break; 00686 case NITIO_G1_Interrupt_Enable_Reg: 00687 ni_660x_register = G1InterruptEnable; 00688 break; 00689 case NITIO_G2_Interrupt_Enable_Reg: 00690 ni_660x_register = G2InterruptEnable; 00691 break; 00692 case NITIO_G3_Interrupt_Enable_Reg: 00693 ni_660x_register = G3InterruptEnable; 00694 break; 00695 default: 00696 rt_printk("%s: unhandled register 0x%x in switch.\n", 00697 __FUNCTION__, reg); 00698 BUG(); 00699 return 0; 00700 break; 00701 } 00702 return ni_660x_register; 00703 } 00704 00705 static inline void ni_660x_write_register(comedi_device * dev, 00706 unsigned chip_index, unsigned bits, NI_660x_Register reg) 00707 { 00708 void *const write_address = 00709 private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + 00710 registerData[reg].offset; 00711 00712 switch (registerData[reg].size) { 00713 case DATA_2B: 00714 writew(bits, write_address); 00715 break; 00716 case DATA_4B: 00717 writel(bits, write_address); 00718 break; 00719 default: 00720 rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", 00721 __FILE__, __FUNCTION__, reg); 00722 BUG(); 00723 break; 00724 } 00725 } 00726 00727 static inline unsigned ni_660x_read_register(comedi_device * dev, 00728 unsigned chip_index, NI_660x_Register reg) 00729 { 00730 void *const read_address = 00731 private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] + 00732 registerData[reg].offset; 00733 00734 switch (registerData[reg].size) { 00735 case DATA_2B: 00736 return readw(read_address); 00737 break; 00738 case DATA_4B: 00739 return readl(read_address); 00740 break; 00741 default: 00742 rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n", 00743 __FILE__, __FUNCTION__, reg); 00744 BUG(); 00745 break; 00746 } 00747 return 0; 00748 } 00749 00750 static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits, 00751 enum ni_gpct_register reg) 00752 { 00753 comedi_device *dev = counter->counter_dev->dev; 00754 NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg); 00755 ni_660x_write_register(dev, counter->chip_index, bits, 00756 ni_660x_register); 00757 } 00758 00759 static unsigned ni_gpct_read_register(struct ni_gpct *counter, 00760 enum ni_gpct_register reg) 00761 { 00762 comedi_device *dev = counter->counter_dev->dev; 00763 NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg); 00764 return ni_660x_read_register(dev, counter->chip_index, 00765 ni_660x_register); 00766 } 00767 00768 static inline struct mite_dma_descriptor_ring *mite_ring(ni_660x_private * priv, 00769 struct ni_gpct *counter) 00770 { 00771 return priv->mite_rings[counter->chip_index][counter->counter_index]; 00772 } 00773 00774 static inline void ni_660x_set_dma_channel(comedi_device * dev, 00775 unsigned mite_channel, struct ni_gpct *counter) 00776 { 00777 unsigned long flags; 00778 comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); 00779 private(dev)->dma_configuration_soft_copies[counter->chip_index] &= 00780 ~dma_select_mask(mite_channel); 00781 private(dev)->dma_configuration_soft_copies[counter->chip_index] |= 00782 dma_select_bits(mite_channel, 00783 dma_selection_counter(counter->counter_index)); 00784 ni_660x_write_register(dev, counter->chip_index, 00785 private(dev)->dma_configuration_soft_copies[counter-> 00786 chip_index] | dma_reset_bit(mite_channel), 00787 DMAConfigRegister); 00788 mmiowb(); 00789 comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); 00790 } 00791 00792 static inline void ni_660x_unset_dma_channel(comedi_device * dev, 00793 unsigned mite_channel, struct ni_gpct *counter) 00794 { 00795 unsigned long flags; 00796 comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags); 00797 private(dev)->dma_configuration_soft_copies[counter->chip_index] &= 00798 ~dma_select_mask(mite_channel); 00799 private(dev)->dma_configuration_soft_copies[counter->chip_index] |= 00800 dma_select_bits(mite_channel, dma_selection_none); 00801 ni_660x_write_register(dev, counter->chip_index, 00802 private(dev)->dma_configuration_soft_copies[counter-> 00803 chip_index], DMAConfigRegister); 00804 mmiowb(); 00805 comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags); 00806 } 00807 00808 static int ni_660x_request_mite_channel(comedi_device * dev, 00809 struct ni_gpct *counter, enum comedi_io_direction direction) 00810 { 00811 unsigned long flags; 00812 struct mite_channel *mite_chan; 00813 00814 comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags); 00815 BUG_ON(counter->mite_chan); 00816 mite_chan = 00817 mite_request_channel(private(dev)->mite, mite_ring(private(dev), 00818 counter)); 00819 if (mite_chan == NULL) { 00820 comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, 00821 flags); 00822 comedi_error(dev, 00823 "failed to reserve mite dma channel for counter."); 00824 return -EBUSY; 00825 } 00826 mite_chan->dir = direction; 00827 ni_tio_set_mite_channel(counter, mite_chan); 00828 ni_660x_set_dma_channel(dev, mite_chan->channel, counter); 00829 comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); 00830 return 0; 00831 } 00832 00833 void ni_660x_release_mite_channel(comedi_device * dev, struct ni_gpct *counter) 00834 { 00835 unsigned long flags; 00836 00837 comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags); 00838 if (counter->mite_chan) { 00839 struct mite_channel *mite_chan = counter->mite_chan; 00840 00841 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter); 00842 ni_tio_set_mite_channel(counter, NULL); 00843 mite_release_channel(mite_chan); 00844 } 00845 comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags); 00846 } 00847 00848 static int ni_660x_cmd(comedi_device * dev, comedi_subdevice * s) 00849 { 00850 int retval; 00851 00852 struct ni_gpct *counter = subdev_to_counter(s); 00853 // const comedi_cmd *cmd = &s->async->cmd; 00854 00855 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT); 00856 if (retval) { 00857 comedi_error(dev, 00858 "no dma channel available for use by counter"); 00859 return retval; 00860 } 00861 ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL); 00862 retval = ni_tio_cmd(counter, s->async); 00863 00864 return retval; 00865 } 00866 00867 static int ni_660x_cmdtest(comedi_device * dev, comedi_subdevice * s, 00868 comedi_cmd * cmd) 00869 { 00870 struct ni_gpct *counter = subdev_to_counter(s); 00871 00872 return ni_tio_cmdtest(counter, cmd); 00873 } 00874 00875 static int ni_660x_cancel(comedi_device * dev, comedi_subdevice * s) 00876 { 00877 struct ni_gpct *counter = subdev_to_counter(s); 00878 int retval; 00879 00880 retval = ni_tio_cancel(counter); 00881 ni_660x_release_mite_channel(dev, counter); 00882 return retval; 00883 } 00884 00885 static void set_tio_counterswap(comedi_device * dev, int chipset) 00886 { 00887 /* See P. 3.5 of the Register-Level Programming manual. The 00888 CounterSwap bit has to be set on the second chip, otherwise 00889 it will try to use the same pins as the first chip. 00890 */ 00891 if (chipset) 00892 ni_660x_write_register(dev, chipset, CounterSwap, 00893 ClockConfigRegister); 00894 else 00895 ni_660x_write_register(dev, chipset, 0, ClockConfigRegister); 00896 } 00897 00898 static void ni_660x_handle_gpct_interrupt(comedi_device * dev, 00899 comedi_subdevice * s) 00900 { 00901 ni_tio_handle_interrupt(subdev_to_counter(s), s); 00902 if (s->async->events) { 00903 if (s->async-> 00904 events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | 00905 COMEDI_CB_OVERFLOW)) { 00906 ni_660x_cancel(dev, s); 00907 } 00908 comedi_event(dev, s); 00909 } 00910 } 00911 00912 static irqreturn_t ni_660x_interrupt(int irq, void *d PT_REGS_ARG) 00913 { 00914 comedi_device *dev = d; 00915 comedi_subdevice *s; 00916 unsigned i; 00917 unsigned long flags; 00918 00919 if (dev->attached == 0) 00920 return IRQ_NONE; 00921 // lock to avoid race with comedi_poll 00922 comedi_spin_lock_irqsave(&private(dev)->interrupt_lock, flags); 00923 smp_mb(); 00924 for (i = 0; i < ni_660x_num_counters(dev); ++i) { 00925 s = dev->subdevices + NI_660X_GPCT_SUBDEV(i); 00926 ni_660x_handle_gpct_interrupt(dev, s); 00927 } 00928 comedi_spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); 00929 return IRQ_HANDLED; 00930 } 00931 00932 static int ni_660x_input_poll(comedi_device * dev, comedi_subdevice * s) 00933 { 00934 unsigned long flags; 00935 // lock to avoid race with comedi_poll 00936 comedi_spin_lock_irqsave(&private(dev)->interrupt_lock, flags); 00937 mite_sync_input_dma(subdev_to_counter(s)->mite_chan, s->async); 00938 comedi_spin_unlock_irqrestore(&private(dev)->interrupt_lock, flags); 00939 return comedi_buf_read_n_available(s->async); 00940 } 00941 00942 static int ni_660x_buf_change(comedi_device * dev, comedi_subdevice * s, 00943 unsigned long new_size) 00944 { 00945 int ret; 00946 00947 ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)), 00948 s->async); 00949 if (ret < 0) 00950 return ret; 00951 00952 return 0; 00953 } 00954 00955 static int ni_660x_allocate_private(comedi_device * dev) 00956 { 00957 int retval; 00958 unsigned i; 00959 00960 if ((retval = alloc_private(dev, sizeof(ni_660x_private))) < 0) 00961 return retval; 00962 spin_lock_init(&private(dev)->mite_channel_lock); 00963 spin_lock_init(&private(dev)->interrupt_lock); 00964 spin_lock_init(&private(dev)->soft_reg_copy_lock); 00965 for (i = 0; i < NUM_PFI_CHANNELS; ++i) { 00966 private(dev)->pfi_output_selects[i] = pfi_output_select_counter; 00967 } 00968 return 0; 00969 } 00970 00971 static int ni_660x_alloc_mite_rings(comedi_device * dev) 00972 { 00973 unsigned i; 00974 unsigned j; 00975 00976 for (i = 0; i < board(dev)->n_chips; ++i) { 00977 for (j = 0; j < counters_per_chip; ++j) { 00978 private(dev)->mite_rings[i][j] = 00979 mite_alloc_ring(private(dev)->mite); 00980 if (private(dev)->mite_rings[i][j] == NULL) { 00981 return -ENOMEM; 00982 } 00983 } 00984 } 00985 return 0; 00986 } 00987 00988 static void ni_660x_free_mite_rings(comedi_device * dev) 00989 { 00990 unsigned i; 00991 unsigned j; 00992 00993 for (i = 0; i < board(dev)->n_chips; ++i) { 00994 for (j = 0; j < counters_per_chip; ++j) { 00995 mite_free_ring(private(dev)->mite_rings[i][j]); 00996 } 00997 } 00998 } 00999 01000 static int ni_660x_attach(comedi_device * dev, comedi_devconfig * it) 01001 { 01002 comedi_subdevice *s; 01003 int ret; 01004 unsigned i; 01005 unsigned global_interrupt_config_bits; 01006 01007 printk("comedi%d: ni_660x: ", dev->minor); 01008 01009 ret = ni_660x_allocate_private(dev); 01010 if (ret < 0) 01011 return ret; 01012 ret = ni_660x_find_device(dev, it->options[0], it->options[1]); 01013 if (ret < 0) 01014 return ret; 01015 01016 dev->board_name = board(dev)->name; 01017 01018 ret = mite_setup2(private(dev)->mite, 1); 01019 if (ret < 0) { 01020 printk("error setting up mite\n"); 01021 return ret; 01022 } 01023 comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev); 01024 ret = ni_660x_alloc_mite_rings(dev); 01025 if (ret < 0) 01026 return ret; 01027 01028 printk(" %s ", dev->board_name); 01029 01030 dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS; 01031 01032 if (alloc_subdevices(dev, dev->n_subdevices) < 0) 01033 return -ENOMEM; 01034 01035 s = dev->subdevices + 0; 01036 /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */ 01037 s->type = COMEDI_SUBD_UNUSED; 01038 01039 s = dev->subdevices + NI_660X_DIO_SUBDEV; 01040 /* DIGITAL I/O SUBDEVICE */ 01041 s->type = COMEDI_SUBD_DIO; 01042 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 01043 s->n_chan = NUM_PFI_CHANNELS; 01044 s->maxdata = 1; 01045 s->range_table = &range_digital; 01046 s->insn_bits = ni_660x_dio_insn_bits; 01047 s->insn_config = ni_660x_dio_insn_config; 01048 s->io_bits = 0; /* all bits default to input */ 01049 // we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg 01050 ni_660x_write_register(dev, 0, 0, STCDIOControl); 01051 01052 private(dev)->counter_dev = ni_gpct_device_construct(dev, 01053 &ni_gpct_write_register, &ni_gpct_read_register, 01054 ni_gpct_variant_660x, ni_660x_num_counters(dev)); 01055 if (private(dev)->counter_dev == NULL) 01056 return -ENOMEM; 01057 for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) { 01058 s = dev->subdevices + NI_660X_GPCT_SUBDEV(i); 01059 if (i < ni_660x_num_counters(dev)) { 01060 s->type = COMEDI_SUBD_COUNTER; 01061 s->subdev_flags = 01062 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | 01063 SDF_CMD_READ /* | SDF_CMD_WRITE */ ; 01064 s->n_chan = 3; 01065 s->maxdata = 0xffffffff; 01066 s->insn_read = ni_660x_GPCT_rinsn; 01067 s->insn_write = ni_660x_GPCT_winsn; 01068 s->insn_config = ni_660x_GPCT_insn_config; 01069 s->do_cmd = &ni_660x_cmd; 01070 s->len_chanlist = 1; 01071 s->do_cmdtest = &ni_660x_cmdtest; 01072 s->cancel = &ni_660x_cancel; 01073 s->poll = &ni_660x_input_poll; 01074 s->async_dma_dir = DMA_BIDIRECTIONAL; 01075 s->buf_change = &ni_660x_buf_change; 01076 s->private = &private(dev)->counter_dev->counters[i]; 01077 01078 private(dev)->counter_dev->counters[i].chip_index = 01079 i / counters_per_chip; 01080 private(dev)->counter_dev->counters[i].counter_index = 01081 i % counters_per_chip; 01082 } else { 01083 s->type = COMEDI_SUBD_UNUSED; 01084 } 01085 } 01086 for (i = 0; i < board(dev)->n_chips; ++i) { 01087 init_tio_chip(dev, i); 01088 } 01089 for (i = 0; i < ni_660x_num_counters(dev); ++i) { 01090 ni_tio_init_counter(&private(dev)->counter_dev->counters[i]); 01091 } 01092 for (i = 0; i < NUM_PFI_CHANNELS; ++i) { 01093 if (i < min_counter_pfi_chan) 01094 ni_660x_set_pfi_routing(dev, i, pfi_output_select_do); 01095 else 01096 ni_660x_set_pfi_routing(dev, i, 01097 pfi_output_select_counter); 01098 ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z); 01099 } 01100 /* to be safe, set counterswap bits on tio chips after all the counter 01101 outputs have been set to high impedance mode */ 01102 for (i = 0; i < board(dev)->n_chips; ++i) { 01103 set_tio_counterswap(dev, i); 01104 } 01105 if ((ret = comedi_request_irq(mite_irq(private(dev)->mite), 01106 &ni_660x_interrupt, IRQF_SHARED, "ni_660x", 01107 dev)) < 0) { 01108 printk(" irq not available\n"); 01109 return ret; 01110 } 01111 dev->irq = mite_irq(private(dev)->mite); 01112 global_interrupt_config_bits = Global_Int_Enable_Bit; 01113 if (board(dev)->n_chips > 1) 01114 global_interrupt_config_bits |= Cascade_Int_Enable_Bit; 01115 ni_660x_write_register(dev, 0, global_interrupt_config_bits, 01116 GlobalInterruptConfigRegister); 01117 printk("attached\n"); 01118 return 0; 01119 } 01120 01121 static int ni_660x_detach(comedi_device * dev) 01122 { 01123 printk("comedi%d: ni_660x: remove\n", dev->minor); 01124 01125 /* Free irq */ 01126 if (dev->irq) 01127 comedi_free_irq(dev->irq, dev); 01128 01129 if (dev->private) { 01130 if (private(dev)->counter_dev) 01131 ni_gpct_device_destroy(private(dev)->counter_dev); 01132 if (private(dev)->mite) { 01133 ni_660x_free_mite_rings(dev); 01134 mite_unsetup(private(dev)->mite); 01135 } 01136 } 01137 return 0; 01138 } 01139 01140 static int 01141 ni_660x_GPCT_rinsn(comedi_device * dev, comedi_subdevice * s, 01142 comedi_insn * insn, lsampl_t * data) 01143 { 01144 return ni_tio_rinsn(subdev_to_counter(s), insn, data); 01145 } 01146 01147 static void init_tio_chip(comedi_device * dev, int chipset) 01148 { 01149 unsigned i; 01150 01151 // init dma configuration register 01152 private(dev)->dma_configuration_soft_copies[chipset] = 0; 01153 for (i = 0; i < MAX_DMA_CHANNEL; ++i) { 01154 private(dev)->dma_configuration_soft_copies[chipset] |= 01155 dma_select_bits(i, 01156 dma_selection_none) & dma_select_mask(i); 01157 } 01158 ni_660x_write_register(dev, chipset, 01159 private(dev)->dma_configuration_soft_copies[chipset], 01160 DMAConfigRegister); 01161 for(i = 0; i < NUM_PFI_CHANNELS; ++i) 01162 { 01163 ni_660x_write_register(dev, chipset, 0, IOConfigReg(i)); 01164 } 01165 } 01166 01167 static int 01168 ni_660x_GPCT_insn_config(comedi_device * dev, comedi_subdevice * s, 01169 comedi_insn * insn, lsampl_t * data) 01170 { 01171 return ni_tio_insn_config(subdev_to_counter(s), insn, data); 01172 } 01173 01174 static int ni_660x_GPCT_winsn(comedi_device * dev, 01175 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data) 01176 { 01177 return ni_tio_winsn(subdev_to_counter(s), insn, data); 01178 } 01179 01180 static int ni_660x_find_device(comedi_device * dev, int bus, int slot) 01181 { 01182 struct mite_struct *mite; 01183 int i; 01184 01185 for (mite = mite_devices; mite; mite = mite->next) { 01186 if (mite->used) 01187 continue; 01188 if (bus || slot) { 01189 if (bus != mite->pcidev->bus->number || 01190 slot != PCI_SLOT(mite->pcidev->devfn)) 01191 continue; 01192 } 01193 01194 for (i = 0; i < n_ni_660x_boards; i++) { 01195 if (mite_device_id(mite) == ni_660x_boards[i].dev_id) { 01196 dev->board_ptr = ni_660x_boards + i; 01197 private(dev)->mite = mite; 01198 return 0; 01199 } 01200 } 01201 } 01202 printk("no device found\n"); 01203 mite_list_devices(); 01204 return -EIO; 01205 } 01206 01207 static int ni_660x_dio_insn_bits(comedi_device * dev, 01208 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data) 01209 { 01210 unsigned base_bitfield_channel = CR_CHAN(insn->chanspec); 01211 01212 // Check if we have to write some bits 01213 if (data[0]) { 01214 s->state &= ~(data[0] << base_bitfield_channel); 01215 s->state |= (data[0] & data[1]) << base_bitfield_channel; 01216 /* Write out the new digital output lines */ 01217 ni_660x_write_register(dev, 0, s->state, DIO32Output); 01218 } 01219 /* on return, data[1] contains the value of the digital 01220 * input and output lines. */ 01221 data[1] = 01222 (ni_660x_read_register(dev, 0, 01223 DIO32Input) >> base_bitfield_channel); 01224 return 2; 01225 } 01226 01227 static void ni_660x_select_pfi_output(comedi_device * dev, unsigned pfi_channel, 01228 unsigned output_select) 01229 { 01230 static const unsigned counter_4_7_first_pfi = 8; 01231 static const unsigned counter_4_7_last_pfi = 23; 01232 unsigned active_chipset = 0; 01233 unsigned idle_chipset = 0; 01234 unsigned active_bits; 01235 unsigned idle_bits; 01236 01237 if(board(dev)->n_chips > 1) { 01238 if(output_select == pfi_output_select_counter && 01239 pfi_channel >= counter_4_7_first_pfi && 01240 pfi_channel <= counter_4_7_last_pfi) { 01241 active_chipset = 1; 01242 idle_chipset = 0; 01243 }else { 01244 active_chipset = 0; 01245 idle_chipset = 1; 01246 } 01247 } 01248 01249 if(idle_chipset != active_chipset) { 01250 idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel)); 01251 idle_bits &= ~pfi_output_select_mask(pfi_channel); 01252 idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z); 01253 ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel)); 01254 } 01255 01256 active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel)); 01257 active_bits &= ~pfi_output_select_mask(pfi_channel); 01258 active_bits |= pfi_output_select_bits(pfi_channel, output_select); 01259 ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel)); 01260 } 01261 01262 static int ni_660x_set_pfi_routing(comedi_device * dev, unsigned chan, 01263 unsigned source) 01264 { 01265 if (source > num_pfi_output_selects) 01266 return -EINVAL; 01267 if (source == pfi_output_select_high_Z) 01268 return -EINVAL; 01269 if (chan < min_counter_pfi_chan) { 01270 if (source == pfi_output_select_counter) 01271 return -EINVAL; 01272 } else if (chan > max_dio_pfi_chan) { 01273 if (source == pfi_output_select_do) 01274 return -EINVAL; 01275 } 01276 BUG_ON(chan >= NUM_PFI_CHANNELS); 01277 01278 private(dev)->pfi_output_selects[chan] = source; 01279 if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan)) 01280 ni_660x_select_pfi_output(dev, chan, 01281 private(dev)->pfi_output_selects[chan]); 01282 return 0; 01283 } 01284 01285 static unsigned ni_660x_get_pfi_routing(comedi_device * dev, unsigned chan) 01286 { 01287 BUG_ON(chan >= NUM_PFI_CHANNELS); 01288 return private(dev)->pfi_output_selects[chan]; 01289 } 01290 01291 static void ni660x_config_filter(comedi_device * dev, unsigned pfi_channel, 01292 enum ni_gpct_filter_select filter) 01293 { 01294 unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel)); 01295 bits &= ~pfi_input_select_mask(pfi_channel); 01296 bits |= pfi_input_select_bits(pfi_channel, filter); 01297 ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel)); 01298 } 01299 01300 static int ni_660x_dio_insn_config(comedi_device * dev, 01301 comedi_subdevice * s, comedi_insn * insn, lsampl_t * data) 01302 { 01303 int chan = CR_CHAN(insn->chanspec); 01304 01305 /* The input or output configuration of each digital line is 01306 * configured by a special insn_config instruction. chanspec 01307 * contains the channel to be changed, and data[0] contains the 01308 * value COMEDI_INPUT or COMEDI_OUTPUT. */ 01309 01310 switch (data[0]) { 01311 case INSN_CONFIG_DIO_OUTPUT: 01312 private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan; 01313 ni_660x_select_pfi_output(dev, chan, 01314 private(dev)->pfi_output_selects[chan]); 01315 break; 01316 case INSN_CONFIG_DIO_INPUT: 01317 private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan); 01318 ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z); 01319 break; 01320 case INSN_CONFIG_DIO_QUERY: 01321 data[1] = 01322 (private(dev)-> 01323 pfi_direction_bits & (((uint64_t) 1) << chan)) ? 01324 COMEDI_OUTPUT : COMEDI_INPUT; 01325 return 0; 01326 case INSN_CONFIG_SET_ROUTING: 01327 return ni_660x_set_pfi_routing(dev, chan, data[1]); 01328 break; 01329 case INSN_CONFIG_GET_ROUTING: 01330 data[1] = ni_660x_get_pfi_routing(dev, chan); 01331 break; 01332 case INSN_CONFIG_FILTER: 01333 ni660x_config_filter(dev, chan, data[1]); 01334 break; 01335 default: 01336 return -EINVAL; 01337 break; 01338 }; 01339 return 0; 01340 }