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