staging: comedi: cb_pcidas: tidy up interrupt/ADC FIFO register
[deliverable/linux.git] / drivers / staging / comedi / drivers / cb_pcidas.c
1 /*
2 * cb_pcidas.c
3 * Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
4 * David Schleef and the rest of the Comedi developers comunity.
5 *
6 * Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
7 * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
8 *
9 * COMEDI - Linux Control and Measurement Device Interface
10 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 */
22
23 /*
24 * Driver: cb_pcidas
25 * Description: MeasurementComputing PCI-DAS series
26 * with the AMCC S5933 PCI controller
27 * Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
28 * PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
29 * PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
30 * Author: Ivan Martinez <imr@oersted.dtu.dk>,
31 * Frank Mori Hess <fmhess@users.sourceforge.net>
32 * Updated: 2003-3-11
33 *
34 * Status:
35 * There are many reports of the driver being used with most of the
36 * supported cards. Despite no detailed log is maintained, it can
37 * be said that the driver is quite tested and stable.
38 *
39 * The boards may be autocalibrated using the comedi_calibrate
40 * utility.
41 *
42 * Configuration options: not applicable, uses PCI auto config
43 *
44 * For commands, the scanned channels must be consecutive
45 * (i.e. 4-5-6-7, 2-3-4,...), and must all have the same
46 * range and aref.
47 *
48 * AI Triggering:
49 * For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used.
50 * For 1602 series, the start_arg is interpreted as follows:
51 * start_arg == 0 => gated trigger (level high)
52 * start_arg == CR_INVERT => gated trigger (level low)
53 * start_arg == CR_EDGE => Rising edge
54 * start_arg == CR_EDGE | CR_INVERT => Falling edge
55 * For the other boards the trigger will be done on rising edge
56 */
57
58 /*
59 * TODO:
60 * analog triggering on 1602 series
61 */
62
63 #include <linux/module.h>
64 #include <linux/delay.h>
65 #include <linux/interrupt.h>
66
67 #include "../comedi_pci.h"
68
69 #include "comedi_8254.h"
70 #include "8255.h"
71 #include "amcc_s5933.h"
72
73 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */
74 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */
75
76 /*
77 * PCI BAR1 Register map (devpriv->pcibar1)
78 */
79 #define PCIDAS_CTRL_REG 0x00 /* INTERRUPT / ADC FIFO register */
80 #define PCIDAS_CTRL_INT(x) (((x) & 0x3) << 0)
81 #define PCIDAS_CTRL_INT_NONE PCIDAS_CTRL_INT(0) /* no int selected */
82 #define PCIDAS_CTRL_INT_EOS PCIDAS_CTRL_INT(1) /* int on end of scan */
83 #define PCIDAS_CTRL_INT_FHF PCIDAS_CTRL_INT(2) /* int on fifo half full */
84 #define PCIDAS_CTRL_INT_FNE PCIDAS_CTRL_INT(3) /* int on fifo not empty */
85 #define PCIDAS_CTRL_INT_MASK PCIDAS_CTRL_INT(3) /* mask of int select bits */
86 #define PCIDAS_CTRL_INTE BIT(2) /* int enable */
87 #define PCIDAS_CTRL_DAHFIE BIT(3) /* dac half full int enable */
88 #define PCIDAS_CTRL_EOAIE BIT(4) /* end of acq. int enable */
89 #define PCIDAS_CTRL_DAHFI BIT(5) /* dac half full status / clear */
90 #define PCIDAS_CTRL_EOAI BIT(6) /* end of acq. int status / clear */
91 #define PCIDAS_CTRL_INT_CLR BIT(7) /* int status / clear */
92 #define PCIDAS_CTRL_EOBI BIT(9) /* end of burst int status */
93 #define PCIDAS_CTRL_ADHFI BIT(10) /* half-full int status */
94 #define PCIDAS_CTRL_ADNEI BIT(11) /* fifo not empty int status (latch) */
95 #define PCIDAS_CTRL_ADNE BIT(12) /* fifo not empty status (realtime) */
96 #define PCIDAS_CTRL_DAEMIE BIT(12) /* dac empty int enable */
97 #define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */
98 #define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */
99
100 #define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */
101 #define BEGIN_SCAN(x) ((x) & 0xf)
102 #define END_SCAN(x) (((x) & 0xf) << 4)
103 #define GAIN_BITS(x) (((x) & 0x3) << 8)
104 #define UNIP 0x800 /* Analog front-end unipolar mode */
105 #define SE 0x400 /* Inputs in single-ended mode */
106 #define PACER_MASK 0x3000 /* pacer source bits */
107 #define PACER_INT 0x1000 /* int. pacer */
108 #define PACER_EXT_FALL 0x2000 /* ext. falling edge */
109 #define PACER_EXT_RISE 0x3000 /* ext. rising edge */
110 #define EOC 0x4000 /* adc not busy */
111
112 #define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */
113 #define SW_TRIGGER 0x1 /* software start trigger */
114 #define EXT_TRIGGER 0x2 /* ext. start trigger */
115 #define ANALOG_TRIGGER 0x3 /* ext. analog trigger */
116 #define TRIGGER_MASK 0x3 /* start trigger mask */
117 #define TGPOL 0x04 /* invert trigger (1602 only) */
118 #define TGSEL 0x08 /* edge/level trigerred (1602 only) */
119 #define TGEN 0x10 /* enable external start trigger */
120 #define BURSTE 0x20 /* burst mode enable */
121 #define XTRCL 0x80 /* clear external trigger */
122
123 #define CALIBRATION_REG 6 /* CALIBRATION register */
124 #define SELECT_8800_BIT 0x100 /* select 8800 caldac */
125 #define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */
126 #define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */
127 #define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
128 #define CAL_EN_BIT 0x4000 /* calibration source enable */
129 #define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */
130
131 #define DAC_CSR 0x8 /* dac control and status register */
132 #define DACEN 0x02 /* dac enable */
133 #define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */
134
135 #define DAC_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1)))
136 #define DAC_RANGE_MASK(c) DAC_RANGE((c), 0x3)
137
138 /* bits for 1602 series only */
139 #define DAC_EMPTY 0x1 /* fifo empty, read, write clear */
140 #define DAC_START 0x4 /* start/arm fifo operations */
141 #define DAC_PACER_MASK 0x18 /* bits that set pacer source */
142 #define DAC_PACER_INT 0x8 /* int. pacing */
143 #define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */
144 #define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */
145
146 #define DAC_CHAN_EN(c) BIT(5 + ((c) & 0x1))
147
148 /*
149 * PCI BAR2 Register map (devpriv->pcibar2)
150 */
151 #define PCIDAS_AI_DATA_REG 0x00
152 #define PCIDAS_AI_FIFO_CLR_REG 0x02
153
154 /*
155 * PCI BAR3 Register map (dev->iobase)
156 */
157 #define PCIDAS_AI_8254_BASE 0x00
158 #define PCIDAS_8255_BASE 0x04
159 #define PCIDAS_AO_8254_BASE 0x08
160
161 /*
162 * PCI BAR4 Register map (devpriv->pcibar4)
163 */
164 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2))
165 #define PCIDAS_AO_FIFO_REG 0x00
166 #define PCIDAS_AO_FIFO_CLR_REG 0x02
167
168 /* analog input ranges for most boards */
169 static const struct comedi_lrange cb_pcidas_ranges = {
170 8, {
171 BIP_RANGE(10),
172 BIP_RANGE(5),
173 BIP_RANGE(2.5),
174 BIP_RANGE(1.25),
175 UNI_RANGE(10),
176 UNI_RANGE(5),
177 UNI_RANGE(2.5),
178 UNI_RANGE(1.25)
179 }
180 };
181
182 /* pci-das1001 input ranges */
183 static const struct comedi_lrange cb_pcidas_alt_ranges = {
184 8, {
185 BIP_RANGE(10),
186 BIP_RANGE(1),
187 BIP_RANGE(0.1),
188 BIP_RANGE(0.01),
189 UNI_RANGE(10),
190 UNI_RANGE(1),
191 UNI_RANGE(0.1),
192 UNI_RANGE(0.01)
193 }
194 };
195
196 /* analog output ranges */
197 static const struct comedi_lrange cb_pcidas_ao_ranges = {
198 4, {
199 BIP_RANGE(5),
200 BIP_RANGE(10),
201 UNI_RANGE(5),
202 UNI_RANGE(10)
203 }
204 };
205
206 enum trimpot_model {
207 AD7376,
208 AD8402,
209 };
210
211 enum cb_pcidas_boardid {
212 BOARD_PCIDAS1602_16,
213 BOARD_PCIDAS1200,
214 BOARD_PCIDAS1602_12,
215 BOARD_PCIDAS1200_JR,
216 BOARD_PCIDAS1602_16_JR,
217 BOARD_PCIDAS1000,
218 BOARD_PCIDAS1001,
219 BOARD_PCIDAS1002,
220 };
221
222 struct cb_pcidas_board {
223 const char *name;
224 int ai_speed; /* fastest conversion period in ns */
225 int ao_scan_speed; /* analog output scan speed for 1602 series */
226 int fifo_size; /* number of samples fifo can hold */
227 enum trimpot_model trimpot;
228 unsigned int is_16bit; /* ai/ao is 1=16-bit; 0=12-bit */
229 unsigned int use_alt_range:1; /* use alternate ai range table */
230 unsigned int has_ao:1; /* has 2 analog output channels */
231 unsigned int has_ao_fifo:1; /* analog output has fifo */
232 unsigned int has_dac08:1;
233 unsigned int is_1602:1;
234 };
235
236 static const struct cb_pcidas_board cb_pcidas_boards[] = {
237 [BOARD_PCIDAS1602_16] = {
238 .name = "pci-das1602/16",
239 .ai_speed = 5000,
240 .ao_scan_speed = 10000,
241 .fifo_size = 512,
242 .trimpot = AD8402,
243 .is_16bit = 1,
244 .has_ao = 1,
245 .has_ao_fifo = 1,
246 .has_dac08 = 1,
247 .is_1602 = 1,
248 },
249 [BOARD_PCIDAS1200] = {
250 .name = "pci-das1200",
251 .ai_speed = 3200,
252 .fifo_size = 1024,
253 .trimpot = AD7376,
254 .has_ao = 1,
255 },
256 [BOARD_PCIDAS1602_12] = {
257 .name = "pci-das1602/12",
258 .ai_speed = 3200,
259 .ao_scan_speed = 4000,
260 .fifo_size = 1024,
261 .trimpot = AD7376,
262 .has_ao = 1,
263 .has_ao_fifo = 1,
264 .is_1602 = 1,
265 },
266 [BOARD_PCIDAS1200_JR] = {
267 .name = "pci-das1200/jr",
268 .ai_speed = 3200,
269 .fifo_size = 1024,
270 .trimpot = AD7376,
271 },
272 [BOARD_PCIDAS1602_16_JR] = {
273 .name = "pci-das1602/16/jr",
274 .ai_speed = 5000,
275 .fifo_size = 512,
276 .trimpot = AD8402,
277 .is_16bit = 1,
278 .has_dac08 = 1,
279 .is_1602 = 1,
280 },
281 [BOARD_PCIDAS1000] = {
282 .name = "pci-das1000",
283 .ai_speed = 4000,
284 .fifo_size = 1024,
285 .trimpot = AD7376,
286 },
287 [BOARD_PCIDAS1001] = {
288 .name = "pci-das1001",
289 .ai_speed = 6800,
290 .fifo_size = 1024,
291 .trimpot = AD7376,
292 .use_alt_range = 1,
293 .has_ao = 1,
294 },
295 [BOARD_PCIDAS1002] = {
296 .name = "pci-das1002",
297 .ai_speed = 6800,
298 .fifo_size = 1024,
299 .trimpot = AD7376,
300 .has_ao = 1,
301 },
302 };
303
304 struct cb_pcidas_private {
305 struct comedi_8254 *ao_pacer;
306 /* base addresses */
307 unsigned long s5933_config;
308 unsigned long pcibar1;
309 unsigned long pcibar2;
310 unsigned long pcibar4;
311 /* bits to write to registers */
312 unsigned int ctrl;
313 unsigned int s5933_intcsr_bits;
314 unsigned int ao_control_bits;
315 /* fifo buffers */
316 unsigned short ai_buffer[AI_BUFFER_SIZE];
317 unsigned short ao_buffer[AO_BUFFER_SIZE];
318 unsigned int calibration_source;
319 };
320
321 static inline unsigned int cal_enable_bits(struct comedi_device *dev)
322 {
323 struct cb_pcidas_private *devpriv = dev->private;
324
325 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
326 }
327
328 static int cb_pcidas_ai_eoc(struct comedi_device *dev,
329 struct comedi_subdevice *s,
330 struct comedi_insn *insn,
331 unsigned long context)
332 {
333 struct cb_pcidas_private *devpriv = dev->private;
334 unsigned int status;
335
336 status = inw(devpriv->pcibar1 + ADCMUX_CONT);
337 if (status & EOC)
338 return 0;
339 return -EBUSY;
340 }
341
342 static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
343 struct comedi_subdevice *s,
344 struct comedi_insn *insn, unsigned int *data)
345 {
346 struct cb_pcidas_private *devpriv = dev->private;
347 unsigned int chan = CR_CHAN(insn->chanspec);
348 unsigned int range = CR_RANGE(insn->chanspec);
349 unsigned int aref = CR_AREF(insn->chanspec);
350 unsigned int bits;
351 int ret;
352 int n;
353
354 /* enable calibration input if appropriate */
355 if (insn->chanspec & CR_ALT_SOURCE) {
356 outw(cal_enable_bits(dev),
357 devpriv->pcibar1 + CALIBRATION_REG);
358 chan = 0;
359 } else {
360 outw(0, devpriv->pcibar1 + CALIBRATION_REG);
361 }
362
363 /* set mux limits and gain */
364 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
365 /* set unipolar/bipolar */
366 if (comedi_range_is_unipolar(s, range))
367 bits |= UNIP;
368 /* set single-ended/differential */
369 if (aref != AREF_DIFF)
370 bits |= SE;
371 outw(bits, devpriv->pcibar1 + ADCMUX_CONT);
372
373 /* clear fifo */
374 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
375
376 /* convert n samples */
377 for (n = 0; n < insn->n; n++) {
378 /* trigger conversion */
379 outw(0, devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
380
381 /* wait for conversion to end */
382 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
383 if (ret)
384 return ret;
385
386 /* read data */
387 data[n] = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
388 }
389
390 /* return the number of samples read/written */
391 return n;
392 }
393
394 static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
395 struct comedi_insn *insn, unsigned int *data)
396 {
397 struct cb_pcidas_private *devpriv = dev->private;
398 int id = data[0];
399 unsigned int source = data[1];
400
401 switch (id) {
402 case INSN_CONFIG_ALT_SOURCE:
403 if (source >= 8) {
404 dev_err(dev->class_dev,
405 "invalid calibration source: %i\n",
406 source);
407 return -EINVAL;
408 }
409 devpriv->calibration_source = source;
410 break;
411 default:
412 return -EINVAL;
413 }
414 return insn->n;
415 }
416
417 /* analog output insn for pcidas-1000 and 1200 series */
418 static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
419 struct comedi_subdevice *s,
420 struct comedi_insn *insn,
421 unsigned int *data)
422 {
423 struct cb_pcidas_private *devpriv = dev->private;
424 unsigned int chan = CR_CHAN(insn->chanspec);
425 unsigned int range = CR_RANGE(insn->chanspec);
426 unsigned long flags;
427
428 /* set channel and range */
429 spin_lock_irqsave(&dev->spinlock, flags);
430 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
431 ~DAC_RANGE_MASK(chan));
432 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
433 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
434 spin_unlock_irqrestore(&dev->spinlock, flags);
435
436 /* remember value for readback */
437 s->readback[chan] = data[0];
438
439 /* send data */
440 outw(data[0], devpriv->pcibar4 + PCIDAS_AO_DATA_REG(chan));
441
442 return insn->n;
443 }
444
445 /* analog output insn for pcidas-1602 series */
446 static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
447 struct comedi_subdevice *s,
448 struct comedi_insn *insn, unsigned int *data)
449 {
450 struct cb_pcidas_private *devpriv = dev->private;
451 unsigned int chan = CR_CHAN(insn->chanspec);
452 unsigned int range = CR_RANGE(insn->chanspec);
453 unsigned long flags;
454
455 /* clear dac fifo */
456 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
457
458 /* set channel and range */
459 spin_lock_irqsave(&dev->spinlock, flags);
460 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
461 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
462 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
463 DAC_CHAN_EN(chan) | DAC_START);
464 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
465 spin_unlock_irqrestore(&dev->spinlock, flags);
466
467 /* remember value for readback */
468 s->readback[chan] = data[0];
469
470 /* send data */
471 outw(data[0], devpriv->pcibar4 + PCIDAS_AO_FIFO_REG);
472
473 return insn->n;
474 }
475
476 static int wait_for_nvram_ready(unsigned long s5933_base_addr)
477 {
478 static const int timeout = 1000;
479 unsigned int i;
480
481 for (i = 0; i < timeout; i++) {
482 if ((inb(s5933_base_addr +
483 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
484 == 0)
485 return 0;
486 udelay(1);
487 }
488 return -1;
489 }
490
491 static int nvram_read(struct comedi_device *dev, unsigned int address,
492 uint8_t *data)
493 {
494 struct cb_pcidas_private *devpriv = dev->private;
495 unsigned long iobase = devpriv->s5933_config;
496
497 if (wait_for_nvram_ready(iobase) < 0)
498 return -ETIMEDOUT;
499
500 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
501 iobase + AMCC_OP_REG_MCSR_NVCMD);
502 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
503 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
504 iobase + AMCC_OP_REG_MCSR_NVCMD);
505 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
506 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
507
508 if (wait_for_nvram_ready(iobase) < 0)
509 return -ETIMEDOUT;
510
511 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
512
513 return 0;
514 }
515
516 static int eeprom_read_insn(struct comedi_device *dev,
517 struct comedi_subdevice *s,
518 struct comedi_insn *insn, unsigned int *data)
519 {
520 uint8_t nvram_data;
521 int retval;
522
523 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
524 if (retval < 0)
525 return retval;
526
527 data[0] = nvram_data;
528
529 return 1;
530 }
531
532 static void write_calibration_bitstream(struct comedi_device *dev,
533 unsigned int register_bits,
534 unsigned int bitstream,
535 unsigned int bitstream_length)
536 {
537 struct cb_pcidas_private *devpriv = dev->private;
538 static const int write_delay = 1;
539 unsigned int bit;
540
541 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
542 if (bitstream & bit)
543 register_bits |= SERIAL_DATA_IN_BIT;
544 else
545 register_bits &= ~SERIAL_DATA_IN_BIT;
546 udelay(write_delay);
547 outw(register_bits, devpriv->pcibar1 + CALIBRATION_REG);
548 }
549 }
550
551 static void caldac_8800_write(struct comedi_device *dev,
552 unsigned int chan, uint8_t val)
553 {
554 struct cb_pcidas_private *devpriv = dev->private;
555 static const int bitstream_length = 11;
556 unsigned int bitstream = ((chan & 0x7) << 8) | val;
557 static const int caldac_8800_udelay = 1;
558
559 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
560 bitstream_length);
561
562 udelay(caldac_8800_udelay);
563 outw(cal_enable_bits(dev) | SELECT_8800_BIT,
564 devpriv->pcibar1 + CALIBRATION_REG);
565 udelay(caldac_8800_udelay);
566 outw(cal_enable_bits(dev), devpriv->pcibar1 + CALIBRATION_REG);
567 }
568
569 static int cb_pcidas_caldac_insn_write(struct comedi_device *dev,
570 struct comedi_subdevice *s,
571 struct comedi_insn *insn,
572 unsigned int *data)
573 {
574 unsigned int chan = CR_CHAN(insn->chanspec);
575
576 if (insn->n) {
577 unsigned int val = data[insn->n - 1];
578
579 if (s->readback[chan] != val) {
580 caldac_8800_write(dev, chan, val);
581 s->readback[chan] = val;
582 }
583 }
584
585 return insn->n;
586 }
587
588 /* 1602/16 pregain offset */
589 static void dac08_write(struct comedi_device *dev, unsigned int value)
590 {
591 struct cb_pcidas_private *devpriv = dev->private;
592
593 value &= 0xff;
594 value |= cal_enable_bits(dev);
595
596 /* latch the new value into the caldac */
597 outw(value, devpriv->pcibar1 + CALIBRATION_REG);
598 udelay(1);
599 outw(value | SELECT_DAC08_BIT,
600 devpriv->pcibar1 + CALIBRATION_REG);
601 udelay(1);
602 outw(value, devpriv->pcibar1 + CALIBRATION_REG);
603 udelay(1);
604 }
605
606 static int cb_pcidas_dac08_insn_write(struct comedi_device *dev,
607 struct comedi_subdevice *s,
608 struct comedi_insn *insn,
609 unsigned int *data)
610 {
611 unsigned int chan = CR_CHAN(insn->chanspec);
612
613 if (insn->n) {
614 unsigned int val = data[insn->n - 1];
615
616 if (s->readback[chan] != val) {
617 dac08_write(dev, val);
618 s->readback[chan] = val;
619 }
620 }
621
622 return insn->n;
623 }
624
625 static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
626 {
627 struct cb_pcidas_private *devpriv = dev->private;
628 static const int bitstream_length = 7;
629 unsigned int bitstream = value & 0x7f;
630 unsigned int register_bits;
631 static const int ad7376_udelay = 1;
632
633 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
634 udelay(ad7376_udelay);
635 outw(register_bits, devpriv->pcibar1 + CALIBRATION_REG);
636
637 write_calibration_bitstream(dev, register_bits, bitstream,
638 bitstream_length);
639
640 udelay(ad7376_udelay);
641 outw(cal_enable_bits(dev), devpriv->pcibar1 + CALIBRATION_REG);
642
643 return 0;
644 }
645
646 /* For 1602/16 only
647 * ch 0 : adc gain
648 * ch 1 : adc postgain offset */
649 static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
650 uint8_t value)
651 {
652 struct cb_pcidas_private *devpriv = dev->private;
653 static const int bitstream_length = 10;
654 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
655 unsigned int register_bits;
656 static const int ad8402_udelay = 1;
657
658 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
659 udelay(ad8402_udelay);
660 outw(register_bits, devpriv->pcibar1 + CALIBRATION_REG);
661
662 write_calibration_bitstream(dev, register_bits, bitstream,
663 bitstream_length);
664
665 udelay(ad8402_udelay);
666 outw(cal_enable_bits(dev), devpriv->pcibar1 + CALIBRATION_REG);
667
668 return 0;
669 }
670
671 static void cb_pcidas_trimpot_write(struct comedi_device *dev,
672 unsigned int chan, unsigned int val)
673 {
674 const struct cb_pcidas_board *board = dev->board_ptr;
675
676 switch (board->trimpot) {
677 case AD7376:
678 trimpot_7376_write(dev, val);
679 break;
680 case AD8402:
681 trimpot_8402_write(dev, chan, val);
682 break;
683 default:
684 dev_err(dev->class_dev, "driver bug?\n");
685 break;
686 }
687 }
688
689 static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev,
690 struct comedi_subdevice *s,
691 struct comedi_insn *insn,
692 unsigned int *data)
693 {
694 unsigned int chan = CR_CHAN(insn->chanspec);
695
696 if (insn->n) {
697 unsigned int val = data[insn->n - 1];
698
699 if (s->readback[chan] != val) {
700 cb_pcidas_trimpot_write(dev, chan, val);
701 s->readback[chan] = val;
702 }
703 }
704
705 return insn->n;
706 }
707
708 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
709 struct comedi_subdevice *s,
710 struct comedi_cmd *cmd)
711 {
712 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
713 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
714 int i;
715
716 for (i = 1; i < cmd->chanlist_len; i++) {
717 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
718 unsigned int range = CR_RANGE(cmd->chanlist[i]);
719
720 if (chan != (chan0 + i) % s->n_chan) {
721 dev_dbg(dev->class_dev,
722 "entries in chanlist must be consecutive channels, counting upwards\n");
723 return -EINVAL;
724 }
725
726 if (range != range0) {
727 dev_dbg(dev->class_dev,
728 "entries in chanlist must all have the same gain\n");
729 return -EINVAL;
730 }
731 }
732 return 0;
733 }
734
735 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
736 struct comedi_subdevice *s,
737 struct comedi_cmd *cmd)
738 {
739 const struct cb_pcidas_board *board = dev->board_ptr;
740 int err = 0;
741 unsigned int arg;
742
743 /* Step 1 : check if triggers are trivially valid */
744
745 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
746 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
747 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
748 err |= comedi_check_trigger_src(&cmd->convert_src,
749 TRIG_TIMER | TRIG_NOW | TRIG_EXT);
750 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
751 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
752
753 if (err)
754 return 1;
755
756 /* Step 2a : make sure trigger sources are unique */
757
758 err |= comedi_check_trigger_is_unique(cmd->start_src);
759 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
760 err |= comedi_check_trigger_is_unique(cmd->convert_src);
761 err |= comedi_check_trigger_is_unique(cmd->stop_src);
762
763 /* Step 2b : and mutually compatible */
764
765 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
766 err |= -EINVAL;
767 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
768 err |= -EINVAL;
769 if (cmd->start_src == TRIG_EXT &&
770 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
771 err |= -EINVAL;
772
773 if (err)
774 return 2;
775
776 /* Step 3: check if arguments are trivially valid */
777
778 switch (cmd->start_src) {
779 case TRIG_NOW:
780 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
781 break;
782 case TRIG_EXT:
783 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
784 if ((cmd->start_arg
785 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
786 cmd->start_arg &= ~(CR_FLAGS_MASK &
787 ~(CR_EDGE | CR_INVERT));
788 err |= -EINVAL;
789 }
790 if (!board->is_1602 && (cmd->start_arg & CR_INVERT)) {
791 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
792 err |= -EINVAL;
793 }
794 break;
795 }
796
797 if (cmd->scan_begin_src == TRIG_TIMER) {
798 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
799 board->ai_speed *
800 cmd->chanlist_len);
801 }
802
803 if (cmd->convert_src == TRIG_TIMER) {
804 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
805 board->ai_speed);
806 }
807
808 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
809 cmd->chanlist_len);
810
811 if (cmd->stop_src == TRIG_COUNT)
812 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
813 else /* TRIG_NONE */
814 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
815
816 if (err)
817 return 3;
818
819 /* step 4: fix up any arguments */
820
821 if (cmd->scan_begin_src == TRIG_TIMER) {
822 arg = cmd->scan_begin_arg;
823 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
824 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
825 }
826 if (cmd->convert_src == TRIG_TIMER) {
827 arg = cmd->convert_arg;
828 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
829 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
830 }
831
832 if (err)
833 return 4;
834
835 /* Step 5: check channel list if it exists */
836 if (cmd->chanlist && cmd->chanlist_len > 0)
837 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
838
839 if (err)
840 return 5;
841
842 return 0;
843 }
844
845 static int cb_pcidas_ai_cmd(struct comedi_device *dev,
846 struct comedi_subdevice *s)
847 {
848 const struct cb_pcidas_board *board = dev->board_ptr;
849 struct cb_pcidas_private *devpriv = dev->private;
850 struct comedi_async *async = s->async;
851 struct comedi_cmd *cmd = &async->cmd;
852 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
853 unsigned int bits;
854 unsigned long flags;
855
856 /* make sure CAL_EN_BIT is disabled */
857 outw(0, devpriv->pcibar1 + CALIBRATION_REG);
858 /* initialize before settings pacer source and count values */
859 outw(0, devpriv->pcibar1 + TRIG_CONTSTAT);
860 /* clear fifo */
861 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG);
862
863 /* set mux limits, gain and pacer source */
864 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
865 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
866 GAIN_BITS(range0);
867 /* set unipolar/bipolar */
868 if (comedi_range_is_unipolar(s, range0))
869 bits |= UNIP;
870 /* set singleended/differential */
871 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
872 bits |= SE;
873 /* set pacer source */
874 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
875 bits |= PACER_EXT_RISE;
876 else
877 bits |= PACER_INT;
878 outw(bits, devpriv->pcibar1 + ADCMUX_CONT);
879
880 /* load counters */
881 if (cmd->scan_begin_src == TRIG_TIMER ||
882 cmd->convert_src == TRIG_TIMER) {
883 comedi_8254_update_divisors(dev->pacer);
884 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
885 }
886
887 /* enable interrupts */
888 spin_lock_irqsave(&dev->spinlock, flags);
889 devpriv->ctrl |= PCIDAS_CTRL_INTE;
890 devpriv->ctrl &= ~PCIDAS_CTRL_INT_MASK;
891 if (cmd->flags & CMDF_WAKE_EOS) {
892 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
893 /* interrupt end of burst */
894 devpriv->ctrl |= PCIDAS_CTRL_INT_EOS;
895 } else {
896 /* interrupt fifo not empty */
897 devpriv->ctrl |= PCIDAS_CTRL_INT_FNE;
898 }
899 } else {
900 /* interrupt fifo half full */
901 devpriv->ctrl |= PCIDAS_CTRL_INT_FHF;
902 }
903
904 /* enable (and clear) interrupts */
905 outw(devpriv->ctrl |
906 PCIDAS_CTRL_EOAI | PCIDAS_CTRL_INT_CLR | PCIDAS_CTRL_LADFUL,
907 devpriv->pcibar1 + PCIDAS_CTRL_REG);
908 spin_unlock_irqrestore(&dev->spinlock, flags);
909
910 /* set start trigger and burst mode */
911 bits = 0;
912 if (cmd->start_src == TRIG_NOW) {
913 bits |= SW_TRIGGER;
914 } else { /* TRIG_EXT */
915 bits |= EXT_TRIGGER | TGEN | XTRCL;
916 if (board->is_1602) {
917 if (cmd->start_arg & CR_INVERT)
918 bits |= TGPOL;
919 if (cmd->start_arg & CR_EDGE)
920 bits |= TGSEL;
921 }
922 }
923 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
924 bits |= BURSTE;
925 outw(bits, devpriv->pcibar1 + TRIG_CONTSTAT);
926
927 return 0;
928 }
929
930 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
931 struct comedi_subdevice *s,
932 struct comedi_cmd *cmd)
933 {
934 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
935
936 if (cmd->chanlist_len > 1) {
937 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
938
939 if (chan0 != 0 || chan1 != 1) {
940 dev_dbg(dev->class_dev,
941 "channels must be ordered channel 0, channel 1 in chanlist\n");
942 return -EINVAL;
943 }
944 }
945
946 return 0;
947 }
948
949 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
950 struct comedi_subdevice *s,
951 struct comedi_cmd *cmd)
952 {
953 const struct cb_pcidas_board *board = dev->board_ptr;
954 struct cb_pcidas_private *devpriv = dev->private;
955 int err = 0;
956
957 /* Step 1 : check if triggers are trivially valid */
958
959 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
960 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
961 TRIG_TIMER | TRIG_EXT);
962 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
963 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
964 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
965
966 if (err)
967 return 1;
968
969 /* Step 2a : make sure trigger sources are unique */
970
971 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
972 err |= comedi_check_trigger_is_unique(cmd->stop_src);
973
974 /* Step 2b : and mutually compatible */
975
976 if (err)
977 return 2;
978
979 /* Step 3: check if arguments are trivially valid */
980
981 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
982
983 if (cmd->scan_begin_src == TRIG_TIMER) {
984 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
985 board->ao_scan_speed);
986 }
987
988 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
989 cmd->chanlist_len);
990
991 if (cmd->stop_src == TRIG_COUNT)
992 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
993 else /* TRIG_NONE */
994 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
995
996 if (err)
997 return 3;
998
999 /* step 4: fix up any arguments */
1000
1001 if (cmd->scan_begin_src == TRIG_TIMER) {
1002 unsigned int arg = cmd->scan_begin_arg;
1003
1004 comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer,
1005 &arg, cmd->flags);
1006 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1007 }
1008
1009 if (err)
1010 return 4;
1011
1012 /* Step 5: check channel list if it exists */
1013 if (cmd->chanlist && cmd->chanlist_len > 0)
1014 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1015
1016 if (err)
1017 return 5;
1018
1019 return 0;
1020 }
1021
1022 /* cancel analog input command */
1023 static int cb_pcidas_cancel(struct comedi_device *dev,
1024 struct comedi_subdevice *s)
1025 {
1026 struct cb_pcidas_private *devpriv = dev->private;
1027 unsigned long flags;
1028
1029 spin_lock_irqsave(&dev->spinlock, flags);
1030 /* disable interrupts */
1031 devpriv->ctrl &= ~(PCIDAS_CTRL_INTE | PCIDAS_CTRL_EOAIE);
1032 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
1033 spin_unlock_irqrestore(&dev->spinlock, flags);
1034
1035 /* disable start trigger source and burst mode */
1036 outw(0, devpriv->pcibar1 + TRIG_CONTSTAT);
1037 /* software pacer source */
1038 outw(0, devpriv->pcibar1 + ADCMUX_CONT);
1039
1040 return 0;
1041 }
1042
1043 static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
1044 struct comedi_subdevice *s,
1045 unsigned int nsamples)
1046 {
1047 struct cb_pcidas_private *devpriv = dev->private;
1048 unsigned int nbytes;
1049
1050 nsamples = comedi_nsamples_left(s, nsamples);
1051 nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
1052
1053 nsamples = comedi_bytes_to_samples(s, nbytes);
1054 outsw(devpriv->pcibar4 + PCIDAS_AO_FIFO_REG,
1055 devpriv->ao_buffer, nsamples);
1056 }
1057
1058 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1059 struct comedi_subdevice *s,
1060 unsigned int trig_num)
1061 {
1062 const struct cb_pcidas_board *board = dev->board_ptr;
1063 struct cb_pcidas_private *devpriv = dev->private;
1064 struct comedi_async *async = s->async;
1065 struct comedi_cmd *cmd = &async->cmd;
1066 unsigned long flags;
1067
1068 if (trig_num != cmd->start_arg)
1069 return -EINVAL;
1070
1071 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size);
1072
1073 /* enable dac half-full and empty interrupts */
1074 spin_lock_irqsave(&dev->spinlock, flags);
1075 devpriv->ctrl |= PCIDAS_CTRL_DAEMIE | PCIDAS_CTRL_DAHFIE;
1076
1077 /* enable and clear interrupts */
1078 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI | PCIDAS_CTRL_DAHFI,
1079 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1080
1081 /* start dac */
1082 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1083 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1084
1085 spin_unlock_irqrestore(&dev->spinlock, flags);
1086
1087 async->inttrig = NULL;
1088
1089 return 0;
1090 }
1091
1092 static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1093 struct comedi_subdevice *s)
1094 {
1095 struct cb_pcidas_private *devpriv = dev->private;
1096 struct comedi_async *async = s->async;
1097 struct comedi_cmd *cmd = &async->cmd;
1098 unsigned int i;
1099 unsigned long flags;
1100
1101 /* set channel limits, gain */
1102 spin_lock_irqsave(&dev->spinlock, flags);
1103 for (i = 0; i < cmd->chanlist_len; i++) {
1104 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
1105 unsigned int range = CR_RANGE(cmd->chanlist[i]);
1106
1107 /* enable channel */
1108 devpriv->ao_control_bits |= DAC_CHAN_EN(chan);
1109 /* set range */
1110 devpriv->ao_control_bits |= DAC_RANGE(chan, range);
1111 }
1112
1113 /* disable analog out before settings pacer source and count values */
1114 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1115 spin_unlock_irqrestore(&dev->spinlock, flags);
1116
1117 /* clear fifo */
1118 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG);
1119
1120 /* load counters */
1121 if (cmd->scan_begin_src == TRIG_TIMER) {
1122 comedi_8254_update_divisors(devpriv->ao_pacer);
1123 comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true);
1124 }
1125
1126 /* set pacer source */
1127 spin_lock_irqsave(&dev->spinlock, flags);
1128 switch (cmd->scan_begin_src) {
1129 case TRIG_TIMER:
1130 devpriv->ao_control_bits |= DAC_PACER_INT;
1131 break;
1132 case TRIG_EXT:
1133 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1134 break;
1135 default:
1136 spin_unlock_irqrestore(&dev->spinlock, flags);
1137 dev_err(dev->class_dev, "error setting dac pacer source\n");
1138 return -1;
1139 }
1140 spin_unlock_irqrestore(&dev->spinlock, flags);
1141
1142 async->inttrig = cb_pcidas_ao_inttrig;
1143
1144 return 0;
1145 }
1146
1147 /* cancel analog output command */
1148 static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1149 struct comedi_subdevice *s)
1150 {
1151 struct cb_pcidas_private *devpriv = dev->private;
1152 unsigned long flags;
1153
1154 spin_lock_irqsave(&dev->spinlock, flags);
1155 /* disable interrupts */
1156 devpriv->ctrl &= ~(PCIDAS_CTRL_DAHFIE | PCIDAS_CTRL_DAEMIE);
1157 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG);
1158
1159 /* disable output */
1160 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1161 outw(devpriv->ao_control_bits, devpriv->pcibar1 + DAC_CSR);
1162 spin_unlock_irqrestore(&dev->spinlock, flags);
1163
1164 return 0;
1165 }
1166
1167 static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1168 {
1169 const struct cb_pcidas_board *board = dev->board_ptr;
1170 struct cb_pcidas_private *devpriv = dev->private;
1171 struct comedi_subdevice *s = dev->write_subdev;
1172 struct comedi_async *async = s->async;
1173 struct comedi_cmd *cmd = &async->cmd;
1174 unsigned long flags;
1175
1176 if (status & PCIDAS_CTRL_DAEMI) {
1177 /* clear dac empty interrupt latch */
1178 spin_lock_irqsave(&dev->spinlock, flags);
1179 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI,
1180 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1181 spin_unlock_irqrestore(&dev->spinlock, flags);
1182 if (inw(devpriv->pcibar4 + DAC_CSR) & DAC_EMPTY) {
1183 if (cmd->stop_src == TRIG_COUNT &&
1184 async->scans_done >= cmd->stop_arg) {
1185 async->events |= COMEDI_CB_EOA;
1186 } else {
1187 dev_err(dev->class_dev, "dac fifo underflow\n");
1188 async->events |= COMEDI_CB_ERROR;
1189 }
1190 }
1191 } else if (status & PCIDAS_CTRL_DAHFI) {
1192 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size / 2);
1193
1194 /* clear half-full interrupt latch */
1195 spin_lock_irqsave(&dev->spinlock, flags);
1196 outw(devpriv->ctrl | PCIDAS_CTRL_DAHFI,
1197 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1198 spin_unlock_irqrestore(&dev->spinlock, flags);
1199 }
1200
1201 comedi_handle_events(dev, s);
1202 }
1203
1204 static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1205 {
1206 struct comedi_device *dev = d;
1207 const struct cb_pcidas_board *board = dev->board_ptr;
1208 struct cb_pcidas_private *devpriv = dev->private;
1209 struct comedi_subdevice *s = dev->read_subdev;
1210 struct comedi_async *async;
1211 struct comedi_cmd *cmd;
1212 int status, s5933_status;
1213 int half_fifo = board->fifo_size / 2;
1214 unsigned int num_samples, i;
1215 static const int timeout = 10000;
1216 unsigned long flags;
1217
1218 if (!dev->attached)
1219 return IRQ_NONE;
1220
1221 async = s->async;
1222 cmd = &async->cmd;
1223
1224 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1225
1226 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1227 return IRQ_NONE;
1228
1229 /* make sure mailbox 4 is empty */
1230 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1231 /* clear interrupt on amcc s5933 */
1232 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1233 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1234
1235 status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG);
1236
1237 /* check for analog output interrupt */
1238 if (status & (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI))
1239 handle_ao_interrupt(dev, status);
1240 /* check for analog input interrupts */
1241 /* if fifo half-full */
1242 if (status & PCIDAS_CTRL_ADHFI) {
1243 /* read data */
1244 num_samples = comedi_nsamples_left(s, half_fifo);
1245 insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG,
1246 devpriv->ai_buffer, num_samples);
1247 comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples);
1248
1249 if (cmd->stop_src == TRIG_COUNT &&
1250 async->scans_done >= cmd->stop_arg)
1251 async->events |= COMEDI_CB_EOA;
1252
1253 /* clear half-full interrupt latch */
1254 spin_lock_irqsave(&dev->spinlock, flags);
1255 outw(devpriv->ctrl | PCIDAS_CTRL_INT_CLR,
1256 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1257 spin_unlock_irqrestore(&dev->spinlock, flags);
1258 /* else if fifo not empty */
1259 } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) {
1260 for (i = 0; i < timeout; i++) {
1261 unsigned short val;
1262
1263 /* break if fifo is empty */
1264 if ((inw(devpriv->pcibar1 + PCIDAS_CTRL_REG) &
1265 PCIDAS_CTRL_ADNE) == 0)
1266 break;
1267 val = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG);
1268 comedi_buf_write_samples(s, &val, 1);
1269
1270 if (cmd->stop_src == TRIG_COUNT &&
1271 async->scans_done >= cmd->stop_arg) {
1272 async->events |= COMEDI_CB_EOA;
1273 break;
1274 }
1275 }
1276 /* clear not-empty interrupt latch */
1277 spin_lock_irqsave(&dev->spinlock, flags);
1278 outw(devpriv->ctrl | PCIDAS_CTRL_INT_CLR,
1279 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1280 spin_unlock_irqrestore(&dev->spinlock, flags);
1281 } else if (status & PCIDAS_CTRL_EOAI) {
1282 dev_err(dev->class_dev,
1283 "bug! encountered end of acquisition interrupt?\n");
1284 /* clear EOA interrupt latch */
1285 spin_lock_irqsave(&dev->spinlock, flags);
1286 outw(devpriv->ctrl | PCIDAS_CTRL_EOAI,
1287 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1288 spin_unlock_irqrestore(&dev->spinlock, flags);
1289 }
1290 /* check for fifo overflow */
1291 if (status & PCIDAS_CTRL_LADFUL) {
1292 dev_err(dev->class_dev, "fifo overflow\n");
1293 /* clear overflow interrupt latch */
1294 spin_lock_irqsave(&dev->spinlock, flags);
1295 outw(devpriv->ctrl | PCIDAS_CTRL_LADFUL,
1296 devpriv->pcibar1 + PCIDAS_CTRL_REG);
1297 spin_unlock_irqrestore(&dev->spinlock, flags);
1298 async->events |= COMEDI_CB_ERROR;
1299 }
1300
1301 comedi_handle_events(dev, s);
1302
1303 return IRQ_HANDLED;
1304 }
1305
1306 static int cb_pcidas_auto_attach(struct comedi_device *dev,
1307 unsigned long context)
1308 {
1309 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1310 const struct cb_pcidas_board *board = NULL;
1311 struct cb_pcidas_private *devpriv;
1312 struct comedi_subdevice *s;
1313 int i;
1314 int ret;
1315
1316 if (context < ARRAY_SIZE(cb_pcidas_boards))
1317 board = &cb_pcidas_boards[context];
1318 if (!board)
1319 return -ENODEV;
1320 dev->board_ptr = board;
1321 dev->board_name = board->name;
1322
1323 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1324 if (!devpriv)
1325 return -ENOMEM;
1326
1327 ret = comedi_pci_enable(dev);
1328 if (ret)
1329 return ret;
1330
1331 devpriv->s5933_config = pci_resource_start(pcidev, 0);
1332 devpriv->pcibar1 = pci_resource_start(pcidev, 1);
1333 devpriv->pcibar2 = pci_resource_start(pcidev, 2);
1334 dev->iobase = pci_resource_start(pcidev, 3);
1335 if (board->has_ao)
1336 devpriv->pcibar4 = pci_resource_start(pcidev, 4);
1337
1338 /* disable and clear interrupts on amcc s5933 */
1339 outl(INTCSR_INBOX_INTR_STATUS,
1340 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1341
1342 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED,
1343 dev->board_name, dev);
1344 if (ret) {
1345 dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1346 pcidev->irq);
1347 return ret;
1348 }
1349 dev->irq = pcidev->irq;
1350
1351 dev->pacer = comedi_8254_init(dev->iobase + PCIDAS_AI_8254_BASE,
1352 I8254_OSC_BASE_10MHZ, I8254_IO8, 0);
1353 if (!dev->pacer)
1354 return -ENOMEM;
1355
1356 devpriv->ao_pacer = comedi_8254_init(dev->iobase + PCIDAS_AO_8254_BASE,
1357 I8254_OSC_BASE_10MHZ,
1358 I8254_IO8, 0);
1359 if (!devpriv->ao_pacer)
1360 return -ENOMEM;
1361
1362 ret = comedi_alloc_subdevices(dev, 7);
1363 if (ret)
1364 return ret;
1365
1366 s = &dev->subdevices[0];
1367 /* analog input subdevice */
1368 dev->read_subdev = s;
1369 s->type = COMEDI_SUBD_AI;
1370 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1371 /* WARNING: Number of inputs in differential mode is ignored */
1372 s->n_chan = 16;
1373 s->len_chanlist = s->n_chan;
1374 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1375 s->range_table = board->use_alt_range ? &cb_pcidas_alt_ranges
1376 : &cb_pcidas_ranges;
1377 s->insn_read = cb_pcidas_ai_rinsn;
1378 s->insn_config = ai_config_insn;
1379 s->do_cmd = cb_pcidas_ai_cmd;
1380 s->do_cmdtest = cb_pcidas_ai_cmdtest;
1381 s->cancel = cb_pcidas_cancel;
1382
1383 /* analog output subdevice */
1384 s = &dev->subdevices[1];
1385 if (board->has_ao) {
1386 s->type = COMEDI_SUBD_AO;
1387 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1388 s->n_chan = 2;
1389 s->maxdata = board->is_16bit ? 0xffff : 0x0fff;
1390 s->range_table = &cb_pcidas_ao_ranges;
1391 /* default to no fifo (*insn_write) */
1392 s->insn_write = cb_pcidas_ao_nofifo_winsn;
1393
1394 ret = comedi_alloc_subdev_readback(s);
1395 if (ret)
1396 return ret;
1397
1398 if (board->has_ao_fifo) {
1399 dev->write_subdev = s;
1400 s->subdev_flags |= SDF_CMD_WRITE;
1401 /* use fifo (*insn_write) instead */
1402 s->insn_write = cb_pcidas_ao_fifo_winsn;
1403 s->do_cmdtest = cb_pcidas_ao_cmdtest;
1404 s->do_cmd = cb_pcidas_ao_cmd;
1405 s->cancel = cb_pcidas_ao_cancel;
1406 }
1407 } else {
1408 s->type = COMEDI_SUBD_UNUSED;
1409 }
1410
1411 /* 8255 */
1412 s = &dev->subdevices[2];
1413 ret = subdev_8255_init(dev, s, NULL, PCIDAS_8255_BASE);
1414 if (ret)
1415 return ret;
1416
1417 /* serial EEPROM, */
1418 s = &dev->subdevices[3];
1419 s->type = COMEDI_SUBD_MEMORY;
1420 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1421 s->n_chan = 256;
1422 s->maxdata = 0xff;
1423 s->insn_read = eeprom_read_insn;
1424
1425 /* 8800 caldac */
1426 s = &dev->subdevices[4];
1427 s->type = COMEDI_SUBD_CALIB;
1428 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1429 s->n_chan = 8;
1430 s->maxdata = 0xff;
1431 s->insn_write = cb_pcidas_caldac_insn_write;
1432
1433 ret = comedi_alloc_subdev_readback(s);
1434 if (ret)
1435 return ret;
1436
1437 for (i = 0; i < s->n_chan; i++) {
1438 caldac_8800_write(dev, i, s->maxdata / 2);
1439 s->readback[i] = s->maxdata / 2;
1440 }
1441
1442 /* trim potentiometer */
1443 s = &dev->subdevices[5];
1444 s->type = COMEDI_SUBD_CALIB;
1445 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1446 if (board->trimpot == AD7376) {
1447 s->n_chan = 1;
1448 s->maxdata = 0x7f;
1449 } else {
1450 s->n_chan = 2;
1451 s->maxdata = 0xff;
1452 }
1453 s->insn_write = cb_pcidas_trimpot_insn_write;
1454
1455 ret = comedi_alloc_subdev_readback(s);
1456 if (ret)
1457 return ret;
1458
1459 for (i = 0; i < s->n_chan; i++) {
1460 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1461 s->readback[i] = s->maxdata / 2;
1462 }
1463
1464 /* dac08 caldac */
1465 s = &dev->subdevices[6];
1466 if (board->has_dac08) {
1467 s->type = COMEDI_SUBD_CALIB;
1468 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1469 s->n_chan = 1;
1470 s->maxdata = 0xff;
1471 s->insn_write = cb_pcidas_dac08_insn_write;
1472
1473 ret = comedi_alloc_subdev_readback(s);
1474 if (ret)
1475 return ret;
1476
1477 for (i = 0; i < s->n_chan; i++) {
1478 dac08_write(dev, s->maxdata / 2);
1479 s->readback[i] = s->maxdata / 2;
1480 }
1481 } else {
1482 s->type = COMEDI_SUBD_UNUSED;
1483 }
1484
1485 /* make sure mailbox 4 is empty */
1486 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1487 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1488 devpriv->s5933_intcsr_bits =
1489 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1490 INTCSR_INBOX_FULL_INT;
1491 /* clear and enable interrupt on amcc s5933 */
1492 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1493 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1494
1495 return 0;
1496 }
1497
1498 static void cb_pcidas_detach(struct comedi_device *dev)
1499 {
1500 struct cb_pcidas_private *devpriv = dev->private;
1501
1502 if (devpriv) {
1503 if (devpriv->s5933_config)
1504 outl(INTCSR_INBOX_INTR_STATUS,
1505 devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1506 kfree(devpriv->ao_pacer);
1507 }
1508 comedi_pci_detach(dev);
1509 }
1510
1511 static struct comedi_driver cb_pcidas_driver = {
1512 .driver_name = "cb_pcidas",
1513 .module = THIS_MODULE,
1514 .auto_attach = cb_pcidas_auto_attach,
1515 .detach = cb_pcidas_detach,
1516 };
1517
1518 static int cb_pcidas_pci_probe(struct pci_dev *dev,
1519 const struct pci_device_id *id)
1520 {
1521 return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1522 id->driver_data);
1523 }
1524
1525 static const struct pci_device_id cb_pcidas_pci_table[] = {
1526 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1527 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1528 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1529 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1530 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1531 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1532 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1533 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1534 { 0 }
1535 };
1536 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1537
1538 static struct pci_driver cb_pcidas_pci_driver = {
1539 .name = "cb_pcidas",
1540 .id_table = cb_pcidas_pci_table,
1541 .probe = cb_pcidas_pci_probe,
1542 .remove = comedi_pci_auto_unconfig,
1543 };
1544 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1545
1546 MODULE_AUTHOR("Comedi http://www.comedi.org");
1547 MODULE_DESCRIPTION("Comedi low-level driver");
1548 MODULE_LICENSE("GPL");
This page took 0.066321 seconds and 5 git commands to generate.