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