aef946df27e2f22ba85c48e3072ffbc6866d7431
[deliverable/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_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 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 <ivanmr@altavista.com>.\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;
693 s->subdev_flags = SDF_WRITABLE;
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 {
754 comedi_pci_auto_unconfig(dev);
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");
This page took 0.059056 seconds and 5 git commands to generate.