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