Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cb_pcidda.c
Go to the documentation of this file.
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 <[email protected]>
7  Copyright (C) 2001 Frank Mori Hess <[email protected]>
8 
9  COMEDI - Linux Control and Measurement Device Interface
10  Copyright (C) 1997-8 David A. Schleef <[email protected]>
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 <[email protected]>, Frank Mori Hess <[email protected]>
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
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  */
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  */
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 */
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  comedi_set_hw_dev(dev, &pcidev->dev);
660 
661  thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
662  if (!pcidev)
663  return -ENODEV;
664  dev->board_ptr = thisboard;
665  dev->board_name = thisboard->name;
666 
667  ret = alloc_private(dev, sizeof(*devpriv));
668  if (ret)
669  return ret;
670  devpriv = dev->private;
671 
672  ret = comedi_pci_enable(pcidev, dev->board_name);
673  if (ret)
674  return ret;
675 
676  devpriv->digitalio = pci_resource_start(pcidev, 2);
677  devpriv->dac = pci_resource_start(pcidev, 3);
678  dev->iobase = devpriv->dac;
679 
680  if (thisboard->status == 2)
681  printk
682  ("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. "
683  "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. "
684  "PLEASE REPORT USAGE TO <[email protected]>.\n");
685 
686  ret = comedi_alloc_subdevices(dev, 3);
687  if (ret)
688  return ret;
689 
690  s = &dev->subdevices[0];
691  /* analog output subdevice */
692  s->type = COMEDI_SUBD_AO;
694  s->n_chan = thisboard->ao_chans;
695  s->maxdata = (1 << thisboard->ao_bits) - 1;
696  s->range_table = thisboard->ranges;
697  s->insn_write = cb_pcidda_ao_winsn;
698 
699  /* s->subdev_flags |= SDF_CMD_READ; */
700  /* s->do_cmd = cb_pcidda_ai_cmd; */
701  /* s->do_cmdtest = cb_pcidda_ai_cmdtest; */
702 
703  /* two 8255 digital io subdevices */
704  s = &dev->subdevices[1];
705  subdev_8255_init(dev, s, NULL, devpriv->digitalio);
706  s = &dev->subdevices[2];
707  subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
708 
709  dev_dbg(dev->class_dev, "eeprom:\n");
710  for (index = 0; index < EEPROM_SIZE; index++) {
711  devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
712  dev_dbg(dev->class_dev, "%i:0x%x\n", index,
713  devpriv->eeprom_data[index]);
714  }
715 
716  /* set calibrations dacs */
717  for (index = 0; index < thisboard->ao_chans; index++)
718  cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
719 
720  dev_info(dev->class_dev, "%s attached\n", dev->board_name);
721 
722  return 0;
723 }
724 
725 static void cb_pcidda_detach(struct comedi_device *dev)
726 {
727  struct pci_dev *pcidev = comedi_to_pci_dev(dev);
728 
729  if (dev->subdevices) {
730  subdev_8255_cleanup(dev, &dev->subdevices[1]);
731  subdev_8255_cleanup(dev, &dev->subdevices[2]);
732  }
733  if (pcidev) {
734  if (dev->iobase)
735  comedi_pci_disable(pcidev);
736  }
737 }
738 
739 static struct comedi_driver cb_pcidda_driver = {
740  .driver_name = "cb_pcidda",
741  .module = THIS_MODULE,
742  .attach_pci = cb_pcidda_attach_pci,
743  .detach = cb_pcidda_detach,
744 };
745 
746 static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev,
747  const struct pci_device_id *ent)
748 {
749  return comedi_pci_auto_config(dev, &cb_pcidda_driver);
750 }
751 
752 static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev)
753 {
755 }
756 
757 static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
758  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0020) },
759  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0021) },
760  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0022) },
761  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0023) },
762  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0024) },
763  { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0025) },
764  { 0 }
765 };
766 MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
767 
768 static struct pci_driver cb_pcidda_pci_driver = {
769  .name = "cb_pcidda",
770  .id_table = cb_pcidda_pci_table,
771  .probe = cb_pcidda_pci_probe,
772  .remove = __devexit_p(cb_pcidda_pci_remove),
773 };
774 module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
775 
776 MODULE_AUTHOR("Comedi http://www.comedi.org");
777 MODULE_DESCRIPTION("Comedi low-level driver");
778 MODULE_LICENSE("GPL");