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