1 /*
2 comedi/drivers/cb_pcidda.c
3 This intends to be a driver for the ComputerBoards / MeasurementComputing
4 PCI-DDA series.
5
6 Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
7 Copyright (C) 2001 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 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26 */
27 /*
28 Driver: cb_pcidda
29 Description: MeasurementComputing PCI-DDA series
30 Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
31 Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
32 Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
33 PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
34
35 Configuration options:
36 [0] - PCI bus of device (optional)
37 [1] - PCI slot of device (optional)
38 If bus/slot is not specified, the first available PCI
39 device will be used.
40
41 Only simple analog output writing is supported.
42
43 So far it has only been tested with:
44 - PCI-DDA08/12
45 Please report success/failure with other different cards to
46 <comedi@comedi.org>.
47 */
48
49 #include "../comedidev.h"
50
51 #include "comedi_pci.h"
52 #include "8255.h"
53
54 #define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */
55 #define EEPROM_SIZE 128 /* number of entries in eeprom */
56 #define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */
57
58 /* PCI-DDA base addresses */
59 #define DIGITALIO_BADRINDEX 2
60 /* DIGITAL I/O is pci_dev->resource[2] */
61 #define DIGITALIO_SIZE 8
62 /* DIGITAL I/O uses 8 I/O port addresses */
63 #define DAC_BADRINDEX 3
64 /* DAC is pci_dev->resource[3] */
65
66 /* Digital I/O registers */
67 #define PORT1A 0 /* PORT 1A DATA */
68
69 #define PORT1B 1 /* PORT 1B DATA */
70
71 #define PORT1C 2 /* PORT 1C DATA */
72
73 #define CONTROL1 3 /* CONTROL REGISTER 1 */
74
75 #define PORT2A 4 /* PORT 2A DATA */
76
77 #define PORT2B 5 /* PORT 2B DATA */
78
79 #define PORT2C 6 /* PORT 2C DATA */
80
81 #define CONTROL2 7 /* CONTROL REGISTER 2 */
82
83 /* DAC registers */
84 #define DACONTROL 0 /* D/A CONTROL REGISTER */
85 #define SU 0000001 /* Simultaneous update enabled */
86 #define NOSU 0000000 /* Simultaneous update disabled */
87 #define ENABLEDAC 0000002 /* Enable specified DAC */
88 #define DISABLEDAC 0000000 /* Disable specified DAC */
89 #define RANGE2V5 0000000 /* 2.5V */
90 #define RANGE5V 0000200 /* 5V */
91 #define RANGE10V 0000300 /* 10V */
92 #define UNIP 0000400 /* Unipolar outputs */
93 #define BIP 0000000 /* Bipolar outputs */
94
95 #define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */
96 /* write bits */
97 #define SERIAL_IN_BIT 0x1 /* serial data input for eeprom, caldacs, reference dac */
98 #define CAL_CHANNEL_MASK (0x7 << 1)
99 #define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
100 /* read bits */
101 #define CAL_COUNTER_MASK 0x1f
102 #define CAL_COUNTER_OVERFLOW_BIT 0x20 /* calibration counter overflow status bit */
103 #define AO_BELOW_REF_BIT 0x40 /* analog output is less than reference dac voltage */
104 #define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */
105
106 #define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */
107 #define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */
108 #define DESELECT_REF_DAC_BIT 0x2 /* don't send serial data to MAX542 reference dac */
109 #define DESELECT_CALDAC_BIT(n) (0x4 << (n)) /* don't send serial data to caldac n */
110 #define DUMMY_BIT 0x40 /* manual says to set this bit with no explanation */
111
112 #define DADATA 8 /* FIRST D/A DATA REGISTER (0) */
113
114 static const struct comedi_lrange cb_pcidda_ranges = {
115 6,
116 {
117 BIP_RANGE(10),
118 BIP_RANGE(5),
119 BIP_RANGE(2.5),
120 UNI_RANGE(10),
121 UNI_RANGE(5),
122 UNI_RANGE(2.5),
123 }
124 };
125
126 /*
127 * Board descriptions for two imaginary boards. Describing the
128 * boards in this way is optional, and completely driver-dependent.
129 * Some drivers use arrays such as this, other do not.
130 */
131 struct cb_pcidda_board {
132 const char *name;
133 char status; /* Driver status: */
134
135 /*
136 * 0 - tested
137 * 1 - manual read, not tested
138 * 2 - manual not read
139 */
140
141 unsigned short device_id;
142 int ao_chans;
143 int ao_bits;
144 const struct comedi_lrange *ranges;
145 };
146
147 static const struct cb_pcidda_board cb_pcidda_boards[] = {
148 {
149 .name = "pci-dda02/12",
150 .status = 1,
151 .device_id = 0x20,
152 .ao_chans = 2,
153 .ao_bits = 12,
154 .ranges = &cb_pcidda_ranges,
155 },
156 {
157 .name = "pci-dda04/12",
158 .status = 1,
159 .device_id = 0x21,
160 .ao_chans = 4,
161 .ao_bits = 12,
162 .ranges = &cb_pcidda_ranges,
163 },
164 {
165 .name = "pci-dda08/12",
166 .status = 0,
167 .device_id = 0x22,
168 .ao_chans = 8,
169 .ao_bits = 12,
170 .ranges = &cb_pcidda_ranges,
171 },
172 {
173 .name = "pci-dda02/16",
174 .status = 2,
175 .device_id = 0x23,
176 .ao_chans = 2,
177 .ao_bits = 16,
178 .ranges = &cb_pcidda_ranges,
179 },
180 {
181 .name = "pci-dda04/16",
182 .status = 2,
183 .device_id = 0x24,
184 .ao_chans = 4,
185 .ao_bits = 16,
186 .ranges = &cb_pcidda_ranges,
187 },
188 {
189 .name = "pci-dda08/16",
190 .status = 0,
191 .device_id = 0x25,
192 .ao_chans = 8,
193 .ao_bits = 16,
194 .ranges = &cb_pcidda_ranges,
195 },
196 };
197
198 static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
199 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
200 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
201 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
202 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
203 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
204 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
205 { 0 }
206 };
207
208 MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
209
210 /*
211 * Useful for shorthand access to the particular board structure
212 */
213 #define thisboard ((const struct cb_pcidda_board *)dev->board_ptr)
214
215 /* this structure is for data unique to this hardware driver. If
216 several hardware drivers keep similar information in this structure,
217 feel free to suggest moving the variable to the struct comedi_device struct. */
218 struct cb_pcidda_private {
219 int data;
220
221 /* would be useful for a PCI device */
222 struct pci_dev *pci_dev;
223
224 unsigned long digitalio;
225 unsigned long dac;
226
227 /* unsigned long control_status; */
228 /* unsigned long adc_fifo; */
229
230 unsigned int dac_cal1_bits; /* bits last written to da calibration register 1 */
231 unsigned int ao_range[MAX_AO_CHANNELS]; /* current range settings for output channels */
232 u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */
233 };
234
235 /*
236 * most drivers define the following macro to make it easy to
237 * access the private structure.
238 */
239 #define devpriv ((struct cb_pcidda_private *)dev->private)
240
241 static int cb_pcidda_attach(struct comedi_device *dev,
242 struct comedi_devconfig *it);
243 static int cb_pcidda_detach(struct comedi_device *dev);
244 /* static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
245 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
246 struct comedi_subdevice *s,
247 struct comedi_insn *insn, unsigned int *data);
248
249 /* static int cb_pcidda_ai_cmd(struct comedi_device *dev, struct *comedi_subdevice *s);*/
250 /* static int cb_pcidda_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd); */
251 /* static int cb_pcidda_ns_to_timer(unsigned int *ns,int *round); */
252
253 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev);
254 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
255 unsigned int num_bits);
256 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
257 unsigned int address);
258 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
259 unsigned int range);
260
261 /*
262 * The struct comedi_driver structure tells the Comedi core module
263 * which functions to call to configure/deconfigure (attach/detach)
264 * the board, and also about the kernel module that contains
265 * the device code.
266 */
267 static struct comedi_driver driver_cb_pcidda = {
268 .driver_name = "cb_pcidda",
269 .module = THIS_MODULE,
270 .attach = cb_pcidda_attach,
271 .detach = cb_pcidda_detach,
272 };
273
274 /*
275 * Attach is called by the Comedi core to configure the driver
276 * for a particular board.
277 */
cb_pcidda_attach(struct comedi_device * dev,struct comedi_devconfig * it)278 static int cb_pcidda_attach(struct comedi_device *dev,
279 struct comedi_devconfig *it)
280 {
281 struct comedi_subdevice *s;
282 struct pci_dev *pcidev = NULL;
283 int index;
284
285
286 /*
287 * Allocate the private structure area.
288 */
289 if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
290 return -ENOMEM;
291
292 /*
293 * Probe the device to determine what device in the series it is.
294 */
295
296 for_each_pci_dev(pcidev) {
297 if (pcidev->vendor == PCI_VENDOR_ID_CB) {
298 if (it->options[0] || it->options[1]) {
299 if (pcidev->bus->number != it->options[0] ||
300 PCI_SLOT(pcidev->devfn) != it->options[1]) {
301 continue;
302 }
303 }
304 for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) {
305 if (cb_pcidda_boards[index].device_id ==
306 pcidev->device) {
307 goto found;
308 }
309 }
310 }
311 }
312 if (!pcidev) {
313 dev_err(dev->hw_dev, "Not a ComputerBoards/MeasurementComputing card on requested position\n");
314 return -EIO;
315 }
316 found:
317 devpriv->pci_dev = pcidev;
318 dev->board_ptr = cb_pcidda_boards + index;
319 /* "thisboard" macro can be used from here. */
320 dev_dbg(dev->hw_dev, "Found %s at requested position\n",
321 thisboard->name);
322
323 /*
324 * Enable PCI device and request regions.
325 */
326 if (comedi_pci_enable(pcidev, thisboard->name)) {
327 dev_err(dev->hw_dev, "cb_pcidda: failed to enable PCI device and request regions\n");
328 return -EIO;
329 }
330
331 /*
332 * Allocate the I/O ports.
333 */
334 devpriv->digitalio =
335 pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
336 devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
337
338 /*
339 * Warn about the status of the driver.
340 */
341 if (thisboard->status == 2)
342 printk
343 ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
344 "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
345 "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
346
347 /*
348 * Initialize dev->board_name.
349 */
350 dev->board_name = thisboard->name;
351
352 /*
353 * Allocate the subdevice structures.
354 */
355 if (alloc_subdevices(dev, 3) < 0)
356 return -ENOMEM;
357
358 s = dev->subdevices + 0;
359 /* analog output subdevice */
360 s->type = COMEDI_SUBD_AO;
361 s->subdev_flags = SDF_WRITABLE;
362 s->n_chan = thisboard->ao_chans;
363 s->maxdata = (1 << thisboard->ao_bits) - 1;
364 s->range_table = thisboard->ranges;
365 s->insn_write = cb_pcidda_ao_winsn;
366
367 /* s->subdev_flags |= SDF_CMD_READ; */
368 /* s->do_cmd = cb_pcidda_ai_cmd; */
369 /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
370
371 /* two 8255 digital io subdevices */
372 s = dev->subdevices + 1;
373 subdev_8255_init(dev, s, NULL, devpriv->digitalio);
374 s = dev->subdevices + 2;
375 subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
376
377 dev_dbg(dev->hw_dev, "eeprom:\n");
378 for (index = 0; index < EEPROM_SIZE; index++) {
379 devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
380 dev_dbg(dev->hw_dev, "%i:0x%x\n", index, devpriv->eeprom_data[index]);
381 }
382
383 /* set calibrations dacs */
384 for (index = 0; index < thisboard->ao_chans; index++)
385 cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
386
387 return 1;
388 }
389
390 /*
391 * _detach is called to deconfigure a device. It should deallocate
392 * resources.
393 * This function is also called when _attach() fails, so it should be
394 * careful not to release resources that were not necessarily
395 * allocated by _attach(). dev->private and dev->subdevices are
396 * deallocated automatically by the core.
397 */
cb_pcidda_detach(struct comedi_device * dev)398 static int cb_pcidda_detach(struct comedi_device *dev)
399 {
400 /*
401 * Deallocate the I/O ports.
402 */
403 if (devpriv) {
404 if (devpriv->pci_dev) {
405 if (devpriv->dac)
406 comedi_pci_disable(devpriv->pci_dev);
407 pci_dev_put(devpriv->pci_dev);
408 }
409 }
410 /* cleanup 8255 */
411 if (dev->subdevices) {
412 subdev_8255_cleanup(dev, dev->subdevices + 1);
413 subdev_8255_cleanup(dev, dev->subdevices + 2);
414 }
415
416 return 0;
417 }
418
419 /*
420 * I will program this later... ;-)
421 */
422 #if 0
423 static int cb_pcidda_ai_cmd(struct comedi_device *dev,
424 struct comedi_subdevice *s)
425 {
426 printk("cb_pcidda_ai_cmd\n");
427 printk("subdev: %d\n", cmd->subdev);
428 printk("flags: %d\n", cmd->flags);
429 printk("start_src: %d\n", cmd->start_src);
430 printk("start_arg: %d\n", cmd->start_arg);
431 printk("scan_begin_src: %d\n", cmd->scan_begin_src);
432 printk("convert_src: %d\n", cmd->convert_src);
433 printk("convert_arg: %d\n", cmd->convert_arg);
434 printk("scan_end_src: %d\n", cmd->scan_end_src);
435 printk("scan_end_arg: %d\n", cmd->scan_end_arg);
436 printk("stop_src: %d\n", cmd->stop_src);
437 printk("stop_arg: %d\n", cmd->stop_arg);
438 printk("chanlist_len: %d\n", cmd->chanlist_len);
439 }
440 #endif
441
442 #if 0
443 static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
444 struct comedi_subdevice *s,
445 struct comedi_cmd *cmd)
446 {
447 int err = 0;
448 int tmp;
449
450 /* cmdtest tests a particular command to see if it is valid.
451 * Using the cmdtest ioctl, a user can create a valid cmd
452 * and then have it executes by the cmd ioctl.
453 *
454 * cmdtest returns 1,2,3,4 or 0, depending on which tests
455 * the command passes. */
456
457 /* step 1: make sure trigger sources are trivially valid */
458
459 tmp = cmd->start_src;
460 cmd->start_src &= TRIG_NOW;
461 if (!cmd->start_src || tmp != cmd->start_src)
462 err++;
463
464 tmp = cmd->scan_begin_src;
465 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
466 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
467 err++;
468
469 tmp = cmd->convert_src;
470 cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
471 if (!cmd->convert_src || tmp != cmd->convert_src)
472 err++;
473
474 tmp = cmd->scan_end_src;
475 cmd->scan_end_src &= TRIG_COUNT;
476 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
477 err++;
478
479 tmp = cmd->stop_src;
480 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
481 if (!cmd->stop_src || tmp != cmd->stop_src)
482 err++;
483
484 if (err)
485 return 1;
486
487 /* step 2: make sure trigger sources are unique and mutually compatible */
488
489 /* note that mutual compatibility is not an issue here */
490 if (cmd->scan_begin_src != TRIG_TIMER
491 && cmd->scan_begin_src != TRIG_EXT)
492 err++;
493 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
494 err++;
495 if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
496 err++;
497
498 if (err)
499 return 2;
500
501 /* step 3: make sure arguments are trivially compatible */
502
503 if (cmd->start_arg != 0) {
504 cmd->start_arg = 0;
505 err++;
506 }
507 #define MAX_SPEED 10000 /* in nanoseconds */
508 #define MIN_SPEED 1000000000 /* in nanoseconds */
509
510 if (cmd->scan_begin_src == TRIG_TIMER) {
511 if (cmd->scan_begin_arg < MAX_SPEED) {
512 cmd->scan_begin_arg = MAX_SPEED;
513 err++;
514 }
515 if (cmd->scan_begin_arg > MIN_SPEED) {
516 cmd->scan_begin_arg = MIN_SPEED;
517 err++;
518 }
519 } else {
520 /* external trigger */
521 /* should be level/edge, hi/lo specification here */
522 /* should specify multiple external triggers */
523 if (cmd->scan_begin_arg > 9) {
524 cmd->scan_begin_arg = 9;
525 err++;
526 }
527 }
528 if (cmd->convert_src == TRIG_TIMER) {
529 if (cmd->convert_arg < MAX_SPEED) {
530 cmd->convert_arg = MAX_SPEED;
531 err++;
532 }
533 if (cmd->convert_arg > MIN_SPEED) {
534 cmd->convert_arg = MIN_SPEED;
535 err++;
536 }
537 } else {
538 /* external trigger */
539 /* see above */
540 if (cmd->convert_arg > 9) {
541 cmd->convert_arg = 9;
542 err++;
543 }
544 }
545
546 if (cmd->scan_end_arg != cmd->chanlist_len) {
547 cmd->scan_end_arg = cmd->chanlist_len;
548 err++;
549 }
550 if (cmd->stop_src == TRIG_COUNT) {
551 if (cmd->stop_arg > 0x00ffffff) {
552 cmd->stop_arg = 0x00ffffff;
553 err++;
554 }
555 } else {
556 /* TRIG_NONE */
557 if (cmd->stop_arg != 0) {
558 cmd->stop_arg = 0;
559 err++;
560 }
561 }
562
563 if (err)
564 return 3;
565
566 /* step 4: fix up any arguments */
567
568 if (cmd->scan_begin_src == TRIG_TIMER) {
569 tmp = cmd->scan_begin_arg;
570 cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
571 cmd->flags & TRIG_ROUND_MASK);
572 if (tmp != cmd->scan_begin_arg)
573 err++;
574 }
575 if (cmd->convert_src == TRIG_TIMER) {
576 tmp = cmd->convert_arg;
577 cb_pcidda_ns_to_timer(&cmd->convert_arg,
578 cmd->flags & TRIG_ROUND_MASK);
579 if (tmp != cmd->convert_arg)
580 err++;
581 if (cmd->scan_begin_src == TRIG_TIMER &&
582 cmd->scan_begin_arg <
583 cmd->convert_arg * cmd->scan_end_arg) {
584 cmd->scan_begin_arg =
585 cmd->convert_arg * cmd->scan_end_arg;
586 err++;
587 }
588 }
589
590 if (err)
591 return 4;
592
593 return 0;
594 }
595 #endif
596
597 /* This function doesn't require a particular form, this is just
598 * what happens to be used in some of the drivers. It should
599 * convert ns nanoseconds to a counter value suitable for programming
600 * the device. Also, it should adjust ns so that it cooresponds to
601 * the actual time that the device will use. */
602 #if 0
603 static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
604 {
605 /* trivial timer */
606 return *ns;
607 }
608 #endif
609
cb_pcidda_ao_winsn(struct comedi_device * dev,struct comedi_subdevice * s,struct comedi_insn * insn,unsigned int * data)610 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
611 struct comedi_subdevice *s,
612 struct comedi_insn *insn, unsigned int *data)
613 {
614 unsigned int command;
615 unsigned int channel, range;
616
617 channel = CR_CHAN(insn->chanspec);
618 range = CR_RANGE(insn->chanspec);
619
620 /* adjust calibration dacs if range has changed */
621 if (range != devpriv->ao_range[channel])
622 cb_pcidda_calibrate(dev, channel, range);
623
624 /* output channel configuration */
625 command = NOSU | ENABLEDAC;
626
627 /* output channel range */
628 switch (range) {
629 case 0:
630 command |= BIP | RANGE10V;
631 break;
632 case 1:
633 command |= BIP | RANGE5V;
634 break;
635 case 2:
636 command |= BIP | RANGE2V5;
637 break;
638 case 3:
639 command |= UNIP | RANGE10V;
640 break;
641 case 4:
642 command |= UNIP | RANGE5V;
643 break;
644 case 5:
645 command |= UNIP | RANGE2V5;
646 break;
647 }
648
649 /* output channel specification */
650 command |= channel << 2;
651 outw(command, devpriv->dac + DACONTROL);
652
653 /* write data */
654 outw(data[0], devpriv->dac + DADATA + channel * 2);
655
656 /* return the number of samples read/written */
657 return 1;
658 }
659
660 /* lowlevel read from eeprom */
cb_pcidda_serial_in(struct comedi_device * dev)661 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
662 {
663 unsigned int value = 0;
664 int i;
665 const int value_width = 16; /* number of bits wide values are */
666
667 for (i = 1; i <= value_width; i++) {
668 /* read bits most significant bit first */
669 if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
670 value |= 1 << (value_width - i);
671 }
672
673 return value;
674 }
675
676 /* lowlevel write to eeprom/dac */
cb_pcidda_serial_out(struct comedi_device * dev,unsigned int value,unsigned int num_bits)677 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
678 unsigned int num_bits)
679 {
680 int i;
681
682 for (i = 1; i <= num_bits; i++) {
683 /* send bits most significant bit first */
684 if (value & (1 << (num_bits - i)))
685 devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
686 else
687 devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
688 outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
689 }
690 }
691
692 /* reads a 16 bit value from board's eeprom */
cb_pcidda_read_eeprom(struct comedi_device * dev,unsigned int address)693 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
694 unsigned int address)
695 {
696 unsigned int i;
697 unsigned int cal2_bits;
698 unsigned int value;
699 const int max_num_caldacs = 4; /* one caldac for every two dac channels */
700 const int read_instruction = 0x6; /* bits to send to tell eeprom we want to read */
701 const int instruction_length = 3;
702 const int address_length = 8;
703
704 /* send serial output stream to eeprom */
705 cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
706 /* deactivate caldacs (one caldac for every two channels) */
707 for (i = 0; i < max_num_caldacs; i++)
708 cal2_bits |= DESELECT_CALDAC_BIT(i);
709 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
710
711 /* tell eeprom we want to read */
712 cb_pcidda_serial_out(dev, read_instruction, instruction_length);
713 /* send address we want to read from */
714 cb_pcidda_serial_out(dev, address, address_length);
715
716 value = cb_pcidda_serial_in(dev);
717
718 /* deactivate eeprom */
719 cal2_bits &= ~SELECT_EEPROM_BIT;
720 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
721
722 return value;
723 }
724
725 /* writes to 8 bit calibration dacs */
cb_pcidda_write_caldac(struct comedi_device * dev,unsigned int caldac,unsigned int channel,unsigned int value)726 static void cb_pcidda_write_caldac(struct comedi_device *dev,
727 unsigned int caldac, unsigned int channel,
728 unsigned int value)
729 {
730 unsigned int cal2_bits;
731 unsigned int i;
732 const int num_channel_bits = 3; /* caldacs use 3 bit channel specification */
733 const int num_caldac_bits = 8; /* 8 bit calibration dacs */
734 const int max_num_caldacs = 4; /* one caldac for every two dac channels */
735
736 /* write 3 bit channel */
737 cb_pcidda_serial_out(dev, channel, num_channel_bits);
738 /* write 8 bit caldac value */
739 cb_pcidda_serial_out(dev, value, num_caldac_bits);
740
741 /*
742 * latch stream into appropriate caldac deselect reference dac
743 */
744 cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
745 /* deactivate caldacs (one caldac for every two channels) */
746 for (i = 0; i < max_num_caldacs; i++)
747 cal2_bits |= DESELECT_CALDAC_BIT(i);
748 /* activate the caldac we want */
749 cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
750 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
751 /* deactivate caldac */
752 cal2_bits |= DESELECT_CALDAC_BIT(caldac);
753 outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
754 }
755
756 /* returns caldac that calibrates given analog out channel */
caldac_number(unsigned int channel)757 static unsigned int caldac_number(unsigned int channel)
758 {
759 return channel / 2;
760 }
761
762 /* returns caldac channel that provides fine gain for given ao channel */
fine_gain_channel(unsigned int ao_channel)763 static unsigned int fine_gain_channel(unsigned int ao_channel)
764 {
765 return 4 * (ao_channel % 2);
766 }
767
768 /* returns caldac channel that provides coarse gain for given ao channel */
coarse_gain_channel(unsigned int ao_channel)769 static unsigned int coarse_gain_channel(unsigned int ao_channel)
770 {
771 return 1 + 4 * (ao_channel % 2);
772 }
773
774 /* returns caldac channel that provides coarse offset for given ao channel */
coarse_offset_channel(unsigned int ao_channel)775 static unsigned int coarse_offset_channel(unsigned int ao_channel)
776 {
777 return 2 + 4 * (ao_channel % 2);
778 }
779
780 /* returns caldac channel that provides fine offset for given ao channel */
fine_offset_channel(unsigned int ao_channel)781 static unsigned int fine_offset_channel(unsigned int ao_channel)
782 {
783 return 3 + 4 * (ao_channel % 2);
784 }
785
786 /* returns eeprom address that provides offset for given ao channel and range */
offset_eeprom_address(unsigned int ao_channel,unsigned int range)787 static unsigned int offset_eeprom_address(unsigned int ao_channel,
788 unsigned int range)
789 {
790 return 0x7 + 2 * range + 12 * ao_channel;
791 }
792
793 /* returns eeprom address that provides gain calibration for given ao channel and range */
gain_eeprom_address(unsigned int ao_channel,unsigned int range)794 static unsigned int gain_eeprom_address(unsigned int ao_channel,
795 unsigned int range)
796 {
797 return 0x8 + 2 * range + 12 * ao_channel;
798 }
799
800 /* returns upper byte of eeprom entry, which gives the coarse adjustment values */
eeprom_coarse_byte(unsigned int word)801 static unsigned int eeprom_coarse_byte(unsigned int word)
802 {
803 return (word >> 8) & 0xff;
804 }
805
806 /* returns lower byte of eeprom entry, which gives the fine adjustment values */
eeprom_fine_byte(unsigned int word)807 static unsigned int eeprom_fine_byte(unsigned int word)
808 {
809 return word & 0xff;
810 }
811
812 /* set caldacs to eeprom values for given channel and range */
cb_pcidda_calibrate(struct comedi_device * dev,unsigned int channel,unsigned int range)813 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
814 unsigned int range)
815 {
816 unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
817
818 /* remember range so we can tell when we need to readjust calibration */
819 devpriv->ao_range[channel] = range;
820
821 /* get values from eeprom data */
822 coarse_offset =
823 eeprom_coarse_byte(devpriv->eeprom_data
824 [offset_eeprom_address(channel, range)]);
825 fine_offset =
826 eeprom_fine_byte(devpriv->eeprom_data
827 [offset_eeprom_address(channel, range)]);
828 coarse_gain =
829 eeprom_coarse_byte(devpriv->eeprom_data
830 [gain_eeprom_address(channel, range)]);
831 fine_gain =
832 eeprom_fine_byte(devpriv->eeprom_data
833 [gain_eeprom_address(channel, range)]);
834
835 /* set caldacs */
836 cb_pcidda_write_caldac(dev, caldac_number(channel),
837 coarse_offset_channel(channel), coarse_offset);
838 cb_pcidda_write_caldac(dev, caldac_number(channel),
839 fine_offset_channel(channel), fine_offset);
840 cb_pcidda_write_caldac(dev, caldac_number(channel),
841 coarse_gain_channel(channel), coarse_gain);
842 cb_pcidda_write_caldac(dev, caldac_number(channel),
843 fine_gain_channel(channel), fine_gain);
844 }
845
846 /*
847 * A convenient macro that defines init_module() and cleanup_module(),
848 * as necessary.
849 */
driver_cb_pcidda_pci_probe(struct pci_dev * dev,const struct pci_device_id * ent)850 static int __devinit driver_cb_pcidda_pci_probe(struct pci_dev *dev,
851 const struct pci_device_id *ent)
852 {
853 return comedi_pci_auto_config(dev, driver_cb_pcidda.driver_name);
854 }
855
driver_cb_pcidda_pci_remove(struct pci_dev * dev)856 static void __devexit driver_cb_pcidda_pci_remove(struct pci_dev *dev)
857 {
858 comedi_pci_auto_unconfig(dev);
859 }
860
861 static struct pci_driver driver_cb_pcidda_pci_driver = {
862 .id_table = cb_pcidda_pci_table,
863 .probe = &driver_cb_pcidda_pci_probe,
864 .remove = __devexit_p(&driver_cb_pcidda_pci_remove)
865 };
866
driver_cb_pcidda_init_module(void)867 static int __init driver_cb_pcidda_init_module(void)
868 {
869 int retval;
870
871 retval = comedi_driver_register(&driver_cb_pcidda);
872 if (retval < 0)
873 return retval;
874
875 driver_cb_pcidda_pci_driver.name = (char *)driver_cb_pcidda.driver_name;
876 return pci_register_driver(&driver_cb_pcidda_pci_driver);
877 }
878
driver_cb_pcidda_cleanup_module(void)879 static void __exit driver_cb_pcidda_cleanup_module(void)
880 {
881 pci_unregister_driver(&driver_cb_pcidda_pci_driver);
882 comedi_driver_unregister(&driver_cb_pcidda);
883 }
884
885 module_init(driver_cb_pcidda_init_module);
886 module_exit(driver_cb_pcidda_cleanup_module);
887
888 MODULE_AUTHOR("Comedi http://www.comedi.org");
889 MODULE_DESCRIPTION("Comedi low-level driver");
890 MODULE_LICENSE("GPL");
891