]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/cb_pcidda.c
06e546f3fdb478310f13064a38602d9d7d28f266
[~andy/linux] / 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_fc.h"
52 #include "8255.h"
53
54 /* PCI vendor number of ComputerBoards */
55 #define PCI_VENDOR_ID_CB        0x1307
56 #define EEPROM_SIZE     128     /*  number of entries in eeprom */
57 /* maximum number of ao channels for supported boards */
58 #define MAX_AO_CHANNELS 8
59
60 /* Digital I/O registers */
61 #define PORT1A 0                /*  PORT 1A DATA */
62
63 #define PORT1B 1                /*  PORT 1B DATA */
64
65 #define PORT1C 2                /*  PORT 1C DATA */
66
67 #define CONTROL1 3              /*  CONTROL REGISTER 1 */
68
69 #define PORT2A 4                /*  PORT 2A DATA */
70
71 #define PORT2B 5                /*  PORT 2B DATA */
72
73 #define PORT2C 6                /*  PORT 2C DATA */
74
75 #define CONTROL2 7              /*  CONTROL REGISTER 2 */
76
77 /* DAC registers */
78 #define DACONTROL       0       /*  D/A CONTROL REGISTER */
79 #define SU      0000001         /*  Simultaneous update enabled */
80 #define NOSU    0000000         /*  Simultaneous update disabled */
81 #define ENABLEDAC       0000002 /*  Enable specified DAC */
82 #define DISABLEDAC      0000000 /*  Disable specified DAC */
83 #define RANGE2V5        0000000 /*  2.5V */
84 #define RANGE5V 0000200         /*  5V */
85 #define RANGE10V        0000300 /*  10V */
86 #define UNIP    0000400         /*  Unipolar outputs */
87 #define BIP     0000000         /*  Bipolar outputs */
88
89 #define DACALIBRATION1  4       /*  D/A CALIBRATION REGISTER 1 */
90 /* write bits */
91 /* serial data input for eeprom, caldacs, reference dac */
92 #define SERIAL_IN_BIT   0x1
93 #define CAL_CHANNEL_MASK        (0x7 << 1)
94 #define CAL_CHANNEL_BITS(channel)       (((channel) << 1) & CAL_CHANNEL_MASK)
95 /* read bits */
96 #define CAL_COUNTER_MASK        0x1f
97 /* calibration counter overflow status bit */
98 #define CAL_COUNTER_OVERFLOW_BIT        0x20
99 /* analog output is less than reference dac voltage */
100 #define AO_BELOW_REF_BIT        0x40
101 #define SERIAL_OUT_BIT  0x80    /*  serial data out, for reading from eeprom */
102
103 #define DACALIBRATION2  6       /*  D/A CALIBRATION REGISTER 2 */
104 #define SELECT_EEPROM_BIT       0x1     /*  send serial data in to eeprom */
105 /* don't send serial data to MAX542 reference dac */
106 #define DESELECT_REF_DAC_BIT    0x2
107 /* don't send serial data to caldac n */
108 #define DESELECT_CALDAC_BIT(n)  (0x4 << (n))
109 /* manual says to set this bit with no explanation */
110 #define DUMMY_BIT       0x40
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 /*
199  * this structure is for data unique to this hardware driver.  If
200  * several hardware drivers keep similar information in this structure,
201  * feel free to suggest moving the variable to the struct comedi_device
202  * struct.
203  */
204 struct cb_pcidda_private {
205         int data;
206
207         unsigned long digitalio;
208         unsigned long dac;
209
210         /* unsigned long control_status; */
211         /* unsigned long adc_fifo; */
212
213         /* bits last written to da calibration register 1 */
214         unsigned int dac_cal1_bits;
215         /* current range settings for output channels */
216         unsigned int ao_range[MAX_AO_CHANNELS];
217         u16 eeprom_data[EEPROM_SIZE];   /*  software copy of board's eeprom */
218 };
219
220 /*
221  * I will program this later... ;-)
222  */
223 #if 0
224 static int cb_pcidda_ai_cmd(struct comedi_device *dev,
225                             struct comedi_subdevice *s)
226 {
227         printk("cb_pcidda_ai_cmd\n");
228         printk("subdev: %d\n", cmd->subdev);
229         printk("flags: %d\n", cmd->flags);
230         printk("start_src: %d\n", cmd->start_src);
231         printk("start_arg: %d\n", cmd->start_arg);
232         printk("scan_begin_src: %d\n", cmd->scan_begin_src);
233         printk("convert_src: %d\n", cmd->convert_src);
234         printk("convert_arg: %d\n", cmd->convert_arg);
235         printk("scan_end_src: %d\n", cmd->scan_end_src);
236         printk("scan_end_arg: %d\n", cmd->scan_end_arg);
237         printk("stop_src: %d\n", cmd->stop_src);
238         printk("stop_arg: %d\n", cmd->stop_arg);
239         printk("chanlist_len: %d\n", cmd->chanlist_len);
240 }
241 #endif
242
243 #if 0
244 static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,
245                                 struct comedi_subdevice *s,
246                                 struct comedi_cmd *cmd)
247 {
248         int err = 0;
249         int tmp;
250
251         /* Step 1 : check if triggers are trivially valid */
252
253         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
254         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
255                                         TRIG_TIMER | TRIG_EXT);
256         err |= cfc_check_trigger_src(&cmd->convert_src,
257                                         TRIG_TIMER | TRIG_EXT);
258         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
259         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
260
261         if (err)
262                 return 1;
263
264         /* Step 2a : make sure trigger sources are unique */
265
266         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
267         err |= cfc_check_trigger_is_unique(cmd->convert_src);
268         err |= cfc_check_trigger_is_unique(cmd->stop_src);
269
270         /* Step 2b : and mutually compatible */
271
272         if (err)
273                 return 2;
274
275         /* step 3: make sure arguments are trivially compatible */
276
277         if (cmd->start_arg != 0) {
278                 cmd->start_arg = 0;
279                 err++;
280         }
281 #define MAX_SPEED       10000   /* in nanoseconds */
282 #define MIN_SPEED       1000000000      /* in nanoseconds */
283
284         if (cmd->scan_begin_src == TRIG_TIMER) {
285                 if (cmd->scan_begin_arg < MAX_SPEED) {
286                         cmd->scan_begin_arg = MAX_SPEED;
287                         err++;
288                 }
289                 if (cmd->scan_begin_arg > MIN_SPEED) {
290                         cmd->scan_begin_arg = MIN_SPEED;
291                         err++;
292                 }
293         } else {
294                 /* external trigger */
295                 /* should be level/edge, hi/lo specification here */
296                 /* should specify multiple external triggers */
297                 if (cmd->scan_begin_arg > 9) {
298                         cmd->scan_begin_arg = 9;
299                         err++;
300                 }
301         }
302         if (cmd->convert_src == TRIG_TIMER) {
303                 if (cmd->convert_arg < MAX_SPEED) {
304                         cmd->convert_arg = MAX_SPEED;
305                         err++;
306                 }
307                 if (cmd->convert_arg > MIN_SPEED) {
308                         cmd->convert_arg = MIN_SPEED;
309                         err++;
310                 }
311         } else {
312                 /* external trigger */
313                 /* see above */
314                 if (cmd->convert_arg > 9) {
315                         cmd->convert_arg = 9;
316                         err++;
317                 }
318         }
319
320         if (cmd->scan_end_arg != cmd->chanlist_len) {
321                 cmd->scan_end_arg = cmd->chanlist_len;
322                 err++;
323         }
324         if (cmd->stop_src == TRIG_COUNT) {
325                 if (cmd->stop_arg > 0x00ffffff) {
326                         cmd->stop_arg = 0x00ffffff;
327                         err++;
328                 }
329         } else {
330                 /* TRIG_NONE */
331                 if (cmd->stop_arg != 0) {
332                         cmd->stop_arg = 0;
333                         err++;
334                 }
335         }
336
337         if (err)
338                 return 3;
339
340         /* step 4: fix up any arguments */
341
342         if (cmd->scan_begin_src == TRIG_TIMER) {
343                 tmp = cmd->scan_begin_arg;
344                 cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
345                                       cmd->flags & TRIG_ROUND_MASK);
346                 if (tmp != cmd->scan_begin_arg)
347                         err++;
348         }
349         if (cmd->convert_src == TRIG_TIMER) {
350                 tmp = cmd->convert_arg;
351                 cb_pcidda_ns_to_timer(&cmd->convert_arg,
352                                       cmd->flags & TRIG_ROUND_MASK);
353                 if (tmp != cmd->convert_arg)
354                         err++;
355                 if (cmd->scan_begin_src == TRIG_TIMER &&
356                     cmd->scan_begin_arg <
357                     cmd->convert_arg * cmd->scan_end_arg) {
358                         cmd->scan_begin_arg =
359                             cmd->convert_arg * cmd->scan_end_arg;
360                         err++;
361                 }
362         }
363
364         if (err)
365                 return 4;
366
367         return 0;
368 }
369 #endif
370
371 /* This function doesn't require a particular form, this is just
372  * what happens to be used in some of the drivers.  It should
373  * convert ns nanoseconds to a counter value suitable for programming
374  * the device.  Also, it should adjust ns so that it cooresponds to
375  * the actual time that the device will use. */
376 #if 0
377 static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
378 {
379         /* trivial timer */
380         return *ns;
381 }
382 #endif
383
384 /* lowlevel read from eeprom */
385 static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
386 {
387         struct cb_pcidda_private *devpriv = dev->private;
388         unsigned int value = 0;
389         int i;
390         const int value_width = 16;     /*  number of bits wide values are */
391
392         for (i = 1; i <= value_width; i++) {
393                 /*  read bits most significant bit first */
394                 if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT)
395                         value |= 1 << (value_width - i);
396         }
397
398         return value;
399 }
400
401 /* lowlevel write to eeprom/dac */
402 static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
403                                  unsigned int num_bits)
404 {
405         struct cb_pcidda_private *devpriv = dev->private;
406         int i;
407
408         for (i = 1; i <= num_bits; i++) {
409                 /*  send bits most significant bit first */
410                 if (value & (1 << (num_bits - i)))
411                         devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
412                 else
413                         devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
414                 outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
415         }
416 }
417
418 /* reads a 16 bit value from board's eeprom */
419 static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
420                                           unsigned int address)
421 {
422         struct cb_pcidda_private *devpriv = dev->private;
423         unsigned int i;
424         unsigned int cal2_bits;
425         unsigned int value;
426         /* one caldac for every two dac channels */
427         const int max_num_caldacs = 4;
428         /* bits to send to tell eeprom we want to read */
429         const int read_instruction = 0x6;
430         const int instruction_length = 3;
431         const int address_length = 8;
432
433         /*  send serial output stream to eeprom */
434         cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
435         /*  deactivate caldacs (one caldac for every two channels) */
436         for (i = 0; i < max_num_caldacs; i++)
437                 cal2_bits |= DESELECT_CALDAC_BIT(i);
438         outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
439
440         /*  tell eeprom we want to read */
441         cb_pcidda_serial_out(dev, read_instruction, instruction_length);
442         /*  send address we want to read from */
443         cb_pcidda_serial_out(dev, address, address_length);
444
445         value = cb_pcidda_serial_in(dev);
446
447         /*  deactivate eeprom */
448         cal2_bits &= ~SELECT_EEPROM_BIT;
449         outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
450
451         return value;
452 }
453
454 /* writes to 8 bit calibration dacs */
455 static void cb_pcidda_write_caldac(struct comedi_device *dev,
456                                    unsigned int caldac, unsigned int channel,
457                                    unsigned int value)
458 {
459         struct cb_pcidda_private *devpriv = dev->private;
460         unsigned int cal2_bits;
461         unsigned int i;
462         /* caldacs use 3 bit channel specification */
463         const int num_channel_bits = 3;
464         const int num_caldac_bits = 8;  /*  8 bit calibration dacs */
465         /* one caldac for every two dac channels */
466         const int max_num_caldacs = 4;
467
468         /* write 3 bit channel */
469         cb_pcidda_serial_out(dev, channel, num_channel_bits);
470         /*  write 8 bit caldac value */
471         cb_pcidda_serial_out(dev, value, num_caldac_bits);
472
473 /*
474 * latch stream into appropriate caldac deselect reference dac
475 */
476         cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
477         /*  deactivate caldacs (one caldac for every two channels) */
478         for (i = 0; i < max_num_caldacs; i++)
479                 cal2_bits |= DESELECT_CALDAC_BIT(i);
480         /*  activate the caldac we want */
481         cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
482         outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
483         /*  deactivate caldac */
484         cal2_bits |= DESELECT_CALDAC_BIT(caldac);
485         outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
486 }
487
488 /* returns caldac that calibrates given analog out channel */
489 static unsigned int caldac_number(unsigned int channel)
490 {
491         return channel / 2;
492 }
493
494 /* returns caldac channel that provides fine gain for given ao channel */
495 static unsigned int fine_gain_channel(unsigned int ao_channel)
496 {
497         return 4 * (ao_channel % 2);
498 }
499
500 /* returns caldac channel that provides coarse gain for given ao channel */
501 static unsigned int coarse_gain_channel(unsigned int ao_channel)
502 {
503         return 1 + 4 * (ao_channel % 2);
504 }
505
506 /* returns caldac channel that provides coarse offset for given ao channel */
507 static unsigned int coarse_offset_channel(unsigned int ao_channel)
508 {
509         return 2 + 4 * (ao_channel % 2);
510 }
511
512 /* returns caldac channel that provides fine offset for given ao channel */
513 static unsigned int fine_offset_channel(unsigned int ao_channel)
514 {
515         return 3 + 4 * (ao_channel % 2);
516 }
517
518 /* returns eeprom address that provides offset for given ao channel and range */
519 static unsigned int offset_eeprom_address(unsigned int ao_channel,
520                                           unsigned int range)
521 {
522         return 0x7 + 2 * range + 12 * ao_channel;
523 }
524
525 /*
526  * returns eeprom address that provides gain calibration for given ao
527  * channel and range
528  */
529 static unsigned int gain_eeprom_address(unsigned int ao_channel,
530                                         unsigned int range)
531 {
532         return 0x8 + 2 * range + 12 * ao_channel;
533 }
534
535 /*
536  * returns upper byte of eeprom entry, which gives the coarse adjustment
537  * values
538  */
539 static unsigned int eeprom_coarse_byte(unsigned int word)
540 {
541         return (word >> 8) & 0xff;
542 }
543
544 /* returns lower byte of eeprom entry, which gives the fine adjustment values */
545 static unsigned int eeprom_fine_byte(unsigned int word)
546 {
547         return word & 0xff;
548 }
549
550 /* set caldacs to eeprom values for given channel and range */
551 static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
552                                 unsigned int range)
553 {
554         struct cb_pcidda_private *devpriv = dev->private;
555         unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
556
557         /* remember range so we can tell when we need to readjust calibration */
558         devpriv->ao_range[channel] = range;
559
560         /*  get values from eeprom data */
561         coarse_offset =
562             eeprom_coarse_byte(devpriv->eeprom_data
563                                [offset_eeprom_address(channel, range)]);
564         fine_offset =
565             eeprom_fine_byte(devpriv->eeprom_data
566                              [offset_eeprom_address(channel, range)]);
567         coarse_gain =
568             eeprom_coarse_byte(devpriv->eeprom_data
569                                [gain_eeprom_address(channel, range)]);
570         fine_gain =
571             eeprom_fine_byte(devpriv->eeprom_data
572                              [gain_eeprom_address(channel, range)]);
573
574         /*  set caldacs */
575         cb_pcidda_write_caldac(dev, caldac_number(channel),
576                                coarse_offset_channel(channel), coarse_offset);
577         cb_pcidda_write_caldac(dev, caldac_number(channel),
578                                fine_offset_channel(channel), fine_offset);
579         cb_pcidda_write_caldac(dev, caldac_number(channel),
580                                coarse_gain_channel(channel), coarse_gain);
581         cb_pcidda_write_caldac(dev, caldac_number(channel),
582                                fine_gain_channel(channel), fine_gain);
583 }
584
585 static int cb_pcidda_ao_winsn(struct comedi_device *dev,
586                               struct comedi_subdevice *s,
587                               struct comedi_insn *insn, unsigned int *data)
588 {
589         struct cb_pcidda_private *devpriv = dev->private;
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 static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
637                                             struct pci_dev *pcidev)
638 {
639         const struct cb_pcidda_board *thisboard;
640         int i;
641
642         for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) {
643                 thisboard = &cb_pcidda_boards[i];
644                 if (thisboard->device_id != pcidev->device)
645                         return thisboard;
646         }
647         return NULL;
648 }
649
650 static int cb_pcidda_attach_pci(struct comedi_device *dev,
651                                 struct pci_dev *pcidev)
652 {
653         const struct cb_pcidda_board *thisboard;
654         struct cb_pcidda_private *devpriv;
655         struct comedi_subdevice *s;
656         int index;
657         int ret;
658
659         thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
660         if (!thisboard)
661                 return -ENODEV;
662         dev->board_ptr = thisboard;
663         dev->board_name = thisboard->name;
664
665         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
666         if (!devpriv)
667                 return -ENOMEM;
668         dev->private = devpriv;
669
670         ret = comedi_pci_enable(pcidev, dev->board_name);
671         if (ret)
672                 return ret;
673
674         devpriv->digitalio = pci_resource_start(pcidev, 2);
675         devpriv->dac = pci_resource_start(pcidev, 3);
676         dev->iobase = devpriv->dac;
677
678         if (thisboard->status == 2)
679                 printk
680                     ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
681                      "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
682                      "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
683
684         ret = comedi_alloc_subdevices(dev, 3);
685         if (ret)
686                 return ret;
687
688         s = &dev->subdevices[0];
689         /* analog output subdevice */
690         s->type = COMEDI_SUBD_AO;
691         s->subdev_flags = SDF_WRITABLE;
692         s->n_chan = thisboard->ao_chans;
693         s->maxdata = (1 << thisboard->ao_bits) - 1;
694         s->range_table = thisboard->ranges;
695         s->insn_write = cb_pcidda_ao_winsn;
696
697         /* s->subdev_flags |= SDF_CMD_READ; */
698         /* s->do_cmd = cb_pcidda_ai_cmd; */
699         /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
700
701         /*  two 8255 digital io subdevices */
702         s = &dev->subdevices[1];
703         subdev_8255_init(dev, s, NULL, devpriv->digitalio);
704         s = &dev->subdevices[2];
705         subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
706
707         dev_dbg(dev->class_dev, "eeprom:\n");
708         for (index = 0; index < EEPROM_SIZE; index++) {
709                 devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
710                 dev_dbg(dev->class_dev, "%i:0x%x\n", index,
711                         devpriv->eeprom_data[index]);
712         }
713
714         /*  set calibrations dacs */
715         for (index = 0; index < thisboard->ao_chans; index++)
716                 cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
717
718         dev_info(dev->class_dev, "%s attached\n", dev->board_name);
719
720         return 0;
721 }
722
723 static void cb_pcidda_detach(struct comedi_device *dev)
724 {
725         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
726
727         if (dev->subdevices) {
728                 subdev_8255_cleanup(dev, &dev->subdevices[1]);
729                 subdev_8255_cleanup(dev, &dev->subdevices[2]);
730         }
731         if (pcidev) {
732                 if (dev->iobase)
733                         comedi_pci_disable(pcidev);
734         }
735 }
736
737 static struct comedi_driver cb_pcidda_driver = {
738         .driver_name    = "cb_pcidda",
739         .module         = THIS_MODULE,
740         .attach_pci     = cb_pcidda_attach_pci,
741         .detach         = cb_pcidda_detach,
742 };
743
744 static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev,
745                                          const struct pci_device_id *ent)
746 {
747         return comedi_pci_auto_config(dev, &cb_pcidda_driver);
748 }
749
750 static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev)
751 {
752         comedi_pci_auto_unconfig(dev);
753 }
754
755 static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
756         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
757         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
758         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
759         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
760         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
761         { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
762         { 0 }
763 };
764 MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
765
766 static struct pci_driver cb_pcidda_pci_driver = {
767         .name           = "cb_pcidda",
768         .id_table       = cb_pcidda_pci_table,
769         .probe          = cb_pcidda_pci_probe,
770         .remove         = __devexit_p(cb_pcidda_pci_remove),
771 };
772 module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
773
774 MODULE_AUTHOR("Comedi http://www.comedi.org");
775 MODULE_DESCRIPTION("Comedi low-level driver");
776 MODULE_LICENSE("GPL");