adl_pci9118.c revision a285bf995da256be5d96110ec0e7592cb6b2e600
1/* 2 * comedi/drivers/adl_pci9118.c 3 * 4 * hardware driver for ADLink cards: 5 * card: PCI-9118DG, PCI-9118HG, PCI-9118HR 6 * driver: pci9118dg, pci9118hg, pci9118hr 7 * 8 * Author: Michal Dobes <dobes@tesnet.cz> 9 * 10*/ 11/* 12Driver: adl_pci9118 13Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR 14Author: Michal Dobes <dobes@tesnet.cz> 15Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg), 16 PCI-9118HR (pci9118hr) 17Status: works 18 19This driver supports AI, AO, DI and DO subdevices. 20AI subdevice supports cmd and insn interface, 21other subdevices support only insn interface. 22For AI: 23- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46). 24- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44). 25- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46). 26- It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but 27 cmd.scan_end_arg modulo cmd.chanlist_len must by 0. 28- If return value of cmdtest is 5 then you've bad channel list 29 (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar 30 ranges). 31 32There are some hardware limitations: 33a) You cann't use mixture of unipolar/bipoar ranges or differencial/single 34 ended inputs. 35b) DMA transfers must have the length aligned to two samples (32 bit), 36 so there is some problems if cmd->chanlist_len is odd. This driver tries 37 bypass this with adding one sample to the end of the every scan and discard 38 it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW 39 and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode 40 with interrupt after every sample. 41c) If isn't used DMA then you can use only mode where 42 cmd->scan_begin_src=TRIG_FOLLOW. 43 44Configuration options: 45 [0] - PCI bus of device (optional) 46 [1] - PCI slot of device (optional) 47 If bus/slot is not specified, then first available PCI 48 card will be used. 49 [2] - 0= standard 8 DIFF/16 SE channels configuration 50 n = external multiplexer connected, 1 <= n <= 256 51 [3] - 0=autoselect DMA or EOC interrupts operation 52 1 = disable DMA mode 53 3 = disable DMA and INT, only insn interface will work 54 [4] - sample&hold signal - card can generate signal for external S&H board 55 0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic 56 0 != use ADCHN7(pin 23) signal is generated from driver, number say how 57 long delay is requested in ns and sign polarity of the hold 58 (in this case external multiplexor can serve only 128 channels) 59 [5] - 0=stop measure on all hardware errors 60 2 | = ignore ADOR - A/D Overrun status 61 8|=ignore Bover - A/D Burst Mode Overrun status 62 256|=ignore nFull - A/D FIFO Full status 63 64*/ 65#include "../comedidev.h" 66 67#include <linux/delay.h> 68#include <linux/gfp.h> 69#include <linux/interrupt.h> 70 71#include "amcc_s5933.h" 72#include "8253.h" 73#include "comedi_pci.h" 74#include "comedi_fc.h" 75 76#define PCI_VENDOR_ID_AMCC 0x10e8 77 78/* paranoid checks are broken */ 79#undef PCI9118_PARANOIDCHECK /* 80 * if defined, then is used code which control 81 * correct channel number on every 12 bit sample 82 */ 83 84#undef PCI9118_EXTDEBUG /* 85 * if defined then driver prints 86 * a lot of messages 87 */ 88 89#undef DPRINTK 90#ifdef PCI9118_EXTDEBUG 91#define DPRINTK(fmt, args...) printk(fmt, ## args) 92#else 93#define DPRINTK(fmt, args...) 94#endif 95 96#define IORANGE_9118 64 /* I hope */ 97#define PCI9118_CHANLEN 255 /* 98 * len of chanlist, some source say 256, 99 * but reality looks like 255 :-( 100 */ 101 102#define PCI9118_CNT0 0x00 /* R/W: 8254 counter 0 */ 103#define PCI9118_CNT1 0x04 /* R/W: 8254 counter 0 */ 104#define PCI9118_CNT2 0x08 /* R/W: 8254 counter 0 */ 105#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */ 106#define PCI9118_AD_DATA 0x10 /* R: A/D data */ 107#define PCI9118_DA1 0x10 /* W: D/A registers */ 108#define PCI9118_DA2 0x14 109#define PCI9118_ADSTAT 0x18 /* R: A/D status register */ 110#define PCI9118_ADCNTRL 0x18 /* W: A/D control register */ 111#define PCI9118_DI 0x1c /* R: digi input register */ 112#define PCI9118_DO 0x1c /* W: digi output register */ 113#define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */ 114#define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */ 115#define PCI9118_BURST 0x28 /* W: A/D burst number register */ 116#define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */ 117#define PCI9118_ADFUNC 0x30 /* W: A/D function register */ 118#define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */ 119#define PCI9118_INTSRC 0x38 /* R: interrupt reason register */ 120#define PCI9118_INTCTRL 0x38 /* W: interrupt control register */ 121 122/* bits from A/D control register (PCI9118_ADCNTRL) */ 123#define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */ 124#define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */ 125#define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */ 126#define AdControl_ExtG 0x10 /* 127 * 1=8254 countrol controlled by TGIN(pin 46), 128 * 0=controlled by SoftG 129 */ 130#define AdControl_ExtM 0x08 /* 131 * 1=external hardware trigger (pin 44), 132 * 0=internal trigger 133 */ 134#define AdControl_TmrTr 0x04 /* 135 * 1=8254 is iternal trigger source, 136 * 0=software trigger is source 137 * (register PCI9118_SOFTTRG) 138 */ 139#define AdControl_Int 0x02 /* 1=enable INT, 0=disable */ 140#define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */ 141 142/* bits from A/D function register (PCI9118_ADFUNC) */ 143#define AdFunction_PDTrg 0x80 /* 144 * 1=positive, 145 * 0=negative digital trigger 146 * (only positive is correct) 147 */ 148#define AdFunction_PETrg 0x40 /* 149 * 1=positive, 150 * 0=negative external trigger 151 * (only positive is correct) 152 */ 153#define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */ 154#define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */ 155#define AdFunction_BS 0x08 /* 156 * 1=burst mode start, 157 * 0=burst mode stop 158 */ 159#define AdFunction_PM 0x04 /* 160 * 1=post trigger mode, 161 * 0=not post trigger 162 */ 163#define AdFunction_AM 0x02 /* 164 * 1=about trigger mode, 165 * 0=not about trigger 166 */ 167#define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */ 168 169/* bits from A/D status register (PCI9118_ADSTAT) */ 170#define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */ 171#define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */ 172#define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */ 173#define AdStatus_Acmp 0x020 /* */ 174#define AdStatus_DTH 0x010 /* 1=external digital trigger */ 175#define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */ 176#define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */ 177#define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */ 178#define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */ 179 180/* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */ 181/* 1=interrupt occur, enable source, 0=interrupt not occur, disable source */ 182#define Int_Timer 0x08 /* timer interrupt */ 183#define Int_About 0x04 /* about trigger complete */ 184#define Int_Hfull 0x02 /* A/D FIFO hlaf full */ 185#define Int_DTrg 0x01 /* external digital trigger */ 186 187#define START_AI_EXT 0x01 /* start measure on external trigger */ 188#define STOP_AI_EXT 0x02 /* stop measure on external trigger */ 189#define START_AI_INT 0x04 /* start measure on internal trigger */ 190#define STOP_AI_INT 0x08 /* stop measure on internal trigger */ 191 192#define EXTTRG_AI 0 /* ext trg is used by AI */ 193 194static const struct comedi_lrange range_pci9118dg_hr = { 8, { 195 BIP_RANGE(5), 196 BIP_RANGE(2.5), 197 BIP_RANGE(1.25), 198 BIP_RANGE(0.625), 199 UNI_RANGE(10), 200 UNI_RANGE(5), 201 UNI_RANGE(2.5), 202 UNI_RANGE(1.25) 203 } 204}; 205 206static const struct comedi_lrange range_pci9118hg = { 8, { 207 BIP_RANGE(5), 208 BIP_RANGE(0.5), 209 BIP_RANGE(0.05), 210 BIP_RANGE(0.005), 211 UNI_RANGE(10), 212 UNI_RANGE(1), 213 UNI_RANGE(0.1), 214 UNI_RANGE(0.01) 215 } 216}; 217 218#define PCI9118_BIPOLAR_RANGES 4 /* 219 * used for test on mixture 220 * of BIP/UNI ranges 221 */ 222 223static int pci9118_attach(struct comedi_device *dev, 224 struct comedi_devconfig *it); 225static int pci9118_detach(struct comedi_device *dev); 226 227struct boardtype { 228 const char *name; /* board name */ 229 int vendor_id; /* PCI vendor a device ID of card */ 230 int device_id; 231 int iorange_amcc; /* iorange for own S5933 region */ 232 int iorange_9118; /* pass thru card region size */ 233 int n_aichan; /* num of A/D chans */ 234 int n_aichand; /* num of A/D chans in diff mode */ 235 int mux_aichan; /* 236 * num of A/D chans with 237 * external multiplexor 238 */ 239 int n_aichanlist; /* len of chanlist */ 240 int n_aochan; /* num of D/A chans */ 241 int ai_maxdata; /* resolution of A/D */ 242 int ao_maxdata; /* resolution of D/A */ 243 const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */ 244 const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */ 245 unsigned int ai_ns_min; /* max sample speed of card v ns */ 246 unsigned int ai_pacer_min; /* 247 * minimal pacer value 248 * (c1*c2 or c1 in burst) 249 */ 250 int half_fifo_size; /* size of FIFO/2 */ 251 252}; 253 254static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = { 255 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) }, 256 { 0 } 257}; 258 259MODULE_DEVICE_TABLE(pci, pci9118_pci_table); 260 261static const struct boardtype boardtypes[] = { 262 {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9, 263 AMCC_OP_REG_SIZE, IORANGE_9118, 264 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff, 265 &range_pci9118dg_hr, &range_bipolar10, 266 3000, 12, 512}, 267 {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9, 268 AMCC_OP_REG_SIZE, IORANGE_9118, 269 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff, 270 &range_pci9118hg, &range_bipolar10, 271 3000, 12, 512}, 272 {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9, 273 AMCC_OP_REG_SIZE, IORANGE_9118, 274 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff, 275 &range_pci9118dg_hr, &range_bipolar10, 276 10000, 40, 512}, 277}; 278 279#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype)) 280 281static struct comedi_driver driver_pci9118 = { 282 .driver_name = "adl_pci9118", 283 .module = THIS_MODULE, 284 .attach = pci9118_attach, 285 .detach = pci9118_detach, 286 .num_names = n_boardtypes, 287 .board_name = &boardtypes[0].name, 288 .offset = sizeof(struct boardtype), 289}; 290 291static int __devinit driver_pci9118_pci_probe(struct pci_dev *dev, 292 const struct pci_device_id *ent) 293{ 294 return comedi_pci_auto_config(dev, driver_pci9118.driver_name); 295} 296 297static void __devexit driver_pci9118_pci_remove(struct pci_dev *dev) 298{ 299 comedi_pci_auto_unconfig(dev); 300} 301 302static struct pci_driver driver_pci9118_pci_driver = { 303 .id_table = pci9118_pci_table, 304 .probe = &driver_pci9118_pci_probe, 305 .remove = __devexit_p(&driver_pci9118_pci_remove) 306}; 307 308static int __init driver_pci9118_init_module(void) 309{ 310 int retval; 311 312 retval = comedi_driver_register(&driver_pci9118); 313 if (retval < 0) 314 return retval; 315 316 driver_pci9118_pci_driver.name = (char *)driver_pci9118.driver_name; 317 return pci_register_driver(&driver_pci9118_pci_driver); 318} 319 320static void __exit driver_pci9118_cleanup_module(void) 321{ 322 pci_unregister_driver(&driver_pci9118_pci_driver); 323 comedi_driver_unregister(&driver_pci9118); 324} 325 326module_init(driver_pci9118_init_module); 327module_exit(driver_pci9118_cleanup_module); 328 329struct pci9118_private { 330 unsigned long iobase_a; /* base+size for AMCC chip */ 331 unsigned int master; /* master capable */ 332 struct pci_dev *pcidev; /* ptr to actual pcidev */ 333 unsigned int usemux; /* we want to use external multiplexor! */ 334#ifdef PCI9118_PARANOIDCHECK 335 unsigned short chanlist[PCI9118_CHANLEN + 1]; /* 336 * list of 337 * scanned channel 338 */ 339 unsigned char chanlistlen; /* number of scanlist */ 340#endif 341 unsigned char AdControlReg; /* A/D control register */ 342 unsigned char IntControlReg; /* Interrupt control register */ 343 unsigned char AdFunctionReg; /* A/D function register */ 344 char valid; /* driver is ok */ 345 char ai_neverending; /* we do unlimited AI */ 346 unsigned int i8254_osc_base; /* frequence of onboard oscilator */ 347 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */ 348 unsigned int ai_act_scan; /* how many scans we finished */ 349 unsigned int ai_buf_ptr; /* data buffer ptr in samples */ 350 unsigned int ai_n_chan; /* how many channels is measured */ 351 unsigned int ai_n_scanlen; /* len of actual scanlist */ 352 unsigned int ai_n_realscanlen; /* 353 * what we must transfer for one 354 * outgoing scan include front/back adds 355 */ 356 unsigned int ai_act_dmapos; /* position in actual real stream */ 357 unsigned int ai_add_front; /* 358 * how many channels we must add 359 * before scan to satisfy S&H? 360 */ 361 unsigned int ai_add_back; /* 362 * how many channels we must add 363 * before scan to satisfy DMA? 364 */ 365 unsigned int *ai_chanlist; /* actual chanlist */ 366 unsigned int ai_timer1; 367 unsigned int ai_timer2; 368 unsigned int ai_flags; 369 char ai12_startstop; /* 370 * measure can start/stop 371 * on external trigger 372 */ 373 unsigned int ai_divisor1, ai_divisor2; /* 374 * divisors for start of measure 375 * on external start 376 */ 377 unsigned int ai_data_len; 378 short *ai_data; 379 short ao_data[2]; /* data output buffer */ 380 unsigned int ai_scans; /* number of scans to do */ 381 char dma_doublebuf; /* we can use double buffring */ 382 unsigned int dma_actbuf; /* which buffer is used now */ 383 short *dmabuf_virt[2]; /* 384 * pointers to begin of 385 * DMA buffer 386 */ 387 unsigned long dmabuf_hw[2]; /* hw address of DMA buff */ 388 unsigned int dmabuf_size[2]; /* 389 * size of dma buffer in bytes 390 */ 391 unsigned int dmabuf_use_size[2]; /* 392 * which size we may now use 393 * for transfer 394 */ 395 unsigned int dmabuf_used_size[2]; /* which size was truly used */ 396 unsigned int dmabuf_panic_size[2]; 397 unsigned int dmabuf_samples[2]; /* size in samples */ 398 int dmabuf_pages[2]; /* number of pages in buffer */ 399 unsigned char cnt0_users; /* 400 * bit field of 8254 CNT0 users 401 * (0-unused, 1-AO, 2-DI, 3-DO) 402 */ 403 unsigned char exttrg_users; /* 404 * bit field of external trigger 405 * users(0-AI, 1-AO, 2-DI, 3-DO) 406 */ 407 unsigned int cnt0_divisor; /* actual CNT0 divisor */ 408 void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, 409 unsigned short, 410 unsigned int, 411 unsigned short); /* 412 * ptr to actual interrupt 413 * AI function 414 */ 415 unsigned char ai16bits; /* =1 16 bit card */ 416 unsigned char usedma; /* =1 use DMA transfer and not INT */ 417 unsigned char useeoshandle; /* 418 * =1 change WAKE_EOS DMA transfer 419 * to fit on every second 420 */ 421 unsigned char usessh; /* =1 turn on S&H support */ 422 int softsshdelay; /* 423 * >0 use software S&H, 424 * numer is requested delay in ns 425 */ 426 unsigned char softsshsample; /* 427 * polarity of S&H signal 428 * in sample state 429 */ 430 unsigned char softsshhold; /* 431 * polarity of S&H signal 432 * in hold state 433 */ 434 unsigned int ai_maskerr; /* which warning was printed */ 435 unsigned int ai_maskharderr; /* on which error bits stops */ 436 unsigned int ai_inttrig_start; /* TRIG_INT for start */ 437}; 438 439#define devpriv ((struct pci9118_private *)dev->private) 440#define this_board ((struct boardtype *)dev->board_ptr) 441 442/* 443============================================================================== 444*/ 445 446static int check_channel_list(struct comedi_device *dev, 447 struct comedi_subdevice *s, int n_chan, 448 unsigned int *chanlist, int frontadd, 449 int backadd); 450static int setup_channel_list(struct comedi_device *dev, 451 struct comedi_subdevice *s, int n_chan, 452 unsigned int *chanlist, int rot, int frontadd, 453 int backadd, int usedma, char eoshandle); 454static void start_pacer(struct comedi_device *dev, int mode, 455 unsigned int divisor1, unsigned int divisor2); 456static int pci9118_reset(struct comedi_device *dev); 457static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source); 458static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source); 459static int pci9118_ai_cancel(struct comedi_device *dev, 460 struct comedi_subdevice *s); 461static void pci9118_calc_divisors(char mode, struct comedi_device *dev, 462 struct comedi_subdevice *s, 463 unsigned int *tim1, unsigned int *tim2, 464 unsigned int flags, int chans, 465 unsigned int *div1, unsigned int *div2, 466 char usessh, unsigned int chnsshfront); 467 468/* 469============================================================================== 470*/ 471static int pci9118_insn_read_ai(struct comedi_device *dev, 472 struct comedi_subdevice *s, 473 struct comedi_insn *insn, unsigned int *data) 474{ 475 476 int n, timeout; 477 478 devpriv->AdControlReg = AdControl_Int & 0xff; 479 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 480 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 481 /* 482 * positive triggers, no S&H, 483 * no burst, burst stop, 484 * no post trigger, 485 * no about trigger, 486 * trigger stop 487 */ 488 489 if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0)) 490 return -EINVAL; 491 492 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 493 494 for (n = 0; n < insn->n; n++) { 495 outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */ 496 udelay(2); 497 timeout = 100; 498 while (timeout--) { 499 if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy) 500 goto conv_finish; 501 udelay(1); 502 } 503 504 comedi_error(dev, "A/D insn timeout"); 505 data[n] = 0; 506 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 507 return -ETIME; 508 509conv_finish: 510 if (devpriv->ai16bits) { 511 data[n] = 512 (inl(dev->iobase + 513 PCI9118_AD_DATA) & 0xffff) ^ 0x8000; 514 } else { 515 data[n] = 516 (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff; 517 } 518 } 519 520 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 521 return n; 522 523} 524 525/* 526============================================================================== 527*/ 528static int pci9118_insn_write_ao(struct comedi_device *dev, 529 struct comedi_subdevice *s, 530 struct comedi_insn *insn, unsigned int *data) 531{ 532 int n, chanreg, ch; 533 534 ch = CR_CHAN(insn->chanspec); 535 if (ch) 536 chanreg = PCI9118_DA2; 537 else 538 chanreg = PCI9118_DA1; 539 540 541 for (n = 0; n < insn->n; n++) { 542 outl(data[n], dev->iobase + chanreg); 543 devpriv->ao_data[ch] = data[n]; 544 } 545 546 return n; 547} 548 549/* 550============================================================================== 551*/ 552static int pci9118_insn_read_ao(struct comedi_device *dev, 553 struct comedi_subdevice *s, 554 struct comedi_insn *insn, unsigned int *data) 555{ 556 int n, chan; 557 558 chan = CR_CHAN(insn->chanspec); 559 for (n = 0; n < insn->n; n++) 560 data[n] = devpriv->ao_data[chan]; 561 562 return n; 563} 564 565/* 566============================================================================== 567*/ 568static int pci9118_insn_bits_di(struct comedi_device *dev, 569 struct comedi_subdevice *s, 570 struct comedi_insn *insn, unsigned int *data) 571{ 572 data[1] = inl(dev->iobase + PCI9118_DI) & 0xf; 573 574 return 2; 575} 576 577/* 578============================================================================== 579*/ 580static int pci9118_insn_bits_do(struct comedi_device *dev, 581 struct comedi_subdevice *s, 582 struct comedi_insn *insn, unsigned int *data) 583{ 584 if (data[0]) { 585 s->state &= ~data[0]; 586 s->state |= (data[0] & data[1]); 587 outl(s->state & 0x0f, dev->iobase + PCI9118_DO); 588 } 589 data[1] = s->state; 590 591 return 2; 592} 593 594/* 595============================================================================== 596*/ 597static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev) 598{ 599 devpriv->AdFunctionReg = 600 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM; 601 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 602 outl(0x30, dev->iobase + PCI9118_CNTCTRL); 603 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff, 604 dev->iobase + PCI9118_CNT0); 605 outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff, 606 dev->iobase + PCI9118_CNT0); 607 devpriv->AdFunctionReg |= AdFunction_Start; 608 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 609} 610 611static unsigned int defragment_dma_buffer(struct comedi_device *dev, 612 struct comedi_subdevice *s, 613 short *dma_buffer, 614 unsigned int num_samples) 615{ 616 unsigned int i = 0, j = 0; 617 unsigned int start_pos = devpriv->ai_add_front, 618 stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan; 619 unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan + 620 devpriv->ai_add_back; 621 622 for (i = 0; i < num_samples; i++) { 623 if (devpriv->ai_act_dmapos >= start_pos && 624 devpriv->ai_act_dmapos < stop_pos) { 625 dma_buffer[j++] = dma_buffer[i]; 626 } 627 devpriv->ai_act_dmapos++; 628 devpriv->ai_act_dmapos %= raw_scanlen; 629 } 630 631 return j; 632} 633 634/* 635============================================================================== 636*/ 637static int move_block_from_dma(struct comedi_device *dev, 638 struct comedi_subdevice *s, 639 short *dma_buffer, 640 unsigned int num_samples) 641{ 642 unsigned int num_bytes; 643 644 num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples); 645 devpriv->ai_act_scan += 646 (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen; 647 s->async->cur_chan += num_samples; 648 s->async->cur_chan %= devpriv->ai_n_scanlen; 649 num_bytes = 650 cfc_write_array_to_buffer(s, dma_buffer, 651 num_samples * sizeof(short)); 652 if (num_bytes < num_samples * sizeof(short)) 653 return -1; 654 return 0; 655} 656 657/* 658============================================================================== 659*/ 660static char pci9118_decode_error_status(struct comedi_device *dev, 661 struct comedi_subdevice *s, 662 unsigned char m) 663{ 664 if (m & 0x100) { 665 comedi_error(dev, "A/D FIFO Full status (Fatal Error!)"); 666 devpriv->ai_maskerr &= ~0x100L; 667 } 668 if (m & 0x008) { 669 comedi_error(dev, 670 "A/D Burst Mode Overrun Status (Fatal Error!)"); 671 devpriv->ai_maskerr &= ~0x008L; 672 } 673 if (m & 0x004) { 674 comedi_error(dev, "A/D Over Speed Status (Warning!)"); 675 devpriv->ai_maskerr &= ~0x004L; 676 } 677 if (m & 0x002) { 678 comedi_error(dev, "A/D Overrun Status (Fatal Error!)"); 679 devpriv->ai_maskerr &= ~0x002L; 680 } 681 if (m & devpriv->ai_maskharderr) { 682 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 683 pci9118_ai_cancel(dev, s); 684 comedi_event(dev, s); 685 return 1; 686 } 687 688 return 0; 689} 690 691static void pci9118_ai_munge(struct comedi_device *dev, 692 struct comedi_subdevice *s, void *data, 693 unsigned int num_bytes, 694 unsigned int start_chan_index) 695{ 696 unsigned int i, num_samples = num_bytes / sizeof(short); 697 short *array = data; 698 699 for (i = 0; i < num_samples; i++) { 700 if (devpriv->usedma) 701 array[i] = be16_to_cpu(array[i]); 702 if (devpriv->ai16bits) 703 array[i] ^= 0x8000; 704 else 705 array[i] = (array[i] >> 4) & 0x0fff; 706 707 } 708} 709 710/* 711============================================================================== 712*/ 713static void interrupt_pci9118_ai_onesample(struct comedi_device *dev, 714 struct comedi_subdevice *s, 715 unsigned short int_adstat, 716 unsigned int int_amcc, 717 unsigned short int_daq) 718{ 719 register short sampl; 720 721 s->async->events = 0; 722 723 if (int_adstat & devpriv->ai_maskerr) 724 if (pci9118_decode_error_status(dev, s, int_adstat)) 725 return; 726 727 sampl = inw(dev->iobase + PCI9118_AD_DATA); 728 729#ifdef PCI9118_PARANOIDCHECK 730 if (devpriv->ai16bits == 0) { 731 if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { 732 /* data dropout! */ 733 printk 734 ("comedi: A/D SAMPL - data dropout: " 735 "received channel %d, expected %d!\n", 736 sampl & 0x000f, 737 devpriv->chanlist[s->async->cur_chan]); 738 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 739 pci9118_ai_cancel(dev, s); 740 comedi_event(dev, s); 741 return; 742 } 743 } 744#endif 745 cfc_write_to_buffer(s, sampl); 746 s->async->cur_chan++; 747 if (s->async->cur_chan >= devpriv->ai_n_scanlen) { 748 /* one scan done */ 749 s->async->cur_chan %= devpriv->ai_n_scanlen; 750 devpriv->ai_act_scan++; 751 if (!(devpriv->ai_neverending)) 752 if (devpriv->ai_act_scan >= devpriv->ai_scans) { 753 /* all data sampled */ 754 pci9118_ai_cancel(dev, s); 755 s->async->events |= COMEDI_CB_EOA; 756 } 757 } 758 759 if (s->async->events) 760 comedi_event(dev, s); 761} 762 763/* 764============================================================================== 765*/ 766static void interrupt_pci9118_ai_dma(struct comedi_device *dev, 767 struct comedi_subdevice *s, 768 unsigned short int_adstat, 769 unsigned int int_amcc, 770 unsigned short int_daq) 771{ 772 unsigned int next_dma_buf, samplesinbuf, sampls, m; 773 774 if (int_amcc & MASTER_ABORT_INT) { 775 comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!"); 776 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 777 pci9118_ai_cancel(dev, s); 778 comedi_event(dev, s); 779 return; 780 } 781 782 if (int_amcc & TARGET_ABORT_INT) { 783 comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!"); 784 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 785 pci9118_ai_cancel(dev, s); 786 comedi_event(dev, s); 787 return; 788 } 789 if (int_adstat & devpriv->ai_maskerr) 790 /* if (int_adstat & 0x106) */ 791 if (pci9118_decode_error_status(dev, s, int_adstat)) 792 return; 793 794 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; 795 /* number of received real samples */ 796/* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */ 797 798 if (devpriv->dma_doublebuf) { /* 799 * switch DMA buffers if is used 800 * double buffering 801 */ 802 next_dma_buf = 1 - devpriv->dma_actbuf; 803 outl(devpriv->dmabuf_hw[next_dma_buf], 804 devpriv->iobase_a + AMCC_OP_REG_MWAR); 805 outl(devpriv->dmabuf_use_size[next_dma_buf], 806 devpriv->iobase_a + AMCC_OP_REG_MWTC); 807 devpriv->dmabuf_used_size[next_dma_buf] = 808 devpriv->dmabuf_use_size[next_dma_buf]; 809 if (devpriv->ai_do == 4) 810 interrupt_pci9118_ai_mode4_switch(dev); 811 } 812 813 if (samplesinbuf) { 814 m = devpriv->ai_data_len >> 1; /* 815 * how many samples is to 816 * end of buffer 817 */ 818/* 819 * DPRINTK("samps=%d m=%d %d %d\n", 820 * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); 821 */ 822 sampls = m; 823 move_block_from_dma(dev, s, 824 devpriv->dmabuf_virt[devpriv->dma_actbuf], 825 samplesinbuf); 826 m = m - sampls; /* m= how many samples was transfered */ 827 } 828/* DPRINTK("YYY\n"); */ 829 830 if (!devpriv->ai_neverending) 831 if (devpriv->ai_act_scan >= devpriv->ai_scans) { 832 /* all data sampled */ 833 pci9118_ai_cancel(dev, s); 834 s->async->events |= COMEDI_CB_EOA; 835 } 836 837 if (devpriv->dma_doublebuf) { /* switch dma buffers */ 838 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf; 839 } else { /* restart DMA if is not used double buffering */ 840 outl(devpriv->dmabuf_hw[0], 841 devpriv->iobase_a + AMCC_OP_REG_MWAR); 842 outl(devpriv->dmabuf_use_size[0], 843 devpriv->iobase_a + AMCC_OP_REG_MWTC); 844 if (devpriv->ai_do == 4) 845 interrupt_pci9118_ai_mode4_switch(dev); 846 } 847 848 comedi_event(dev, s); 849} 850 851/* 852============================================================================== 853*/ 854static irqreturn_t interrupt_pci9118(int irq, void *d) 855{ 856 struct comedi_device *dev = d; 857 unsigned int int_daq = 0, int_amcc, int_adstat; 858 859 if (!dev->attached) 860 return IRQ_NONE; /* not fully initialized */ 861 862 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; 863 /* get IRQ reasons from card */ 864 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); 865 /* get INT register from AMCC chip */ 866 867/* 868 * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x 869 * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", 870 * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), 871 * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), 872 * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); 873 */ 874 875 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) 876 return IRQ_NONE; /* interrupt from other source */ 877 878 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); 879 /* shutdown IRQ reasons in AMCC */ 880 881 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; 882 /* get STATUS register */ 883 884 if (devpriv->ai_do) { 885 if (devpriv->ai12_startstop) 886 if ((int_adstat & AdStatus_DTH) && 887 (int_daq & Int_DTrg)) { 888 /* start stop of measure */ 889 if (devpriv->ai12_startstop & START_AI_EXT) { 890 devpriv->ai12_startstop &= 891 ~START_AI_EXT; 892 if (!(devpriv->ai12_startstop & 893 STOP_AI_EXT)) 894 pci9118_exttrg_del 895 (dev, EXTTRG_AI); 896 /* deactivate EXT trigger */ 897 start_pacer(dev, devpriv->ai_do, 898 devpriv->ai_divisor1, 899 devpriv->ai_divisor2); 900 /* start pacer */ 901 outl(devpriv->AdControlReg, 902 dev->iobase + PCI9118_ADCNTRL); 903 } else { 904 if (devpriv->ai12_startstop & 905 STOP_AI_EXT) { 906 devpriv->ai12_startstop &= 907 ~STOP_AI_EXT; 908 pci9118_exttrg_del 909 (dev, EXTTRG_AI); 910 /* deactivate EXT trigger */ 911 devpriv->ai_neverending = 0; 912 /* 913 * well, on next interrupt from 914 * DMA/EOC measure will stop 915 */ 916 } 917 } 918 } 919 920 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat, 921 int_amcc, int_daq); 922 923 } 924 return IRQ_HANDLED; 925} 926 927/* 928============================================================================== 929*/ 930static int pci9118_ai_inttrig(struct comedi_device *dev, 931 struct comedi_subdevice *s, unsigned int trignum) 932{ 933 if (trignum != devpriv->ai_inttrig_start) 934 return -EINVAL; 935 936 devpriv->ai12_startstop &= ~START_AI_INT; 937 s->async->inttrig = NULL; 938 939 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 940 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 941 if (devpriv->ai_do != 3) { 942 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 943 devpriv->ai_divisor2); 944 devpriv->AdControlReg |= AdControl_SoftG; 945 } 946 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 947 948 return 1; 949} 950 951/* 952============================================================================== 953*/ 954static int pci9118_ai_cmdtest(struct comedi_device *dev, 955 struct comedi_subdevice *s, 956 struct comedi_cmd *cmd) 957{ 958 int err = 0; 959 int tmp; 960 unsigned int divisor1 = 0, divisor2 = 0; 961 962 /* step 1: make sure trigger sources are trivially valid */ 963 964 tmp = cmd->start_src; 965 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT; 966 if (!cmd->start_src || tmp != cmd->start_src) 967 err++; 968 969 tmp = cmd->scan_begin_src; 970 if (devpriv->master) 971 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; 972 else 973 cmd->scan_begin_src &= TRIG_FOLLOW; 974 975 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 976 err++; 977 978 tmp = cmd->convert_src; 979 if (devpriv->master) 980 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; 981 else 982 cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 983 984 if (!cmd->convert_src || tmp != cmd->convert_src) 985 err++; 986 987 tmp = cmd->scan_end_src; 988 cmd->scan_end_src &= TRIG_COUNT; 989 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 990 err++; 991 992 tmp = cmd->stop_src; 993 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT; 994 if (!cmd->stop_src || tmp != cmd->stop_src) 995 err++; 996 997 if (err) 998 return 1; 999 1000 /* 1001 * step 2: 1002 * make sure trigger sources are 1003 * unique and mutually compatible 1004 */ 1005 1006 if (cmd->start_src != TRIG_NOW && 1007 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) { 1008 cmd->start_src = TRIG_NOW; 1009 err++; 1010 } 1011 1012 if (cmd->scan_begin_src != TRIG_TIMER && 1013 cmd->scan_begin_src != TRIG_EXT && 1014 cmd->scan_begin_src != TRIG_INT && 1015 cmd->scan_begin_src != TRIG_FOLLOW) { 1016 cmd->scan_begin_src = TRIG_FOLLOW; 1017 err++; 1018 } 1019 1020 if (cmd->convert_src != TRIG_TIMER && 1021 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) { 1022 cmd->convert_src = TRIG_TIMER; 1023 err++; 1024 } 1025 1026 if (cmd->scan_end_src != TRIG_COUNT) { 1027 cmd->scan_end_src = TRIG_COUNT; 1028 err++; 1029 } 1030 1031 if (cmd->stop_src != TRIG_NONE && 1032 cmd->stop_src != TRIG_COUNT && 1033 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) { 1034 cmd->stop_src = TRIG_COUNT; 1035 err++; 1036 } 1037 1038 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { 1039 cmd->start_src = TRIG_NOW; 1040 err++; 1041 } 1042 1043 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) { 1044 cmd->start_src = TRIG_NOW; 1045 err++; 1046 } 1047 1048 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) && 1049 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) { 1050 cmd->convert_src = TRIG_TIMER; 1051 err++; 1052 } 1053 1054 if ((cmd->scan_begin_src == TRIG_FOLLOW) && 1055 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) { 1056 cmd->convert_src = TRIG_TIMER; 1057 err++; 1058 } 1059 1060 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { 1061 cmd->stop_src = TRIG_COUNT; 1062 err++; 1063 } 1064 1065 if (err) 1066 return 2; 1067 1068 /* step 3: make sure arguments are trivially compatible */ 1069 1070 if (cmd->start_src & (TRIG_NOW | TRIG_EXT)) 1071 if (cmd->start_arg != 0) { 1072 cmd->start_arg = 0; 1073 err++; 1074 } 1075 1076 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT)) 1077 if (cmd->scan_begin_arg != 0) { 1078 cmd->scan_begin_arg = 0; 1079 err++; 1080 } 1081 1082 if ((cmd->scan_begin_src == TRIG_TIMER) && 1083 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) { 1084 cmd->scan_begin_src = TRIG_FOLLOW; 1085 cmd->convert_arg = cmd->scan_begin_arg; 1086 cmd->scan_begin_arg = 0; 1087 } 1088 1089 if (cmd->scan_begin_src == TRIG_TIMER) 1090 if (cmd->scan_begin_arg < this_board->ai_ns_min) { 1091 cmd->scan_begin_arg = this_board->ai_ns_min; 1092 err++; 1093 } 1094 1095 if (cmd->scan_begin_src == TRIG_EXT) 1096 if (cmd->scan_begin_arg) { 1097 cmd->scan_begin_arg = 0; 1098 err++; 1099 if (cmd->scan_end_arg > 65535) { 1100 cmd->scan_end_arg = 65535; 1101 err++; 1102 } 1103 } 1104 1105 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) 1106 if (cmd->convert_arg < this_board->ai_ns_min) { 1107 cmd->convert_arg = this_board->ai_ns_min; 1108 err++; 1109 } 1110 1111 if (cmd->convert_src == TRIG_EXT) 1112 if (cmd->convert_arg) { 1113 cmd->convert_arg = 0; 1114 err++; 1115 } 1116 1117 if (cmd->stop_src == TRIG_COUNT) { 1118 if (!cmd->stop_arg) { 1119 cmd->stop_arg = 1; 1120 err++; 1121 } 1122 } else { /* TRIG_NONE */ 1123 if (cmd->stop_arg != 0) { 1124 cmd->stop_arg = 0; 1125 err++; 1126 } 1127 } 1128 1129 if (!cmd->chanlist_len) { 1130 cmd->chanlist_len = 1; 1131 err++; 1132 } 1133 1134 if (cmd->chanlist_len > this_board->n_aichanlist) { 1135 cmd->chanlist_len = this_board->n_aichanlist; 1136 err++; 1137 } 1138 1139 if (cmd->scan_end_arg < cmd->chanlist_len) { 1140 cmd->scan_end_arg = cmd->chanlist_len; 1141 err++; 1142 } 1143 1144 if ((cmd->scan_end_arg % cmd->chanlist_len)) { 1145 cmd->scan_end_arg = 1146 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len); 1147 err++; 1148 } 1149 1150 if (err) 1151 return 3; 1152 1153 /* step 4: fix up any arguments */ 1154 1155 if (cmd->scan_begin_src == TRIG_TIMER) { 1156 tmp = cmd->scan_begin_arg; 1157/* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1158 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, 1159 &divisor2, &cmd->scan_begin_arg, 1160 cmd->flags & TRIG_ROUND_MASK); 1161/* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1162 if (cmd->scan_begin_arg < this_board->ai_ns_min) 1163 cmd->scan_begin_arg = this_board->ai_ns_min; 1164 if (tmp != cmd->scan_begin_arg) 1165 err++; 1166 } 1167 1168 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) { 1169 tmp = cmd->convert_arg; 1170 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, 1171 &divisor2, &cmd->convert_arg, 1172 cmd->flags & TRIG_ROUND_MASK); 1173/* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1174 if (cmd->convert_arg < this_board->ai_ns_min) 1175 cmd->convert_arg = this_board->ai_ns_min; 1176 if (tmp != cmd->convert_arg) 1177 err++; 1178 if (cmd->scan_begin_src == TRIG_TIMER 1179 && cmd->convert_src == TRIG_NOW) { 1180 if (cmd->convert_arg == 0) { 1181 if (cmd->scan_begin_arg < 1182 this_board->ai_ns_min * 1183 (cmd->scan_end_arg + 2)) { 1184 cmd->scan_begin_arg = 1185 this_board->ai_ns_min * 1186 (cmd->scan_end_arg + 2); 1187/* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1188 err++; 1189 } 1190 } else { 1191 if (cmd->scan_begin_arg < 1192 cmd->convert_arg * cmd->chanlist_len) { 1193 cmd->scan_begin_arg = 1194 cmd->convert_arg * 1195 cmd->chanlist_len; 1196/* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1197 err++; 1198 } 1199 } 1200 } 1201 } 1202 1203 if (err) 1204 return 4; 1205 1206 if (cmd->chanlist) 1207 if (!check_channel_list(dev, s, cmd->chanlist_len, 1208 cmd->chanlist, 0, 0)) 1209 return 5; /* incorrect channels list */ 1210 1211 return 0; 1212} 1213 1214/* 1215============================================================================== 1216*/ 1217static int Compute_and_setup_dma(struct comedi_device *dev) 1218{ 1219 unsigned int dmalen0, dmalen1, i; 1220 1221 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n"); 1222 dmalen0 = devpriv->dmabuf_size[0]; 1223 dmalen1 = devpriv->dmabuf_size[1]; 1224 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1, 1225 devpriv->ai_data_len); 1226 /* isn't output buff smaller that our DMA buff? */ 1227 if (dmalen0 > (devpriv->ai_data_len)) { 1228 dmalen0 = devpriv->ai_data_len & ~3L; /* 1229 * align to 32bit down 1230 */ 1231 } 1232 if (dmalen1 > (devpriv->ai_data_len)) { 1233 dmalen1 = devpriv->ai_data_len & ~3L; /* 1234 * align to 32bit down 1235 */ 1236 } 1237 DPRINTK("2 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); 1238 1239 /* we want wake up every scan? */ 1240 if (devpriv->ai_flags & TRIG_WAKE_EOS) { 1241 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { 1242 /* uff, too short DMA buffer, disable EOS support! */ 1243 devpriv->ai_flags &= (~TRIG_WAKE_EOS); 1244 printk 1245 ("comedi%d: WAR: DMA0 buf too short, can't " 1246 "support TRIG_WAKE_EOS (%d<%d)\n", 1247 dev->minor, dmalen0, 1248 devpriv->ai_n_realscanlen << 1); 1249 } else { 1250 /* short first DMA buffer to one scan */ 1251 dmalen0 = devpriv->ai_n_realscanlen << 1; 1252 DPRINTK 1253 ("21 dmalen0=%d ai_n_realscanlen=%d " 1254 "useeoshandle=%d\n", 1255 dmalen0, devpriv->ai_n_realscanlen, 1256 devpriv->useeoshandle); 1257 if (devpriv->useeoshandle) 1258 dmalen0 += 2; 1259 if (dmalen0 < 4) { 1260 printk 1261 ("comedi%d: ERR: DMA0 buf len bug? " 1262 "(%d<4)\n", 1263 dev->minor, dmalen0); 1264 dmalen0 = 4; 1265 } 1266 } 1267 } 1268 if (devpriv->ai_flags & TRIG_WAKE_EOS) { 1269 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { 1270 /* uff, too short DMA buffer, disable EOS support! */ 1271 devpriv->ai_flags &= (~TRIG_WAKE_EOS); 1272 printk 1273 ("comedi%d: WAR: DMA1 buf too short, " 1274 "can't support TRIG_WAKE_EOS (%d<%d)\n", 1275 dev->minor, dmalen1, 1276 devpriv->ai_n_realscanlen << 1); 1277 } else { 1278 /* short second DMA buffer to one scan */ 1279 dmalen1 = devpriv->ai_n_realscanlen << 1; 1280 DPRINTK 1281 ("22 dmalen1=%d ai_n_realscanlen=%d " 1282 "useeoshandle=%d\n", 1283 dmalen1, devpriv->ai_n_realscanlen, 1284 devpriv->useeoshandle); 1285 if (devpriv->useeoshandle) 1286 dmalen1 -= 2; 1287 if (dmalen1 < 4) { 1288 printk 1289 ("comedi%d: ERR: DMA1 buf len bug? " 1290 "(%d<4)\n", 1291 dev->minor, dmalen1); 1292 dmalen1 = 4; 1293 } 1294 } 1295 } 1296 1297 DPRINTK("3 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); 1298 /* transfer without TRIG_WAKE_EOS */ 1299 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) { 1300 /* if it's possible then allign DMA buffers to length of scan */ 1301 i = dmalen0; 1302 dmalen0 = 1303 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * 1304 (devpriv->ai_n_realscanlen << 1); 1305 dmalen0 &= ~3L; 1306 if (!dmalen0) 1307 dmalen0 = i; /* uff. very long scan? */ 1308 i = dmalen1; 1309 dmalen1 = 1310 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) * 1311 (devpriv->ai_n_realscanlen << 1); 1312 dmalen1 &= ~3L; 1313 if (!dmalen1) 1314 dmalen1 = i; /* uff. very long scan? */ 1315 /* 1316 * if measure isn't neverending then test, if it fits whole 1317 * into one or two DMA buffers 1318 */ 1319 if (!devpriv->ai_neverending) { 1320 /* fits whole measure into one DMA buffer? */ 1321 if (dmalen0 > 1322 ((devpriv->ai_n_realscanlen << 1) * 1323 devpriv->ai_scans)) { 1324 DPRINTK 1325 ("3.0 ai_n_realscanlen=%d ai_scans=%d\n", 1326 devpriv->ai_n_realscanlen, 1327 devpriv->ai_scans); 1328 dmalen0 = 1329 (devpriv->ai_n_realscanlen << 1) * 1330 devpriv->ai_scans; 1331 DPRINTK("3.1 dmalen0=%d dmalen1=%d\n", dmalen0, 1332 dmalen1); 1333 dmalen0 &= ~3L; 1334 } else { /* 1335 * fits whole measure into 1336 * two DMA buffer? 1337 */ 1338 if (dmalen1 > 1339 ((devpriv->ai_n_realscanlen << 1) * 1340 devpriv->ai_scans - dmalen0)) 1341 dmalen1 = 1342 (devpriv->ai_n_realscanlen << 1) * 1343 devpriv->ai_scans - dmalen0; 1344 DPRINTK("3.2 dmalen0=%d dmalen1=%d\n", dmalen0, 1345 dmalen1); 1346 dmalen1 &= ~3L; 1347 } 1348 } 1349 } 1350 1351 DPRINTK("4 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); 1352 1353 /* these DMA buffer size will be used */ 1354 devpriv->dma_actbuf = 0; 1355 devpriv->dmabuf_use_size[0] = dmalen0; 1356 devpriv->dmabuf_use_size[1] = dmalen1; 1357 1358 DPRINTK("5 dmalen0=%d dmalen1=%d\n", dmalen0, dmalen1); 1359#if 0 1360 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) { 1361 devpriv->dmabuf_panic_size[0] = 1362 (this_board->half_fifo_size / devpriv->ai_n_scanlen + 1363 1) * devpriv->ai_n_scanlen * sizeof(short); 1364 devpriv->dmabuf_panic_size[1] = 1365 (this_board->half_fifo_size / devpriv->ai_n_scanlen + 1366 1) * devpriv->ai_n_scanlen * sizeof(short); 1367 } else { 1368 devpriv->dmabuf_panic_size[0] = 1369 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0]; 1370 devpriv->dmabuf_panic_size[1] = 1371 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1]; 1372 } 1373#endif 1374 1375 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), 1376 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ 1377 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR); 1378 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC); 1379 /* init DMA transfer */ 1380 outl(0x00000000 | AINT_WRITE_COMPL, 1381 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1382/* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */ 1383 1384 outl(inl(devpriv->iobase_a + 1385 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY | 1386 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR); 1387 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, 1388 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1389 /* allow bus mastering */ 1390 1391 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n"); 1392 return 0; 1393} 1394 1395/* 1396============================================================================== 1397*/ 1398static int pci9118_ai_docmd_sampl(struct comedi_device *dev, 1399 struct comedi_subdevice *s) 1400{ 1401 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n", 1402 dev->minor, devpriv->ai_do); 1403 switch (devpriv->ai_do) { 1404 case 1: 1405 devpriv->AdControlReg |= AdControl_TmrTr; 1406 break; 1407 case 2: 1408 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n"); 1409 return -EIO; 1410 case 3: 1411 devpriv->AdControlReg |= AdControl_ExtM; 1412 break; 1413 case 4: 1414 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n"); 1415 return -EIO; 1416 default: 1417 comedi_error(dev, 1418 "pci9118_ai_docmd_sampl() mode number bug!\n"); 1419 return -EIO; 1420 }; 1421 1422 devpriv->int_ai_func = interrupt_pci9118_ai_onesample; 1423 /* transfer function */ 1424 1425 if (devpriv->ai12_startstop) 1426 pci9118_exttrg_add(dev, EXTTRG_AI); 1427 /* activate EXT trigger */ 1428 1429 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2)) 1430 devpriv->IntControlReg |= Int_Timer; 1431 1432 devpriv->AdControlReg |= AdControl_Int; 1433 1434 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 1435 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1436 /* allow INT in AMCC */ 1437 1438 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) { 1439 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1440 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1441 if (devpriv->ai_do != 3) { 1442 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 1443 devpriv->ai_divisor2); 1444 devpriv->AdControlReg |= AdControl_SoftG; 1445 } 1446 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1447 } 1448 1449 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n"); 1450 return 0; 1451} 1452 1453/* 1454============================================================================== 1455*/ 1456static int pci9118_ai_docmd_dma(struct comedi_device *dev, 1457 struct comedi_subdevice *s) 1458{ 1459 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n", 1460 dev->minor, devpriv->ai_do, devpriv->usedma); 1461 Compute_and_setup_dma(dev); 1462 1463 switch (devpriv->ai_do) { 1464 case 1: 1465 devpriv->AdControlReg |= 1466 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1467 break; 1468 case 2: 1469 devpriv->AdControlReg |= 1470 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1471 devpriv->AdFunctionReg = 1472 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM | 1473 AdFunction_BS; 1474 if (devpriv->usessh && (!devpriv->softsshdelay)) 1475 devpriv->AdFunctionReg |= AdFunction_BSSH; 1476 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST); 1477 break; 1478 case 3: 1479 devpriv->AdControlReg |= 1480 ((AdControl_ExtM | AdControl_Dma) & 0xff); 1481 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 1482 break; 1483 case 4: 1484 devpriv->AdControlReg |= 1485 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1486 devpriv->AdFunctionReg = 1487 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM; 1488 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1489 outl(0x30, dev->iobase + PCI9118_CNTCTRL); 1490 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff, 1491 dev->iobase + PCI9118_CNT0); 1492 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff, 1493 dev->iobase + PCI9118_CNT0); 1494 devpriv->AdFunctionReg |= AdFunction_Start; 1495 break; 1496 default: 1497 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n"); 1498 return -EIO; 1499 }; 1500 1501 if (devpriv->ai12_startstop) { 1502 pci9118_exttrg_add(dev, EXTTRG_AI); 1503 /* activate EXT trigger */ 1504 } 1505 1506 devpriv->int_ai_func = interrupt_pci9118_ai_dma; 1507 /* transfer function */ 1508 1509 outl(0x02000000 | AINT_WRITE_COMPL, 1510 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1511 1512 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) { 1513 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1514 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1515 if (devpriv->ai_do != 3) { 1516 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 1517 devpriv->ai_divisor2); 1518 devpriv->AdControlReg |= AdControl_SoftG; 1519 } 1520 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1521 } 1522 1523 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n"); 1524 return 0; 1525} 1526 1527/* 1528============================================================================== 1529*/ 1530static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 1531{ 1532 struct comedi_cmd *cmd = &s->async->cmd; 1533 unsigned int addchans = 0; 1534 int ret = 0; 1535 1536 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor); 1537 devpriv->ai12_startstop = 0; 1538 devpriv->ai_flags = cmd->flags; 1539 devpriv->ai_n_chan = cmd->chanlist_len; 1540 devpriv->ai_n_scanlen = cmd->scan_end_arg; 1541 devpriv->ai_chanlist = cmd->chanlist; 1542 devpriv->ai_data = s->async->prealloc_buf; 1543 devpriv->ai_data_len = s->async->prealloc_bufsz; 1544 devpriv->ai_timer1 = 0; 1545 devpriv->ai_timer2 = 0; 1546 devpriv->ai_add_front = 0; 1547 devpriv->ai_add_back = 0; 1548 devpriv->ai_maskerr = 0x10e; 1549 1550 /* prepare for start/stop conditions */ 1551 if (cmd->start_src == TRIG_EXT) 1552 devpriv->ai12_startstop |= START_AI_EXT; 1553 if (cmd->stop_src == TRIG_EXT) { 1554 devpriv->ai_neverending = 1; 1555 devpriv->ai12_startstop |= STOP_AI_EXT; 1556 } 1557 if (cmd->start_src == TRIG_INT) { 1558 devpriv->ai12_startstop |= START_AI_INT; 1559 devpriv->ai_inttrig_start = cmd->start_arg; 1560 s->async->inttrig = pci9118_ai_inttrig; 1561 } 1562#if 0 1563 if (cmd->stop_src == TRIG_INT) { 1564 devpriv->ai_neverending = 1; 1565 devpriv->ai12_startstop |= STOP_AI_INT; 1566 } 1567#endif 1568 if (cmd->stop_src == TRIG_NONE) 1569 devpriv->ai_neverending = 1; 1570 if (cmd->stop_src == TRIG_COUNT) { 1571 devpriv->ai_scans = cmd->stop_arg; 1572 devpriv->ai_neverending = 0; 1573 } else { 1574 devpriv->ai_scans = 0; 1575 } 1576 1577 /* use sample&hold signal? */ 1578 if (cmd->convert_src == TRIG_NOW) { 1579 devpriv->usessh = 1; 1580 } /* yes */ 1581 else { 1582 devpriv->usessh = 0; 1583 } /* no */ 1584 1585 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n", 1586 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, 1587 devpriv->ai12_startstop); 1588 1589 /* 1590 * use additional sample at end of every scan 1591 * to satisty DMA 32 bit transfer? 1592 */ 1593 devpriv->ai_add_front = 0; 1594 devpriv->ai_add_back = 0; 1595 devpriv->useeoshandle = 0; 1596 if (devpriv->master) { 1597 devpriv->usedma = 1; 1598 if ((cmd->flags & TRIG_WAKE_EOS) && 1599 (devpriv->ai_n_scanlen == 1)) { 1600 if (cmd->convert_src == TRIG_NOW) { 1601 devpriv->ai_add_back = 1; 1602 } 1603 if (cmd->convert_src == TRIG_TIMER) { 1604 devpriv->usedma = 0; 1605 /* 1606 * use INT transfer if scanlist 1607 * have only one channel 1608 */ 1609 } 1610 } 1611 if ((cmd->flags & TRIG_WAKE_EOS) && 1612 (devpriv->ai_n_scanlen & 1) && 1613 (devpriv->ai_n_scanlen > 1)) { 1614 if (cmd->scan_begin_src == TRIG_FOLLOW) { 1615 /* 1616 * vpriv->useeoshandle=1; // change DMA transfer 1617 * block to fit EOS on every second call 1618 */ 1619 devpriv->usedma = 0; 1620 /* 1621 * XXX maybe can be corrected to use 16 bit DMA 1622 */ 1623 } else { /* 1624 * well, we must insert one sample 1625 * to end of EOS to meet 32 bit transfer 1626 */ 1627 devpriv->ai_add_back = 1; 1628 } 1629 } 1630 } else { /* interrupt transfer don't need any correction */ 1631 devpriv->usedma = 0; 1632 } 1633 1634 /* 1635 * we need software S&H signal? 1636 * It adds two samples before every scan as minimum 1637 */ 1638 if (devpriv->usessh && devpriv->softsshdelay) { 1639 devpriv->ai_add_front = 2; 1640 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { 1641 /* move it to front */ 1642 devpriv->ai_add_front++; 1643 devpriv->ai_add_back = 0; 1644 } 1645 if (cmd->convert_arg < this_board->ai_ns_min) 1646 cmd->convert_arg = this_board->ai_ns_min; 1647 addchans = devpriv->softsshdelay / cmd->convert_arg; 1648 if (devpriv->softsshdelay % cmd->convert_arg) 1649 addchans++; 1650 if (addchans > (devpriv->ai_add_front - 1)) { 1651 /* uff, still short */ 1652 devpriv->ai_add_front = addchans + 1; 1653 if (devpriv->usedma == 1) 1654 if ((devpriv->ai_add_front + 1655 devpriv->ai_n_chan + 1656 devpriv->ai_add_back) & 1) 1657 devpriv->ai_add_front++; 1658 /* round up to 32 bit */ 1659 } 1660 } 1661 /* well, we now know what must be all added */ 1662 devpriv->ai_n_realscanlen = /* 1663 * what we must take from card in real 1664 * to have ai_n_scanlen on output? 1665 */ 1666 (devpriv->ai_add_front + devpriv->ai_n_chan + 1667 devpriv->ai_add_back) * (devpriv->ai_n_scanlen / 1668 devpriv->ai_n_chan); 1669 1670 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n", 1671 devpriv->usedma, 1672 devpriv->ai_n_realscanlen, devpriv->ai_add_front, 1673 devpriv->ai_n_chan, devpriv->ai_add_back, 1674 devpriv->ai_n_scanlen); 1675 1676 /* check and setup channel list */ 1677 if (!check_channel_list(dev, s, devpriv->ai_n_chan, 1678 devpriv->ai_chanlist, devpriv->ai_add_front, 1679 devpriv->ai_add_back)) 1680 return -EINVAL; 1681 if (!setup_channel_list(dev, s, devpriv->ai_n_chan, 1682 devpriv->ai_chanlist, 0, devpriv->ai_add_front, 1683 devpriv->ai_add_back, devpriv->usedma, 1684 devpriv->useeoshandle)) 1685 return -EINVAL; 1686 1687 /* compute timers settings */ 1688 /* 1689 * simplest way, fr=4Mhz/(tim1*tim2), 1690 * channel manipulation without timers effect 1691 */ 1692 if (((cmd->scan_begin_src == TRIG_FOLLOW) || 1693 (cmd->scan_begin_src == TRIG_EXT) || 1694 (cmd->scan_begin_src == TRIG_INT)) && 1695 (cmd->convert_src == TRIG_TIMER)) { 1696 /* both timer is used for one time */ 1697 if (cmd->scan_begin_src == TRIG_EXT) { 1698 devpriv->ai_do = 4; 1699 } else { 1700 devpriv->ai_do = 1; 1701 } 1702 pci9118_calc_divisors(devpriv->ai_do, dev, s, 1703 &cmd->scan_begin_arg, &cmd->convert_arg, 1704 devpriv->ai_flags, 1705 devpriv->ai_n_realscanlen, 1706 &devpriv->ai_divisor1, 1707 &devpriv->ai_divisor2, devpriv->usessh, 1708 devpriv->ai_add_front); 1709 devpriv->ai_timer2 = cmd->convert_arg; 1710 } 1711 1712 if ((cmd->scan_begin_src == TRIG_TIMER) && 1713 ((cmd->convert_src == TRIG_TIMER) || 1714 (cmd->convert_src == TRIG_NOW))) { 1715 /* double timed action */ 1716 if (!devpriv->usedma) { 1717 comedi_error(dev, 1718 "cmd->scan_begin_src=TRIG_TIMER works " 1719 "only with bus mastering!"); 1720 return -EIO; 1721 } 1722 1723 devpriv->ai_do = 2; 1724 pci9118_calc_divisors(devpriv->ai_do, dev, s, 1725 &cmd->scan_begin_arg, &cmd->convert_arg, 1726 devpriv->ai_flags, 1727 devpriv->ai_n_realscanlen, 1728 &devpriv->ai_divisor1, 1729 &devpriv->ai_divisor2, devpriv->usessh, 1730 devpriv->ai_add_front); 1731 devpriv->ai_timer1 = cmd->scan_begin_arg; 1732 devpriv->ai_timer2 = cmd->convert_arg; 1733 } 1734 1735 if ((cmd->scan_begin_src == TRIG_FOLLOW) 1736 && (cmd->convert_src == TRIG_EXT)) { 1737 devpriv->ai_do = 3; 1738 } 1739 1740 start_pacer(dev, -1, 0, 0); /* stop pacer */ 1741 1742 devpriv->AdControlReg = 0; /* 1743 * bipolar, S.E., use 8254, stop 8354, 1744 * internal trigger, soft trigger, 1745 * disable DMA 1746 */ 1747 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1748 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 1749 /* 1750 * positive triggers, no S&H, no burst, 1751 * burst stop, no post trigger, 1752 * no about trigger, trigger stop 1753 */ 1754 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1755 udelay(1); 1756 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 1757 inl(dev->iobase + PCI9118_ADSTAT); /* 1758 * flush A/D and INT 1759 * status register 1760 */ 1761 inl(dev->iobase + PCI9118_INTSRC); 1762 1763 devpriv->ai_act_scan = 0; 1764 devpriv->ai_act_dmapos = 0; 1765 s->async->cur_chan = 0; 1766 devpriv->ai_buf_ptr = 0; 1767 1768 if (devpriv->usedma) 1769 ret = pci9118_ai_docmd_dma(dev, s); 1770 else 1771 ret = pci9118_ai_docmd_sampl(dev, s); 1772 1773 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n"); 1774 return ret; 1775} 1776 1777/* 1778============================================================================== 1779*/ 1780static int check_channel_list(struct comedi_device *dev, 1781 struct comedi_subdevice *s, int n_chan, 1782 unsigned int *chanlist, int frontadd, int backadd) 1783{ 1784 unsigned int i, differencial = 0, bipolar = 0; 1785 1786 /* correct channel and range number check itself comedi/range.c */ 1787 if (n_chan < 1) { 1788 comedi_error(dev, "range/channel list is empty!"); 1789 return 0; 1790 } 1791 if ((frontadd + n_chan + backadd) > s->len_chanlist) { 1792 printk 1793 ("comedi%d: range/channel list is too long for " 1794 "actual configuration (%d>%d)!", 1795 dev->minor, n_chan, s->len_chanlist - frontadd - backadd); 1796 return 0; 1797 } 1798 1799 if (CR_AREF(chanlist[0]) == AREF_DIFF) 1800 differencial = 1; /* all input must be diff */ 1801 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) 1802 bipolar = 1; /* all input must be bipolar */ 1803 if (n_chan > 1) 1804 for (i = 1; i < n_chan; i++) { /* check S.E/diff */ 1805 if ((CR_AREF(chanlist[i]) == AREF_DIFF) != 1806 (differencial)) { 1807 comedi_error(dev, 1808 "Differencial and single ended " 1809 "inputs can't be mixtured!"); 1810 return 0; 1811 } 1812 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) != 1813 (bipolar)) { 1814 comedi_error(dev, 1815 "Bipolar and unipolar ranges " 1816 "can't be mixtured!"); 1817 return 0; 1818 } 1819 if ((!devpriv->usemux) & (differencial) & 1820 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { 1821 comedi_error(dev, 1822 "If AREF_DIFF is used then is " 1823 "available only first 8 channels!"); 1824 return 0; 1825 } 1826 } 1827 1828 return 1; 1829} 1830 1831/* 1832============================================================================== 1833*/ 1834static int setup_channel_list(struct comedi_device *dev, 1835 struct comedi_subdevice *s, int n_chan, 1836 unsigned int *chanlist, int rot, int frontadd, 1837 int backadd, int usedma, char useeos) 1838{ 1839 unsigned int i, differencial = 0, bipolar = 0; 1840 unsigned int scanquad, gain, ssh = 0x00; 1841 1842 DPRINTK 1843 ("adl_pci9118 EDBG: BGN: setup_channel_list" 1844 "(%d,.,%d,.,%d,%d,%d,%d)\n", 1845 dev->minor, n_chan, rot, frontadd, backadd, usedma); 1846 1847 if (usedma == 1) { 1848 rot = 8; 1849 usedma = 0; 1850 } 1851 1852 if (CR_AREF(chanlist[0]) == AREF_DIFF) 1853 differencial = 1; /* all input must be diff */ 1854 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) 1855 bipolar = 1; /* all input must be bipolar */ 1856 1857 /* All is ok, so we can setup channel/range list */ 1858 1859 if (!bipolar) { 1860 devpriv->AdControlReg |= AdControl_UniP; 1861 /* set unibipolar */ 1862 } else { 1863 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); 1864 /* enable bipolar */ 1865 } 1866 1867 if (differencial) { 1868 devpriv->AdControlReg |= AdControl_Diff; 1869 /* enable diff inputs */ 1870 } else { 1871 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); 1872 /* set single ended inputs */ 1873 } 1874 1875 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1876 /* setup mode */ 1877 1878 outl(2, dev->iobase + PCI9118_SCANMOD); 1879 /* gods know why this sequence! */ 1880 outl(0, dev->iobase + PCI9118_SCANMOD); 1881 outl(1, dev->iobase + PCI9118_SCANMOD); 1882 1883#ifdef PCI9118_PARANOIDCHECK 1884 devpriv->chanlistlen = n_chan; 1885 for (i = 0; i < (PCI9118_CHANLEN + 1); i++) 1886 devpriv->chanlist[i] = 0x55aa; 1887#endif 1888 1889 if (frontadd) { /* insert channels for S&H */ 1890 ssh = devpriv->softsshsample; 1891 DPRINTK("FA: %04x: ", ssh); 1892 for (i = 0; i < frontadd; i++) { 1893 /* store range list to card */ 1894 scanquad = CR_CHAN(chanlist[0]); 1895 /* get channel number; */ 1896 gain = CR_RANGE(chanlist[0]); 1897 /* get gain number */ 1898 scanquad |= ((gain & 0x03) << 8); 1899 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1900 DPRINTK("%02x ", scanquad | ssh); 1901 ssh = devpriv->softsshhold; 1902 } 1903 DPRINTK("\n "); 1904 } 1905 1906 DPRINTK("SL: ", ssh); 1907 for (i = 0; i < n_chan; i++) { /* store range list to card */ 1908 scanquad = CR_CHAN(chanlist[i]); /* get channel number */ 1909#ifdef PCI9118_PARANOIDCHECK 1910 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot; 1911#endif 1912 gain = CR_RANGE(chanlist[i]); /* get gain number */ 1913 scanquad |= ((gain & 0x03) << 8); 1914 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1915 DPRINTK("%02x ", scanquad | ssh); 1916 } 1917 DPRINTK("\n "); 1918 1919 if (backadd) { /* insert channels for fit onto 32bit DMA */ 1920 DPRINTK("BA: %04x: ", ssh); 1921 for (i = 0; i < backadd; i++) { /* store range list to card */ 1922 scanquad = CR_CHAN(chanlist[0]); 1923 /* get channel number */ 1924 gain = CR_RANGE(chanlist[0]); /* get gain number */ 1925 scanquad |= ((gain & 0x03) << 8); 1926 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1927 DPRINTK("%02x ", scanquad | ssh); 1928 } 1929 DPRINTK("\n "); 1930 } 1931#ifdef PCI9118_PARANOIDCHECK 1932 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; 1933 /* for 32bit operations */ 1934 if (useeos) { 1935 for (i = 1; i < n_chan; i++) { /* store range list to card */ 1936 devpriv->chanlist[(n_chan + i) ^ usedma] = 1937 (CR_CHAN(chanlist[i]) & 0xf) << rot; 1938 } 1939 devpriv->chanlist[(2 * n_chan) ^ usedma] = 1940 devpriv->chanlist[0 ^ usedma]; 1941 /* for 32bit operations */ 1942 useeos = 2; 1943 } else { 1944 useeos = 1; 1945 } 1946#ifdef PCI9118_EXTDEBUG 1947 DPRINTK("CHL: "); 1948 for (i = 0; i <= (useeos * n_chan); i++) 1949 DPRINTK("%04x ", devpriv->chanlist[i]); 1950 1951 DPRINTK("\n "); 1952#endif 1953#endif 1954 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ 1955 /* udelay(100); important delay, or first sample will be crippled */ 1956 1957 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n"); 1958 return 1; /* we can serve this with scan logic */ 1959} 1960 1961/* 1962============================================================================== 1963 calculate 8254 divisors if they are used for dual timing 1964*/ 1965static void pci9118_calc_divisors(char mode, struct comedi_device *dev, 1966 struct comedi_subdevice *s, 1967 unsigned int *tim1, unsigned int *tim2, 1968 unsigned int flags, int chans, 1969 unsigned int *div1, unsigned int *div2, 1970 char usessh, unsigned int chnsshfront) 1971{ 1972 DPRINTK 1973 ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors" 1974 "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", 1975 mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront); 1976 switch (mode) { 1977 case 1: 1978 case 4: 1979 if (*tim2 < this_board->ai_ns_min) 1980 *tim2 = this_board->ai_ns_min; 1981 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2, 1982 tim2, flags & TRIG_ROUND_NEAREST); 1983 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n", 1984 devpriv->i8254_osc_base, *div1, *div2, *tim1); 1985 break; 1986 case 2: 1987 if (*tim2 < this_board->ai_ns_min) 1988 *tim2 = this_board->ai_ns_min; 1989 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1990 *tim1, *tim2); 1991 *div1 = *tim2 / devpriv->i8254_osc_base; 1992 /* convert timer (burst) */ 1993 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1994 *tim1, *tim2); 1995 if (*div1 < this_board->ai_pacer_min) 1996 *div1 = this_board->ai_pacer_min; 1997 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1998 *tim1, *tim2); 1999 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ 2000 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 2001 *tim1, *tim2); 2002 *div2 = *div2 / *div1; /* major timer is c1*c2 */ 2003 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 2004 *tim1, *tim2); 2005 if (*div2 < chans) 2006 *div2 = chans; 2007 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 2008 *tim1, *tim2); 2009 2010 *tim2 = *div1 * devpriv->i8254_osc_base; 2011 /* real convert timer */ 2012 2013 if (usessh & (chnsshfront == 0)) /* use BSSH signal */ 2014 if (*div2 < (chans + 2)) 2015 *div2 = chans + 2; 2016 2017 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 2018 *tim1, *tim2); 2019 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base; 2020 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n", 2021 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2); 2022 break; 2023 } 2024 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n", 2025 *div1, *div2); 2026} 2027 2028/* 2029============================================================================== 2030*/ 2031static void start_pacer(struct comedi_device *dev, int mode, 2032 unsigned int divisor1, unsigned int divisor2) 2033{ 2034 outl(0x74, dev->iobase + PCI9118_CNTCTRL); 2035 outl(0xb4, dev->iobase + PCI9118_CNTCTRL); 2036/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */ 2037 udelay(1); 2038 2039 if ((mode == 1) || (mode == 2) || (mode == 4)) { 2040 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2); 2041 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2); 2042 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1); 2043 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1); 2044 } 2045} 2046 2047/* 2048============================================================================== 2049*/ 2050static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) 2051{ 2052 if (source > 3) 2053 return -1; /* incorrect source */ 2054 devpriv->exttrg_users |= (1 << source); 2055 devpriv->IntControlReg |= Int_DTrg; 2056 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2057 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 2058 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2059 /* allow INT in AMCC */ 2060 return 0; 2061} 2062 2063/* 2064============================================================================== 2065*/ 2066static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) 2067{ 2068 if (source > 3) 2069 return -1; /* incorrect source */ 2070 devpriv->exttrg_users &= ~(1 << source); 2071 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ 2072 devpriv->IntControlReg &= ~Int_DTrg; 2073 if (!devpriv->IntControlReg) /* all IRQ disabled */ 2074 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & 2075 (~0x00001f00), 2076 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2077 /* disable int in AMCC */ 2078 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2079 } 2080 return 0; 2081} 2082 2083/* 2084============================================================================== 2085*/ 2086static int pci9118_ai_cancel(struct comedi_device *dev, 2087 struct comedi_subdevice *s) 2088{ 2089 if (devpriv->usedma) 2090 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & 2091 (~EN_A2P_TRANSFERS), 2092 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ 2093 pci9118_exttrg_del(dev, EXTTRG_AI); 2094 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ 2095 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 2096 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 2097 /* 2098 * positive triggers, no S&H, no burst, 2099 * burst stop, no post trigger, 2100 * no about trigger, trigger stop 2101 */ 2102 devpriv->AdControlReg = 0x00; 2103 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2104 /* 2105 * bipolar, S.E., use 8254, stop 8354, 2106 * internal trigger, soft trigger, 2107 * disable INT and DMA 2108 */ 2109 outl(0, dev->iobase + PCI9118_BURST); 2110 outl(1, dev->iobase + PCI9118_SCANMOD); 2111 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ 2112 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 2113 2114 devpriv->ai_do = 0; 2115 devpriv->usedma = 0; 2116 2117 devpriv->ai_act_scan = 0; 2118 devpriv->ai_act_dmapos = 0; 2119 s->async->cur_chan = 0; 2120 s->async->inttrig = NULL; 2121 devpriv->ai_buf_ptr = 0; 2122 devpriv->ai_neverending = 0; 2123 devpriv->dma_actbuf = 0; 2124 2125 if (!devpriv->IntControlReg) 2126 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 2127 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2128 /* allow INT in AMCC */ 2129 2130 return 0; 2131} 2132 2133/* 2134============================================================================== 2135*/ 2136static int pci9118_reset(struct comedi_device *dev) 2137{ 2138 devpriv->IntControlReg = 0; 2139 devpriv->exttrg_users = 0; 2140 inl(dev->iobase + PCI9118_INTCTRL); 2141 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2142 /* disable interrupts source */ 2143 outl(0x30, dev->iobase + PCI9118_CNTCTRL); 2144/* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */ 2145 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ 2146 devpriv->AdControlReg = 0; 2147 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2148 /* 2149 * bipolar, S.E., use 8254, 2150 * stop 8354, internal trigger, 2151 * soft trigger, 2152 * disable INT and DMA 2153 */ 2154 outl(0, dev->iobase + PCI9118_BURST); 2155 outl(1, dev->iobase + PCI9118_SCANMOD); 2156 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ 2157 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 2158 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 2159 /* 2160 * positive triggers, no S&H, 2161 * no burst, burst stop, 2162 * no post trigger, 2163 * no about trigger, 2164 * trigger stop 2165 */ 2166 2167 devpriv->ao_data[0] = 2047; 2168 devpriv->ao_data[1] = 2047; 2169 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); 2170 /* reset A/D outs to 0V */ 2171 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2); 2172 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */ 2173 udelay(10); 2174 inl(dev->iobase + PCI9118_AD_DATA); 2175 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 2176 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */ 2177 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */ 2178 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */ 2179 devpriv->AdControlReg = 0; 2180 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2181 /* 2182 * bipolar, S.E., use 8254, 2183 * stop 8354, internal trigger, 2184 * soft trigger, 2185 * disable INT and DMA 2186 */ 2187 2188 devpriv->cnt0_users = 0; 2189 devpriv->exttrg_users = 0; 2190 2191 return 0; 2192} 2193 2194/* 2195============================================================================== 2196*/ 2197static int pci9118_attach(struct comedi_device *dev, 2198 struct comedi_devconfig *it) 2199{ 2200 struct comedi_subdevice *s; 2201 int ret, pages, i; 2202 unsigned short master; 2203 unsigned int irq; 2204 unsigned long iobase_a, iobase_9; 2205 struct pci_dev *pcidev; 2206 int opt_bus, opt_slot; 2207 const char *errstr; 2208 unsigned char pci_bus, pci_slot, pci_func; 2209 u16 u16w; 2210 2211 printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); 2212 2213 opt_bus = it->options[0]; 2214 opt_slot = it->options[1]; 2215 if (it->options[3] & 1) { 2216 master = 0; /* user don't want use bus master */ 2217 } else { 2218 master = 1; 2219 } 2220 2221 ret = alloc_private(dev, sizeof(struct pci9118_private)); 2222 if (ret < 0) { 2223 printk(" - Allocation failed!\n"); 2224 return -ENOMEM; 2225 } 2226 2227 /* Look for matching PCI device */ 2228 errstr = "not found!"; 2229 pcidev = NULL; 2230 while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC, 2231 this_board->device_id, 2232 pcidev))) { 2233 /* Found matching vendor/device. */ 2234 if (opt_bus || opt_slot) { 2235 /* Check bus/slot. */ 2236 if (opt_bus != pcidev->bus->number 2237 || opt_slot != PCI_SLOT(pcidev->devfn)) 2238 continue; /* no match */ 2239 } 2240 /* 2241 * Look for device that isn't in use. 2242 * Enable PCI device and request regions. 2243 */ 2244 if (comedi_pci_enable(pcidev, "adl_pci9118")) { 2245 errstr = 2246 "failed to enable PCI device and request regions!"; 2247 continue; 2248 } 2249 break; 2250 } 2251 2252 if (!pcidev) { 2253 if (opt_bus || opt_slot) { 2254 printk(KERN_ERR " - Card at b:s %d:%d %s\n", 2255 opt_bus, opt_slot, errstr); 2256 } else { 2257 printk(KERN_ERR " - Card %s\n", errstr); 2258 } 2259 return -EIO; 2260 } 2261 2262 if (master) 2263 pci_set_master(pcidev); 2264 2265 2266 pci_bus = pcidev->bus->number; 2267 pci_slot = PCI_SLOT(pcidev->devfn); 2268 pci_func = PCI_FUNC(pcidev->devfn); 2269 irq = pcidev->irq; 2270 iobase_a = pci_resource_start(pcidev, 0); 2271 iobase_9 = pci_resource_start(pcidev, 2); 2272 2273 printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, 2274 pci_slot, pci_func, iobase_9, iobase_a); 2275 2276 dev->iobase = iobase_9; 2277 dev->board_name = this_board->name; 2278 2279 devpriv->pcidev = pcidev; 2280 devpriv->iobase_a = iobase_a; 2281 2282 pci9118_reset(dev); 2283 2284 if (it->options[3] & 2) 2285 irq = 0; /* user don't want use IRQ */ 2286 if (irq > 0) { 2287 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, 2288 "ADLink PCI-9118", dev)) { 2289 printk(", unable to allocate IRQ %d, DISABLING IT", 2290 irq); 2291 irq = 0; /* Can't use IRQ */ 2292 } else { 2293 printk(", irq=%u", irq); 2294 } 2295 } else { 2296 printk(", IRQ disabled"); 2297 } 2298 2299 dev->irq = irq; 2300 2301 if (master) { /* alloc DMA buffers */ 2302 devpriv->dma_doublebuf = 0; 2303 for (i = 0; i < 2; i++) { 2304 for (pages = 4; pages >= 0; pages--) { 2305 devpriv->dmabuf_virt[i] = 2306 (short *)__get_free_pages(GFP_KERNEL, 2307 pages); 2308 if (devpriv->dmabuf_virt[i]) 2309 break; 2310 } 2311 if (devpriv->dmabuf_virt[i]) { 2312 devpriv->dmabuf_pages[i] = pages; 2313 devpriv->dmabuf_size[i] = PAGE_SIZE * pages; 2314 devpriv->dmabuf_samples[i] = 2315 devpriv->dmabuf_size[i] >> 1; 2316 devpriv->dmabuf_hw[i] = 2317 virt_to_bus((void *) 2318 devpriv->dmabuf_virt[i]); 2319 } 2320 } 2321 if (!devpriv->dmabuf_virt[0]) { 2322 printk(", Can't allocate DMA buffer, DMA disabled!"); 2323 master = 0; 2324 } 2325 2326 if (devpriv->dmabuf_virt[1]) 2327 devpriv->dma_doublebuf = 1; 2328 2329 } 2330 2331 devpriv->master = master; 2332 if (devpriv->master) 2333 printk(", bus master"); 2334 else 2335 printk(", no bus master"); 2336 2337 devpriv->usemux = 0; 2338 if (it->options[2] > 0) { 2339 devpriv->usemux = it->options[2]; 2340 if (devpriv->usemux > 256) 2341 devpriv->usemux = 256; /* max 256 channels! */ 2342 if (it->options[4] > 0) 2343 if (devpriv->usemux > 128) { 2344 devpriv->usemux = 128; 2345 /* max 128 channels with softare S&H! */ 2346 } 2347 printk(", ext. mux %d channels", devpriv->usemux); 2348 } 2349 2350 devpriv->softsshdelay = it->options[4]; 2351 if (devpriv->softsshdelay < 0) { 2352 /* select sample&hold signal polarity */ 2353 devpriv->softsshdelay = -devpriv->softsshdelay; 2354 devpriv->softsshsample = 0x80; 2355 devpriv->softsshhold = 0x00; 2356 } else { 2357 devpriv->softsshsample = 0x00; 2358 devpriv->softsshhold = 0x80; 2359 } 2360 2361 printk(".\n"); 2362 2363 pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w); 2364 pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); 2365 /* Enable parity check for parity error */ 2366 2367 ret = alloc_subdevices(dev, 4); 2368 if (ret < 0) 2369 return ret; 2370 2371 s = dev->subdevices + 0; 2372 dev->read_subdev = s; 2373 s->type = COMEDI_SUBD_AI; 2374 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; 2375 if (devpriv->usemux) 2376 s->n_chan = devpriv->usemux; 2377 else 2378 s->n_chan = this_board->n_aichan; 2379 2380 s->maxdata = this_board->ai_maxdata; 2381 s->len_chanlist = this_board->n_aichanlist; 2382 s->range_table = this_board->rangelist_ai; 2383 s->cancel = pci9118_ai_cancel; 2384 s->insn_read = pci9118_insn_read_ai; 2385 if (dev->irq) { 2386 s->subdev_flags |= SDF_CMD_READ; 2387 s->do_cmdtest = pci9118_ai_cmdtest; 2388 s->do_cmd = pci9118_ai_cmd; 2389 s->munge = pci9118_ai_munge; 2390 } 2391 2392 s = dev->subdevices + 1; 2393 s->type = COMEDI_SUBD_AO; 2394 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; 2395 s->n_chan = this_board->n_aochan; 2396 s->maxdata = this_board->ao_maxdata; 2397 s->len_chanlist = this_board->n_aochan; 2398 s->range_table = this_board->rangelist_ao; 2399 s->insn_write = pci9118_insn_write_ao; 2400 s->insn_read = pci9118_insn_read_ao; 2401 2402 s = dev->subdevices + 2; 2403 s->type = COMEDI_SUBD_DI; 2404 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; 2405 s->n_chan = 4; 2406 s->maxdata = 1; 2407 s->len_chanlist = 4; 2408 s->range_table = &range_digital; 2409 s->io_bits = 0; /* all bits input */ 2410 s->insn_bits = pci9118_insn_bits_di; 2411 2412 s = dev->subdevices + 3; 2413 s->type = COMEDI_SUBD_DO; 2414 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; 2415 s->n_chan = 4; 2416 s->maxdata = 1; 2417 s->len_chanlist = 4; 2418 s->range_table = &range_digital; 2419 s->io_bits = 0xf; /* all bits output */ 2420 s->insn_bits = pci9118_insn_bits_do; 2421 2422 devpriv->valid = 1; 2423 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ 2424 devpriv->ai_maskharderr = 0x10a; 2425 /* default measure crash condition */ 2426 if (it->options[5]) /* disable some requested */ 2427 devpriv->ai_maskharderr &= ~it->options[5]; 2428 2429 switch (this_board->ai_maxdata) { 2430 case 0xffff: 2431 devpriv->ai16bits = 1; 2432 break; 2433 default: 2434 devpriv->ai16bits = 0; 2435 break; 2436 } 2437 return 0; 2438} 2439 2440/* 2441============================================================================== 2442*/ 2443static int pci9118_detach(struct comedi_device *dev) 2444{ 2445 if (dev->private) { 2446 if (devpriv->valid) 2447 pci9118_reset(dev); 2448 if (dev->irq) 2449 free_irq(dev->irq, dev); 2450 if (devpriv->pcidev) { 2451 if (dev->iobase) 2452 comedi_pci_disable(devpriv->pcidev); 2453 2454 pci_dev_put(devpriv->pcidev); 2455 } 2456 if (devpriv->dmabuf_virt[0]) 2457 free_pages((unsigned long)devpriv->dmabuf_virt[0], 2458 devpriv->dmabuf_pages[0]); 2459 if (devpriv->dmabuf_virt[1]) 2460 free_pages((unsigned long)devpriv->dmabuf_virt[1], 2461 devpriv->dmabuf_pages[1]); 2462 } 2463 2464 return 0; 2465} 2466 2467/* 2468============================================================================== 2469*/ 2470 2471MODULE_AUTHOR("Comedi http://www.comedi.org"); 2472MODULE_DESCRIPTION("Comedi low-level driver"); 2473MODULE_LICENSE("GPL"); 2474