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