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