adl_pci9118.c revision a41aec1be2b3b21c08b84fb1e70e23aab29c5820
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 if (int_adstat & devpriv->ai_maskerr) 754 /* if (int_adstat & 0x106) */ 755 if (pci9118_decode_error_status(dev, s, int_adstat)) 756 return; 757 758 samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; 759 /* number of received real samples */ 760/* DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf); */ 761 762 if (devpriv->dma_doublebuf) { /* 763 * switch DMA buffers if is used 764 * double buffering 765 */ 766 next_dma_buf = 1 - devpriv->dma_actbuf; 767 outl(devpriv->dmabuf_hw[next_dma_buf], 768 devpriv->iobase_a + AMCC_OP_REG_MWAR); 769 outl(devpriv->dmabuf_use_size[next_dma_buf], 770 devpriv->iobase_a + AMCC_OP_REG_MWTC); 771 devpriv->dmabuf_used_size[next_dma_buf] = 772 devpriv->dmabuf_use_size[next_dma_buf]; 773 if (devpriv->ai_do == 4) 774 interrupt_pci9118_ai_mode4_switch(dev); 775 } 776 777 if (samplesinbuf) { 778 m = devpriv->ai_data_len >> 1; /* 779 * how many samples is to 780 * end of buffer 781 */ 782/* 783 * DPRINTK("samps=%d m=%d %d %d\n", 784 * samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr); 785 */ 786 sampls = m; 787 move_block_from_dma(dev, s, 788 devpriv->dmabuf_virt[devpriv->dma_actbuf], 789 samplesinbuf); 790 m = m - sampls; /* m= how many samples was transfered */ 791 } 792/* DPRINTK("YYY\n"); */ 793 794 if (!devpriv->ai_neverending) 795 if (devpriv->ai_act_scan >= devpriv->ai_scans) { 796 /* all data sampled */ 797 pci9118_ai_cancel(dev, s); 798 s->async->events |= COMEDI_CB_EOA; 799 } 800 801 if (devpriv->dma_doublebuf) { /* switch dma buffers */ 802 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf; 803 } else { /* restart DMA if is not used double buffering */ 804 outl(devpriv->dmabuf_hw[0], 805 devpriv->iobase_a + AMCC_OP_REG_MWAR); 806 outl(devpriv->dmabuf_use_size[0], 807 devpriv->iobase_a + AMCC_OP_REG_MWTC); 808 if (devpriv->ai_do == 4) 809 interrupt_pci9118_ai_mode4_switch(dev); 810 } 811 812 comedi_event(dev, s); 813} 814 815/* 816============================================================================== 817*/ 818static irqreturn_t interrupt_pci9118(int irq, void *d) 819{ 820 struct comedi_device *dev = d; 821 unsigned int int_daq = 0, int_amcc, int_adstat; 822 823 if (!dev->attached) 824 return IRQ_NONE; /* not fully initialized */ 825 826 int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; 827 /* get IRQ reasons from card */ 828 int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); 829 /* get INT register from AMCC chip */ 830 831/* 832 * DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x 833 * MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", 834 * int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), 835 * inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), 836 * inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do); 837 */ 838 839 if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) 840 return IRQ_NONE; /* interrupt from other source */ 841 842 outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); 843 /* shutdown IRQ reasons in AMCC */ 844 845 int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; 846 /* get STATUS register */ 847 848 if (devpriv->ai_do) { 849 if (devpriv->ai12_startstop) 850 if ((int_adstat & AdStatus_DTH) && 851 (int_daq & Int_DTrg)) { 852 /* start stop of measure */ 853 if (devpriv->ai12_startstop & START_AI_EXT) { 854 devpriv->ai12_startstop &= 855 ~START_AI_EXT; 856 if (!(devpriv->ai12_startstop & 857 STOP_AI_EXT)) 858 pci9118_exttrg_del 859 (dev, EXTTRG_AI); 860 /* deactivate EXT trigger */ 861 start_pacer(dev, devpriv->ai_do, 862 devpriv->ai_divisor1, 863 devpriv->ai_divisor2); 864 /* start pacer */ 865 outl(devpriv->AdControlReg, 866 dev->iobase + PCI9118_ADCNTRL); 867 } else { 868 if (devpriv->ai12_startstop & 869 STOP_AI_EXT) { 870 devpriv->ai12_startstop &= 871 ~STOP_AI_EXT; 872 pci9118_exttrg_del 873 (dev, EXTTRG_AI); 874 /* deactivate EXT trigger */ 875 devpriv->ai_neverending = 0; 876 /* 877 * well, on next interrupt from 878 * DMA/EOC measure will stop 879 */ 880 } 881 } 882 } 883 884 (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat, 885 int_amcc, int_daq); 886 887 } 888 return IRQ_HANDLED; 889} 890 891/* 892============================================================================== 893*/ 894static int pci9118_ai_inttrig(struct comedi_device *dev, 895 struct comedi_subdevice *s, unsigned int trignum) 896{ 897 if (trignum != devpriv->ai_inttrig_start) 898 return -EINVAL; 899 900 devpriv->ai12_startstop &= ~START_AI_INT; 901 s->async->inttrig = NULL; 902 903 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 904 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 905 if (devpriv->ai_do != 3) { 906 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 907 devpriv->ai_divisor2); 908 devpriv->AdControlReg |= AdControl_SoftG; 909 } 910 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 911 912 return 1; 913} 914 915/* 916============================================================================== 917*/ 918static int pci9118_ai_cmdtest(struct comedi_device *dev, 919 struct comedi_subdevice *s, 920 struct comedi_cmd *cmd) 921{ 922 int err = 0; 923 int tmp, divisor1 = 0, divisor2 = 0; 924 925 /* step 1: make sure trigger sources are trivially valid */ 926 927 tmp = cmd->start_src; 928 cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT; 929 if (!cmd->start_src || tmp != cmd->start_src) 930 err++; 931 932 tmp = cmd->scan_begin_src; 933 if (devpriv->master) 934 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW; 935 else 936 cmd->scan_begin_src &= TRIG_FOLLOW; 937 938 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 939 err++; 940 941 tmp = cmd->convert_src; 942 if (devpriv->master) 943 cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW; 944 else 945 cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 946 947 if (!cmd->convert_src || tmp != cmd->convert_src) 948 err++; 949 950 tmp = cmd->scan_end_src; 951 cmd->scan_end_src &= TRIG_COUNT; 952 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 953 err++; 954 955 tmp = cmd->stop_src; 956 cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT; 957 if (!cmd->stop_src || tmp != cmd->stop_src) 958 err++; 959 960 if (err) 961 return 1; 962 963 /* 964 * step 2: 965 * make sure trigger sources are 966 * unique and mutually compatible 967 */ 968 969 if (cmd->start_src != TRIG_NOW && 970 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) { 971 cmd->start_src = TRIG_NOW; 972 err++; 973 } 974 975 if (cmd->scan_begin_src != TRIG_TIMER && 976 cmd->scan_begin_src != TRIG_EXT && 977 cmd->scan_begin_src != TRIG_INT && 978 cmd->scan_begin_src != TRIG_FOLLOW) { 979 cmd->scan_begin_src = TRIG_FOLLOW; 980 err++; 981 } 982 983 if (cmd->convert_src != TRIG_TIMER && 984 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) { 985 cmd->convert_src = TRIG_TIMER; 986 err++; 987 } 988 989 if (cmd->scan_end_src != TRIG_COUNT) { 990 cmd->scan_end_src = TRIG_COUNT; 991 err++; 992 } 993 994 if (cmd->stop_src != TRIG_NONE && 995 cmd->stop_src != TRIG_COUNT && 996 cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) { 997 cmd->stop_src = TRIG_COUNT; 998 err++; 999 } 1000 1001 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { 1002 cmd->start_src = TRIG_NOW; 1003 err++; 1004 } 1005 1006 if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) { 1007 cmd->start_src = TRIG_NOW; 1008 err++; 1009 } 1010 1011 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) && 1012 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) { 1013 cmd->convert_src = TRIG_TIMER; 1014 err++; 1015 } 1016 1017 if ((cmd->scan_begin_src == TRIG_FOLLOW) && 1018 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) { 1019 cmd->convert_src = TRIG_TIMER; 1020 err++; 1021 } 1022 1023 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) { 1024 cmd->stop_src = TRIG_COUNT; 1025 err++; 1026 } 1027 1028 if (err) 1029 return 2; 1030 1031 /* step 3: make sure arguments are trivially compatible */ 1032 1033 if (cmd->start_src & (TRIG_NOW | TRIG_EXT)) 1034 if (cmd->start_arg != 0) { 1035 cmd->start_arg = 0; 1036 err++; 1037 } 1038 1039 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT)) 1040 if (cmd->scan_begin_arg != 0) { 1041 cmd->scan_begin_arg = 0; 1042 err++; 1043 } 1044 1045 if ((cmd->scan_begin_src == TRIG_TIMER) && 1046 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) { 1047 cmd->scan_begin_src = TRIG_FOLLOW; 1048 cmd->convert_arg = cmd->scan_begin_arg; 1049 cmd->scan_begin_arg = 0; 1050 } 1051 1052 if (cmd->scan_begin_src == TRIG_TIMER) 1053 if (cmd->scan_begin_arg < this_board->ai_ns_min) { 1054 cmd->scan_begin_arg = this_board->ai_ns_min; 1055 err++; 1056 } 1057 1058 if (cmd->scan_begin_src == TRIG_EXT) 1059 if (cmd->scan_begin_arg) { 1060 cmd->scan_begin_arg = 0; 1061 err++; 1062 if (cmd->scan_end_arg > 65535) { 1063 cmd->scan_end_arg = 65535; 1064 err++; 1065 } 1066 } 1067 1068 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) 1069 if (cmd->convert_arg < this_board->ai_ns_min) { 1070 cmd->convert_arg = this_board->ai_ns_min; 1071 err++; 1072 } 1073 1074 if (cmd->convert_src == TRIG_EXT) 1075 if (cmd->convert_arg) { 1076 cmd->convert_arg = 0; 1077 err++; 1078 } 1079 1080 if (cmd->stop_src == TRIG_COUNT) { 1081 if (!cmd->stop_arg) { 1082 cmd->stop_arg = 1; 1083 err++; 1084 } 1085 } else { /* TRIG_NONE */ 1086 if (cmd->stop_arg != 0) { 1087 cmd->stop_arg = 0; 1088 err++; 1089 } 1090 } 1091 1092 if (!cmd->chanlist_len) { 1093 cmd->chanlist_len = 1; 1094 err++; 1095 } 1096 1097 if (cmd->chanlist_len > this_board->n_aichanlist) { 1098 cmd->chanlist_len = this_board->n_aichanlist; 1099 err++; 1100 } 1101 1102 if (cmd->scan_end_arg < cmd->chanlist_len) { 1103 cmd->scan_end_arg = cmd->chanlist_len; 1104 err++; 1105 } 1106 1107 if ((cmd->scan_end_arg % cmd->chanlist_len)) { 1108 cmd->scan_end_arg = 1109 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len); 1110 err++; 1111 } 1112 1113 if (err) 1114 return 3; 1115 1116 /* step 4: fix up any arguments */ 1117 1118 if (cmd->scan_begin_src == TRIG_TIMER) { 1119 tmp = cmd->scan_begin_arg; 1120/* printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1121 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, 1122 &divisor2, &cmd->scan_begin_arg, 1123 cmd->flags & TRIG_ROUND_MASK); 1124/* printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1125 if (cmd->scan_begin_arg < this_board->ai_ns_min) 1126 cmd->scan_begin_arg = this_board->ai_ns_min; 1127 if (tmp != cmd->scan_begin_arg) 1128 err++; 1129 } 1130 1131 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) { 1132 tmp = cmd->convert_arg; 1133 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1, 1134 &divisor2, &cmd->convert_arg, 1135 cmd->flags & TRIG_ROUND_MASK); 1136/* printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1137 if (cmd->convert_arg < this_board->ai_ns_min) 1138 cmd->convert_arg = this_board->ai_ns_min; 1139 if (tmp != cmd->convert_arg) 1140 err++; 1141 if (cmd->scan_begin_src == TRIG_TIMER 1142 && cmd->convert_src == TRIG_NOW) { 1143 if (cmd->convert_arg == 0) { 1144 if (cmd->scan_begin_arg < 1145 this_board->ai_ns_min * 1146 (cmd->scan_end_arg + 2)) { 1147 cmd->scan_begin_arg = 1148 this_board->ai_ns_min * 1149 (cmd->scan_end_arg + 2); 1150/* printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1151 err++; 1152 } 1153 } else { 1154 if (cmd->scan_begin_arg < 1155 cmd->convert_arg * cmd->chanlist_len) { 1156 cmd->scan_begin_arg = 1157 cmd->convert_arg * 1158 cmd->chanlist_len; 1159/* printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg); */ 1160 err++; 1161 } 1162 } 1163 } 1164 } 1165 1166 if (err) 1167 return 4; 1168 1169 if (cmd->chanlist) 1170 if (!check_channel_list(dev, s, cmd->chanlist_len, 1171 cmd->chanlist, 0, 0)) 1172 return 5; /* incorrect channels list */ 1173 1174 return 0; 1175} 1176 1177/* 1178============================================================================== 1179*/ 1180static int Compute_and_setup_dma(struct comedi_device *dev) 1181{ 1182 unsigned int dmalen0, dmalen1, i; 1183 1184 DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n"); 1185 dmalen0 = devpriv->dmabuf_size[0]; 1186 dmalen1 = devpriv->dmabuf_size[1]; 1187 DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1, 1188 devpriv->ai_data_len); 1189 /* isn't output buff smaller that our DMA buff? */ 1190 if (dmalen0 > (devpriv->ai_data_len)) { 1191 dmalen0 = devpriv->ai_data_len & ~3L; /* 1192 * align to 32bit down 1193 */ 1194 } 1195 if (dmalen1 > (devpriv->ai_data_len)) { 1196 dmalen1 = devpriv->ai_data_len & ~3L; /* 1197 * align to 32bit down 1198 */ 1199 } 1200 DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); 1201 1202 /* we want wake up every scan? */ 1203 if (devpriv->ai_flags & TRIG_WAKE_EOS) { 1204 if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { 1205 /* uff, too short DMA buffer, disable EOS support! */ 1206 devpriv->ai_flags &= (~TRIG_WAKE_EOS); 1207 printk 1208 ("comedi%d: WAR: DMA0 buf too short, can't " 1209 "support TRIG_WAKE_EOS (%d<%d)\n", 1210 dev->minor, dmalen0, 1211 devpriv->ai_n_realscanlen << 1); 1212 } else { 1213 /* short first DMA buffer to one scan */ 1214 dmalen0 = devpriv->ai_n_realscanlen << 1; 1215 DPRINTK 1216 ("21 dmalen0=%d ai_n_realscanlen=%d " 1217 "useeoshandle=%d\n", 1218 dmalen0, devpriv->ai_n_realscanlen, 1219 devpriv->useeoshandle); 1220 if (devpriv->useeoshandle) 1221 dmalen0 += 2; 1222 if (dmalen0 < 4) { 1223 printk 1224 ("comedi%d: ERR: DMA0 buf len bug? " 1225 "(%d<4)\n", 1226 dev->minor, dmalen0); 1227 dmalen0 = 4; 1228 } 1229 } 1230 } 1231 if (devpriv->ai_flags & TRIG_WAKE_EOS) { 1232 if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { 1233 /* uff, too short DMA buffer, disable EOS support! */ 1234 devpriv->ai_flags &= (~TRIG_WAKE_EOS); 1235 printk 1236 ("comedi%d: WAR: DMA1 buf too short, " 1237 "can't support TRIG_WAKE_EOS (%d<%d)\n", 1238 dev->minor, dmalen1, 1239 devpriv->ai_n_realscanlen << 1); 1240 } else { 1241 /* short second DMA buffer to one scan */ 1242 dmalen1 = devpriv->ai_n_realscanlen << 1; 1243 DPRINTK 1244 ("22 dmalen1=%d ai_n_realscanlen=%d " 1245 "useeoshandle=%d\n", 1246 dmalen1, devpriv->ai_n_realscanlen, 1247 devpriv->useeoshandle); 1248 if (devpriv->useeoshandle) 1249 dmalen1 -= 2; 1250 if (dmalen1 < 4) { 1251 printk 1252 ("comedi%d: ERR: DMA1 buf len bug? " 1253 "(%d<4)\n", 1254 dev->minor, dmalen1); 1255 dmalen1 = 4; 1256 } 1257 } 1258 } 1259 1260 DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); 1261 /* transfer without TRIG_WAKE_EOS */ 1262 if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) { 1263 /* if it's possible then allign DMA buffers to length of scan */ 1264 i = dmalen0; 1265 dmalen0 = 1266 (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * 1267 (devpriv->ai_n_realscanlen << 1); 1268 dmalen0 &= ~3L; 1269 if (!dmalen0) 1270 dmalen0 = i; /* uff. very long scan? */ 1271 i = dmalen1; 1272 dmalen1 = 1273 (dmalen1 / (devpriv->ai_n_realscanlen << 1)) * 1274 (devpriv->ai_n_realscanlen << 1); 1275 dmalen1 &= ~3L; 1276 if (!dmalen1) 1277 dmalen1 = i; /* uff. very long scan? */ 1278 /* 1279 * if measure isn't neverending then test, if it fits whole 1280 * into one or two DMA buffers 1281 */ 1282 if (!devpriv->ai_neverending) { 1283 /* fits whole measure into one DMA buffer? */ 1284 if (dmalen0 > 1285 ((devpriv->ai_n_realscanlen << 1) * 1286 devpriv->ai_scans)) { 1287 DPRINTK 1288 ("3.0 ai_n_realscanlen=%d ai_scans=%d \n", 1289 devpriv->ai_n_realscanlen, 1290 devpriv->ai_scans); 1291 dmalen0 = 1292 (devpriv->ai_n_realscanlen << 1) * 1293 devpriv->ai_scans; 1294 DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0, 1295 dmalen1); 1296 dmalen0 &= ~3L; 1297 } else { /* 1298 * fits whole measure into 1299 * two DMA buffer? 1300 */ 1301 if (dmalen1 > 1302 ((devpriv->ai_n_realscanlen << 1) * 1303 devpriv->ai_scans - dmalen0)) 1304 dmalen1 = 1305 (devpriv->ai_n_realscanlen << 1) * 1306 devpriv->ai_scans - dmalen0; 1307 DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0, 1308 dmalen1); 1309 dmalen1 &= ~3L; 1310 } 1311 } 1312 } 1313 1314 DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); 1315 1316 /* these DMA buffer size will be used */ 1317 devpriv->dma_actbuf = 0; 1318 devpriv->dmabuf_use_size[0] = dmalen0; 1319 devpriv->dmabuf_use_size[1] = dmalen1; 1320 1321 DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1); 1322#if 0 1323 if (devpriv->ai_n_scanlen < this_board->half_fifo_size) { 1324 devpriv->dmabuf_panic_size[0] = 1325 (this_board->half_fifo_size / devpriv->ai_n_scanlen + 1326 1) * devpriv->ai_n_scanlen * sizeof(short); 1327 devpriv->dmabuf_panic_size[1] = 1328 (this_board->half_fifo_size / devpriv->ai_n_scanlen + 1329 1) * devpriv->ai_n_scanlen * sizeof(short); 1330 } else { 1331 devpriv->dmabuf_panic_size[0] = 1332 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0]; 1333 devpriv->dmabuf_panic_size[1] = 1334 (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1]; 1335 } 1336#endif 1337 1338 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), 1339 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ 1340 outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR); 1341 outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC); 1342 /* init DMA transfer */ 1343 outl(0x00000000 | AINT_WRITE_COMPL, 1344 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1345/* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */ 1346 1347 outl(inl(devpriv->iobase_a + 1348 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY | 1349 EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR); 1350 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, 1351 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1352 /* allow bus mastering */ 1353 1354 DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n"); 1355 return 0; 1356} 1357 1358/* 1359============================================================================== 1360*/ 1361static int pci9118_ai_docmd_sampl(struct comedi_device *dev, 1362 struct comedi_subdevice *s) 1363{ 1364 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n", 1365 dev->minor, devpriv->ai_do); 1366 switch (devpriv->ai_do) { 1367 case 1: 1368 devpriv->AdControlReg |= AdControl_TmrTr; 1369 break; 1370 case 2: 1371 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n"); 1372 return -EIO; 1373 case 3: 1374 devpriv->AdControlReg |= AdControl_ExtM; 1375 break; 1376 case 4: 1377 comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n"); 1378 return -EIO; 1379 default: 1380 comedi_error(dev, 1381 "pci9118_ai_docmd_sampl() mode number bug!\n"); 1382 return -EIO; 1383 }; 1384 1385 devpriv->int_ai_func = interrupt_pci9118_ai_onesample; 1386 /* transfer function */ 1387 1388 if (devpriv->ai12_startstop) 1389 pci9118_exttrg_add(dev, EXTTRG_AI); 1390 /* activate EXT trigger */ 1391 1392 if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2)) 1393 devpriv->IntControlReg |= Int_Timer; 1394 1395 devpriv->AdControlReg |= AdControl_Int; 1396 1397 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 1398 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1399 /* allow INT in AMCC */ 1400 1401 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) { 1402 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1403 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1404 if (devpriv->ai_do != 3) { 1405 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 1406 devpriv->ai_divisor2); 1407 devpriv->AdControlReg |= AdControl_SoftG; 1408 } 1409 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1410 } 1411 1412 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n"); 1413 return 0; 1414} 1415 1416/* 1417============================================================================== 1418*/ 1419static int pci9118_ai_docmd_dma(struct comedi_device *dev, 1420 struct comedi_subdevice *s) 1421{ 1422 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n", 1423 dev->minor, devpriv->ai_do, devpriv->usedma); 1424 Compute_and_setup_dma(dev); 1425 1426 switch (devpriv->ai_do) { 1427 case 1: 1428 devpriv->AdControlReg |= 1429 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1430 break; 1431 case 2: 1432 devpriv->AdControlReg |= 1433 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1434 devpriv->AdFunctionReg = 1435 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM | 1436 AdFunction_BS; 1437 if (devpriv->usessh && (!devpriv->softsshdelay)) 1438 devpriv->AdFunctionReg |= AdFunction_BSSH; 1439 outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST); 1440 break; 1441 case 3: 1442 devpriv->AdControlReg |= 1443 ((AdControl_ExtM | AdControl_Dma) & 0xff); 1444 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 1445 break; 1446 case 4: 1447 devpriv->AdControlReg |= 1448 ((AdControl_TmrTr | AdControl_Dma) & 0xff); 1449 devpriv->AdFunctionReg = 1450 AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM; 1451 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1452 outl(0x30, dev->iobase + PCI9118_CNTCTRL); 1453 outl((devpriv->dmabuf_hw[0] >> 1) & 0xff, 1454 dev->iobase + PCI9118_CNT0); 1455 outl((devpriv->dmabuf_hw[0] >> 9) & 0xff, 1456 dev->iobase + PCI9118_CNT0); 1457 devpriv->AdFunctionReg |= AdFunction_Start; 1458 break; 1459 default: 1460 comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n"); 1461 return -EIO; 1462 }; 1463 1464 if (devpriv->ai12_startstop) { 1465 pci9118_exttrg_add(dev, EXTTRG_AI); 1466 /* activate EXT trigger */ 1467 } 1468 1469 devpriv->int_ai_func = interrupt_pci9118_ai_dma; 1470 /* transfer function */ 1471 1472 outl(0x02000000 | AINT_WRITE_COMPL, 1473 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 1474 1475 if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) { 1476 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1477 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 1478 if (devpriv->ai_do != 3) { 1479 start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, 1480 devpriv->ai_divisor2); 1481 devpriv->AdControlReg |= AdControl_SoftG; 1482 } 1483 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1484 } 1485 1486 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n"); 1487 return 0; 1488} 1489 1490/* 1491============================================================================== 1492*/ 1493static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 1494{ 1495 struct comedi_cmd *cmd = &s->async->cmd; 1496 unsigned int addchans = 0; 1497 int ret = 0; 1498 1499 DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor); 1500 devpriv->ai12_startstop = 0; 1501 devpriv->ai_flags = cmd->flags; 1502 devpriv->ai_n_chan = cmd->chanlist_len; 1503 devpriv->ai_n_scanlen = cmd->scan_end_arg; 1504 devpriv->ai_chanlist = cmd->chanlist; 1505 devpriv->ai_data = s->async->prealloc_buf; 1506 devpriv->ai_data_len = s->async->prealloc_bufsz; 1507 devpriv->ai_timer1 = 0; 1508 devpriv->ai_timer2 = 0; 1509 devpriv->ai_add_front = 0; 1510 devpriv->ai_add_back = 0; 1511 devpriv->ai_maskerr = 0x10e; 1512 1513 /* prepare for start/stop conditions */ 1514 if (cmd->start_src == TRIG_EXT) 1515 devpriv->ai12_startstop |= START_AI_EXT; 1516 if (cmd->stop_src == TRIG_EXT) { 1517 devpriv->ai_neverending = 1; 1518 devpriv->ai12_startstop |= STOP_AI_EXT; 1519 } 1520 if (cmd->start_src == TRIG_INT) { 1521 devpriv->ai12_startstop |= START_AI_INT; 1522 devpriv->ai_inttrig_start = cmd->start_arg; 1523 s->async->inttrig = pci9118_ai_inttrig; 1524 } 1525#if 0 1526 if (cmd->stop_src == TRIG_INT) { 1527 devpriv->ai_neverending = 1; 1528 devpriv->ai12_startstop |= STOP_AI_INT; 1529 } 1530#endif 1531 if (cmd->stop_src == TRIG_NONE) 1532 devpriv->ai_neverending = 1; 1533 if (cmd->stop_src == TRIG_COUNT) { 1534 devpriv->ai_scans = cmd->stop_arg; 1535 devpriv->ai_neverending = 0; 1536 } else { 1537 devpriv->ai_scans = 0; 1538 } 1539 1540 /* use sample&hold signal? */ 1541 if (cmd->convert_src == TRIG_NOW) { 1542 devpriv->usessh = 1; 1543 } /* yes */ 1544 else { 1545 devpriv->usessh = 0; 1546 } /* no */ 1547 1548 DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n", 1549 devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh, 1550 devpriv->ai12_startstop); 1551 1552 /* 1553 * use additional sample at end of every scan 1554 * to satisty DMA 32 bit transfer? 1555 */ 1556 devpriv->ai_add_front = 0; 1557 devpriv->ai_add_back = 0; 1558 devpriv->useeoshandle = 0; 1559 if (devpriv->master) { 1560 devpriv->usedma = 1; 1561 if ((cmd->flags & TRIG_WAKE_EOS) && 1562 (devpriv->ai_n_scanlen == 1)) { 1563 if (cmd->convert_src == TRIG_NOW) { 1564 devpriv->ai_add_back = 1; 1565 } 1566 if (cmd->convert_src == TRIG_TIMER) { 1567 devpriv->usedma = 0; 1568 /* 1569 * use INT transfer if scanlist 1570 * have only one channel 1571 */ 1572 } 1573 } 1574 if ((cmd->flags & TRIG_WAKE_EOS) && 1575 (devpriv->ai_n_scanlen & 1) && 1576 (devpriv->ai_n_scanlen > 1)) { 1577 if (cmd->scan_begin_src == TRIG_FOLLOW) { 1578 /* 1579 * vpriv->useeoshandle=1; // change DMA transfer 1580 * block to fit EOS on every second call 1581 */ 1582 devpriv->usedma = 0; 1583 /* 1584 * XXX maybe can be corrected to use 16 bit DMA 1585 */ 1586 } else { /* 1587 * well, we must insert one sample 1588 * to end of EOS to meet 32 bit transfer 1589 */ 1590 devpriv->ai_add_back = 1; 1591 } 1592 } 1593 } else { /* interrupt transfer don't need any correction */ 1594 devpriv->usedma = 0; 1595 } 1596 1597 /* 1598 * we need software S&H signal? 1599 * It adds two samples before every scan as minimum 1600 */ 1601 if (devpriv->usessh && devpriv->softsshdelay) { 1602 devpriv->ai_add_front = 2; 1603 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { 1604 /* move it to front */ 1605 devpriv->ai_add_front++; 1606 devpriv->ai_add_back = 0; 1607 } 1608 if (cmd->convert_arg < this_board->ai_ns_min) 1609 cmd->convert_arg = this_board->ai_ns_min; 1610 addchans = devpriv->softsshdelay / cmd->convert_arg; 1611 if (devpriv->softsshdelay % cmd->convert_arg) 1612 addchans++; 1613 if (addchans > (devpriv->ai_add_front - 1)) { 1614 /* uff, still short */ 1615 devpriv->ai_add_front = addchans + 1; 1616 if (devpriv->usedma == 1) 1617 if ((devpriv->ai_add_front + 1618 devpriv->ai_n_chan + 1619 devpriv->ai_add_back) & 1) 1620 devpriv->ai_add_front++; 1621 /* round up to 32 bit */ 1622 } 1623 } 1624 /* well, we now know what must be all added */ 1625 devpriv->ai_n_realscanlen = /* 1626 * what we must take from card in real 1627 * to have ai_n_scanlen on output? 1628 */ 1629 (devpriv->ai_add_front + devpriv->ai_n_chan + 1630 devpriv->ai_add_back) * (devpriv->ai_n_scanlen / 1631 devpriv->ai_n_chan); 1632 1633 DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n", 1634 devpriv->usedma, 1635 devpriv->ai_n_realscanlen, devpriv->ai_add_front, 1636 devpriv->ai_n_chan, devpriv->ai_add_back, 1637 devpriv->ai_n_scanlen); 1638 1639 /* check and setup channel list */ 1640 if (!check_channel_list(dev, s, devpriv->ai_n_chan, 1641 devpriv->ai_chanlist, devpriv->ai_add_front, 1642 devpriv->ai_add_back)) 1643 return -EINVAL; 1644 if (!setup_channel_list(dev, s, devpriv->ai_n_chan, 1645 devpriv->ai_chanlist, 0, devpriv->ai_add_front, 1646 devpriv->ai_add_back, devpriv->usedma, 1647 devpriv->useeoshandle)) 1648 return -EINVAL; 1649 1650 /* compute timers settings */ 1651 /* 1652 * simplest way, fr=4Mhz/(tim1*tim2), 1653 * channel manipulation without timers effect 1654 */ 1655 if (((cmd->scan_begin_src == TRIG_FOLLOW) || 1656 (cmd->scan_begin_src == TRIG_EXT) || 1657 (cmd->scan_begin_src == TRIG_INT)) && 1658 (cmd->convert_src == TRIG_TIMER)) { 1659 /* both timer is used for one time */ 1660 if (cmd->scan_begin_src == TRIG_EXT) { 1661 devpriv->ai_do = 4; 1662 } else { 1663 devpriv->ai_do = 1; 1664 } 1665 pci9118_calc_divisors(devpriv->ai_do, dev, s, 1666 &cmd->scan_begin_arg, &cmd->convert_arg, 1667 devpriv->ai_flags, 1668 devpriv->ai_n_realscanlen, 1669 &devpriv->ai_divisor1, 1670 &devpriv->ai_divisor2, devpriv->usessh, 1671 devpriv->ai_add_front); 1672 devpriv->ai_timer2 = cmd->convert_arg; 1673 } 1674 1675 if ((cmd->scan_begin_src == TRIG_TIMER) && 1676 ((cmd->convert_src == TRIG_TIMER) || 1677 (cmd->convert_src == TRIG_NOW))) { 1678 /* double timed action */ 1679 if (!devpriv->usedma) { 1680 comedi_error(dev, 1681 "cmd->scan_begin_src=TRIG_TIMER works " 1682 "only with bus mastering!"); 1683 return -EIO; 1684 } 1685 1686 devpriv->ai_do = 2; 1687 pci9118_calc_divisors(devpriv->ai_do, dev, s, 1688 &cmd->scan_begin_arg, &cmd->convert_arg, 1689 devpriv->ai_flags, 1690 devpriv->ai_n_realscanlen, 1691 &devpriv->ai_divisor1, 1692 &devpriv->ai_divisor2, devpriv->usessh, 1693 devpriv->ai_add_front); 1694 devpriv->ai_timer1 = cmd->scan_begin_arg; 1695 devpriv->ai_timer2 = cmd->convert_arg; 1696 } 1697 1698 if ((cmd->scan_begin_src == TRIG_FOLLOW) 1699 && (cmd->convert_src == TRIG_EXT)) { 1700 devpriv->ai_do = 3; 1701 } 1702 1703 start_pacer(dev, -1, 0, 0); /* stop pacer */ 1704 1705 devpriv->AdControlReg = 0; /* 1706 * bipolar, S.E., use 8254, stop 8354, 1707 * internal trigger, soft trigger, 1708 * disable DMA 1709 */ 1710 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1711 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 1712 /* 1713 * positive triggers, no S&H, no burst, 1714 * burst stop, no post trigger, 1715 * no about trigger, trigger stop 1716 */ 1717 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 1718 udelay(1); 1719 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 1720 inl(dev->iobase + PCI9118_ADSTAT); /* 1721 * flush A/D and INT 1722 * status register 1723 */ 1724 inl(dev->iobase + PCI9118_INTSRC); 1725 1726 devpriv->ai_act_scan = 0; 1727 devpriv->ai_act_dmapos = 0; 1728 s->async->cur_chan = 0; 1729 devpriv->ai_buf_ptr = 0; 1730 1731 if (devpriv->usedma) 1732 ret = pci9118_ai_docmd_dma(dev, s); 1733 else 1734 ret = pci9118_ai_docmd_sampl(dev, s); 1735 1736 DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n"); 1737 return ret; 1738} 1739 1740/* 1741============================================================================== 1742*/ 1743static int check_channel_list(struct comedi_device *dev, 1744 struct comedi_subdevice *s, int n_chan, 1745 unsigned int *chanlist, int frontadd, int backadd) 1746{ 1747 unsigned int i, differencial = 0, bipolar = 0; 1748 1749 /* correct channel and range number check itself comedi/range.c */ 1750 if (n_chan < 1) { 1751 comedi_error(dev, "range/channel list is empty!"); 1752 return 0; 1753 } 1754 if ((frontadd + n_chan + backadd) > s->len_chanlist) { 1755 printk 1756 ("comedi%d: range/channel list is too long for " 1757 "actual configuration (%d>%d)!", 1758 dev->minor, n_chan, s->len_chanlist - frontadd - backadd); 1759 return 0; 1760 } 1761 1762 if (CR_AREF(chanlist[0]) == AREF_DIFF) 1763 differencial = 1; /* all input must be diff */ 1764 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) 1765 bipolar = 1; /* all input must be bipolar */ 1766 if (n_chan > 1) 1767 for (i = 1; i < n_chan; i++) { /* check S.E/diff */ 1768 if ((CR_AREF(chanlist[i]) == AREF_DIFF) != 1769 (differencial)) { 1770 comedi_error(dev, 1771 "Differencial and single ended " 1772 "inputs can't be mixtured!"); 1773 return 0; 1774 } 1775 if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) != 1776 (bipolar)) { 1777 comedi_error(dev, 1778 "Bipolar and unipolar ranges " 1779 "can't be mixtured!"); 1780 return 0; 1781 } 1782 if ((!devpriv->usemux) & (differencial) & 1783 (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) { 1784 comedi_error(dev, 1785 "If AREF_DIFF is used then is " 1786 "available only first 8 channels!"); 1787 return 0; 1788 } 1789 } 1790 1791 return 1; 1792} 1793 1794/* 1795============================================================================== 1796*/ 1797static int setup_channel_list(struct comedi_device *dev, 1798 struct comedi_subdevice *s, int n_chan, 1799 unsigned int *chanlist, int rot, int frontadd, 1800 int backadd, int usedma, char useeos) 1801{ 1802 unsigned int i, differencial = 0, bipolar = 0; 1803 unsigned int scanquad, gain, ssh = 0x00; 1804 1805 DPRINTK 1806 ("adl_pci9118 EDBG: BGN: setup_channel_list" 1807 "(%d,.,%d,.,%d,%d,%d,%d)\n", 1808 dev->minor, n_chan, rot, frontadd, backadd, usedma); 1809 1810 if (usedma == 1) { 1811 rot = 8; 1812 usedma = 0; 1813 } 1814 1815 if (CR_AREF(chanlist[0]) == AREF_DIFF) 1816 differencial = 1; /* all input must be diff */ 1817 if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES) 1818 bipolar = 1; /* all input must be bipolar */ 1819 1820 /* All is ok, so we can setup channel/range list */ 1821 1822 if (!bipolar) { 1823 devpriv->AdControlReg |= AdControl_UniP; 1824 /* set unibipolar */ 1825 } else { 1826 devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); 1827 /* enable bipolar */ 1828 } 1829 1830 if (differencial) { 1831 devpriv->AdControlReg |= AdControl_Diff; 1832 /* enable diff inputs */ 1833 } else { 1834 devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); 1835 /* set single ended inputs */ 1836 } 1837 1838 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 1839 /* setup mode */ 1840 1841 outl(2, dev->iobase + PCI9118_SCANMOD); 1842 /* gods know why this sequence! */ 1843 outl(0, dev->iobase + PCI9118_SCANMOD); 1844 outl(1, dev->iobase + PCI9118_SCANMOD); 1845 1846#ifdef PCI9118_PARANOIDCHECK 1847 devpriv->chanlistlen = n_chan; 1848 for (i = 0; i < (PCI9118_CHANLEN + 1); i++) 1849 devpriv->chanlist[i] = 0x55aa; 1850#endif 1851 1852 if (frontadd) { /* insert channels for S&H */ 1853 ssh = devpriv->softsshsample; 1854 DPRINTK("FA: %04x: ", ssh); 1855 for (i = 0; i < frontadd; i++) { 1856 /* store range list to card */ 1857 scanquad = CR_CHAN(chanlist[0]); 1858 /* get channel number; */ 1859 gain = CR_RANGE(chanlist[0]); 1860 /* get gain number */ 1861 scanquad |= ((gain & 0x03) << 8); 1862 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1863 DPRINTK("%02x ", scanquad | ssh); 1864 ssh = devpriv->softsshhold; 1865 } 1866 DPRINTK("\n "); 1867 } 1868 1869 DPRINTK("SL: ", ssh); 1870 for (i = 0; i < n_chan; i++) { /* store range list to card */ 1871 scanquad = CR_CHAN(chanlist[i]); /* get channel number */ 1872#ifdef PCI9118_PARANOIDCHECK 1873 devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot; 1874#endif 1875 gain = CR_RANGE(chanlist[i]); /* get gain number */ 1876 scanquad |= ((gain & 0x03) << 8); 1877 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1878 DPRINTK("%02x ", scanquad | ssh); 1879 } 1880 DPRINTK("\n "); 1881 1882 if (backadd) { /* insert channels for fit onto 32bit DMA */ 1883 DPRINTK("BA: %04x: ", ssh); 1884 for (i = 0; i < backadd; i++) { /* store range list to card */ 1885 scanquad = CR_CHAN(chanlist[0]); 1886 /* get channel number */ 1887 gain = CR_RANGE(chanlist[0]); /* get gain number */ 1888 scanquad |= ((gain & 0x03) << 8); 1889 outl(scanquad | ssh, dev->iobase + PCI9118_GAIN); 1890 DPRINTK("%02x ", scanquad | ssh); 1891 } 1892 DPRINTK("\n "); 1893 } 1894#ifdef PCI9118_PARANOIDCHECK 1895 devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; 1896 /* for 32bit operations */ 1897 if (useeos) { 1898 for (i = 1; i < n_chan; i++) { /* store range list to card */ 1899 devpriv->chanlist[(n_chan + i) ^ usedma] = 1900 (CR_CHAN(chanlist[i]) & 0xf) << rot; 1901 } 1902 devpriv->chanlist[(2 * n_chan) ^ usedma] = 1903 devpriv->chanlist[0 ^ usedma]; 1904 /* for 32bit operations */ 1905 useeos = 2; 1906 } else { 1907 useeos = 1; 1908 } 1909#ifdef PCI9118_EXTDEBUG 1910 DPRINTK("CHL: "); 1911 for (i = 0; i <= (useeos * n_chan); i++) 1912 DPRINTK("%04x ", devpriv->chanlist[i]); 1913 1914 DPRINTK("\n "); 1915#endif 1916#endif 1917 outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */ 1918 /* udelay(100); important delay, or first sample will be crippled */ 1919 1920 DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n"); 1921 return 1; /* we can serve this with scan logic */ 1922} 1923 1924/* 1925============================================================================== 1926 calculate 8254 divisors if they are used for dual timing 1927*/ 1928static void pci9118_calc_divisors(char mode, struct comedi_device *dev, 1929 struct comedi_subdevice *s, 1930 unsigned int *tim1, unsigned int *tim2, 1931 unsigned int flags, int chans, 1932 unsigned int *div1, unsigned int *div2, 1933 char usessh, unsigned int chnsshfront) 1934{ 1935 DPRINTK 1936 ("adl_pci9118 EDBG: BGN: pci9118_calc_divisors" 1937 "(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", 1938 mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront); 1939 switch (mode) { 1940 case 1: 1941 case 4: 1942 if (*tim2 < this_board->ai_ns_min) 1943 *tim2 = this_board->ai_ns_min; 1944 i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2, 1945 tim2, flags & TRIG_ROUND_NEAREST); 1946 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n", 1947 devpriv->i8254_osc_base, *div1, *div2, *tim1); 1948 break; 1949 case 2: 1950 if (*tim2 < this_board->ai_ns_min) 1951 *tim2 = this_board->ai_ns_min; 1952 DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1953 *tim1, *tim2); 1954 *div1 = *tim2 / devpriv->i8254_osc_base; 1955 /* convert timer (burst) */ 1956 DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1957 *tim1, *tim2); 1958 if (*div1 < this_board->ai_pacer_min) 1959 *div1 = this_board->ai_pacer_min; 1960 DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1961 *tim1, *tim2); 1962 *div2 = *tim1 / devpriv->i8254_osc_base; /* scan timer */ 1963 DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1964 *tim1, *tim2); 1965 *div2 = *div2 / *div1; /* major timer is c1*c2 */ 1966 DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1967 *tim1, *tim2); 1968 if (*div2 < chans) 1969 *div2 = chans; 1970 DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1971 *tim1, *tim2); 1972 1973 *tim2 = *div1 * devpriv->i8254_osc_base; 1974 /* real convert timer */ 1975 1976 if (usessh & (chnsshfront == 0)) /* use BSSH signal */ 1977 if (*div2 < (chans + 2)) 1978 *div2 = chans + 2; 1979 1980 DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2, 1981 *tim1, *tim2); 1982 *tim1 = *div1 * *div2 * devpriv->i8254_osc_base; 1983 DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n", 1984 devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2); 1985 break; 1986 } 1987 DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n", 1988 *div1, *div2); 1989} 1990 1991/* 1992============================================================================== 1993*/ 1994static void start_pacer(struct comedi_device *dev, int mode, 1995 unsigned int divisor1, unsigned int divisor2) 1996{ 1997 outl(0x74, dev->iobase + PCI9118_CNTCTRL); 1998 outl(0xb4, dev->iobase + PCI9118_CNTCTRL); 1999/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */ 2000 udelay(1); 2001 2002 if ((mode == 1) || (mode == 2) || (mode == 4)) { 2003 outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2); 2004 outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2); 2005 outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1); 2006 outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1); 2007 } 2008} 2009 2010/* 2011============================================================================== 2012*/ 2013static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source) 2014{ 2015 if (source > 3) 2016 return -1; /* incorrect source */ 2017 devpriv->exttrg_users |= (1 << source); 2018 devpriv->IntControlReg |= Int_DTrg; 2019 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2020 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 2021 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2022 /* allow INT in AMCC */ 2023 return 0; 2024} 2025 2026/* 2027============================================================================== 2028*/ 2029static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source) 2030{ 2031 if (source > 3) 2032 return -1; /* incorrect source */ 2033 devpriv->exttrg_users &= ~(1 << source); 2034 if (!devpriv->exttrg_users) { /* shutdown ext trg intterrupts */ 2035 devpriv->IntControlReg &= ~Int_DTrg; 2036 if (!devpriv->IntControlReg) /* all IRQ disabled */ 2037 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & 2038 (~0x00001f00), 2039 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2040 /* disable int in AMCC */ 2041 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2042 } 2043 return 0; 2044} 2045 2046/* 2047============================================================================== 2048*/ 2049static int pci9118_ai_cancel(struct comedi_device *dev, 2050 struct comedi_subdevice *s) 2051{ 2052 if (devpriv->usedma) 2053 outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & 2054 (~EN_A2P_TRANSFERS), 2055 devpriv->iobase_a + AMCC_OP_REG_MCSR); /* stop DMA */ 2056 pci9118_exttrg_del(dev, EXTTRG_AI); 2057 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ 2058 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 2059 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 2060 /* 2061 * positive triggers, no S&H, no burst, 2062 * burst stop, no post trigger, 2063 * no about trigger, trigger stop 2064 */ 2065 devpriv->AdControlReg = 0x00; 2066 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2067 /* 2068 * bipolar, S.E., use 8254, stop 8354, 2069 * internal trigger, soft trigger, 2070 * disable INT and DMA 2071 */ 2072 outl(0, dev->iobase + PCI9118_BURST); 2073 outl(1, dev->iobase + PCI9118_SCANMOD); 2074 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ 2075 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 2076 2077 devpriv->ai_do = 0; 2078 devpriv->usedma = 0; 2079 2080 devpriv->ai_act_scan = 0; 2081 devpriv->ai_act_dmapos = 0; 2082 s->async->cur_chan = 0; 2083 s->async->inttrig = NULL; 2084 devpriv->ai_buf_ptr = 0; 2085 devpriv->ai_neverending = 0; 2086 devpriv->dma_actbuf = 0; 2087 2088 if (!devpriv->IntControlReg) 2089 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, 2090 devpriv->iobase_a + AMCC_OP_REG_INTCSR); 2091 /* allow INT in AMCC */ 2092 2093 return 0; 2094} 2095 2096/* 2097============================================================================== 2098*/ 2099static int pci9118_reset(struct comedi_device *dev) 2100{ 2101 devpriv->IntControlReg = 0; 2102 devpriv->exttrg_users = 0; 2103 inl(dev->iobase + PCI9118_INTCTRL); 2104 outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); 2105 /* disable interrupts source */ 2106 outl(0x30, dev->iobase + PCI9118_CNTCTRL); 2107/* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */ 2108 start_pacer(dev, 0, 0, 0); /* stop 8254 counters */ 2109 devpriv->AdControlReg = 0; 2110 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2111 /* 2112 * bipolar, S.E., use 8254, 2113 * stop 8354, internal trigger, 2114 * soft trigger, 2115 * disable INT and DMA 2116 */ 2117 outl(0, dev->iobase + PCI9118_BURST); 2118 outl(1, dev->iobase + PCI9118_SCANMOD); 2119 outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */ 2120 devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; 2121 outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); 2122 /* 2123 * positive triggers, no S&H, 2124 * no burst, burst stop, 2125 * no post trigger, 2126 * no about trigger, 2127 * trigger stop 2128 */ 2129 2130 devpriv->ao_data[0] = 2047; 2131 devpriv->ao_data[1] = 2047; 2132 outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); 2133 /* reset A/D outs to 0V */ 2134 outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2); 2135 outl(0, dev->iobase + PCI9118_DO); /* reset digi outs to L */ 2136 udelay(10); 2137 inl(dev->iobase + PCI9118_AD_DATA); 2138 outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */ 2139 outl(0, dev->iobase + PCI9118_INTSRC); /* remove INT requests */ 2140 inl(dev->iobase + PCI9118_ADSTAT); /* flush A/D status register */ 2141 inl(dev->iobase + PCI9118_INTSRC); /* flush INT requests */ 2142 devpriv->AdControlReg = 0; 2143 outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); 2144 /* 2145 * bipolar, S.E., use 8254, 2146 * stop 8354, internal trigger, 2147 * soft trigger, 2148 * disable INT and DMA 2149 */ 2150 2151 devpriv->cnt0_users = 0; 2152 devpriv->exttrg_users = 0; 2153 2154 return 0; 2155} 2156 2157/* 2158============================================================================== 2159*/ 2160static int pci9118_attach(struct comedi_device *dev, 2161 struct comedi_devconfig *it) 2162{ 2163 struct comedi_subdevice *s; 2164 int ret, pages, i; 2165 unsigned short master; 2166 unsigned int irq; 2167 unsigned long iobase_a, iobase_9; 2168 struct pci_dev *pcidev; 2169 int opt_bus, opt_slot; 2170 const char *errstr; 2171 unsigned char pci_bus, pci_slot, pci_func; 2172 u16 u16w; 2173 2174 printk("comedi%d: adl_pci9118: board=%s", dev->minor, this_board->name); 2175 2176 opt_bus = it->options[0]; 2177 opt_slot = it->options[1]; 2178 if (it->options[3] & 1) { 2179 master = 0; /* user don't want use bus master */ 2180 } else { 2181 master = 1; 2182 } 2183 2184 ret = alloc_private(dev, sizeof(struct pci9118_private)); 2185 if (ret < 0) { 2186 printk(" - Allocation failed!\n"); 2187 return -ENOMEM; 2188 } 2189 2190 /* Look for matching PCI device */ 2191 errstr = "not found!"; 2192 pcidev = NULL; 2193 while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC, 2194 this_board->device_id, 2195 pcidev))) { 2196 /* Found matching vendor/device. */ 2197 if (opt_bus || opt_slot) { 2198 /* Check bus/slot. */ 2199 if (opt_bus != pcidev->bus->number 2200 || opt_slot != PCI_SLOT(pcidev->devfn)) 2201 continue; /* no match */ 2202 } 2203 /* 2204 * Look for device that isn't in use. 2205 * Enable PCI device and request regions. 2206 */ 2207 if (comedi_pci_enable(pcidev, "adl_pci9118")) { 2208 errstr = 2209 "failed to enable PCI device and request regions!"; 2210 continue; 2211 } 2212 break; 2213 } 2214 2215 if (!pcidev) { 2216 if (opt_bus || opt_slot) { 2217 printk(KERN_ERR " - Card at b:s %d:%d %s\n", 2218 opt_bus, opt_slot, errstr); 2219 } else { 2220 printk(KERN_ERR " - Card %s\n", errstr); 2221 } 2222 return -EIO; 2223 } 2224 2225 if (master) 2226 pci_set_master(pcidev); 2227 2228 2229 pci_bus = pcidev->bus->number; 2230 pci_slot = PCI_SLOT(pcidev->devfn); 2231 pci_func = PCI_FUNC(pcidev->devfn); 2232 irq = pcidev->irq; 2233 iobase_a = pci_resource_start(pcidev, 0); 2234 iobase_9 = pci_resource_start(pcidev, 2); 2235 2236 printk(KERN_ERR ", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, 2237 pci_slot, pci_func, iobase_9, iobase_a); 2238 2239 dev->iobase = iobase_9; 2240 dev->board_name = this_board->name; 2241 2242 devpriv->pcidev = pcidev; 2243 devpriv->iobase_a = iobase_a; 2244 2245 pci9118_reset(dev); 2246 2247 if (it->options[3] & 2) 2248 irq = 0; /* user don't want use IRQ */ 2249 if (irq > 0) { 2250 if (request_irq(irq, interrupt_pci9118, IRQF_SHARED, 2251 "ADLink PCI-9118", dev)) { 2252 printk(", unable to allocate IRQ %d, DISABLING IT", 2253 irq); 2254 irq = 0; /* Can't use IRQ */ 2255 } else { 2256 printk(", irq=%u", irq); 2257 } 2258 } else { 2259 printk(", IRQ disabled"); 2260 } 2261 2262 dev->irq = irq; 2263 2264 if (master) { /* alloc DMA buffers */ 2265 devpriv->dma_doublebuf = 0; 2266 for (i = 0; i < 2; i++) { 2267 for (pages = 4; pages >= 0; pages--) { 2268 devpriv->dmabuf_virt[i] = 2269 (short *)__get_free_pages(GFP_KERNEL, 2270 pages); 2271 if (devpriv->dmabuf_virt[i]) 2272 break; 2273 } 2274 if (devpriv->dmabuf_virt[i]) { 2275 devpriv->dmabuf_pages[i] = pages; 2276 devpriv->dmabuf_size[i] = PAGE_SIZE * pages; 2277 devpriv->dmabuf_samples[i] = 2278 devpriv->dmabuf_size[i] >> 1; 2279 devpriv->dmabuf_hw[i] = 2280 virt_to_bus((void *) 2281 devpriv->dmabuf_virt[i]); 2282 } 2283 } 2284 if (!devpriv->dmabuf_virt[0]) { 2285 printk(", Can't allocate DMA buffer, DMA disabled!"); 2286 master = 0; 2287 } 2288 2289 if (devpriv->dmabuf_virt[1]) 2290 devpriv->dma_doublebuf = 1; 2291 2292 } 2293 2294 devpriv->master = master; 2295 if (devpriv->master) 2296 printk(", bus master"); 2297 else 2298 printk(", no bus master"); 2299 2300 devpriv->usemux = 0; 2301 if (it->options[2] > 0) { 2302 devpriv->usemux = it->options[2]; 2303 if (devpriv->usemux > 256) 2304 devpriv->usemux = 256; /* max 256 channels! */ 2305 if (it->options[4] > 0) 2306 if (devpriv->usemux > 128) { 2307 devpriv->usemux = 128; 2308 /* max 128 channels with softare S&H! */ 2309 } 2310 printk(", ext. mux %d channels", devpriv->usemux); 2311 } 2312 2313 devpriv->softsshdelay = it->options[4]; 2314 if (devpriv->softsshdelay < 0) { 2315 /* select sample&hold signal polarity */ 2316 devpriv->softsshdelay = -devpriv->softsshdelay; 2317 devpriv->softsshsample = 0x80; 2318 devpriv->softsshhold = 0x00; 2319 } else { 2320 devpriv->softsshsample = 0x00; 2321 devpriv->softsshhold = 0x80; 2322 } 2323 2324 printk(".\n"); 2325 2326 pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w); 2327 pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); 2328 /* Enable parity check for parity error */ 2329 2330 ret = alloc_subdevices(dev, 4); 2331 if (ret < 0) 2332 return ret; 2333 2334 s = dev->subdevices + 0; 2335 dev->read_subdev = s; 2336 s->type = COMEDI_SUBD_AI; 2337 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF; 2338 if (devpriv->usemux) 2339 s->n_chan = devpriv->usemux; 2340 else 2341 s->n_chan = this_board->n_aichan; 2342 2343 s->maxdata = this_board->ai_maxdata; 2344 s->len_chanlist = this_board->n_aichanlist; 2345 s->range_table = this_board->rangelist_ai; 2346 s->cancel = pci9118_ai_cancel; 2347 s->insn_read = pci9118_insn_read_ai; 2348 if (dev->irq) { 2349 s->subdev_flags |= SDF_CMD_READ; 2350 s->do_cmdtest = pci9118_ai_cmdtest; 2351 s->do_cmd = pci9118_ai_cmd; 2352 s->munge = pci9118_ai_munge; 2353 } 2354 2355 s = dev->subdevices + 1; 2356 s->type = COMEDI_SUBD_AO; 2357 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; 2358 s->n_chan = this_board->n_aochan; 2359 s->maxdata = this_board->ao_maxdata; 2360 s->len_chanlist = this_board->n_aochan; 2361 s->range_table = this_board->rangelist_ao; 2362 s->insn_write = pci9118_insn_write_ao; 2363 s->insn_read = pci9118_insn_read_ao; 2364 2365 s = dev->subdevices + 2; 2366 s->type = COMEDI_SUBD_DI; 2367 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; 2368 s->n_chan = 4; 2369 s->maxdata = 1; 2370 s->len_chanlist = 4; 2371 s->range_table = &range_digital; 2372 s->io_bits = 0; /* all bits input */ 2373 s->insn_bits = pci9118_insn_bits_di; 2374 2375 s = dev->subdevices + 3; 2376 s->type = COMEDI_SUBD_DO; 2377 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON; 2378 s->n_chan = 4; 2379 s->maxdata = 1; 2380 s->len_chanlist = 4; 2381 s->range_table = &range_digital; 2382 s->io_bits = 0xf; /* all bits output */ 2383 s->insn_bits = pci9118_insn_bits_do; 2384 2385 devpriv->valid = 1; 2386 devpriv->i8254_osc_base = 250; /* 250ns=4MHz */ 2387 devpriv->ai_maskharderr = 0x10a; 2388 /* default measure crash condition */ 2389 if (it->options[5]) /* disable some requested */ 2390 devpriv->ai_maskharderr &= ~it->options[5]; 2391 2392 switch (this_board->ai_maxdata) { 2393 case 0xffff: 2394 devpriv->ai16bits = 1; 2395 break; 2396 default: 2397 devpriv->ai16bits = 0; 2398 break; 2399 } 2400 return 0; 2401} 2402 2403/* 2404============================================================================== 2405*/ 2406static int pci9118_detach(struct comedi_device *dev) 2407{ 2408 if (dev->private) { 2409 if (devpriv->valid) 2410 pci9118_reset(dev); 2411 if (dev->irq) 2412 free_irq(dev->irq, dev); 2413 if (devpriv->pcidev) { 2414 if (dev->iobase) 2415 comedi_pci_disable(devpriv->pcidev); 2416 2417 pci_dev_put(devpriv->pcidev); 2418 } 2419 if (devpriv->dmabuf_virt[0]) 2420 free_pages((unsigned long)devpriv->dmabuf_virt[0], 2421 devpriv->dmabuf_pages[0]); 2422 if (devpriv->dmabuf_virt[1]) 2423 free_pages((unsigned long)devpriv->dmabuf_virt[1], 2424 devpriv->dmabuf_pages[1]); 2425 } 2426 2427 return 0; 2428} 2429 2430/* 2431============================================================================== 2432*/ 2433