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