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