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