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