]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - drivers/staging/comedi/drivers/adl_pci9118.c
UBUNTU: Ubuntu-5.11.0-22.23
[mirror_ubuntu-hirsute-kernel.git] / drivers / staging / comedi / drivers / adl_pci9118.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * comedi/drivers/adl_pci9118.c
4 *
5 * hardware driver for ADLink cards:
6 * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
7 * driver: pci9118dg, pci9118hg, pci9118hr
8 *
9 * Author: Michal Dobes <dobes@tesnet.cz>
10 *
11 */
12
13 /*
14 * Driver: adl_pci9118
15 * Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
16 * Author: Michal Dobes <dobes@tesnet.cz>
17 * Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
18 * PCI-9118HR (pci9118hr)
19 * Status: works
20 *
21 * This driver supports AI, AO, DI and DO subdevices.
22 * AI subdevice supports cmd and insn interface,
23 * other subdevices support only insn interface.
24 * For AI:
25 * - If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
26 * - If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
27 * - If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
28 * - It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
29 * cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
30 * - If return value of cmdtest is 5 then you've bad channel list
31 * (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
32 * ranges).
33 *
34 * There are some hardware limitations:
35 * a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
36 * ended inputs.
37 * b) DMA transfers must have the length aligned to two samples (32 bit),
38 * so there is some problems if cmd->chanlist_len is odd. This driver tries
39 * bypass this with adding one sample to the end of the every scan and discard
40 * it on output but this can't be used if cmd->scan_begin_src=TRIG_FOLLOW
41 * and is used flag CMDF_WAKE_EOS, then driver switch to interrupt driven mode
42 * with interrupt after every sample.
43 * c) If isn't used DMA then you can use only mode where
44 * cmd->scan_begin_src=TRIG_FOLLOW.
45 *
46 * Configuration options:
47 * [0] - PCI bus of device (optional)
48 * [1] - PCI slot of device (optional)
49 * If bus/slot is not specified, then first available PCI
50 * card will be used.
51 * [2] - 0= standard 8 DIFF/16 SE channels configuration
52 * n = external multiplexer connected, 1 <= n <= 256
53 * [3] - ignored
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] - ignored
60 */
61
62 /*
63 * FIXME
64 *
65 * All the supported boards have the same PCI vendor and device IDs, so
66 * auto-attachment of PCI devices will always find the first board type.
67 *
68 * Perhaps the boards have different subdevice IDs that we could use to
69 * distinguish them?
70 *
71 * Need some device attributes so the board type can be corrected after
72 * attachment if necessary, and possibly to set other options supported by
73 * manual attachment.
74 */
75
76 #include <linux/module.h>
77 #include <linux/delay.h>
78 #include <linux/gfp.h>
79 #include <linux/interrupt.h>
80 #include <linux/io.h>
81
82 #include "../comedi_pci.h"
83
84 #include "amcc_s5933.h"
85 #include "comedi_8254.h"
86
87 /*
88 * PCI BAR2 Register map (dev->iobase)
89 */
90 #define PCI9118_TIMER_BASE 0x00
91 #define PCI9118_AI_FIFO_REG 0x10
92 #define PCI9118_AO_REG(x) (0x10 + ((x) * 4))
93 #define PCI9118_AI_STATUS_REG 0x18
94 #define PCI9118_AI_STATUS_NFULL BIT(8) /* 0=FIFO full (fatal) */
95 #define PCI9118_AI_STATUS_NHFULL BIT(7) /* 0=FIFO half full */
96 #define PCI9118_AI_STATUS_NEPTY BIT(6) /* 0=FIFO empty */
97 #define PCI9118_AI_STATUS_ACMP BIT(5) /* 1=about trigger complete */
98 #define PCI9118_AI_STATUS_DTH BIT(4) /* 1=ext. digital trigger */
99 #define PCI9118_AI_STATUS_BOVER BIT(3) /* 1=burst overrun (fatal) */
100 #define PCI9118_AI_STATUS_ADOS BIT(2) /* 1=A/D over speed (warn) */
101 #define PCI9118_AI_STATUS_ADOR BIT(1) /* 1=A/D overrun (fatal) */
102 #define PCI9118_AI_STATUS_ADRDY BIT(0) /* 1=A/D ready */
103 #define PCI9118_AI_CTRL_REG 0x18
104 #define PCI9118_AI_CTRL_UNIP BIT(7) /* 1=unipolar */
105 #define PCI9118_AI_CTRL_DIFF BIT(6) /* 1=differential inputs */
106 #define PCI9118_AI_CTRL_SOFTG BIT(5) /* 1=8254 software gate */
107 #define PCI9118_AI_CTRL_EXTG BIT(4) /* 1=8254 TGIN(pin 46) gate */
108 #define PCI9118_AI_CTRL_EXTM BIT(3) /* 1=ext. trigger (pin 44) */
109 #define PCI9118_AI_CTRL_TMRTR BIT(2) /* 1=8254 is trigger source */
110 #define PCI9118_AI_CTRL_INT BIT(1) /* 1=enable interrupt */
111 #define PCI9118_AI_CTRL_DMA BIT(0) /* 1=enable DMA */
112 #define PCI9118_DIO_REG 0x1c
113 #define PCI9118_SOFTTRG_REG 0x20
114 #define PCI9118_AI_CHANLIST_REG 0x24
115 #define PCI9118_AI_CHANLIST_RANGE(x) (((x) & 0x3) << 8)
116 #define PCI9118_AI_CHANLIST_CHAN(x) ((x) << 0)
117 #define PCI9118_AI_BURST_NUM_REG 0x28
118 #define PCI9118_AI_AUTOSCAN_MODE_REG 0x2c
119 #define PCI9118_AI_CFG_REG 0x30
120 #define PCI9118_AI_CFG_PDTRG BIT(7) /* 1=positive trigger */
121 #define PCI9118_AI_CFG_PETRG BIT(6) /* 1=positive ext. trigger */
122 #define PCI9118_AI_CFG_BSSH BIT(5) /* 1=with sample & hold */
123 #define PCI9118_AI_CFG_BM BIT(4) /* 1=burst mode */
124 #define PCI9118_AI_CFG_BS BIT(3) /* 1=burst mode start */
125 #define PCI9118_AI_CFG_PM BIT(2) /* 1=post trigger */
126 #define PCI9118_AI_CFG_AM BIT(1) /* 1=about trigger */
127 #define PCI9118_AI_CFG_START BIT(0) /* 1=trigger start */
128 #define PCI9118_FIFO_RESET_REG 0x34
129 #define PCI9118_INT_CTRL_REG 0x38
130 #define PCI9118_INT_CTRL_TIMER BIT(3) /* timer interrupt */
131 #define PCI9118_INT_CTRL_ABOUT BIT(2) /* about trigger complete */
132 #define PCI9118_INT_CTRL_HFULL BIT(1) /* A/D FIFO half full */
133 #define PCI9118_INT_CTRL_DTRG BIT(0) /* ext. digital trigger */
134
135 #define START_AI_EXT 0x01 /* start measure on external trigger */
136 #define STOP_AI_EXT 0x02 /* stop measure on external trigger */
137 #define STOP_AI_INT 0x08 /* stop measure on internal trigger */
138
139 static const struct comedi_lrange pci9118_ai_range = {
140 8, {
141 BIP_RANGE(5),
142 BIP_RANGE(2.5),
143 BIP_RANGE(1.25),
144 BIP_RANGE(0.625),
145 UNI_RANGE(10),
146 UNI_RANGE(5),
147 UNI_RANGE(2.5),
148 UNI_RANGE(1.25)
149 }
150 };
151
152 static const struct comedi_lrange pci9118hg_ai_range = {
153 8, {
154 BIP_RANGE(5),
155 BIP_RANGE(0.5),
156 BIP_RANGE(0.05),
157 BIP_RANGE(0.005),
158 UNI_RANGE(10),
159 UNI_RANGE(1),
160 UNI_RANGE(0.1),
161 UNI_RANGE(0.01)
162 }
163 };
164
165 enum pci9118_boardid {
166 BOARD_PCI9118DG,
167 BOARD_PCI9118HG,
168 BOARD_PCI9118HR,
169 };
170
171 struct pci9118_boardinfo {
172 const char *name;
173 unsigned int ai_is_16bit:1;
174 unsigned int is_hg:1;
175 };
176
177 static const struct pci9118_boardinfo pci9118_boards[] = {
178 [BOARD_PCI9118DG] = {
179 .name = "pci9118dg",
180 },
181 [BOARD_PCI9118HG] = {
182 .name = "pci9118hg",
183 .is_hg = 1,
184 },
185 [BOARD_PCI9118HR] = {
186 .name = "pci9118hr",
187 .ai_is_16bit = 1,
188 },
189 };
190
191 struct pci9118_dmabuf {
192 unsigned short *virt; /* virtual address of buffer */
193 dma_addr_t hw; /* hardware (bus) address of buffer */
194 unsigned int size; /* size of dma buffer in bytes */
195 unsigned int use_size; /* which size we may now use for transfer */
196 };
197
198 struct pci9118_private {
199 unsigned long iobase_a; /* base+size for AMCC chip */
200 unsigned int master:1;
201 unsigned int dma_doublebuf:1;
202 unsigned int ai_neverending:1;
203 unsigned int usedma:1;
204 unsigned int usemux:1;
205 unsigned char ai_ctrl;
206 unsigned char int_ctrl;
207 unsigned char ai_cfg;
208 unsigned int ai_do; /* what do AI? 0=nothing, 1 to 4 mode */
209 unsigned int ai_n_realscanlen; /*
210 * what we must transfer for one
211 * outgoing scan include front/back adds
212 */
213 unsigned int ai_act_dmapos; /* position in actual real stream */
214 unsigned int ai_add_front; /*
215 * how many channels we must add
216 * before scan to satisfy S&H?
217 */
218 unsigned int ai_add_back; /*
219 * how many channels we must add
220 * before scan to satisfy DMA?
221 */
222 unsigned int ai_flags;
223 char ai12_startstop; /*
224 * measure can start/stop
225 * on external trigger
226 */
227 unsigned int dma_actbuf; /* which buffer is used now */
228 struct pci9118_dmabuf dmabuf[2];
229 int softsshdelay; /*
230 * >0 use software S&H,
231 * numer is requested delay in ns
232 */
233 unsigned char softsshsample; /*
234 * polarity of S&H signal
235 * in sample state
236 */
237 unsigned char softsshhold; /*
238 * polarity of S&H signal
239 * in hold state
240 */
241 unsigned int ai_ns_min;
242 };
243
244 static void pci9118_amcc_setup_dma(struct comedi_device *dev, unsigned int buf)
245 {
246 struct pci9118_private *devpriv = dev->private;
247 struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[buf];
248
249 /* set the master write address and transfer count */
250 outl(dmabuf->hw, devpriv->iobase_a + AMCC_OP_REG_MWAR);
251 outl(dmabuf->use_size, devpriv->iobase_a + AMCC_OP_REG_MWTC);
252 }
253
254 static void pci9118_amcc_dma_ena(struct comedi_device *dev, bool enable)
255 {
256 struct pci9118_private *devpriv = dev->private;
257 unsigned int mcsr;
258
259 mcsr = inl(devpriv->iobase_a + AMCC_OP_REG_MCSR);
260 if (enable)
261 mcsr |= RESET_A2P_FLAGS | A2P_HI_PRIORITY | EN_A2P_TRANSFERS;
262 else
263 mcsr &= ~EN_A2P_TRANSFERS;
264 outl(mcsr, devpriv->iobase_a + AMCC_OP_REG_MCSR);
265 }
266
267 static void pci9118_amcc_int_ena(struct comedi_device *dev, bool enable)
268 {
269 struct pci9118_private *devpriv = dev->private;
270 unsigned int intcsr;
271
272 /* enable/disable interrupt for AMCC Incoming Mailbox 4 (32-bit) */
273 intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
274 if (enable)
275 intcsr |= 0x1f00;
276 else
277 intcsr &= ~0x1f00;
278 outl(intcsr, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
279 }
280
281 static void pci9118_ai_reset_fifo(struct comedi_device *dev)
282 {
283 /* writing any value resets the A/D FIFO */
284 outl(0, dev->iobase + PCI9118_FIFO_RESET_REG);
285 }
286
287 static int pci9118_ai_check_chanlist(struct comedi_device *dev,
288 struct comedi_subdevice *s,
289 struct comedi_cmd *cmd)
290 {
291 struct pci9118_private *devpriv = dev->private;
292 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
293 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
294 int i;
295
296 /* single channel scans are always ok */
297 if (cmd->chanlist_len == 1)
298 return 0;
299
300 for (i = 1; i < cmd->chanlist_len; i++) {
301 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
302 unsigned int range = CR_RANGE(cmd->chanlist[i]);
303 unsigned int aref = CR_AREF(cmd->chanlist[i]);
304
305 if (aref != aref0) {
306 dev_err(dev->class_dev,
307 "Differential and single ended inputs can't be mixed!\n");
308 return -EINVAL;
309 }
310 if (comedi_range_is_bipolar(s, range) !=
311 comedi_range_is_bipolar(s, range0)) {
312 dev_err(dev->class_dev,
313 "Bipolar and unipolar ranges can't be mixed!\n");
314 return -EINVAL;
315 }
316 if (!devpriv->usemux && aref == AREF_DIFF &&
317 (chan >= (s->n_chan / 2))) {
318 dev_err(dev->class_dev,
319 "AREF_DIFF is only available for the first 8 channels!\n");
320 return -EINVAL;
321 }
322 }
323
324 return 0;
325 }
326
327 static void pci9118_set_chanlist(struct comedi_device *dev,
328 struct comedi_subdevice *s,
329 int n_chan, unsigned int *chanlist,
330 int frontadd, int backadd)
331 {
332 struct pci9118_private *devpriv = dev->private;
333 unsigned int chan0 = CR_CHAN(chanlist[0]);
334 unsigned int range0 = CR_RANGE(chanlist[0]);
335 unsigned int aref0 = CR_AREF(chanlist[0]);
336 unsigned int ssh = 0x00;
337 unsigned int val;
338 int i;
339
340 /*
341 * Configure analog input based on the first chanlist entry.
342 * All entries are either unipolar or bipolar and single-ended
343 * or differential.
344 */
345 devpriv->ai_ctrl = 0;
346 if (comedi_range_is_unipolar(s, range0))
347 devpriv->ai_ctrl |= PCI9118_AI_CTRL_UNIP;
348 if (aref0 == AREF_DIFF)
349 devpriv->ai_ctrl |= PCI9118_AI_CTRL_DIFF;
350 outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
351
352 /* gods know why this sequence! */
353 outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
354 outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
355 outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
356
357 /* insert channels for S&H */
358 if (frontadd) {
359 val = PCI9118_AI_CHANLIST_CHAN(chan0) |
360 PCI9118_AI_CHANLIST_RANGE(range0);
361 ssh = devpriv->softsshsample;
362 for (i = 0; i < frontadd; i++) {
363 outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
364 ssh = devpriv->softsshhold;
365 }
366 }
367
368 /* store chanlist */
369 for (i = 0; i < n_chan; i++) {
370 unsigned int chan = CR_CHAN(chanlist[i]);
371 unsigned int range = CR_RANGE(chanlist[i]);
372
373 val = PCI9118_AI_CHANLIST_CHAN(chan) |
374 PCI9118_AI_CHANLIST_RANGE(range);
375 outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
376 }
377
378 /* insert channels to fit onto 32bit DMA */
379 if (backadd) {
380 val = PCI9118_AI_CHANLIST_CHAN(chan0) |
381 PCI9118_AI_CHANLIST_RANGE(range0);
382 for (i = 0; i < backadd; i++)
383 outl(val | ssh, dev->iobase + PCI9118_AI_CHANLIST_REG);
384 }
385 /* close scan queue */
386 outl(0, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
387 /* udelay(100); important delay, or first sample will be crippled */
388 }
389
390 static void pci9118_ai_mode4_switch(struct comedi_device *dev,
391 unsigned int next_buf)
392 {
393 struct pci9118_private *devpriv = dev->private;
394 struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[next_buf];
395
396 devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG |
397 PCI9118_AI_CFG_AM;
398 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
399 comedi_8254_load(dev->pacer, 0, dmabuf->hw >> 1,
400 I8254_MODE0 | I8254_BINARY);
401 devpriv->ai_cfg |= PCI9118_AI_CFG_START;
402 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
403 }
404
405 static unsigned int pci9118_ai_samples_ready(struct comedi_device *dev,
406 struct comedi_subdevice *s,
407 unsigned int n_raw_samples)
408 {
409 struct pci9118_private *devpriv = dev->private;
410 struct comedi_cmd *cmd = &s->async->cmd;
411 unsigned int start_pos = devpriv->ai_add_front;
412 unsigned int stop_pos = start_pos + cmd->chanlist_len;
413 unsigned int span_len = stop_pos + devpriv->ai_add_back;
414 unsigned int dma_pos = devpriv->ai_act_dmapos;
415 unsigned int whole_spans, n_samples, x;
416
417 if (span_len == cmd->chanlist_len)
418 return n_raw_samples; /* use all samples */
419
420 /*
421 * Not all samples are to be used. Buffer contents consist of a
422 * possibly non-whole number of spans and a region of each span
423 * is to be used.
424 *
425 * Account for samples in whole number of spans.
426 */
427 whole_spans = n_raw_samples / span_len;
428 n_samples = whole_spans * cmd->chanlist_len;
429 n_raw_samples -= whole_spans * span_len;
430
431 /*
432 * Deal with remaining samples which could overlap up to two spans.
433 */
434 while (n_raw_samples) {
435 if (dma_pos < start_pos) {
436 /* Skip samples before start position. */
437 x = start_pos - dma_pos;
438 if (x > n_raw_samples)
439 x = n_raw_samples;
440 dma_pos += x;
441 n_raw_samples -= x;
442 if (!n_raw_samples)
443 break;
444 }
445 if (dma_pos < stop_pos) {
446 /* Include samples before stop position. */
447 x = stop_pos - dma_pos;
448 if (x > n_raw_samples)
449 x = n_raw_samples;
450 n_samples += x;
451 dma_pos += x;
452 n_raw_samples -= x;
453 }
454 /* Advance to next span. */
455 start_pos += span_len;
456 stop_pos += span_len;
457 }
458 return n_samples;
459 }
460
461 static void pci9118_ai_dma_xfer(struct comedi_device *dev,
462 struct comedi_subdevice *s,
463 unsigned short *dma_buffer,
464 unsigned int n_raw_samples)
465 {
466 struct pci9118_private *devpriv = dev->private;
467 struct comedi_cmd *cmd = &s->async->cmd;
468 unsigned int start_pos = devpriv->ai_add_front;
469 unsigned int stop_pos = start_pos + cmd->chanlist_len;
470 unsigned int span_len = stop_pos + devpriv->ai_add_back;
471 unsigned int dma_pos = devpriv->ai_act_dmapos;
472 unsigned int x;
473
474 if (span_len == cmd->chanlist_len) {
475 /* All samples are to be copied. */
476 comedi_buf_write_samples(s, dma_buffer, n_raw_samples);
477 dma_pos += n_raw_samples;
478 } else {
479 /*
480 * Not all samples are to be copied. Buffer contents consist
481 * of a possibly non-whole number of spans and a region of
482 * each span is to be copied.
483 */
484 while (n_raw_samples) {
485 if (dma_pos < start_pos) {
486 /* Skip samples before start position. */
487 x = start_pos - dma_pos;
488 if (x > n_raw_samples)
489 x = n_raw_samples;
490 dma_pos += x;
491 n_raw_samples -= x;
492 if (!n_raw_samples)
493 break;
494 }
495 if (dma_pos < stop_pos) {
496 /* Copy samples before stop position. */
497 x = stop_pos - dma_pos;
498 if (x > n_raw_samples)
499 x = n_raw_samples;
500 comedi_buf_write_samples(s, dma_buffer, x);
501 dma_pos += x;
502 n_raw_samples -= x;
503 }
504 /* Advance to next span. */
505 start_pos += span_len;
506 stop_pos += span_len;
507 }
508 }
509 /* Update position in span for next time. */
510 devpriv->ai_act_dmapos = dma_pos % span_len;
511 }
512
513 static void pci9118_exttrg_enable(struct comedi_device *dev, bool enable)
514 {
515 struct pci9118_private *devpriv = dev->private;
516
517 if (enable)
518 devpriv->int_ctrl |= PCI9118_INT_CTRL_DTRG;
519 else
520 devpriv->int_ctrl &= ~PCI9118_INT_CTRL_DTRG;
521 outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
522
523 if (devpriv->int_ctrl)
524 pci9118_amcc_int_ena(dev, true);
525 else
526 pci9118_amcc_int_ena(dev, false);
527 }
528
529 static void pci9118_calc_divisors(struct comedi_device *dev,
530 struct comedi_subdevice *s,
531 unsigned int *tim1, unsigned int *tim2,
532 unsigned int flags, int chans,
533 unsigned int *div1, unsigned int *div2,
534 unsigned int chnsshfront)
535 {
536 struct comedi_8254 *pacer = dev->pacer;
537 struct comedi_cmd *cmd = &s->async->cmd;
538
539 *div1 = *tim2 / pacer->osc_base; /* convert timer (burst) */
540 *div2 = *tim1 / pacer->osc_base; /* scan timer */
541 *div2 = *div2 / *div1; /* major timer is c1*c2 */
542 if (*div2 < chans)
543 *div2 = chans;
544
545 *tim2 = *div1 * pacer->osc_base; /* real convert timer */
546
547 if (cmd->convert_src == TRIG_NOW && !chnsshfront) {
548 /* use BSSH signal */
549 if (*div2 < (chans + 2))
550 *div2 = chans + 2;
551 }
552
553 *tim1 = *div1 * *div2 * pacer->osc_base;
554 }
555
556 static void pci9118_start_pacer(struct comedi_device *dev, int mode)
557 {
558 if (mode == 1 || mode == 2 || mode == 4)
559 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
560 }
561
562 static int pci9118_ai_cancel(struct comedi_device *dev,
563 struct comedi_subdevice *s)
564 {
565 struct pci9118_private *devpriv = dev->private;
566
567 if (devpriv->usedma)
568 pci9118_amcc_dma_ena(dev, false);
569 pci9118_exttrg_enable(dev, false);
570 comedi_8254_pacer_enable(dev->pacer, 1, 2, false);
571 /* set default config (disable burst and triggers) */
572 devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
573 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
574 /* reset acquisition control */
575 devpriv->ai_ctrl = 0;
576 outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
577 outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
578 /* reset scan queue */
579 outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
580 outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
581 pci9118_ai_reset_fifo(dev);
582
583 devpriv->int_ctrl = 0;
584 outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
585 pci9118_amcc_int_ena(dev, false);
586
587 devpriv->ai_do = 0;
588 devpriv->usedma = 0;
589
590 devpriv->ai_act_dmapos = 0;
591 s->async->inttrig = NULL;
592 devpriv->ai_neverending = 0;
593 devpriv->dma_actbuf = 0;
594
595 return 0;
596 }
597
598 static void pci9118_ai_munge(struct comedi_device *dev,
599 struct comedi_subdevice *s, void *data,
600 unsigned int num_bytes,
601 unsigned int start_chan_index)
602 {
603 struct pci9118_private *devpriv = dev->private;
604 unsigned short *array = data;
605 unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
606 unsigned int i;
607 __be16 *barray = data;
608
609 for (i = 0; i < num_samples; i++) {
610 if (devpriv->usedma)
611 array[i] = be16_to_cpu(barray[i]);
612 if (s->maxdata == 0xffff)
613 array[i] ^= 0x8000;
614 else
615 array[i] = (array[i] >> 4) & 0x0fff;
616 }
617 }
618
619 static void pci9118_ai_get_onesample(struct comedi_device *dev,
620 struct comedi_subdevice *s)
621 {
622 struct pci9118_private *devpriv = dev->private;
623 struct comedi_cmd *cmd = &s->async->cmd;
624 unsigned short sampl;
625
626 sampl = inl(dev->iobase + PCI9118_AI_FIFO_REG);
627
628 comedi_buf_write_samples(s, &sampl, 1);
629
630 if (!devpriv->ai_neverending) {
631 if (s->async->scans_done >= cmd->stop_arg)
632 s->async->events |= COMEDI_CB_EOA;
633 }
634 }
635
636 static void pci9118_ai_get_dma(struct comedi_device *dev,
637 struct comedi_subdevice *s)
638 {
639 struct pci9118_private *devpriv = dev->private;
640 struct comedi_cmd *cmd = &s->async->cmd;
641 struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[devpriv->dma_actbuf];
642 unsigned int n_all = comedi_bytes_to_samples(s, dmabuf->use_size);
643 unsigned int n_valid;
644 bool more_dma;
645
646 /* determine whether more DMA buffers to do after this one */
647 n_valid = pci9118_ai_samples_ready(dev, s, n_all);
648 more_dma = n_valid < comedi_nsamples_left(s, n_valid + 1);
649
650 /* switch DMA buffers and restart DMA if double buffering */
651 if (more_dma && devpriv->dma_doublebuf) {
652 devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
653 pci9118_amcc_setup_dma(dev, devpriv->dma_actbuf);
654 if (devpriv->ai_do == 4)
655 pci9118_ai_mode4_switch(dev, devpriv->dma_actbuf);
656 }
657
658 if (n_all)
659 pci9118_ai_dma_xfer(dev, s, dmabuf->virt, n_all);
660
661 if (!devpriv->ai_neverending) {
662 if (s->async->scans_done >= cmd->stop_arg)
663 s->async->events |= COMEDI_CB_EOA;
664 }
665
666 if (s->async->events & COMEDI_CB_CANCEL_MASK)
667 more_dma = false;
668
669 /* restart DMA if not double buffering */
670 if (more_dma && !devpriv->dma_doublebuf) {
671 pci9118_amcc_setup_dma(dev, 0);
672 if (devpriv->ai_do == 4)
673 pci9118_ai_mode4_switch(dev, 0);
674 }
675 }
676
677 static irqreturn_t pci9118_interrupt(int irq, void *d)
678 {
679 struct comedi_device *dev = d;
680 struct comedi_subdevice *s = dev->read_subdev;
681 struct pci9118_private *devpriv = dev->private;
682 unsigned int intsrc; /* IRQ reasons from card */
683 unsigned int intcsr; /* INT register from AMCC chip */
684 unsigned int adstat; /* STATUS register */
685
686 if (!dev->attached)
687 return IRQ_NONE;
688
689 intsrc = inl(dev->iobase + PCI9118_INT_CTRL_REG) & 0xf;
690 intcsr = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
691
692 if (!intsrc && !(intcsr & ANY_S593X_INT))
693 return IRQ_NONE;
694
695 outl(intcsr | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
696
697 if (intcsr & MASTER_ABORT_INT) {
698 dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
699 s->async->events |= COMEDI_CB_ERROR;
700 goto interrupt_exit;
701 }
702
703 if (intcsr & TARGET_ABORT_INT) {
704 dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
705 s->async->events |= COMEDI_CB_ERROR;
706 goto interrupt_exit;
707 }
708
709 adstat = inl(dev->iobase + PCI9118_AI_STATUS_REG);
710 if ((adstat & PCI9118_AI_STATUS_NFULL) == 0) {
711 dev_err(dev->class_dev,
712 "A/D FIFO Full status (Fatal Error!)\n");
713 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
714 goto interrupt_exit;
715 }
716 if (adstat & PCI9118_AI_STATUS_BOVER) {
717 dev_err(dev->class_dev,
718 "A/D Burst Mode Overrun Status (Fatal Error!)\n");
719 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
720 goto interrupt_exit;
721 }
722 if (adstat & PCI9118_AI_STATUS_ADOS) {
723 dev_err(dev->class_dev, "A/D Over Speed Status (Warning!)\n");
724 s->async->events |= COMEDI_CB_ERROR;
725 goto interrupt_exit;
726 }
727 if (adstat & PCI9118_AI_STATUS_ADOR) {
728 dev_err(dev->class_dev, "A/D Overrun Status (Fatal Error!)\n");
729 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
730 goto interrupt_exit;
731 }
732
733 if (!devpriv->ai_do)
734 return IRQ_HANDLED;
735
736 if (devpriv->ai12_startstop) {
737 if ((adstat & PCI9118_AI_STATUS_DTH) &&
738 (intsrc & PCI9118_INT_CTRL_DTRG)) {
739 /* start/stop of measure */
740 if (devpriv->ai12_startstop & START_AI_EXT) {
741 /* deactivate EXT trigger */
742 devpriv->ai12_startstop &= ~START_AI_EXT;
743 if (!(devpriv->ai12_startstop & STOP_AI_EXT))
744 pci9118_exttrg_enable(dev, false);
745
746 /* start pacer */
747 pci9118_start_pacer(dev, devpriv->ai_do);
748 outl(devpriv->ai_ctrl,
749 dev->iobase + PCI9118_AI_CTRL_REG);
750 } else if (devpriv->ai12_startstop & STOP_AI_EXT) {
751 /* deactivate EXT trigger */
752 devpriv->ai12_startstop &= ~STOP_AI_EXT;
753 pci9118_exttrg_enable(dev, false);
754
755 /* on next interrupt measure will stop */
756 devpriv->ai_neverending = 0;
757 }
758 }
759 }
760
761 if (devpriv->usedma)
762 pci9118_ai_get_dma(dev, s);
763 else
764 pci9118_ai_get_onesample(dev, s);
765
766 interrupt_exit:
767 comedi_handle_events(dev, s);
768 return IRQ_HANDLED;
769 }
770
771 static void pci9118_ai_cmd_start(struct comedi_device *dev)
772 {
773 struct pci9118_private *devpriv = dev->private;
774
775 outl(devpriv->int_ctrl, dev->iobase + PCI9118_INT_CTRL_REG);
776 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
777 if (devpriv->ai_do != 3) {
778 pci9118_start_pacer(dev, devpriv->ai_do);
779 devpriv->ai_ctrl |= PCI9118_AI_CTRL_SOFTG;
780 }
781 outl(devpriv->ai_ctrl, dev->iobase + PCI9118_AI_CTRL_REG);
782 }
783
784 static int pci9118_ai_inttrig(struct comedi_device *dev,
785 struct comedi_subdevice *s,
786 unsigned int trig_num)
787 {
788 struct comedi_cmd *cmd = &s->async->cmd;
789
790 if (trig_num != cmd->start_arg)
791 return -EINVAL;
792
793 s->async->inttrig = NULL;
794 pci9118_ai_cmd_start(dev);
795
796 return 1;
797 }
798
799 static int pci9118_ai_setup_dma(struct comedi_device *dev,
800 struct comedi_subdevice *s)
801 {
802 struct pci9118_private *devpriv = dev->private;
803 struct comedi_cmd *cmd = &s->async->cmd;
804 struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
805 struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
806 unsigned int dmalen0 = dmabuf0->size;
807 unsigned int dmalen1 = dmabuf1->size;
808 unsigned int scan_bytes = devpriv->ai_n_realscanlen *
809 comedi_bytes_per_sample(s);
810
811 /* isn't output buff smaller that our DMA buff? */
812 if (dmalen0 > s->async->prealloc_bufsz) {
813 /* align to 32bit down */
814 dmalen0 = s->async->prealloc_bufsz & ~3L;
815 }
816 if (dmalen1 > s->async->prealloc_bufsz) {
817 /* align to 32bit down */
818 dmalen1 = s->async->prealloc_bufsz & ~3L;
819 }
820
821 /* we want wake up every scan? */
822 if (devpriv->ai_flags & CMDF_WAKE_EOS) {
823 if (dmalen0 < scan_bytes) {
824 /* uff, too short DMA buffer, disable EOS support! */
825 devpriv->ai_flags &= (~CMDF_WAKE_EOS);
826 dev_info(dev->class_dev,
827 "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
828 dmalen0, scan_bytes);
829 } else {
830 /* short first DMA buffer to one scan */
831 dmalen0 = scan_bytes;
832 if (dmalen0 < 4) {
833 dev_info(dev->class_dev,
834 "ERR: DMA0 buf len bug? (%d<4)\n",
835 dmalen0);
836 dmalen0 = 4;
837 }
838 }
839 }
840 if (devpriv->ai_flags & CMDF_WAKE_EOS) {
841 if (dmalen1 < scan_bytes) {
842 /* uff, too short DMA buffer, disable EOS support! */
843 devpriv->ai_flags &= (~CMDF_WAKE_EOS);
844 dev_info(dev->class_dev,
845 "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n",
846 dmalen1, scan_bytes);
847 } else {
848 /* short second DMA buffer to one scan */
849 dmalen1 = scan_bytes;
850 if (dmalen1 < 4) {
851 dev_info(dev->class_dev,
852 "ERR: DMA1 buf len bug? (%d<4)\n",
853 dmalen1);
854 dmalen1 = 4;
855 }
856 }
857 }
858
859 /* transfer without CMDF_WAKE_EOS */
860 if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) {
861 unsigned int tmp;
862
863 /* if it's possible then align DMA buffers to length of scan */
864 tmp = dmalen0;
865 dmalen0 = (dmalen0 / scan_bytes) * scan_bytes;
866 dmalen0 &= ~3L;
867 if (!dmalen0)
868 dmalen0 = tmp; /* uff. very long scan? */
869 tmp = dmalen1;
870 dmalen1 = (dmalen1 / scan_bytes) * scan_bytes;
871 dmalen1 &= ~3L;
872 if (!dmalen1)
873 dmalen1 = tmp; /* uff. very long scan? */
874 /*
875 * if measure isn't neverending then test, if it fits whole
876 * into one or two DMA buffers
877 */
878 if (!devpriv->ai_neverending) {
879 unsigned long long scanlen;
880
881 scanlen = (unsigned long long)scan_bytes *
882 cmd->stop_arg;
883
884 /* fits whole measure into one DMA buffer? */
885 if (dmalen0 > scanlen) {
886 dmalen0 = scanlen;
887 dmalen0 &= ~3L;
888 } else {
889 /* fits whole measure into two DMA buffer? */
890 if (dmalen1 > (scanlen - dmalen0)) {
891 dmalen1 = scanlen - dmalen0;
892 dmalen1 &= ~3L;
893 }
894 }
895 }
896 }
897
898 /* these DMA buffer size will be used */
899 devpriv->dma_actbuf = 0;
900 dmabuf0->use_size = dmalen0;
901 dmabuf1->use_size = dmalen1;
902
903 pci9118_amcc_dma_ena(dev, false);
904 pci9118_amcc_setup_dma(dev, 0);
905 /* init DMA transfer */
906 outl(0x00000000 | AINT_WRITE_COMPL,
907 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
908 /* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
909 pci9118_amcc_dma_ena(dev, true);
910 outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
911 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
912 /* allow bus mastering */
913
914 return 0;
915 }
916
917 static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
918 {
919 struct pci9118_private *devpriv = dev->private;
920 struct comedi_8254 *pacer = dev->pacer;
921 struct comedi_cmd *cmd = &s->async->cmd;
922 unsigned int addchans = 0;
923 unsigned int scanlen;
924
925 devpriv->ai12_startstop = 0;
926 devpriv->ai_flags = cmd->flags;
927 devpriv->ai_add_front = 0;
928 devpriv->ai_add_back = 0;
929
930 /* prepare for start/stop conditions */
931 if (cmd->start_src == TRIG_EXT)
932 devpriv->ai12_startstop |= START_AI_EXT;
933 if (cmd->stop_src == TRIG_EXT) {
934 devpriv->ai_neverending = 1;
935 devpriv->ai12_startstop |= STOP_AI_EXT;
936 }
937 if (cmd->stop_src == TRIG_NONE)
938 devpriv->ai_neverending = 1;
939 if (cmd->stop_src == TRIG_COUNT)
940 devpriv->ai_neverending = 0;
941
942 /*
943 * use additional sample at end of every scan
944 * to satisty DMA 32 bit transfer?
945 */
946 devpriv->ai_add_front = 0;
947 devpriv->ai_add_back = 0;
948 if (devpriv->master) {
949 devpriv->usedma = 1;
950 if ((cmd->flags & CMDF_WAKE_EOS) &&
951 (cmd->scan_end_arg == 1)) {
952 if (cmd->convert_src == TRIG_NOW)
953 devpriv->ai_add_back = 1;
954 if (cmd->convert_src == TRIG_TIMER) {
955 devpriv->usedma = 0;
956 /*
957 * use INT transfer if scanlist
958 * have only one channel
959 */
960 }
961 }
962 if ((cmd->flags & CMDF_WAKE_EOS) &&
963 (cmd->scan_end_arg & 1) &&
964 (cmd->scan_end_arg > 1)) {
965 if (cmd->scan_begin_src == TRIG_FOLLOW) {
966 devpriv->usedma = 0;
967 /*
968 * XXX maybe can be corrected to use 16 bit DMA
969 */
970 } else { /*
971 * well, we must insert one sample
972 * to end of EOS to meet 32 bit transfer
973 */
974 devpriv->ai_add_back = 1;
975 }
976 }
977 } else { /* interrupt transfer don't need any correction */
978 devpriv->usedma = 0;
979 }
980
981 /*
982 * we need software S&H signal?
983 * It adds two samples before every scan as minimum
984 */
985 if (cmd->convert_src == TRIG_NOW && devpriv->softsshdelay) {
986 devpriv->ai_add_front = 2;
987 if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
988 /* move it to front */
989 devpriv->ai_add_front++;
990 devpriv->ai_add_back = 0;
991 }
992 if (cmd->convert_arg < devpriv->ai_ns_min)
993 cmd->convert_arg = devpriv->ai_ns_min;
994 addchans = devpriv->softsshdelay / cmd->convert_arg;
995 if (devpriv->softsshdelay % cmd->convert_arg)
996 addchans++;
997 if (addchans > (devpriv->ai_add_front - 1)) {
998 /* uff, still short */
999 devpriv->ai_add_front = addchans + 1;
1000 if (devpriv->usedma == 1)
1001 if ((devpriv->ai_add_front +
1002 cmd->chanlist_len +
1003 devpriv->ai_add_back) & 1)
1004 devpriv->ai_add_front++;
1005 /* round up to 32 bit */
1006 }
1007 }
1008 /* well, we now know what must be all added */
1009 scanlen = devpriv->ai_add_front + cmd->chanlist_len +
1010 devpriv->ai_add_back;
1011 /*
1012 * what we must take from card in real to have cmd->scan_end_arg
1013 * on output?
1014 */
1015 devpriv->ai_n_realscanlen = scanlen *
1016 (cmd->scan_end_arg / cmd->chanlist_len);
1017
1018 if (scanlen > s->len_chanlist) {
1019 dev_err(dev->class_dev,
1020 "range/channel list is too long for actual configuration!\n");
1021 return -EINVAL;
1022 }
1023
1024 /*
1025 * Configure analog input and load the chanlist.
1026 * The acquisition control bits are enabled later.
1027 */
1028 pci9118_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist,
1029 devpriv->ai_add_front, devpriv->ai_add_back);
1030
1031 /* Determine acquisition mode and calculate timing */
1032 devpriv->ai_do = 0;
1033 if (cmd->scan_begin_src != TRIG_TIMER &&
1034 cmd->convert_src == TRIG_TIMER) {
1035 /* cascaded timers 1 and 2 are used for convert timing */
1036 if (cmd->scan_begin_src == TRIG_EXT)
1037 devpriv->ai_do = 4;
1038 else
1039 devpriv->ai_do = 1;
1040
1041 comedi_8254_cascade_ns_to_timer(pacer, &cmd->convert_arg,
1042 devpriv->ai_flags &
1043 CMDF_ROUND_NEAREST);
1044 comedi_8254_update_divisors(pacer);
1045
1046 devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1047
1048 if (!devpriv->usedma) {
1049 devpriv->ai_ctrl |= PCI9118_AI_CTRL_INT;
1050 devpriv->int_ctrl |= PCI9118_INT_CTRL_TIMER;
1051 }
1052
1053 if (cmd->scan_begin_src == TRIG_EXT) {
1054 struct pci9118_dmabuf *dmabuf = &devpriv->dmabuf[0];
1055
1056 devpriv->ai_cfg |= PCI9118_AI_CFG_AM;
1057 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1058 comedi_8254_load(pacer, 0, dmabuf->hw >> 1,
1059 I8254_MODE0 | I8254_BINARY);
1060 devpriv->ai_cfg |= PCI9118_AI_CFG_START;
1061 }
1062 }
1063
1064 if (cmd->scan_begin_src == TRIG_TIMER &&
1065 cmd->convert_src != TRIG_EXT) {
1066 if (!devpriv->usedma) {
1067 dev_err(dev->class_dev,
1068 "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!\n");
1069 return -EIO;
1070 }
1071
1072 /* double timed action */
1073 devpriv->ai_do = 2;
1074
1075 pci9118_calc_divisors(dev, s,
1076 &cmd->scan_begin_arg, &cmd->convert_arg,
1077 devpriv->ai_flags,
1078 devpriv->ai_n_realscanlen,
1079 &pacer->divisor1,
1080 &pacer->divisor2,
1081 devpriv->ai_add_front);
1082
1083 devpriv->ai_ctrl |= PCI9118_AI_CTRL_TMRTR;
1084 devpriv->ai_cfg |= PCI9118_AI_CFG_BM | PCI9118_AI_CFG_BS;
1085 if (cmd->convert_src == TRIG_NOW && !devpriv->softsshdelay)
1086 devpriv->ai_cfg |= PCI9118_AI_CFG_BSSH;
1087 outl(devpriv->ai_n_realscanlen,
1088 dev->iobase + PCI9118_AI_BURST_NUM_REG);
1089 }
1090
1091 if (cmd->scan_begin_src == TRIG_FOLLOW &&
1092 cmd->convert_src == TRIG_EXT) {
1093 /* external trigger conversion */
1094 devpriv->ai_do = 3;
1095
1096 devpriv->ai_ctrl |= PCI9118_AI_CTRL_EXTM;
1097 }
1098
1099 if (devpriv->ai_do == 0) {
1100 dev_err(dev->class_dev,
1101 "Unable to determine acquisition mode! BUG in (*do_cmdtest)?\n");
1102 return -EINVAL;
1103 }
1104
1105 if (devpriv->usedma)
1106 devpriv->ai_ctrl |= PCI9118_AI_CTRL_DMA;
1107
1108 /* set default config (disable burst and triggers) */
1109 devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1110 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1111 udelay(1);
1112 pci9118_ai_reset_fifo(dev);
1113
1114 /* clear A/D and INT status registers */
1115 inl(dev->iobase + PCI9118_AI_STATUS_REG);
1116 inl(dev->iobase + PCI9118_INT_CTRL_REG);
1117
1118 devpriv->ai_act_dmapos = 0;
1119
1120 if (devpriv->usedma) {
1121 pci9118_ai_setup_dma(dev, s);
1122
1123 outl(0x02000000 | AINT_WRITE_COMPL,
1124 devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1125 } else {
1126 pci9118_amcc_int_ena(dev, true);
1127 }
1128
1129 /* start async command now or wait for internal trigger */
1130 if (cmd->start_src == TRIG_NOW)
1131 pci9118_ai_cmd_start(dev);
1132 else if (cmd->start_src == TRIG_INT)
1133 s->async->inttrig = pci9118_ai_inttrig;
1134
1135 /* enable external trigger for command start/stop */
1136 if (cmd->start_src == TRIG_EXT || cmd->stop_src == TRIG_EXT)
1137 pci9118_exttrg_enable(dev, true);
1138
1139 return 0;
1140 }
1141
1142 static int pci9118_ai_cmdtest(struct comedi_device *dev,
1143 struct comedi_subdevice *s,
1144 struct comedi_cmd *cmd)
1145 {
1146 struct pci9118_private *devpriv = dev->private;
1147 int err = 0;
1148 unsigned int flags;
1149 unsigned int arg;
1150
1151 /* Step 1 : check if triggers are trivially valid */
1152
1153 err |= comedi_check_trigger_src(&cmd->start_src,
1154 TRIG_NOW | TRIG_EXT | TRIG_INT);
1155
1156 flags = TRIG_FOLLOW;
1157 if (devpriv->master)
1158 flags |= TRIG_TIMER | TRIG_EXT;
1159 err |= comedi_check_trigger_src(&cmd->scan_begin_src, flags);
1160
1161 flags = TRIG_TIMER | TRIG_EXT;
1162 if (devpriv->master)
1163 flags |= TRIG_NOW;
1164 err |= comedi_check_trigger_src(&cmd->convert_src, flags);
1165
1166 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1167 err |= comedi_check_trigger_src(&cmd->stop_src,
1168 TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1169
1170 if (err)
1171 return 1;
1172
1173 /* Step 2a : make sure trigger sources are unique */
1174
1175 err |= comedi_check_trigger_is_unique(cmd->start_src);
1176 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
1177 err |= comedi_check_trigger_is_unique(cmd->convert_src);
1178 err |= comedi_check_trigger_is_unique(cmd->stop_src);
1179
1180 /* Step 2b : and mutually compatible */
1181
1182 if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1183 err |= -EINVAL;
1184
1185 if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1186 (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1187 err |= -EINVAL;
1188
1189 if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1190 (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1191 err |= -EINVAL;
1192
1193 if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1194 err |= -EINVAL;
1195
1196 if (err)
1197 return 2;
1198
1199 /* Step 3: check if arguments are trivially valid */
1200
1201 switch (cmd->start_src) {
1202 case TRIG_NOW:
1203 case TRIG_EXT:
1204 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
1205 break;
1206 case TRIG_INT:
1207 /* start_arg is the internal trigger (any value) */
1208 break;
1209 }
1210
1211 if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1212 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1213
1214 if ((cmd->scan_begin_src == TRIG_TIMER) &&
1215 (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1216 cmd->scan_begin_src = TRIG_FOLLOW;
1217 cmd->convert_arg = cmd->scan_begin_arg;
1218 cmd->scan_begin_arg = 0;
1219 }
1220
1221 if (cmd->scan_begin_src == TRIG_TIMER) {
1222 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
1223 devpriv->ai_ns_min);
1224 }
1225
1226 if (cmd->scan_begin_src == TRIG_EXT) {
1227 if (cmd->scan_begin_arg) {
1228 cmd->scan_begin_arg = 0;
1229 err |= -EINVAL;
1230 err |= comedi_check_trigger_arg_max(&cmd->scan_end_arg,
1231 65535);
1232 }
1233 }
1234
1235 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1236 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
1237 devpriv->ai_ns_min);
1238 }
1239
1240 if (cmd->convert_src == TRIG_EXT)
1241 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
1242
1243 if (cmd->stop_src == TRIG_COUNT)
1244 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
1245 else /* TRIG_NONE */
1246 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
1247
1248 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
1249
1250 err |= comedi_check_trigger_arg_min(&cmd->scan_end_arg,
1251 cmd->chanlist_len);
1252
1253 if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1254 cmd->scan_end_arg =
1255 cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1256 err |= -EINVAL;
1257 }
1258
1259 if (err)
1260 return 3;
1261
1262 /* step 4: fix up any arguments */
1263
1264 if (cmd->scan_begin_src == TRIG_TIMER) {
1265 arg = cmd->scan_begin_arg;
1266 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
1267 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1268 }
1269
1270 if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1271 arg = cmd->convert_arg;
1272 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
1273 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
1274
1275 if (cmd->scan_begin_src == TRIG_TIMER &&
1276 cmd->convert_src == TRIG_NOW) {
1277 if (cmd->convert_arg == 0) {
1278 arg = devpriv->ai_ns_min *
1279 (cmd->scan_end_arg + 2);
1280 } else {
1281 arg = cmd->convert_arg * cmd->chanlist_len;
1282 }
1283 err |= comedi_check_trigger_arg_min(
1284 &cmd->scan_begin_arg, arg);
1285 }
1286 }
1287
1288 if (err)
1289 return 4;
1290
1291 /* Step 5: check channel list if it exists */
1292
1293 if (cmd->chanlist)
1294 err |= pci9118_ai_check_chanlist(dev, s, cmd);
1295
1296 if (err)
1297 return 5;
1298
1299 return 0;
1300 }
1301
1302 static int pci9118_ai_eoc(struct comedi_device *dev,
1303 struct comedi_subdevice *s,
1304 struct comedi_insn *insn,
1305 unsigned long context)
1306 {
1307 unsigned int status;
1308
1309 status = inl(dev->iobase + PCI9118_AI_STATUS_REG);
1310 if (status & PCI9118_AI_STATUS_ADRDY)
1311 return 0;
1312 return -EBUSY;
1313 }
1314
1315 static void pci9118_ai_start_conv(struct comedi_device *dev)
1316 {
1317 /* writing any value triggers an A/D conversion */
1318 outl(0, dev->iobase + PCI9118_SOFTTRG_REG);
1319 }
1320
1321 static int pci9118_ai_insn_read(struct comedi_device *dev,
1322 struct comedi_subdevice *s,
1323 struct comedi_insn *insn,
1324 unsigned int *data)
1325 {
1326 struct pci9118_private *devpriv = dev->private;
1327 unsigned int val;
1328 int ret;
1329 int i;
1330
1331 /*
1332 * Configure analog input based on the chanspec.
1333 * Acqusition is software controlled without interrupts.
1334 */
1335 pci9118_set_chanlist(dev, s, 1, &insn->chanspec, 0, 0);
1336
1337 /* set default config (disable burst and triggers) */
1338 devpriv->ai_cfg = PCI9118_AI_CFG_PDTRG | PCI9118_AI_CFG_PETRG;
1339 outl(devpriv->ai_cfg, dev->iobase + PCI9118_AI_CFG_REG);
1340
1341 pci9118_ai_reset_fifo(dev);
1342
1343 for (i = 0; i < insn->n; i++) {
1344 pci9118_ai_start_conv(dev);
1345
1346 ret = comedi_timeout(dev, s, insn, pci9118_ai_eoc, 0);
1347 if (ret)
1348 return ret;
1349
1350 val = inl(dev->iobase + PCI9118_AI_FIFO_REG);
1351 if (s->maxdata == 0xffff)
1352 data[i] = (val & 0xffff) ^ 0x8000;
1353 else
1354 data[i] = (val >> 4) & 0xfff;
1355 }
1356
1357 return insn->n;
1358 }
1359
1360 static int pci9118_ao_insn_write(struct comedi_device *dev,
1361 struct comedi_subdevice *s,
1362 struct comedi_insn *insn,
1363 unsigned int *data)
1364 {
1365 unsigned int chan = CR_CHAN(insn->chanspec);
1366 unsigned int val = s->readback[chan];
1367 int i;
1368
1369 for (i = 0; i < insn->n; i++) {
1370 val = data[i];
1371 outl(val, dev->iobase + PCI9118_AO_REG(chan));
1372 }
1373 s->readback[chan] = val;
1374
1375 return insn->n;
1376 }
1377
1378 static int pci9118_di_insn_bits(struct comedi_device *dev,
1379 struct comedi_subdevice *s,
1380 struct comedi_insn *insn,
1381 unsigned int *data)
1382 {
1383 /*
1384 * The digital inputs and outputs share the read register.
1385 * bits [7:4] are the digital outputs
1386 * bits [3:0] are the digital inputs
1387 */
1388 data[1] = inl(dev->iobase + PCI9118_DIO_REG) & 0xf;
1389
1390 return insn->n;
1391 }
1392
1393 static int pci9118_do_insn_bits(struct comedi_device *dev,
1394 struct comedi_subdevice *s,
1395 struct comedi_insn *insn,
1396 unsigned int *data)
1397 {
1398 /*
1399 * The digital outputs are set with the same register that
1400 * the digital inputs and outputs are read from. But the
1401 * outputs are set with bits [3:0] so we can simply write
1402 * the s->state to set them.
1403 */
1404 if (comedi_dio_update_state(s, data))
1405 outl(s->state, dev->iobase + PCI9118_DIO_REG);
1406
1407 data[1] = s->state;
1408
1409 return insn->n;
1410 }
1411
1412 static void pci9118_reset(struct comedi_device *dev)
1413 {
1414 /* reset analog input subsystem */
1415 outl(0, dev->iobase + PCI9118_INT_CTRL_REG);
1416 outl(0, dev->iobase + PCI9118_AI_CTRL_REG);
1417 outl(0, dev->iobase + PCI9118_AI_CFG_REG);
1418 pci9118_ai_reset_fifo(dev);
1419
1420 /* clear any pending interrupts and status */
1421 inl(dev->iobase + PCI9118_INT_CTRL_REG);
1422 inl(dev->iobase + PCI9118_AI_STATUS_REG);
1423
1424 /* reset DMA and scan queue */
1425 outl(0, dev->iobase + PCI9118_AI_BURST_NUM_REG);
1426 outl(1, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1427 outl(2, dev->iobase + PCI9118_AI_AUTOSCAN_MODE_REG);
1428
1429 /* reset analog outputs to 0V */
1430 outl(2047, dev->iobase + PCI9118_AO_REG(0));
1431 outl(2047, dev->iobase + PCI9118_AO_REG(1));
1432 }
1433
1434 static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1435 struct comedi_devconfig *it)
1436 {
1437 struct pci_dev *pcidev = NULL;
1438 int bus = it->options[0];
1439 int slot = it->options[1];
1440
1441 for_each_pci_dev(pcidev) {
1442 if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1443 continue;
1444 if (pcidev->device != 0x80d9)
1445 continue;
1446 if (bus || slot) {
1447 /* requested particular bus/slot */
1448 if (pcidev->bus->number != bus ||
1449 PCI_SLOT(pcidev->devfn) != slot)
1450 continue;
1451 }
1452 return pcidev;
1453 }
1454 dev_err(dev->class_dev,
1455 "no supported board found! (req. bus/slot : %d/%d)\n",
1456 bus, slot);
1457 return NULL;
1458 }
1459
1460 static void pci9118_alloc_dma(struct comedi_device *dev)
1461 {
1462 struct pci9118_private *devpriv = dev->private;
1463 struct pci9118_dmabuf *dmabuf;
1464 int order;
1465 int i;
1466
1467 for (i = 0; i < 2; i++) {
1468 dmabuf = &devpriv->dmabuf[i];
1469 for (order = 2; order >= 0; order--) {
1470 dmabuf->virt =
1471 dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order,
1472 &dmabuf->hw, GFP_KERNEL);
1473 if (dmabuf->virt)
1474 break;
1475 }
1476 if (!dmabuf->virt)
1477 break;
1478 dmabuf->size = PAGE_SIZE << order;
1479
1480 if (i == 0)
1481 devpriv->master = 1;
1482 if (i == 1)
1483 devpriv->dma_doublebuf = 1;
1484 }
1485 }
1486
1487 static void pci9118_free_dma(struct comedi_device *dev)
1488 {
1489 struct pci9118_private *devpriv = dev->private;
1490 struct pci9118_dmabuf *dmabuf;
1491 int i;
1492
1493 if (!devpriv)
1494 return;
1495
1496 for (i = 0; i < 2; i++) {
1497 dmabuf = &devpriv->dmabuf[i];
1498 if (dmabuf->virt) {
1499 dma_free_coherent(dev->hw_dev, dmabuf->size,
1500 dmabuf->virt, dmabuf->hw);
1501 }
1502 }
1503 }
1504
1505 static int pci9118_common_attach(struct comedi_device *dev,
1506 int ext_mux, int softsshdelay)
1507 {
1508 const struct pci9118_boardinfo *board = dev->board_ptr;
1509 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1510 struct pci9118_private *devpriv;
1511 struct comedi_subdevice *s;
1512 int ret;
1513 int i;
1514 u16 u16w;
1515
1516 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1517 if (!devpriv)
1518 return -ENOMEM;
1519
1520 ret = comedi_pci_enable(dev);
1521 if (ret)
1522 return ret;
1523 pci_set_master(pcidev);
1524
1525 devpriv->iobase_a = pci_resource_start(pcidev, 0);
1526 dev->iobase = pci_resource_start(pcidev, 2);
1527
1528 dev->pacer = comedi_8254_init(dev->iobase + PCI9118_TIMER_BASE,
1529 I8254_OSC_BASE_4MHZ, I8254_IO32, 0);
1530 if (!dev->pacer)
1531 return -ENOMEM;
1532
1533 pci9118_reset(dev);
1534
1535 if (pcidev->irq) {
1536 ret = request_irq(pcidev->irq, pci9118_interrupt, IRQF_SHARED,
1537 dev->board_name, dev);
1538 if (ret == 0) {
1539 dev->irq = pcidev->irq;
1540
1541 pci9118_alloc_dma(dev);
1542 }
1543 }
1544
1545 if (ext_mux > 0) {
1546 if (ext_mux > 256)
1547 ext_mux = 256; /* max 256 channels! */
1548 if (softsshdelay > 0)
1549 if (ext_mux > 128)
1550 ext_mux = 128;
1551 devpriv->usemux = 1;
1552 } else {
1553 devpriv->usemux = 0;
1554 }
1555
1556 if (softsshdelay < 0) {
1557 /* select sample&hold signal polarity */
1558 devpriv->softsshdelay = -softsshdelay;
1559 devpriv->softsshsample = 0x80;
1560 devpriv->softsshhold = 0x00;
1561 } else {
1562 devpriv->softsshdelay = softsshdelay;
1563 devpriv->softsshsample = 0x00;
1564 devpriv->softsshhold = 0x80;
1565 }
1566
1567 pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
1568 pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
1569 /* Enable parity check for parity error */
1570
1571 ret = comedi_alloc_subdevices(dev, 4);
1572 if (ret)
1573 return ret;
1574
1575 /* Analog Input subdevice */
1576 s = &dev->subdevices[0];
1577 s->type = COMEDI_SUBD_AI;
1578 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1579 s->n_chan = (devpriv->usemux) ? ext_mux : 16;
1580 s->maxdata = board->ai_is_16bit ? 0xffff : 0x0fff;
1581 s->range_table = board->is_hg ? &pci9118hg_ai_range
1582 : &pci9118_ai_range;
1583 s->insn_read = pci9118_ai_insn_read;
1584 if (dev->irq) {
1585 dev->read_subdev = s;
1586 s->subdev_flags |= SDF_CMD_READ;
1587 s->len_chanlist = 255;
1588 s->do_cmdtest = pci9118_ai_cmdtest;
1589 s->do_cmd = pci9118_ai_cmd;
1590 s->cancel = pci9118_ai_cancel;
1591 s->munge = pci9118_ai_munge;
1592 }
1593
1594 if (s->maxdata == 0xffff) {
1595 /*
1596 * 16-bit samples are from an ADS7805 A/D converter.
1597 * Minimum sampling rate is 10us.
1598 */
1599 devpriv->ai_ns_min = 10000;
1600 } else {
1601 /*
1602 * 12-bit samples are from an ADS7800 A/D converter.
1603 * Minimum sampling rate is 3us.
1604 */
1605 devpriv->ai_ns_min = 3000;
1606 }
1607
1608 /* Analog Output subdevice */
1609 s = &dev->subdevices[1];
1610 s->type = COMEDI_SUBD_AO;
1611 s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1612 s->n_chan = 2;
1613 s->maxdata = 0x0fff;
1614 s->range_table = &range_bipolar10;
1615 s->insn_write = pci9118_ao_insn_write;
1616
1617 ret = comedi_alloc_subdev_readback(s);
1618 if (ret)
1619 return ret;
1620
1621 /* the analog outputs were reset to 0V, make the readback match */
1622 for (i = 0; i < s->n_chan; i++)
1623 s->readback[i] = 2047;
1624
1625 /* Digital Input subdevice */
1626 s = &dev->subdevices[2];
1627 s->type = COMEDI_SUBD_DI;
1628 s->subdev_flags = SDF_READABLE;
1629 s->n_chan = 4;
1630 s->maxdata = 1;
1631 s->range_table = &range_digital;
1632 s->insn_bits = pci9118_di_insn_bits;
1633
1634 /* Digital Output subdevice */
1635 s = &dev->subdevices[3];
1636 s->type = COMEDI_SUBD_DO;
1637 s->subdev_flags = SDF_WRITABLE;
1638 s->n_chan = 4;
1639 s->maxdata = 1;
1640 s->range_table = &range_digital;
1641 s->insn_bits = pci9118_do_insn_bits;
1642
1643 /* get the current state of the digital outputs */
1644 s->state = inl(dev->iobase + PCI9118_DIO_REG) >> 4;
1645
1646 return 0;
1647 }
1648
1649 static int pci9118_attach(struct comedi_device *dev,
1650 struct comedi_devconfig *it)
1651 {
1652 struct pci_dev *pcidev;
1653 int ext_mux, softsshdelay;
1654
1655 ext_mux = it->options[2];
1656 softsshdelay = it->options[4];
1657
1658 pcidev = pci9118_find_pci(dev, it);
1659 if (!pcidev)
1660 return -EIO;
1661 comedi_set_hw_dev(dev, &pcidev->dev);
1662
1663 return pci9118_common_attach(dev, ext_mux, softsshdelay);
1664 }
1665
1666 static int pci9118_auto_attach(struct comedi_device *dev,
1667 unsigned long context)
1668 {
1669 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1670 const struct pci9118_boardinfo *board = NULL;
1671
1672 if (context < ARRAY_SIZE(pci9118_boards))
1673 board = &pci9118_boards[context];
1674 if (!board)
1675 return -ENODEV;
1676 dev->board_ptr = board;
1677 dev->board_name = board->name;
1678
1679 /*
1680 * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
1681 * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
1682 */
1683 pci_dev_get(pcidev);
1684 /* no external mux, no sample-hold delay */
1685 return pci9118_common_attach(dev, 0, 0);
1686 }
1687
1688 static void pci9118_detach(struct comedi_device *dev)
1689 {
1690 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1691
1692 if (dev->iobase)
1693 pci9118_reset(dev);
1694 comedi_pci_detach(dev);
1695 pci9118_free_dma(dev);
1696 pci_dev_put(pcidev);
1697 }
1698
1699 static struct comedi_driver adl_pci9118_driver = {
1700 .driver_name = "adl_pci9118",
1701 .module = THIS_MODULE,
1702 .attach = pci9118_attach,
1703 .auto_attach = pci9118_auto_attach,
1704 .detach = pci9118_detach,
1705 .num_names = ARRAY_SIZE(pci9118_boards),
1706 .board_name = &pci9118_boards[0].name,
1707 .offset = sizeof(struct pci9118_boardinfo),
1708 };
1709
1710 static int adl_pci9118_pci_probe(struct pci_dev *dev,
1711 const struct pci_device_id *id)
1712 {
1713 return comedi_pci_auto_config(dev, &adl_pci9118_driver,
1714 id->driver_data);
1715 }
1716
1717 /* FIXME: All the supported board types have the same device ID! */
1718 static const struct pci_device_id adl_pci9118_pci_table[] = {
1719 { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118DG },
1720 /* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HG }, */
1721 /* { PCI_VDEVICE(AMCC, 0x80d9), BOARD_PCI9118HR }, */
1722 { 0 }
1723 };
1724 MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
1725
1726 static struct pci_driver adl_pci9118_pci_driver = {
1727 .name = "adl_pci9118",
1728 .id_table = adl_pci9118_pci_table,
1729 .probe = adl_pci9118_pci_probe,
1730 .remove = comedi_pci_auto_unconfig,
1731 };
1732 module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
1733
1734 MODULE_AUTHOR("Comedi https://www.comedi.org");
1735 MODULE_DESCRIPTION("Comedi low-level driver");
1736 MODULE_LICENSE("GPL");