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