staging: comedi: cb_pcidda: remove the private data 'status'
[linux-2.6-block.git] / drivers / staging / comedi / drivers / cb_pcidda.c
CommitLineData
086df5b5 1/*
3bb18724
HS
2 * comedi/drivers/cb_pcidda.c
3 * Driver for the ComputerBoards / MeasurementComputing PCI-DDA series.
4 *
5 * Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
6 * Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
7 *
8 * COMEDI - Linux Control and Measurement Device Interface
9 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
086df5b5 25
086df5b5 26/*
3bb18724
HS
27 * Driver: cb_pcidda
28 * Description: MeasurementComputing PCI-DDA series
29 * Devices: (Measurement Computing) PCI-DDA08/12 [pci-dda08/12]
30 * (Measurement Computing) PCI-DDA04/12 [pci-dda04/12]
31 * (Measurement Computing) PCI-DDA02/12 [pci-dda02/12]
32 * (Measurement Computing) PCI-DDA08/16 [pci-dda08/16]
33 * (Measurement Computing) PCI-DDA04/16 [pci-dda04/16]
34 * (Measurement Computing) PCI-DDA02/16 [pci-dda02/16]
35 * Author: Ivan Martinez <ivanmr@altavista.com>
36 * Frank Mori Hess <fmhess@users.sourceforge.net>
37 * Status: works
38 *
39 * Configuration options: not applicable, uses PCI auto config
40 *
41 * Only simple analog output writing is supported.
42 */
086df5b5
IM
43
44#include "../comedidev.h"
45
27020ffe 46#include "comedi_fc.h"
086df5b5
IM
47#include "8255.h"
48
b9287a30
HS
49/*
50 * ComputerBoards PCI Device ID's supported by this driver
51 */
b9287a30
HS
52#define PCI_DEVICE_ID_DDA02_12 0x0020
53#define PCI_DEVICE_ID_DDA04_12 0x0021
54#define PCI_DEVICE_ID_DDA08_12 0x0022
55#define PCI_DEVICE_ID_DDA02_16 0x0023
56#define PCI_DEVICE_ID_DDA04_16 0x0024
57#define PCI_DEVICE_ID_DDA08_16 0x0025
58
2696fb57 59#define EEPROM_SIZE 128 /* number of entries in eeprom */
3c5510ba
RKM
60/* maximum number of ao channels for supported boards */
61#define MAX_AO_CHANNELS 8
086df5b5 62
086df5b5 63/* Digital I/O registers */
2696fb57 64#define PORT1A 0 /* PORT 1A DATA */
086df5b5 65
2696fb57 66#define PORT1B 1 /* PORT 1B DATA */
086df5b5 67
2696fb57 68#define PORT1C 2 /* PORT 1C DATA */
086df5b5 69
2696fb57 70#define CONTROL1 3 /* CONTROL REGISTER 1 */
086df5b5 71
2696fb57 72#define PORT2A 4 /* PORT 2A DATA */
086df5b5 73
2696fb57 74#define PORT2B 5 /* PORT 2B DATA */
086df5b5 75
2696fb57 76#define PORT2C 6 /* PORT 2C DATA */
086df5b5 77
2696fb57 78#define CONTROL2 7 /* CONTROL REGISTER 2 */
086df5b5
IM
79
80/* DAC registers */
2696fb57
BP
81#define DACONTROL 0 /* D/A CONTROL REGISTER */
82#define SU 0000001 /* Simultaneous update enabled */
83#define NOSU 0000000 /* Simultaneous update disabled */
84#define ENABLEDAC 0000002 /* Enable specified DAC */
85#define DISABLEDAC 0000000 /* Disable specified DAC */
86#define RANGE2V5 0000000 /* 2.5V */
87#define RANGE5V 0000200 /* 5V */
88#define RANGE10V 0000300 /* 10V */
89#define UNIP 0000400 /* Unipolar outputs */
90#define BIP 0000000 /* Bipolar outputs */
91
92#define DACALIBRATION1 4 /* D/A CALIBRATION REGISTER 1 */
93/* write bits */
3c5510ba
RKM
94/* serial data input for eeprom, caldacs, reference dac */
95#define SERIAL_IN_BIT 0x1
086df5b5
IM
96#define CAL_CHANNEL_MASK (0x7 << 1)
97#define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
2696fb57 98/* read bits */
086df5b5 99#define CAL_COUNTER_MASK 0x1f
3c5510ba
RKM
100/* calibration counter overflow status bit */
101#define CAL_COUNTER_OVERFLOW_BIT 0x20
102/* analog output is less than reference dac voltage */
103#define AO_BELOW_REF_BIT 0x40
2696fb57 104#define SERIAL_OUT_BIT 0x80 /* serial data out, for reading from eeprom */
086df5b5 105
2696fb57
BP
106#define DACALIBRATION2 6 /* D/A CALIBRATION REGISTER 2 */
107#define SELECT_EEPROM_BIT 0x1 /* send serial data in to eeprom */
3c5510ba
RKM
108/* don't send serial data to MAX542 reference dac */
109#define DESELECT_REF_DAC_BIT 0x2
110/* don't send serial data to caldac n */
111#define DESELECT_CALDAC_BIT(n) (0x4 << (n))
112/* manual says to set this bit with no explanation */
113#define DUMMY_BIT 0x40
086df5b5 114
2696fb57 115#define DADATA 8 /* FIRST D/A DATA REGISTER (0) */
086df5b5 116
9ced1de6 117static const struct comedi_lrange cb_pcidda_ranges = {
f9c62f3f
HS
118 6, {
119 BIP_RANGE(10),
120 BIP_RANGE(5),
121 BIP_RANGE(2.5),
122 UNI_RANGE(10),
123 UNI_RANGE(5),
124 UNI_RANGE(2.5)
125 }
086df5b5
IM
126};
127
128/*
129 * Board descriptions for two imaginary boards. Describing the
130 * boards in this way is optional, and completely driver-dependent.
131 * Some drivers use arrays such as this, other do not.
132 */
1657e325 133struct cb_pcidda_board {
086df5b5 134 const char *name;
086df5b5
IM
135 unsigned short device_id;
136 int ao_chans;
137 int ao_bits;
1657e325 138};
2696fb57 139
1657e325 140static const struct cb_pcidda_board cb_pcidda_boards[] = {
086df5b5 141 {
0a85b6f0 142 .name = "pci-dda02/12",
b9287a30 143 .device_id = PCI_DEVICE_ID_DDA02_12,
0a85b6f0
MT
144 .ao_chans = 2,
145 .ao_bits = 12,
0a85b6f0 146 },
086df5b5 147 {
0a85b6f0 148 .name = "pci-dda04/12",
b9287a30 149 .device_id = PCI_DEVICE_ID_DDA04_12,
0a85b6f0
MT
150 .ao_chans = 4,
151 .ao_bits = 12,
0a85b6f0 152 },
086df5b5 153 {
0a85b6f0 154 .name = "pci-dda08/12",
b9287a30 155 .device_id = PCI_DEVICE_ID_DDA08_12,
0a85b6f0
MT
156 .ao_chans = 8,
157 .ao_bits = 12,
0a85b6f0 158 },
086df5b5 159 {
0a85b6f0 160 .name = "pci-dda02/16",
b9287a30 161 .device_id = PCI_DEVICE_ID_DDA02_16,
0a85b6f0
MT
162 .ao_chans = 2,
163 .ao_bits = 16,
0a85b6f0 164 },
086df5b5 165 {
0a85b6f0 166 .name = "pci-dda04/16",
b9287a30 167 .device_id = PCI_DEVICE_ID_DDA04_16,
0a85b6f0
MT
168 .ao_chans = 4,
169 .ao_bits = 16,
0a85b6f0 170 },
086df5b5 171 {
0a85b6f0 172 .name = "pci-dda08/16",
b9287a30 173 .device_id = PCI_DEVICE_ID_DDA08_16,
0a85b6f0
MT
174 .ao_chans = 8,
175 .ao_bits = 16,
0a85b6f0 176 },
086df5b5
IM
177};
178
cc7bb61e 179struct cb_pcidda_private {
3c5510ba
RKM
180 /* bits last written to da calibration register 1 */
181 unsigned int dac_cal1_bits;
182 /* current range settings for output channels */
183 unsigned int ao_range[MAX_AO_CHANNELS];
2696fb57 184 u16 eeprom_data[EEPROM_SIZE]; /* software copy of board's eeprom */
cc7bb61e 185};
086df5b5 186
2696fb57 187/* lowlevel read from eeprom */
da91b269 188static unsigned int cb_pcidda_serial_in(struct comedi_device *dev)
086df5b5
IM
189{
190 unsigned int value = 0;
191 int i;
2696fb57 192 const int value_width = 16; /* number of bits wide values are */
086df5b5
IM
193
194 for (i = 1; i <= value_width; i++) {
2696fb57 195 /* read bits most significant bit first */
a74531a5 196 if (inw_p(dev->iobase + DACALIBRATION1) & SERIAL_OUT_BIT)
086df5b5 197 value |= 1 << (value_width - i);
086df5b5
IM
198 }
199
200 return value;
201}
202
2696fb57 203/* lowlevel write to eeprom/dac */
da91b269 204static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value,
0a85b6f0 205 unsigned int num_bits)
086df5b5 206{
c6ad306b 207 struct cb_pcidda_private *devpriv = dev->private;
086df5b5
IM
208 int i;
209
210 for (i = 1; i <= num_bits; i++) {
2696fb57 211 /* send bits most significant bit first */
086df5b5
IM
212 if (value & (1 << (num_bits - i)))
213 devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
214 else
215 devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
a74531a5 216 outw_p(devpriv->dac_cal1_bits, dev->iobase + DACALIBRATION1);
086df5b5
IM
217 }
218}
219
2696fb57 220/* reads a 16 bit value from board's eeprom */
da91b269 221static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev,
0a85b6f0 222 unsigned int address)
086df5b5
IM
223{
224 unsigned int i;
225 unsigned int cal2_bits;
226 unsigned int value;
3c5510ba
RKM
227 /* one caldac for every two dac channels */
228 const int max_num_caldacs = 4;
229 /* bits to send to tell eeprom we want to read */
230 const int read_instruction = 0x6;
086df5b5
IM
231 const int instruction_length = 3;
232 const int address_length = 8;
233
2696fb57 234 /* send serial output stream to eeprom */
086df5b5 235 cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
2696fb57 236 /* deactivate caldacs (one caldac for every two channels) */
20db7d7d 237 for (i = 0; i < max_num_caldacs; i++)
086df5b5 238 cal2_bits |= DESELECT_CALDAC_BIT(i);
a74531a5 239 outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
086df5b5 240
2696fb57 241 /* tell eeprom we want to read */
086df5b5 242 cb_pcidda_serial_out(dev, read_instruction, instruction_length);
2696fb57 243 /* send address we want to read from */
086df5b5
IM
244 cb_pcidda_serial_out(dev, address, address_length);
245
246 value = cb_pcidda_serial_in(dev);
247
2696fb57 248 /* deactivate eeprom */
086df5b5 249 cal2_bits &= ~SELECT_EEPROM_BIT;
a74531a5 250 outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
086df5b5
IM
251
252 return value;
253}
254
2696fb57 255/* writes to 8 bit calibration dacs */
0a85b6f0
MT
256static void cb_pcidda_write_caldac(struct comedi_device *dev,
257 unsigned int caldac, unsigned int channel,
258 unsigned int value)
086df5b5
IM
259{
260 unsigned int cal2_bits;
261 unsigned int i;
3c5510ba
RKM
262 /* caldacs use 3 bit channel specification */
263 const int num_channel_bits = 3;
2696fb57 264 const int num_caldac_bits = 8; /* 8 bit calibration dacs */
3c5510ba
RKM
265 /* one caldac for every two dac channels */
266 const int max_num_caldacs = 4;
086df5b5
IM
267
268 /* write 3 bit channel */
269 cb_pcidda_serial_out(dev, channel, num_channel_bits);
2696fb57 270 /* write 8 bit caldac value */
086df5b5
IM
271 cb_pcidda_serial_out(dev, value, num_caldac_bits);
272
2696fb57
BP
273/*
274* latch stream into appropriate caldac deselect reference dac
275*/
086df5b5 276 cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
2696fb57 277 /* deactivate caldacs (one caldac for every two channels) */
20db7d7d 278 for (i = 0; i < max_num_caldacs; i++)
086df5b5 279 cal2_bits |= DESELECT_CALDAC_BIT(i);
2696fb57 280 /* activate the caldac we want */
086df5b5 281 cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
a74531a5 282 outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
2696fb57 283 /* deactivate caldac */
086df5b5 284 cal2_bits |= DESELECT_CALDAC_BIT(caldac);
a74531a5 285 outw_p(cal2_bits, dev->iobase + DACALIBRATION2);
086df5b5
IM
286}
287
2696fb57 288/* returns caldac that calibrates given analog out channel */
086df5b5
IM
289static unsigned int caldac_number(unsigned int channel)
290{
291 return channel / 2;
292}
293
2696fb57 294/* returns caldac channel that provides fine gain for given ao channel */
086df5b5
IM
295static unsigned int fine_gain_channel(unsigned int ao_channel)
296{
297 return 4 * (ao_channel % 2);
298}
299
2696fb57 300/* returns caldac channel that provides coarse gain for given ao channel */
086df5b5
IM
301static unsigned int coarse_gain_channel(unsigned int ao_channel)
302{
303 return 1 + 4 * (ao_channel % 2);
304}
305
2696fb57 306/* returns caldac channel that provides coarse offset for given ao channel */
086df5b5
IM
307static unsigned int coarse_offset_channel(unsigned int ao_channel)
308{
309 return 2 + 4 * (ao_channel % 2);
310}
311
2696fb57 312/* returns caldac channel that provides fine offset for given ao channel */
086df5b5
IM
313static unsigned int fine_offset_channel(unsigned int ao_channel)
314{
315 return 3 + 4 * (ao_channel % 2);
316}
317
2696fb57 318/* returns eeprom address that provides offset for given ao channel and range */
086df5b5 319static unsigned int offset_eeprom_address(unsigned int ao_channel,
0a85b6f0 320 unsigned int range)
086df5b5
IM
321{
322 return 0x7 + 2 * range + 12 * ao_channel;
323}
324
3c5510ba
RKM
325/*
326 * returns eeprom address that provides gain calibration for given ao
327 * channel and range
328 */
086df5b5 329static unsigned int gain_eeprom_address(unsigned int ao_channel,
0a85b6f0 330 unsigned int range)
086df5b5
IM
331{
332 return 0x8 + 2 * range + 12 * ao_channel;
333}
334
3c5510ba
RKM
335/*
336 * returns upper byte of eeprom entry, which gives the coarse adjustment
337 * values
338 */
086df5b5
IM
339static unsigned int eeprom_coarse_byte(unsigned int word)
340{
341 return (word >> 8) & 0xff;
342}
343
2696fb57 344/* returns lower byte of eeprom entry, which gives the fine adjustment values */
086df5b5
IM
345static unsigned int eeprom_fine_byte(unsigned int word)
346{
347 return word & 0xff;
348}
349
2696fb57 350/* set caldacs to eeprom values for given channel and range */
da91b269 351static void cb_pcidda_calibrate(struct comedi_device *dev, unsigned int channel,
0a85b6f0 352 unsigned int range)
086df5b5 353{
c6ad306b 354 struct cb_pcidda_private *devpriv = dev->private;
086df5b5
IM
355 unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
356
3c5510ba 357 /* remember range so we can tell when we need to readjust calibration */
086df5b5
IM
358 devpriv->ao_range[channel] = range;
359
2696fb57 360 /* get values from eeprom data */
086df5b5 361 coarse_offset =
0a85b6f0
MT
362 eeprom_coarse_byte(devpriv->eeprom_data
363 [offset_eeprom_address(channel, range)]);
086df5b5 364 fine_offset =
0a85b6f0
MT
365 eeprom_fine_byte(devpriv->eeprom_data
366 [offset_eeprom_address(channel, range)]);
086df5b5 367 coarse_gain =
0a85b6f0
MT
368 eeprom_coarse_byte(devpriv->eeprom_data
369 [gain_eeprom_address(channel, range)]);
086df5b5 370 fine_gain =
0a85b6f0
MT
371 eeprom_fine_byte(devpriv->eeprom_data
372 [gain_eeprom_address(channel, range)]);
086df5b5 373
2696fb57 374 /* set caldacs */
086df5b5 375 cb_pcidda_write_caldac(dev, caldac_number(channel),
0a85b6f0 376 coarse_offset_channel(channel), coarse_offset);
086df5b5 377 cb_pcidda_write_caldac(dev, caldac_number(channel),
0a85b6f0 378 fine_offset_channel(channel), fine_offset);
086df5b5 379 cb_pcidda_write_caldac(dev, caldac_number(channel),
0a85b6f0 380 coarse_gain_channel(channel), coarse_gain);
086df5b5 381 cb_pcidda_write_caldac(dev, caldac_number(channel),
0a85b6f0 382 fine_gain_channel(channel), fine_gain);
086df5b5
IM
383}
384
6d336a56
HS
385static int cb_pcidda_ao_winsn(struct comedi_device *dev,
386 struct comedi_subdevice *s,
387 struct comedi_insn *insn, unsigned int *data)
388{
389 struct cb_pcidda_private *devpriv = dev->private;
390 unsigned int command;
391 unsigned int channel, range;
392
393 channel = CR_CHAN(insn->chanspec);
394 range = CR_RANGE(insn->chanspec);
395
396 /* adjust calibration dacs if range has changed */
397 if (range != devpriv->ao_range[channel])
398 cb_pcidda_calibrate(dev, channel, range);
399
400 /* output channel configuration */
401 command = NOSU | ENABLEDAC;
402
403 /* output channel range */
404 switch (range) {
405 case 0:
406 command |= BIP | RANGE10V;
407 break;
408 case 1:
409 command |= BIP | RANGE5V;
410 break;
411 case 2:
412 command |= BIP | RANGE2V5;
413 break;
414 case 3:
415 command |= UNIP | RANGE10V;
416 break;
417 case 4:
418 command |= UNIP | RANGE5V;
419 break;
420 case 5:
421 command |= UNIP | RANGE2V5;
422 break;
423 }
424
425 /* output channel specification */
426 command |= channel << 2;
a74531a5 427 outw(command, dev->iobase + DACONTROL);
6d336a56
HS
428
429 /* write data */
a74531a5 430 outw(data[0], dev->iobase + DADATA + channel * 2);
6d336a56
HS
431
432 /* return the number of samples read/written */
433 return 1;
434}
435
2c0db011
HS
436static const void *cb_pcidda_find_boardinfo(struct comedi_device *dev,
437 struct pci_dev *pcidev)
6d336a56 438{
2c0db011 439 const struct cb_pcidda_board *thisboard;
6d336a56
HS
440 int i;
441
2c0db011
HS
442 for (i = 0; i < ARRAY_SIZE(cb_pcidda_boards); i++) {
443 thisboard = &cb_pcidda_boards[i];
444 if (thisboard->device_id != pcidev->device)
445 return thisboard;
6d336a56 446 }
6d336a56
HS
447 return NULL;
448}
449
2c0db011
HS
450static int cb_pcidda_attach_pci(struct comedi_device *dev,
451 struct pci_dev *pcidev)
6d336a56
HS
452{
453 const struct cb_pcidda_board *thisboard;
454 struct cb_pcidda_private *devpriv;
6d336a56 455 struct comedi_subdevice *s;
08f082ed 456 unsigned long iobase_8255;
2730c736 457 int i;
6d336a56
HS
458 int ret;
459
2c0db011 460 thisboard = cb_pcidda_find_boardinfo(dev, pcidev);
ff331f7d 461 if (!thisboard)
2c0db011
HS
462 return -ENODEV;
463 dev->board_ptr = thisboard;
464 dev->board_name = thisboard->name;
465
c34fa261
HS
466 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
467 if (!devpriv)
468 return -ENOMEM;
469 dev->private = devpriv;
6d336a56 470
2c0db011
HS
471 ret = comedi_pci_enable(pcidev, dev->board_name);
472 if (ret)
473 return ret;
a74531a5 474 dev->iobase = pci_resource_start(pcidev, 3);
08f082ed 475 iobase_8255 = pci_resource_start(pcidev, 2);
6d336a56 476
6d336a56
HS
477 ret = comedi_alloc_subdevices(dev, 3);
478 if (ret)
479 return ret;
480
82ec595a 481 s = &dev->subdevices[0];
6d336a56
HS
482 /* analog output subdevice */
483 s->type = COMEDI_SUBD_AO;
484 s->subdev_flags = SDF_WRITABLE;
485 s->n_chan = thisboard->ao_chans;
486 s->maxdata = (1 << thisboard->ao_bits) - 1;
f9c62f3f 487 s->range_table = &cb_pcidda_ranges;
6d336a56
HS
488 s->insn_write = cb_pcidda_ao_winsn;
489
618351ae
HS
490 /* two 8255 digital io subdevices */
491 for (i = 0; i < 2; i++) {
492 s = &dev->subdevices[1 + i];
493 ret = subdev_8255_init(dev, s, NULL, iobase_8255 + (i * 4));
494 if (ret)
495 return ret;
496 }
6d336a56 497
66483378 498 /* Read the caldac eeprom data */
2730c736
HS
499 for (i = 0; i < EEPROM_SIZE; i++)
500 devpriv->eeprom_data[i] = cb_pcidda_read_eeprom(dev, i);
6d336a56
HS
501
502 /* set calibrations dacs */
2730c736
HS
503 for (i = 0; i < thisboard->ao_chans; i++)
504 cb_pcidda_calibrate(dev, i, devpriv->ao_range[i]);
6d336a56 505
2c0db011
HS
506 dev_info(dev->class_dev, "%s attached\n", dev->board_name);
507
508 return 0;
6d336a56
HS
509}
510
511static void cb_pcidda_detach(struct comedi_device *dev)
512{
513 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
514
6d336a56 515 if (dev->subdevices) {
82ec595a
HS
516 subdev_8255_cleanup(dev, &dev->subdevices[1]);
517 subdev_8255_cleanup(dev, &dev->subdevices[2]);
6d336a56 518 }
2c0db011
HS
519 if (pcidev) {
520 if (dev->iobase)
521 comedi_pci_disable(pcidev);
522 }
6d336a56
HS
523}
524
954ca6c9
HS
525static struct comedi_driver cb_pcidda_driver = {
526 .driver_name = "cb_pcidda",
527 .module = THIS_MODULE,
2c0db011 528 .attach_pci = cb_pcidda_attach_pci,
954ca6c9
HS
529 .detach = cb_pcidda_detach,
530};
531
532static int __devinit cb_pcidda_pci_probe(struct pci_dev *dev,
533 const struct pci_device_id *ent)
727b286b 534{
954ca6c9 535 return comedi_pci_auto_config(dev, &cb_pcidda_driver);
727b286b
AT
536}
537
954ca6c9 538static void __devexit cb_pcidda_pci_remove(struct pci_dev *dev)
727b286b
AT
539{
540 comedi_pci_auto_unconfig(dev);
541}
542
954ca6c9 543static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
b9287a30
HS
544 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_12) },
545 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_12) },
546 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_12) },
547 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA02_16) },
548 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA04_16) },
549 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_DEVICE_ID_DDA08_16) },
954ca6c9 550 { 0 }
727b286b 551};
954ca6c9 552MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
727b286b 553
954ca6c9
HS
554static struct pci_driver cb_pcidda_pci_driver = {
555 .name = "cb_pcidda",
556 .id_table = cb_pcidda_pci_table,
557 .probe = cb_pcidda_pci_probe,
558 .remove = __devexit_p(cb_pcidda_pci_remove),
559};
560module_comedi_pci_driver(cb_pcidda_driver, cb_pcidda_pci_driver);
90f703d3
AT
561
562MODULE_AUTHOR("Comedi http://www.comedi.org");
563MODULE_DESCRIPTION("Comedi low-level driver");
564MODULE_LICENSE("GPL");