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