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