1/* 2 comedi/drivers/ni_tiocmd.c 3 Command support for NI general purpose counters 4 5 Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net> 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20*/ 21 22/* 23Driver: ni_tiocmd 24Description: National Instruments general purpose counters command support 25Devices: 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: Fri, 11 Apr 2008 12:32:35 +0100 32Status: works 33 34This module is not used directly by end-users. Rather, it 35is used by other drivers (for example ni_660x and ni_pcimio) 36to provide command support for NI's general purpose counters. 37It was originally split out of ni_tio.c to stop the 'ni_tio' 38module depending on the 'mite' module. 39 40References: 41DAQ 660x Register-Level Programmer Manual (NI 370505A-01) 42DAQ 6601/6602 User Manual (NI 322137B-01) 43340934b.pdf DAQ-STC reference manual 44 45*/ 46/* 47TODO: 48 Support use of both banks X and Y 49*/ 50 51#include "ni_tio_internal.h" 52#include "mite.h" 53 54MODULE_AUTHOR("Comedi <comedi@comedi.org>"); 55MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters"); 56MODULE_LICENSE("GPL"); 57 58static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, 59 short read_not_write) 60{ 61 struct ni_gpct_device *counter_dev = counter->counter_dev; 62 unsigned input_select_bits = 0; 63 64 if (enable) { 65 if (read_not_write) 66 input_select_bits |= Gi_Read_Acknowledges_Irq; 67 else 68 input_select_bits |= Gi_Write_Acknowledges_Irq; 69 } 70 ni_tio_set_bits(counter, 71 NITIO_Gi_Input_Select_Reg(counter->counter_index), 72 Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq, 73 input_select_bits); 74 switch (counter_dev->variant) { 75 case ni_gpct_variant_e_series: 76 break; 77 case ni_gpct_variant_m_series: 78 case ni_gpct_variant_660x: 79 { 80 unsigned gi_dma_config_bits = 0; 81 82 if (enable) { 83 gi_dma_config_bits |= Gi_DMA_Enable_Bit; 84 gi_dma_config_bits |= Gi_DMA_Int_Bit; 85 } 86 if (read_not_write == 0) 87 gi_dma_config_bits |= Gi_DMA_Write_Bit; 88 ni_tio_set_bits(counter, 89 NITIO_Gi_DMA_Config_Reg(counter-> 90 counter_index), 91 Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit | 92 Gi_DMA_Write_Bit, gi_dma_config_bits); 93 } 94 break; 95 } 96} 97 98static int ni_tio_input_inttrig(struct comedi_device *dev, 99 struct comedi_subdevice *s, 100 unsigned int trignum) 101{ 102 unsigned long flags; 103 int retval = 0; 104 struct ni_gpct *counter = s->private; 105 106 BUG_ON(counter == NULL); 107 if (trignum != 0) 108 return -EINVAL; 109 110 spin_lock_irqsave(&counter->lock, flags); 111 if (counter->mite_chan) 112 mite_dma_arm(counter->mite_chan); 113 else 114 retval = -EIO; 115 spin_unlock_irqrestore(&counter->lock, flags); 116 if (retval < 0) 117 return retval; 118 retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); 119 s->async->inttrig = NULL; 120 121 return retval; 122} 123 124static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) 125{ 126 struct ni_gpct_device *counter_dev = counter->counter_dev; 127 struct comedi_cmd *cmd = &async->cmd; 128 int retval = 0; 129 130 /* write alloc the entire buffer */ 131 comedi_buf_write_alloc(async, async->prealloc_bufsz); 132 counter->mite_chan->dir = COMEDI_INPUT; 133 switch (counter_dev->variant) { 134 case ni_gpct_variant_m_series: 135 case ni_gpct_variant_660x: 136 mite_prep_dma(counter->mite_chan, 32, 32); 137 break; 138 case ni_gpct_variant_e_series: 139 mite_prep_dma(counter->mite_chan, 16, 32); 140 break; 141 default: 142 BUG(); 143 break; 144 } 145 ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index), 146 Gi_Save_Trace_Bit, 0); 147 ni_tio_configure_dma(counter, 1, 1); 148 switch (cmd->start_src) { 149 case TRIG_NOW: 150 async->inttrig = NULL; 151 mite_dma_arm(counter->mite_chan); 152 retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); 153 break; 154 case TRIG_INT: 155 async->inttrig = &ni_tio_input_inttrig; 156 break; 157 case TRIG_EXT: 158 async->inttrig = NULL; 159 mite_dma_arm(counter->mite_chan); 160 retval = ni_tio_arm(counter, 1, cmd->start_arg); 161 case TRIG_OTHER: 162 async->inttrig = NULL; 163 mite_dma_arm(counter->mite_chan); 164 break; 165 default: 166 BUG(); 167 break; 168 } 169 return retval; 170} 171 172static int ni_tio_output_cmd(struct ni_gpct *counter, 173 struct comedi_async *async) 174{ 175 printk(KERN_ERR "ni_tio: output commands not yet implemented.\n"); 176 return -ENOTSUPP; 177 178 counter->mite_chan->dir = COMEDI_OUTPUT; 179 mite_prep_dma(counter->mite_chan, 32, 32); 180 ni_tio_configure_dma(counter, 1, 0); 181 mite_dma_arm(counter->mite_chan); 182 return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE); 183} 184 185static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async) 186{ 187 struct comedi_cmd *cmd = &async->cmd; 188 int set_gate_source = 0; 189 unsigned gate_source; 190 int retval = 0; 191 192 if (cmd->scan_begin_src == TRIG_EXT) { 193 set_gate_source = 1; 194 gate_source = cmd->scan_begin_arg; 195 } else if (cmd->convert_src == TRIG_EXT) { 196 set_gate_source = 1; 197 gate_source = cmd->convert_arg; 198 } 199 if (set_gate_source) 200 retval = ni_tio_set_gate_src(counter, 0, gate_source); 201 if (cmd->flags & TRIG_WAKE_EOS) { 202 ni_tio_set_bits(counter, 203 NITIO_Gi_Interrupt_Enable_Reg(counter-> 204 counter_index), 205 Gi_Gate_Interrupt_Enable_Bit(counter-> 206 counter_index), 207 Gi_Gate_Interrupt_Enable_Bit(counter-> 208 counter_index)); 209 } 210 return retval; 211} 212 213int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) 214{ 215 struct comedi_cmd *cmd = &async->cmd; 216 int retval = 0; 217 unsigned long flags; 218 219 spin_lock_irqsave(&counter->lock, flags); 220 if (counter->mite_chan == NULL) { 221 printk(KERN_ERR "ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n"); 222 retval = -EIO; 223 } else { 224 retval = ni_tio_cmd_setup(counter, async); 225 if (retval == 0) { 226 if (cmd->flags & CMDF_WRITE) 227 retval = ni_tio_output_cmd(counter, async); 228 else 229 retval = ni_tio_input_cmd(counter, async); 230 } 231 } 232 spin_unlock_irqrestore(&counter->lock, flags); 233 return retval; 234} 235EXPORT_SYMBOL_GPL(ni_tio_cmd); 236 237int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) 238{ 239 int err = 0; 240 int tmp; 241 int sources; 242 243 /* step 1: make sure trigger sources are trivially valid */ 244 245 tmp = cmd->start_src; 246 sources = TRIG_NOW | TRIG_INT | TRIG_OTHER; 247 if (ni_tio_counting_mode_registers_present(counter->counter_dev)) 248 sources |= TRIG_EXT; 249 cmd->start_src &= sources; 250 if (!cmd->start_src || tmp != cmd->start_src) 251 err++; 252 253 tmp = cmd->scan_begin_src; 254 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER; 255 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 256 err++; 257 258 tmp = cmd->convert_src; 259 sources = TRIG_NOW | TRIG_EXT | TRIG_OTHER; 260 cmd->convert_src &= sources; 261 if (!cmd->convert_src || tmp != cmd->convert_src) 262 err++; 263 264 tmp = cmd->scan_end_src; 265 cmd->scan_end_src &= TRIG_COUNT; 266 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 267 err++; 268 269 tmp = cmd->stop_src; 270 cmd->stop_src &= TRIG_NONE; 271 if (!cmd->stop_src || tmp != cmd->stop_src) 272 err++; 273 274 if (err) 275 return 1; 276 277 /* step 2: make sure trigger sources are unique... */ 278 279 if (cmd->start_src != TRIG_NOW && 280 cmd->start_src != TRIG_INT && 281 cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_OTHER) 282 err++; 283 if (cmd->scan_begin_src != TRIG_FOLLOW && 284 cmd->scan_begin_src != TRIG_EXT && 285 cmd->scan_begin_src != TRIG_OTHER) 286 err++; 287 if (cmd->convert_src != TRIG_OTHER && 288 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 289 err++; 290 if (cmd->stop_src != TRIG_NONE) 291 err++; 292 /* ... and mutually compatible */ 293 if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW) 294 err++; 295 296 if (err) 297 return 2; 298 299 /* step 3: make sure arguments are trivially compatible */ 300 if (cmd->start_src != TRIG_EXT) { 301 if (cmd->start_arg != 0) { 302 cmd->start_arg = 0; 303 err++; 304 } 305 } 306 if (cmd->scan_begin_src != TRIG_EXT) { 307 if (cmd->scan_begin_arg) { 308 cmd->scan_begin_arg = 0; 309 err++; 310 } 311 } 312 if (cmd->convert_src != TRIG_EXT) { 313 if (cmd->convert_arg) { 314 cmd->convert_arg = 0; 315 err++; 316 } 317 } 318 319 if (cmd->scan_end_arg != cmd->chanlist_len) { 320 cmd->scan_end_arg = cmd->chanlist_len; 321 err++; 322 } 323 324 if (cmd->stop_src == TRIG_NONE) { 325 if (cmd->stop_arg != 0) { 326 cmd->stop_arg = 0; 327 err++; 328 } 329 } 330 331 if (err) 332 return 3; 333 334 /* step 4: fix up any arguments */ 335 336 if (err) 337 return 4; 338 339 return 0; 340} 341EXPORT_SYMBOL_GPL(ni_tio_cmdtest); 342 343int ni_tio_cancel(struct ni_gpct *counter) 344{ 345 unsigned long flags; 346 347 ni_tio_arm(counter, 0, 0); 348 spin_lock_irqsave(&counter->lock, flags); 349 if (counter->mite_chan) 350 mite_dma_disarm(counter->mite_chan); 351 spin_unlock_irqrestore(&counter->lock, flags); 352 ni_tio_configure_dma(counter, 0, 0); 353 354 ni_tio_set_bits(counter, 355 NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), 356 Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), 357 0x0); 358 return 0; 359} 360EXPORT_SYMBOL_GPL(ni_tio_cancel); 361 362 /* During buffered input counter operation for e-series, the gate 363 interrupt is acked automatically by the dma controller, due to the 364 Gi_Read/Write_Acknowledges_IRQ bits in the input select register. */ 365static int should_ack_gate(struct ni_gpct *counter) 366{ 367 unsigned long flags; 368 int retval = 0; 369 370 switch (counter->counter_dev->variant) { 371 case ni_gpct_variant_m_series: 372 /* not sure if 660x really supports gate 373 interrupts (the bits are not listed 374 in register-level manual) */ 375 case ni_gpct_variant_660x: 376 return 1; 377 break; 378 case ni_gpct_variant_e_series: 379 spin_lock_irqsave(&counter->lock, flags); 380 { 381 if (counter->mite_chan == NULL || 382 counter->mite_chan->dir != COMEDI_INPUT || 383 (mite_done(counter->mite_chan))) { 384 retval = 1; 385 } 386 } 387 spin_unlock_irqrestore(&counter->lock, flags); 388 break; 389 } 390 return retval; 391} 392 393void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, 394 int *tc_error, int *perm_stale_data, 395 int *stale_data) 396{ 397 const unsigned short gxx_status = read_register(counter, 398 NITIO_Gxx_Status_Reg 399 (counter-> 400 counter_index)); 401 const unsigned short gi_status = read_register(counter, 402 NITIO_Gi_Status_Reg 403 (counter-> 404 counter_index)); 405 unsigned ack = 0; 406 407 if (gate_error) 408 *gate_error = 0; 409 if (tc_error) 410 *tc_error = 0; 411 if (perm_stale_data) 412 *perm_stale_data = 0; 413 if (stale_data) 414 *stale_data = 0; 415 416 if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) { 417 ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index); 418 if (gate_error) { 419 /*660x don't support automatic acknowledgement 420 of gate interrupt via dma read/write 421 and report bogus gate errors */ 422 if (counter->counter_dev->variant != 423 ni_gpct_variant_660x) { 424 *gate_error = 1; 425 } 426 } 427 } 428 if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) { 429 ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index); 430 if (tc_error) 431 *tc_error = 1; 432 } 433 if (gi_status & Gi_TC_Bit) 434 ack |= Gi_TC_Interrupt_Ack_Bit; 435 if (gi_status & Gi_Gate_Interrupt_Bit) { 436 if (should_ack_gate(counter)) 437 ack |= Gi_Gate_Interrupt_Ack_Bit; 438 } 439 if (ack) 440 write_register(counter, ack, 441 NITIO_Gi_Interrupt_Acknowledge_Reg 442 (counter->counter_index)); 443 if (ni_tio_get_soft_copy 444 (counter, 445 NITIO_Gi_Mode_Reg(counter->counter_index)) & 446 Gi_Loading_On_Gate_Bit) { 447 if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) { 448 if (stale_data) 449 *stale_data = 1; 450 } 451 if (read_register(counter, 452 NITIO_Gxx_Joint_Status2_Reg 453 (counter->counter_index)) & 454 Gi_Permanent_Stale_Bit(counter->counter_index)) { 455 printk(KERN_INFO "%s: Gi_Permanent_Stale_Data detected.\n", 456 __func__); 457 if (perm_stale_data) 458 *perm_stale_data = 1; 459 } 460 } 461} 462EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm); 463 464void ni_tio_handle_interrupt(struct ni_gpct *counter, 465 struct comedi_subdevice *s) 466{ 467 unsigned gpct_mite_status; 468 unsigned long flags; 469 int gate_error; 470 int tc_error; 471 int perm_stale_data; 472 473 ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, 474 &perm_stale_data, NULL); 475 if (gate_error) { 476 printk(KERN_NOTICE "%s: Gi_Gate_Error detected.\n", __func__); 477 s->async->events |= COMEDI_CB_OVERFLOW; 478 } 479 if (perm_stale_data) 480 s->async->events |= COMEDI_CB_ERROR; 481 switch (counter->counter_dev->variant) { 482 case ni_gpct_variant_m_series: 483 case ni_gpct_variant_660x: 484 if (read_register(counter, 485 NITIO_Gi_DMA_Status_Reg 486 (counter->counter_index)) & Gi_DRQ_Error_Bit) { 487 printk(KERN_NOTICE "%s: Gi_DRQ_Error detected.\n", 488 __func__); 489 s->async->events |= COMEDI_CB_OVERFLOW; 490 } 491 break; 492 case ni_gpct_variant_e_series: 493 break; 494 } 495 spin_lock_irqsave(&counter->lock, flags); 496 if (counter->mite_chan == NULL) { 497 spin_unlock_irqrestore(&counter->lock, flags); 498 return; 499 } 500 gpct_mite_status = mite_get_status(counter->mite_chan); 501 if (gpct_mite_status & CHSR_LINKC) { 502 writel(CHOR_CLRLC, 503 counter->mite_chan->mite->mite_io_addr + 504 MITE_CHOR(counter->mite_chan->channel)); 505 } 506 mite_sync_input_dma(counter->mite_chan, s->async); 507 spin_unlock_irqrestore(&counter->lock, flags); 508} 509EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt); 510 511void ni_tio_set_mite_channel(struct ni_gpct *counter, 512 struct mite_channel *mite_chan) 513{ 514 unsigned long flags; 515 516 spin_lock_irqsave(&counter->lock, flags); 517 counter->mite_chan = mite_chan; 518 spin_unlock_irqrestore(&counter->lock, flags); 519} 520EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel); 521 522static int __init ni_tiocmd_init_module(void) 523{ 524 return 0; 525} 526 527module_init(ni_tiocmd_init_module); 528 529static void __exit ni_tiocmd_cleanup_module(void) 530{ 531} 532 533module_exit(ni_tiocmd_cleanup_module); 534