]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/das1800.c
staging: comedi: remove duplicate pointer assignments in attach functions
[karo-tx-linux.git] / drivers / staging / comedi / drivers / das1800.c
1 /*
2     comedi/drivers/das1800.c
3     Driver for Keitley das1700/das1800 series boards
4     Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
5
6     COMEDI - Linux Control and Measurement Device Interface
7     Copyright (C) 2000 David A. Schleef <ds@schleef.org>
8
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 */
19 /*
20 Driver: das1800
21 Description: Keithley Metrabyte DAS1800 (& compatibles)
22 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
23 Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
24   DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
25   DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
26   DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
27   DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
28   DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
29   DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
30   DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
31   DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
32   DAS-1802AO (das-1802ao)
33 Status: works
34
35 The waveform analog output on the 'ao' cards is not supported.
36 If you need it, send me (Frank Hess) an email.
37
38 Configuration options:
39   [0] - I/O port base address
40   [1] - IRQ (optional, required for timed or externally triggered conversions)
41   [2] - DMA0 (optional, requires irq)
42   [3] - DMA1 (optional, requires irq and dma0)
43 */
44 /*
45
46 This driver supports the following Keithley boards:
47
48 das-1701st
49 das-1701st-da
50 das-1701ao
51 das-1702st
52 das-1702st-da
53 das-1702hr
54 das-1702hr-da
55 das-1702ao
56 das-1801st
57 das-1801st-da
58 das-1801hc
59 das-1801ao
60 das-1802st
61 das-1802st-da
62 das-1802hr
63 das-1802hr-da
64 das-1802hc
65 das-1802ao
66
67 Options:
68         [0] - base io address
69         [1] - irq (optional, required for timed or externally triggered conversions)
70         [2] - dma0 (optional, requires irq)
71         [3] - dma1 (optional, requires irq and dma0)
72
73 irq can be omitted, although the cmd interface will not work without it.
74
75 analog input cmd triggers supported:
76         start_src:      TRIG_NOW | TRIG_EXT
77         scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
78         scan_end_src:   TRIG_COUNT
79         convert_src:    TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
80         stop_src:       TRIG_COUNT | TRIG_EXT | TRIG_NONE
81
82 scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
83 'burst mode' which limits the valid conversion time to 64 microseconds
84 (convert_arg <= 64000).  This limitation does not apply if scan_begin_src
85 is TRIG_FOLLOW.
86
87 NOTES:
88 Only the DAS-1801ST has been tested by me.
89 Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
90
91 TODO:
92         Make it automatically allocate irq and dma channels if they are not specified
93         Add support for analog out on 'ao' cards
94         read insn for analog out
95 */
96
97 #include <linux/module.h>
98 #include <linux/interrupt.h>
99 #include <linux/slab.h>
100 #include <linux/io.h>
101 #include "../comedidev.h"
102
103 #include <asm/dma.h>
104
105 #include "8253.h"
106 #include "comedi_fc.h"
107
108 /* misc. defines */
109 #define DAS1800_SIZE           16       /* uses 16 io addresses */
110 #define FIFO_SIZE              1024     /*  1024 sample fifo */
111 #define UNIPOLAR               0x4      /*  bit that determines whether input range is uni/bipolar */
112 #define DMA_BUF_SIZE           0x1ff00  /*  size in bytes of dma buffers */
113
114 /* Registers for the das1800 */
115 #define DAS1800_FIFO            0x0
116 #define DAS1800_QRAM            0x0
117 #define DAS1800_DAC             0x0
118 #define DAS1800_SELECT          0x2
119 #define   ADC                     0x0
120 #define   QRAM                    0x1
121 #define   DAC(a)                  (0x2 + a)
122 #define DAS1800_DIGITAL         0x3
123 #define DAS1800_CONTROL_A       0x4
124 #define   FFEN                    0x1
125 #define   CGEN                    0x4
126 #define   CGSL                    0x8
127 #define   TGEN                    0x10
128 #define   TGSL                    0x20
129 #define   ATEN                    0x80
130 #define DAS1800_CONTROL_B       0x5
131 #define   DMA_CH5                 0x1
132 #define   DMA_CH6                 0x2
133 #define   DMA_CH7                 0x3
134 #define   DMA_CH5_CH6             0x5
135 #define   DMA_CH6_CH7             0x6
136 #define   DMA_CH7_CH5             0x7
137 #define   DMA_ENABLED             0x3   /* mask used to determine if dma is enabled */
138 #define   DMA_DUAL                0x4
139 #define   IRQ3                    0x8
140 #define   IRQ5                    0x10
141 #define   IRQ7                    0x18
142 #define   IRQ10                   0x28
143 #define   IRQ11                   0x30
144 #define   IRQ15                   0x38
145 #define   FIMD                    0x40
146 #define DAS1800_CONTROL_C       0X6
147 #define   IPCLK                   0x1
148 #define   XPCLK                   0x3
149 #define   BMDE                    0x4
150 #define   CMEN                    0x8
151 #define   UQEN                    0x10
152 #define   SD                      0x40
153 #define   UB                      0x80
154 #define DAS1800_STATUS          0x7
155 /* bits that prevent interrupt status bits (and CVEN) from being cleared on write */
156 #define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
157 #define   INT                     0x1
158 #define   DMATC                   0x2
159 #define   CT0TC                   0x8
160 #define   OVF                     0x10
161 #define   FHF                     0x20
162 #define   FNE                     0x40
163 #define   CVEN_MASK               0x40  /*  masks CVEN on write */
164 #define   CVEN                    0x80
165 #define DAS1800_BURST_LENGTH    0x8
166 #define DAS1800_BURST_RATE      0x9
167 #define DAS1800_QRAM_ADDRESS    0xa
168 #define DAS1800_COUNTER         0xc
169
170 #define IOBASE2                   0x400 /* offset of additional ioports used on 'ao' cards */
171
172 enum {
173         das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
174         das1702hr_da,
175         das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
176         das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
177 };
178
179 /* analog input ranges */
180 static const struct comedi_lrange range_ai_das1801 = {
181         8, {
182                 BIP_RANGE(5),
183                 BIP_RANGE(1),
184                 BIP_RANGE(0.1),
185                 BIP_RANGE(0.02),
186                 UNI_RANGE(5),
187                 UNI_RANGE(1),
188                 UNI_RANGE(0.1),
189                 UNI_RANGE(0.02)
190         }
191 };
192
193 static const struct comedi_lrange range_ai_das1802 = {
194         8, {
195                 BIP_RANGE(10),
196                 BIP_RANGE(5),
197                 BIP_RANGE(2.5),
198                 BIP_RANGE(1.25),
199                 UNI_RANGE(10),
200                 UNI_RANGE(5),
201                 UNI_RANGE(2.5),
202                 UNI_RANGE(1.25)
203         }
204 };
205
206 struct das1800_board {
207         const char *name;
208         int ai_speed;           /* max conversion period in nanoseconds */
209         int resolution;         /* bits of ai resolution */
210         int qram_len;           /* length of card's channel / gain queue */
211         int common;             /* supports AREF_COMMON flag */
212         int do_n_chan;          /* number of digital output channels */
213         int ao_ability;         /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
214         int ao_n_chan;          /* number of analog out channels */
215         const struct comedi_lrange *range_ai;   /* available input ranges */
216 };
217
218 /* Warning: the maximum conversion speeds listed below are
219  * not always achievable depending on board setup (see
220  * user manual.)
221  */
222 static const struct das1800_board das1800_boards[] = {
223         {
224          .name = "das-1701st",
225          .ai_speed = 6250,
226          .resolution = 12,
227          .qram_len = 256,
228          .common = 1,
229          .do_n_chan = 4,
230          .ao_ability = 0,
231          .ao_n_chan = 0,
232          .range_ai = &range_ai_das1801,
233          },
234         {
235          .name = "das-1701st-da",
236          .ai_speed = 6250,
237          .resolution = 12,
238          .qram_len = 256,
239          .common = 1,
240          .do_n_chan = 4,
241          .ao_ability = 1,
242          .ao_n_chan = 4,
243          .range_ai = &range_ai_das1801,
244          },
245         {
246          .name = "das-1702st",
247          .ai_speed = 6250,
248          .resolution = 12,
249          .qram_len = 256,
250          .common = 1,
251          .do_n_chan = 4,
252          .ao_ability = 0,
253          .ao_n_chan = 0,
254          .range_ai = &range_ai_das1802,
255          },
256         {
257          .name = "das-1702st-da",
258          .ai_speed = 6250,
259          .resolution = 12,
260          .qram_len = 256,
261          .common = 1,
262          .do_n_chan = 4,
263          .ao_ability = 1,
264          .ao_n_chan = 4,
265          .range_ai = &range_ai_das1802,
266          },
267         {
268          .name = "das-1702hr",
269          .ai_speed = 20000,
270          .resolution = 16,
271          .qram_len = 256,
272          .common = 1,
273          .do_n_chan = 4,
274          .ao_ability = 0,
275          .ao_n_chan = 0,
276          .range_ai = &range_ai_das1802,
277          },
278         {
279          .name = "das-1702hr-da",
280          .ai_speed = 20000,
281          .resolution = 16,
282          .qram_len = 256,
283          .common = 1,
284          .do_n_chan = 4,
285          .ao_ability = 1,
286          .ao_n_chan = 2,
287          .range_ai = &range_ai_das1802,
288          },
289         {
290          .name = "das-1701ao",
291          .ai_speed = 6250,
292          .resolution = 12,
293          .qram_len = 256,
294          .common = 1,
295          .do_n_chan = 4,
296          .ao_ability = 2,
297          .ao_n_chan = 2,
298          .range_ai = &range_ai_das1801,
299          },
300         {
301          .name = "das-1702ao",
302          .ai_speed = 6250,
303          .resolution = 12,
304          .qram_len = 256,
305          .common = 1,
306          .do_n_chan = 4,
307          .ao_ability = 2,
308          .ao_n_chan = 2,
309          .range_ai = &range_ai_das1802,
310          },
311         {
312          .name = "das-1801st",
313          .ai_speed = 3000,
314          .resolution = 12,
315          .qram_len = 256,
316          .common = 1,
317          .do_n_chan = 4,
318          .ao_ability = 0,
319          .ao_n_chan = 0,
320          .range_ai = &range_ai_das1801,
321          },
322         {
323          .name = "das-1801st-da",
324          .ai_speed = 3000,
325          .resolution = 12,
326          .qram_len = 256,
327          .common = 1,
328          .do_n_chan = 4,
329          .ao_ability = 0,
330          .ao_n_chan = 4,
331          .range_ai = &range_ai_das1801,
332          },
333         {
334          .name = "das-1802st",
335          .ai_speed = 3000,
336          .resolution = 12,
337          .qram_len = 256,
338          .common = 1,
339          .do_n_chan = 4,
340          .ao_ability = 0,
341          .ao_n_chan = 0,
342          .range_ai = &range_ai_das1802,
343          },
344         {
345          .name = "das-1802st-da",
346          .ai_speed = 3000,
347          .resolution = 12,
348          .qram_len = 256,
349          .common = 1,
350          .do_n_chan = 4,
351          .ao_ability = 1,
352          .ao_n_chan = 4,
353          .range_ai = &range_ai_das1802,
354          },
355         {
356          .name = "das-1802hr",
357          .ai_speed = 10000,
358          .resolution = 16,
359          .qram_len = 256,
360          .common = 1,
361          .do_n_chan = 4,
362          .ao_ability = 0,
363          .ao_n_chan = 0,
364          .range_ai = &range_ai_das1802,
365          },
366         {
367          .name = "das-1802hr-da",
368          .ai_speed = 10000,
369          .resolution = 16,
370          .qram_len = 256,
371          .common = 1,
372          .do_n_chan = 4,
373          .ao_ability = 1,
374          .ao_n_chan = 2,
375          .range_ai = &range_ai_das1802,
376          },
377         {
378          .name = "das-1801hc",
379          .ai_speed = 3000,
380          .resolution = 12,
381          .qram_len = 64,
382          .common = 0,
383          .do_n_chan = 8,
384          .ao_ability = 1,
385          .ao_n_chan = 2,
386          .range_ai = &range_ai_das1801,
387          },
388         {
389          .name = "das-1802hc",
390          .ai_speed = 3000,
391          .resolution = 12,
392          .qram_len = 64,
393          .common = 0,
394          .do_n_chan = 8,
395          .ao_ability = 1,
396          .ao_n_chan = 2,
397          .range_ai = &range_ai_das1802,
398          },
399         {
400          .name = "das-1801ao",
401          .ai_speed = 3000,
402          .resolution = 12,
403          .qram_len = 256,
404          .common = 1,
405          .do_n_chan = 4,
406          .ao_ability = 2,
407          .ao_n_chan = 2,
408          .range_ai = &range_ai_das1801,
409          },
410         {
411          .name = "das-1802ao",
412          .ai_speed = 3000,
413          .resolution = 12,
414          .qram_len = 256,
415          .common = 1,
416          .do_n_chan = 4,
417          .ao_ability = 2,
418          .ao_n_chan = 2,
419          .range_ai = &range_ai_das1802,
420          },
421 };
422
423 struct das1800_private {
424         volatile unsigned int count;    /* number of data points left to be taken */
425         unsigned int divisor1;  /* value to load into board's counter 1 for timed conversions */
426         unsigned int divisor2;  /* value to load into board's counter 2 for timed conversions */
427         int irq_dma_bits;       /* bits for control register b */
428         /* dma bits for control register b, stored so that dma can be
429          * turned on and off */
430         int dma_bits;
431         unsigned int dma0;      /* dma channels used */
432         unsigned int dma1;
433         volatile unsigned int dma_current;      /* dma channel currently in use */
434         uint16_t *ai_buf0;      /* pointers to dma buffers */
435         uint16_t *ai_buf1;
436         uint16_t *dma_current_buf;      /* pointer to dma buffer currently being used */
437         unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
438         unsigned long iobase2;  /* secondary io address used for analog out on 'ao' boards */
439         unsigned short ao_update_bits;  /* remembers the last write to the
440                                          * 'update' dac */
441 };
442
443 /* analog out range for 'ao' boards */
444 /*
445 static const struct comedi_lrange range_ao_2 = {
446         2, {
447                 BIP_RANGE(10),
448                 BIP_RANGE(5)
449         }
450 };
451 */
452
453 static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev,
454                                             uint16_t sample)
455 {
456         const struct das1800_board *thisboard = comedi_board(dev);
457
458         sample += 1 << (thisboard->resolution - 1);
459         return sample;
460 }
461
462 static void munge_data(struct comedi_device *dev, uint16_t *array,
463                        unsigned int num_elements)
464 {
465         unsigned int i;
466         int unipolar;
467
468         /* see if card is using a unipolar or bipolar range so we can munge data correctly */
469         unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
470
471         /* convert to unsigned type if we are in a bipolar mode */
472         if (!unipolar) {
473                 for (i = 0; i < num_elements; i++)
474                         array[i] = munge_bipolar_sample(dev, array[i]);
475         }
476 }
477
478 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
479                                           struct comedi_subdevice *s)
480 {
481         struct das1800_private *devpriv = dev->private;
482         int numPoints = 0;      /* number of points to read */
483         struct comedi_cmd *cmd = &s->async->cmd;
484
485         numPoints = FIFO_SIZE / 2;
486         /* if we only need some of the points */
487         if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
488                 numPoints = devpriv->count;
489         insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
490         munge_data(dev, devpriv->ai_buf0, numPoints);
491         cfc_write_array_to_buffer(s, devpriv->ai_buf0,
492                                   numPoints * sizeof(devpriv->ai_buf0[0]));
493         if (cmd->stop_src == TRIG_COUNT)
494                 devpriv->count -= numPoints;
495         return;
496 }
497
498 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
499                                           struct comedi_subdevice *s)
500 {
501         struct das1800_private *devpriv = dev->private;
502         unsigned short dpnt;
503         int unipolar;
504         struct comedi_cmd *cmd = &s->async->cmd;
505
506         unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
507
508         while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
509                 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
510                         break;
511                 dpnt = inw(dev->iobase + DAS1800_FIFO);
512                 /* convert to unsigned type if we are in a bipolar mode */
513                 if (!unipolar)
514                         ;
515                 dpnt = munge_bipolar_sample(dev, dpnt);
516                 cfc_write_to_buffer(s, dpnt);
517                 if (cmd->stop_src == TRIG_COUNT)
518                         devpriv->count--;
519         }
520
521         return;
522 }
523
524 /* Utility function used by das1800_flush_dma() and das1800_handle_dma().
525  * Assumes dma lock is held */
526 static void das1800_flush_dma_channel(struct comedi_device *dev,
527                                       struct comedi_subdevice *s,
528                                       unsigned int channel, uint16_t *buffer)
529 {
530         struct das1800_private *devpriv = dev->private;
531         unsigned int num_bytes, num_samples;
532         struct comedi_cmd *cmd = &s->async->cmd;
533
534         disable_dma(channel);
535
536         /* clear flip-flop to make sure 2-byte registers
537          * get set correctly */
538         clear_dma_ff(channel);
539
540         /*  figure out how many points to read */
541         num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
542         num_samples = num_bytes / sizeof(short);
543
544         /* if we only need some of the points */
545         if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
546                 num_samples = devpriv->count;
547
548         munge_data(dev, buffer, num_samples);
549         cfc_write_array_to_buffer(s, buffer, num_bytes);
550         if (s->async->cmd.stop_src == TRIG_COUNT)
551                 devpriv->count -= num_samples;
552
553         return;
554 }
555
556 /* flushes remaining data from board when external trigger has stopped acquisition
557  * and we are using dma transfers */
558 static void das1800_flush_dma(struct comedi_device *dev,
559                               struct comedi_subdevice *s)
560 {
561         struct das1800_private *devpriv = dev->private;
562         unsigned long flags;
563         const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
564
565         flags = claim_dma_lock();
566         das1800_flush_dma_channel(dev, s, devpriv->dma_current,
567                                   devpriv->dma_current_buf);
568
569         if (dual_dma) {
570                 /*  switch to other channel and flush it */
571                 if (devpriv->dma_current == devpriv->dma0) {
572                         devpriv->dma_current = devpriv->dma1;
573                         devpriv->dma_current_buf = devpriv->ai_buf1;
574                 } else {
575                         devpriv->dma_current = devpriv->dma0;
576                         devpriv->dma_current_buf = devpriv->ai_buf0;
577                 }
578                 das1800_flush_dma_channel(dev, s, devpriv->dma_current,
579                                           devpriv->dma_current_buf);
580         }
581
582         release_dma_lock(flags);
583
584         /*  get any remaining samples in fifo */
585         das1800_handle_fifo_not_empty(dev, s);
586
587         return;
588 }
589
590 static void das1800_handle_dma(struct comedi_device *dev,
591                                struct comedi_subdevice *s, unsigned int status)
592 {
593         struct das1800_private *devpriv = dev->private;
594         unsigned long flags;
595         const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
596
597         flags = claim_dma_lock();
598         das1800_flush_dma_channel(dev, s, devpriv->dma_current,
599                                   devpriv->dma_current_buf);
600         /*  re-enable  dma channel */
601         set_dma_addr(devpriv->dma_current,
602                      virt_to_bus(devpriv->dma_current_buf));
603         set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
604         enable_dma(devpriv->dma_current);
605         release_dma_lock(flags);
606
607         if (status & DMATC) {
608                 /*  clear DMATC interrupt bit */
609                 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
610                 /*  switch dma channels for next time, if appropriate */
611                 if (dual_dma) {
612                         /*  read data from the other channel next time */
613                         if (devpriv->dma_current == devpriv->dma0) {
614                                 devpriv->dma_current = devpriv->dma1;
615                                 devpriv->dma_current_buf = devpriv->ai_buf1;
616                         } else {
617                                 devpriv->dma_current = devpriv->dma0;
618                                 devpriv->dma_current_buf = devpriv->ai_buf0;
619                         }
620                 }
621         }
622
623         return;
624 }
625
626 static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
627 {
628         struct das1800_private *devpriv = dev->private;
629
630         outb(0x0, dev->iobase + DAS1800_STATUS);        /* disable conversions */
631         outb(0x0, dev->iobase + DAS1800_CONTROL_B);     /* disable interrupts and dma */
632         outb(0x0, dev->iobase + DAS1800_CONTROL_A);     /* disable and clear fifo and stop triggering */
633         if (devpriv->dma0)
634                 disable_dma(devpriv->dma0);
635         if (devpriv->dma1)
636                 disable_dma(devpriv->dma1);
637         return 0;
638 }
639
640 /* the guts of the interrupt handler, that is shared with das1800_ai_poll */
641 static void das1800_ai_handler(struct comedi_device *dev)
642 {
643         struct das1800_private *devpriv = dev->private;
644         struct comedi_subdevice *s = dev->read_subdev;
645         struct comedi_async *async = s->async;
646         struct comedi_cmd *cmd = &async->cmd;
647         unsigned int status = inb(dev->iobase + DAS1800_STATUS);
648
649         /*  select adc for base address + 0 */
650         outb(ADC, dev->iobase + DAS1800_SELECT);
651         /*  dma buffer full */
652         if (devpriv->irq_dma_bits & DMA_ENABLED) {
653                 /*  look for data from dma transfer even if dma terminal count hasn't happened yet */
654                 das1800_handle_dma(dev, s, status);
655         } else if (status & FHF) {      /*  if fifo half full */
656                 das1800_handle_fifo_half_full(dev, s);
657         } else if (status & FNE) {      /*  if fifo not empty */
658                 das1800_handle_fifo_not_empty(dev, s);
659         }
660
661         async->events |= COMEDI_CB_BLOCK;
662         /* if the card's fifo has overflowed */
663         if (status & OVF) {
664                 /*  clear OVF interrupt bit */
665                 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
666                 comedi_error(dev, "DAS1800 FIFO overflow");
667                 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
668                 cfc_handle_events(dev, s);
669                 return;
670         }
671         /*  stop taking data if appropriate */
672         /* stop_src TRIG_EXT */
673         if (status & CT0TC) {
674                 /*  clear CT0TC interrupt bit */
675                 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
676                 /*  make sure we get all remaining data from board before quitting */
677                 if (devpriv->irq_dma_bits & DMA_ENABLED)
678                         das1800_flush_dma(dev, s);
679                 else
680                         das1800_handle_fifo_not_empty(dev, s);
681                 async->events |= COMEDI_CB_EOA;
682         } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) {        /*  stop_src TRIG_COUNT */
683                 async->events |= COMEDI_CB_EOA;
684         }
685
686         cfc_handle_events(dev, s);
687 }
688
689 static int das1800_ai_poll(struct comedi_device *dev,
690                            struct comedi_subdevice *s)
691 {
692         unsigned long flags;
693
694         /*  prevent race with interrupt handler */
695         spin_lock_irqsave(&dev->spinlock, flags);
696         das1800_ai_handler(dev);
697         spin_unlock_irqrestore(&dev->spinlock, flags);
698
699         return s->async->buf_write_count - s->async->buf_read_count;
700 }
701
702 static irqreturn_t das1800_interrupt(int irq, void *d)
703 {
704         struct comedi_device *dev = d;
705         unsigned int status;
706
707         if (!dev->attached) {
708                 comedi_error(dev, "premature interrupt");
709                 return IRQ_HANDLED;
710         }
711
712         /* Prevent race with das1800_ai_poll() on multi processor systems.
713          * Also protects indirect addressing in das1800_ai_handler */
714         spin_lock(&dev->spinlock);
715         status = inb(dev->iobase + DAS1800_STATUS);
716
717         /* if interrupt was not caused by das-1800 */
718         if (!(status & INT)) {
719                 spin_unlock(&dev->spinlock);
720                 return IRQ_NONE;
721         }
722         /* clear the interrupt status bit INT */
723         outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
724         /*  handle interrupt */
725         das1800_ai_handler(dev);
726
727         spin_unlock(&dev->spinlock);
728         return IRQ_HANDLED;
729 }
730
731 /* converts requested conversion timing to timing compatible with
732  * hardware, used only when card is in 'burst mode'
733  */
734 static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
735 {
736         unsigned int micro_sec;
737
738         /*  in burst mode, the maximum conversion time is 64 microseconds */
739         if (convert_arg > 64000)
740                 convert_arg = 64000;
741
742         /*  the conversion time must be an integral number of microseconds */
743         switch (round_mode) {
744         case TRIG_ROUND_NEAREST:
745         default:
746                 micro_sec = (convert_arg + 500) / 1000;
747                 break;
748         case TRIG_ROUND_DOWN:
749                 micro_sec = convert_arg / 1000;
750                 break;
751         case TRIG_ROUND_UP:
752                 micro_sec = (convert_arg - 1) / 1000 + 1;
753                 break;
754         }
755
756         /*  return number of nanoseconds */
757         return micro_sec * 1000;
758 }
759
760 static int das1800_ai_check_chanlist(struct comedi_device *dev,
761                                      struct comedi_subdevice *s,
762                                      struct comedi_cmd *cmd)
763 {
764         unsigned int unipolar0 = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
765         int i;
766
767         for (i = 1; i < cmd->chanlist_len; i++) {
768                 unsigned int unipolar = CR_RANGE(cmd->chanlist[i]) & UNIPOLAR;
769
770                 if (unipolar != unipolar0) {
771                         dev_dbg(dev->class_dev,
772                                 "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
773                         return -EINVAL;
774                 }
775         }
776
777         return 0;
778 }
779
780 /* test analog input cmd */
781 static int das1800_ai_do_cmdtest(struct comedi_device *dev,
782                                  struct comedi_subdevice *s,
783                                  struct comedi_cmd *cmd)
784 {
785         const struct das1800_board *thisboard = comedi_board(dev);
786         struct das1800_private *devpriv = dev->private;
787         int err = 0;
788         unsigned int tmp_arg;
789
790         /* Step 1 : check if triggers are trivially valid */
791
792         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
793         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
794                                         TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
795         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
796         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
797         err |= cfc_check_trigger_src(&cmd->stop_src,
798                                         TRIG_COUNT | TRIG_EXT | TRIG_NONE);
799
800         if (err)
801                 return 1;
802
803         /* Step 2a : make sure trigger sources are unique */
804
805         err |= cfc_check_trigger_is_unique(cmd->start_src);
806         err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
807         err |= cfc_check_trigger_is_unique(cmd->convert_src);
808         err |= cfc_check_trigger_is_unique(cmd->stop_src);
809
810         /* Step 2b : and mutually compatible */
811
812         if (cmd->scan_begin_src != TRIG_FOLLOW &&
813             cmd->convert_src != TRIG_TIMER)
814                 err |= -EINVAL;
815
816         if (err)
817                 return 2;
818
819         /* Step 3: check if arguments are trivially valid */
820
821         err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
822
823         if (cmd->convert_src == TRIG_TIMER)
824                 err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
825                                                  thisboard->ai_speed);
826
827         err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
828         err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
829
830         switch (cmd->stop_src) {
831         case TRIG_COUNT:
832                 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
833                 break;
834         case TRIG_NONE:
835                 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
836                 break;
837         default:
838                 break;
839         }
840
841         if (err)
842                 return 3;
843
844         /* step 4: fix up any arguments */
845
846         if (cmd->convert_src == TRIG_TIMER) {
847                 /*  if we are not in burst mode */
848                 if (cmd->scan_begin_src == TRIG_FOLLOW) {
849                         tmp_arg = cmd->convert_arg;
850                         /* calculate counter values that give desired timing */
851                         i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
852                                                   &devpriv->divisor1,
853                                                   &devpriv->divisor2,
854                                                   &cmd->convert_arg,
855                                                   cmd->flags);
856                         if (tmp_arg != cmd->convert_arg)
857                                 err++;
858                 }
859                 /*  if we are in burst mode */
860                 else {
861                         /*  check that convert_arg is compatible */
862                         tmp_arg = cmd->convert_arg;
863                         cmd->convert_arg =
864                             burst_convert_arg(cmd->convert_arg,
865                                               cmd->flags & TRIG_ROUND_MASK);
866                         if (tmp_arg != cmd->convert_arg)
867                                 err++;
868
869                         if (cmd->scan_begin_src == TRIG_TIMER) {
870                                 /*  if scans are timed faster than conversion rate allows */
871                                 if (cmd->convert_arg * cmd->chanlist_len >
872                                     cmd->scan_begin_arg) {
873                                         cmd->scan_begin_arg =
874                                             cmd->convert_arg *
875                                             cmd->chanlist_len;
876                                         err++;
877                                 }
878                                 tmp_arg = cmd->scan_begin_arg;
879                                 /* calculate counter values that give desired timing */
880                                 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
881                                                           &devpriv->divisor1,
882                                                           &devpriv->divisor2,
883                                                           &cmd->scan_begin_arg,
884                                                           cmd->flags);
885                                 if (tmp_arg != cmd->scan_begin_arg)
886                                         err++;
887                         }
888                 }
889         }
890
891         if (err)
892                 return 4;
893
894         /* Step 5: check channel list if it exists */
895         if (cmd->chanlist && cmd->chanlist_len > 0)
896                 err |= das1800_ai_check_chanlist(dev, s, cmd);
897
898         if (err)
899                 return 5;
900
901         return 0;
902 }
903
904 /* returns appropriate bits for control register a, depending on command */
905 static int control_a_bits(const struct comedi_cmd *cmd)
906 {
907         int control_a;
908
909         control_a = FFEN;       /* enable fifo */
910         if (cmd->stop_src == TRIG_EXT)
911                 control_a |= ATEN;
912         switch (cmd->start_src) {
913         case TRIG_EXT:
914                 control_a |= TGEN | CGSL;
915                 break;
916         case TRIG_NOW:
917                 control_a |= CGEN;
918                 break;
919         default:
920                 break;
921         }
922
923         return control_a;
924 }
925
926 /* returns appropriate bits for control register c, depending on command */
927 static int control_c_bits(const struct comedi_cmd *cmd)
928 {
929         int control_c;
930         int aref;
931
932         /* set clock source to internal or external, select analog reference,
933          * select unipolar / bipolar
934          */
935         aref = CR_AREF(cmd->chanlist[0]);
936         control_c = UQEN;       /* enable upper qram addresses */
937         if (aref != AREF_DIFF)
938                 control_c |= SD;
939         if (aref == AREF_COMMON)
940                 control_c |= CMEN;
941         /* if a unipolar range was selected */
942         if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR)
943                 control_c |= UB;
944         switch (cmd->scan_begin_src) {
945         case TRIG_FOLLOW:       /*  not in burst mode */
946                 switch (cmd->convert_src) {
947                 case TRIG_TIMER:
948                         /* trig on cascaded counters */
949                         control_c |= IPCLK;
950                         break;
951                 case TRIG_EXT:
952                         /* trig on falling edge of external trigger */
953                         control_c |= XPCLK;
954                         break;
955                 default:
956                         break;
957                 }
958                 break;
959         case TRIG_TIMER:
960                 /*  burst mode with internal pacer clock */
961                 control_c |= BMDE | IPCLK;
962                 break;
963         case TRIG_EXT:
964                 /*  burst mode with external trigger */
965                 control_c |= BMDE | XPCLK;
966                 break;
967         default:
968                 break;
969         }
970
971         return control_c;
972 }
973
974 /* loads counters with divisor1, divisor2 from private structure */
975 static int das1800_set_frequency(struct comedi_device *dev)
976 {
977         struct das1800_private *devpriv = dev->private;
978         int err = 0;
979
980         /*  counter 1, mode 2 */
981         if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
982                        2))
983                 err++;
984         /*  counter 2, mode 2 */
985         if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
986                        2))
987                 err++;
988         if (err)
989                 return -1;
990
991         return 0;
992 }
993
994 /* sets up counters */
995 static int setup_counters(struct comedi_device *dev,
996                           const struct comedi_cmd *cmd)
997 {
998         struct das1800_private *devpriv = dev->private;
999         unsigned int period;
1000
1001         /*  setup cascaded counters for conversion/scan frequency */
1002         switch (cmd->scan_begin_src) {
1003         case TRIG_FOLLOW:       /*  not in burst mode */
1004                 if (cmd->convert_src == TRIG_TIMER) {
1005                         /* set conversion frequency */
1006                         period = cmd->convert_arg;
1007                         i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
1008                                                   &devpriv->divisor1,
1009                                                   &devpriv->divisor2,
1010                                                   &period, cmd->flags);
1011                         if (das1800_set_frequency(dev) < 0)
1012                                 return -1;
1013                 }
1014                 break;
1015         case TRIG_TIMER:        /*  in burst mode */
1016                 /* set scan frequency */
1017                 period = cmd->scan_begin_arg;
1018                 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ,
1019                                           &devpriv->divisor1,
1020                                           &devpriv->divisor2,
1021                                           &period, cmd->flags);
1022                 if (das1800_set_frequency(dev) < 0)
1023                         return -1;
1024                 break;
1025         default:
1026                 break;
1027         }
1028
1029         /*  setup counter 0 for 'about triggering' */
1030         if (cmd->stop_src == TRIG_EXT) {
1031                 /*  load counter 0 in mode 0 */
1032                 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
1033         }
1034
1035         return 0;
1036 }
1037
1038 /* utility function that suggests a dma transfer size based on the conversion period 'ns' */
1039 static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd)
1040 {
1041         unsigned int size = DMA_BUF_SIZE;
1042         static const int sample_size = 2;       /*  size in bytes of one sample from board */
1043         unsigned int fill_time = 300000000;     /*  target time in nanoseconds for filling dma buffer */
1044         unsigned int max_size;  /*  maximum size we will allow for a transfer */
1045
1046         /*  make dma buffer fill in 0.3 seconds for timed modes */
1047         switch (cmd->scan_begin_src) {
1048         case TRIG_FOLLOW:       /*  not in burst mode */
1049                 if (cmd->convert_src == TRIG_TIMER)
1050                         size = (fill_time / cmd->convert_arg) * sample_size;
1051                 break;
1052         case TRIG_TIMER:
1053                 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
1054                     sample_size;
1055                 break;
1056         default:
1057                 size = DMA_BUF_SIZE;
1058                 break;
1059         }
1060
1061         /*  set a minimum and maximum size allowed */
1062         max_size = DMA_BUF_SIZE;
1063         /*  if we are taking limited number of conversions, limit transfer size to that */
1064         if (cmd->stop_src == TRIG_COUNT &&
1065             cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
1066                 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
1067
1068         if (size > max_size)
1069                 size = max_size;
1070         if (size < sample_size)
1071                 size = sample_size;
1072
1073         return size;
1074 }
1075
1076 /* sets up dma */
1077 static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
1078 {
1079         struct das1800_private *devpriv = dev->private;
1080         unsigned long lock_flags;
1081         const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
1082
1083         if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
1084                 return;
1085
1086         /* determine a reasonable dma transfer size */
1087         devpriv->dma_transfer_size = suggest_transfer_size(cmd);
1088         lock_flags = claim_dma_lock();
1089         disable_dma(devpriv->dma0);
1090         /* clear flip-flop to make sure 2-byte registers for
1091          * count and address get set correctly */
1092         clear_dma_ff(devpriv->dma0);
1093         set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
1094         /*  set appropriate size of transfer */
1095         set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
1096         devpriv->dma_current = devpriv->dma0;
1097         devpriv->dma_current_buf = devpriv->ai_buf0;
1098         enable_dma(devpriv->dma0);
1099         /*  set up dual dma if appropriate */
1100         if (dual_dma) {
1101                 disable_dma(devpriv->dma1);
1102                 /* clear flip-flop to make sure 2-byte registers for
1103                  * count and address get set correctly */
1104                 clear_dma_ff(devpriv->dma1);
1105                 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
1106                 /*  set appropriate size of transfer */
1107                 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
1108                 enable_dma(devpriv->dma1);
1109         }
1110         release_dma_lock(lock_flags);
1111
1112         return;
1113 }
1114
1115 /* programs channel/gain list into card */
1116 static void program_chanlist(struct comedi_device *dev,
1117                              const struct comedi_cmd *cmd)
1118 {
1119         int i, n, chan_range;
1120         unsigned long irq_flags;
1121         const int range_mask = 0x3;     /* masks unipolar/bipolar bit off range */
1122         const int range_bitshift = 8;
1123
1124         n = cmd->chanlist_len;
1125         /*  spinlock protects indirect addressing */
1126         spin_lock_irqsave(&dev->spinlock, irq_flags);
1127         outb(QRAM, dev->iobase + DAS1800_SELECT);       /* select QRAM for baseAddress + 0x0 */
1128         outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);        /*set QRAM address start */
1129         /* make channel / gain list */
1130         for (i = 0; i < n; i++) {
1131                 chan_range =
1132                     CR_CHAN(cmd->chanlist[i]) |
1133                     ((CR_RANGE(cmd->chanlist[i]) & range_mask) <<
1134                      range_bitshift);
1135                 outw(chan_range, dev->iobase + DAS1800_QRAM);
1136         }
1137         outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS);        /*finish write to QRAM */
1138         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1139
1140         return;
1141 }
1142
1143 /* analog input do_cmd */
1144 static int das1800_ai_do_cmd(struct comedi_device *dev,
1145                              struct comedi_subdevice *s)
1146 {
1147         struct das1800_private *devpriv = dev->private;
1148         int ret;
1149         int control_a, control_c;
1150         struct comedi_async *async = s->async;
1151         const struct comedi_cmd *cmd = &async->cmd;
1152
1153         /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
1154          * (because dma in handler is unsafe at hard real-time priority) */
1155         if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT))
1156                 devpriv->irq_dma_bits &= ~DMA_ENABLED;
1157         else
1158                 devpriv->irq_dma_bits |= devpriv->dma_bits;
1159         /*  interrupt on end of conversion for TRIG_WAKE_EOS */
1160         if (cmd->flags & TRIG_WAKE_EOS) {
1161                 /*  interrupt fifo not empty */
1162                 devpriv->irq_dma_bits &= ~FIMD;
1163         } else {
1164                 /*  interrupt fifo half full */
1165                 devpriv->irq_dma_bits |= FIMD;
1166         }
1167         /*  determine how many conversions we need */
1168         if (cmd->stop_src == TRIG_COUNT)
1169                 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
1170
1171         das1800_cancel(dev, s);
1172
1173         /*  determine proper bits for control registers */
1174         control_a = control_a_bits(cmd);
1175         control_c = control_c_bits(cmd);
1176
1177         /* setup card and start */
1178         program_chanlist(dev, cmd);
1179         ret = setup_counters(dev, cmd);
1180         if (ret < 0) {
1181                 comedi_error(dev, "Error setting up counters");
1182                 return ret;
1183         }
1184         setup_dma(dev, cmd);
1185         outb(control_c, dev->iobase + DAS1800_CONTROL_C);
1186         /*  set conversion rate and length for burst mode */
1187         if (control_c & BMDE) {
1188                 /*  program conversion period with number of microseconds minus 1 */
1189                 outb(cmd->convert_arg / 1000 - 1,
1190                      dev->iobase + DAS1800_BURST_RATE);
1191                 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
1192         }
1193         outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);   /*  enable irq/dma */
1194         outb(control_a, dev->iobase + DAS1800_CONTROL_A);       /* enable fifo and triggering */
1195         outb(CVEN, dev->iobase + DAS1800_STATUS);       /* enable conversions */
1196
1197         return 0;
1198 }
1199
1200 /* read analog input */
1201 static int das1800_ai_rinsn(struct comedi_device *dev,
1202                             struct comedi_subdevice *s,
1203                             struct comedi_insn *insn, unsigned int *data)
1204 {
1205         const struct das1800_board *thisboard = comedi_board(dev);
1206         int i, n;
1207         int chan, range, aref, chan_range;
1208         int timeout = 1000;
1209         unsigned short dpnt;
1210         int conv_flags = 0;
1211         unsigned long irq_flags;
1212
1213         /* set up analog reference and unipolar / bipolar mode */
1214         aref = CR_AREF(insn->chanspec);
1215         conv_flags |= UQEN;
1216         if (aref != AREF_DIFF)
1217                 conv_flags |= SD;
1218         if (aref == AREF_COMMON)
1219                 conv_flags |= CMEN;
1220         /* if a unipolar range was selected */
1221         if (CR_RANGE(insn->chanspec) & UNIPOLAR)
1222                 conv_flags |= UB;
1223
1224         outb(conv_flags, dev->iobase + DAS1800_CONTROL_C);      /* software conversion enabled */
1225         outb(CVEN, dev->iobase + DAS1800_STATUS);       /* enable conversions */
1226         outb(0x0, dev->iobase + DAS1800_CONTROL_A);     /* reset fifo */
1227         outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
1228
1229         chan = CR_CHAN(insn->chanspec);
1230         /* mask of unipolar/bipolar bit from range */
1231         range = CR_RANGE(insn->chanspec) & 0x3;
1232         chan_range = chan | (range << 8);
1233         spin_lock_irqsave(&dev->spinlock, irq_flags);
1234         outb(QRAM, dev->iobase + DAS1800_SELECT);       /* select QRAM for baseAddress + 0x0 */
1235         outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);  /* set QRAM address start */
1236         outw(chan_range, dev->iobase + DAS1800_QRAM);
1237         outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS);  /*finish write to QRAM */
1238         outb(ADC, dev->iobase + DAS1800_SELECT);        /* select ADC for baseAddress + 0x0 */
1239
1240         for (n = 0; n < insn->n; n++) {
1241                 /* trigger conversion */
1242                 outb(0, dev->iobase + DAS1800_FIFO);
1243                 for (i = 0; i < timeout; i++) {
1244                         if (inb(dev->iobase + DAS1800_STATUS) & FNE)
1245                                 break;
1246                 }
1247                 if (i == timeout) {
1248                         comedi_error(dev, "timeout");
1249                         n = -ETIME;
1250                         goto exit;
1251                 }
1252                 dpnt = inw(dev->iobase + DAS1800_FIFO);
1253                 /* shift data to offset binary for bipolar ranges */
1254                 if ((conv_flags & UB) == 0)
1255                         dpnt += 1 << (thisboard->resolution - 1);
1256                 data[n] = dpnt;
1257         }
1258 exit:
1259         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1260
1261         return n;
1262 }
1263
1264 /* writes to an analog output channel */
1265 static int das1800_ao_winsn(struct comedi_device *dev,
1266                             struct comedi_subdevice *s,
1267                             struct comedi_insn *insn, unsigned int *data)
1268 {
1269         const struct das1800_board *thisboard = comedi_board(dev);
1270         struct das1800_private *devpriv = dev->private;
1271         int chan = CR_CHAN(insn->chanspec);
1272 /* int range = CR_RANGE(insn->chanspec); */
1273         int update_chan = thisboard->ao_n_chan - 1;
1274         unsigned short output;
1275         unsigned long irq_flags;
1276
1277         /*   card expects two's complement data */
1278         output = data[0] - (1 << (thisboard->resolution - 1));
1279         /*  if the write is to the 'update' channel, we need to remember its value */
1280         if (chan == update_chan)
1281                 devpriv->ao_update_bits = output;
1282         /*  write to channel */
1283         spin_lock_irqsave(&dev->spinlock, irq_flags);
1284         outb(DAC(chan), dev->iobase + DAS1800_SELECT);  /* select dac channel for baseAddress + 0x0 */
1285         outw(output, dev->iobase + DAS1800_DAC);
1286         /*  now we need to write to 'update' channel to update all dac channels */
1287         if (chan != update_chan) {
1288                 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);   /* select 'update' channel for baseAddress + 0x0 */
1289                 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1290         }
1291         spin_unlock_irqrestore(&dev->spinlock, irq_flags);
1292
1293         return 1;
1294 }
1295
1296 /* reads from digital input channels */
1297 static int das1800_di_rbits(struct comedi_device *dev,
1298                             struct comedi_subdevice *s,
1299                             struct comedi_insn *insn, unsigned int *data)
1300 {
1301
1302         data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1303         data[0] = 0;
1304
1305         return insn->n;
1306 }
1307
1308 static int das1800_do_wbits(struct comedi_device *dev,
1309                             struct comedi_subdevice *s,
1310                             struct comedi_insn *insn,
1311                             unsigned int *data)
1312 {
1313         if (comedi_dio_update_state(s, data))
1314                 outb(s->state, dev->iobase + DAS1800_DIGITAL);
1315
1316         data[1] = s->state;
1317
1318         return insn->n;
1319 }
1320
1321 static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0,
1322                             unsigned int dma1)
1323 {
1324         struct das1800_private *devpriv = dev->private;
1325         unsigned long flags;
1326
1327         /*  need an irq to do dma */
1328         if (dev->irq && dma0) {
1329                 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */
1330                 switch ((dma0 & 0x7) | (dma1 << 4)) {
1331                 case 0x5:       /*  dma0 == 5 */
1332                         devpriv->dma_bits |= DMA_CH5;
1333                         break;
1334                 case 0x6:       /*  dma0 == 6 */
1335                         devpriv->dma_bits |= DMA_CH6;
1336                         break;
1337                 case 0x7:       /*  dma0 == 7 */
1338                         devpriv->dma_bits |= DMA_CH7;
1339                         break;
1340                 case 0x65:      /*  dma0 == 5, dma1 == 6 */
1341                         devpriv->dma_bits |= DMA_CH5_CH6;
1342                         break;
1343                 case 0x76:      /*  dma0 == 6, dma1 == 7 */
1344                         devpriv->dma_bits |= DMA_CH6_CH7;
1345                         break;
1346                 case 0x57:      /*  dma0 == 7, dma1 == 5 */
1347                         devpriv->dma_bits |= DMA_CH7_CH5;
1348                         break;
1349                 default:
1350                         dev_err(dev->class_dev,
1351                                 "only supports dma channels 5 through 7\n");
1352                         dev_err(dev->class_dev,
1353                                 "Dual dma only allows the following combinations:\n");
1354                         dev_err(dev->class_dev,
1355                                 "dma 5,6 / 6,7 / or 7,5\n");
1356                         return -EINVAL;
1357                         break;
1358                 }
1359                 if (request_dma(dma0, dev->driver->driver_name)) {
1360                         dev_err(dev->class_dev,
1361                                 "failed to allocate dma channel %i\n", dma0);
1362                         return -EINVAL;
1363                 }
1364                 devpriv->dma0 = dma0;
1365                 devpriv->dma_current = dma0;
1366                 if (dma1) {
1367                         if (request_dma(dma1, dev->driver->driver_name)) {
1368                                 dev_err(dev->class_dev,
1369                                         "failed to allocate dma channel %i\n",
1370                                         dma1);
1371                                 return -EINVAL;
1372                         }
1373                         devpriv->dma1 = dma1;
1374                 }
1375                 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1376                 if (devpriv->ai_buf0 == NULL)
1377                         return -ENOMEM;
1378                 devpriv->dma_current_buf = devpriv->ai_buf0;
1379                 if (dma1) {
1380                         devpriv->ai_buf1 =
1381                             kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
1382                         if (devpriv->ai_buf1 == NULL)
1383                                 return -ENOMEM;
1384                 }
1385                 flags = claim_dma_lock();
1386                 disable_dma(devpriv->dma0);
1387                 set_dma_mode(devpriv->dma0, DMA_MODE_READ);
1388                 if (dma1) {
1389                         disable_dma(devpriv->dma1);
1390                         set_dma_mode(devpriv->dma1, DMA_MODE_READ);
1391                 }
1392                 release_dma_lock(flags);
1393         }
1394         return 0;
1395 }
1396
1397 static int das1800_probe(struct comedi_device *dev)
1398 {
1399         int id;
1400         int board;
1401
1402         id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;   /* get id bits */
1403         board = ((struct das1800_board *)dev->board_ptr) - das1800_boards;
1404
1405         switch (id) {
1406         case 0x3:
1407                 if (board == das1801st_da || board == das1802st_da ||
1408                     board == das1701st_da || board == das1702st_da) {
1409                         dev_dbg(dev->class_dev, "Board model: %s\n",
1410                                 das1800_boards[board].name);
1411                         return board;
1412                 }
1413                 printk
1414                     (" Board model (probed, not recommended): das-1800st-da series\n");
1415                 return das1801st;
1416                 break;
1417         case 0x4:
1418                 if (board == das1802hr_da || board == das1702hr_da) {
1419                         dev_dbg(dev->class_dev, "Board model: %s\n",
1420                                 das1800_boards[board].name);
1421                         return board;
1422                 }
1423                 printk
1424                     (" Board model (probed, not recommended): das-1802hr-da\n");
1425                 return das1802hr;
1426                 break;
1427         case 0x5:
1428                 if (board == das1801ao || board == das1802ao ||
1429                     board == das1701ao || board == das1702ao) {
1430                         dev_dbg(dev->class_dev, "Board model: %s\n",
1431                                 das1800_boards[board].name);
1432                         return board;
1433                 }
1434                 printk
1435                     (" Board model (probed, not recommended): das-1800ao series\n");
1436                 return das1801ao;
1437                 break;
1438         case 0x6:
1439                 if (board == das1802hr || board == das1702hr) {
1440                         dev_dbg(dev->class_dev, "Board model: %s\n",
1441                                 das1800_boards[board].name);
1442                         return board;
1443                 }
1444                 printk
1445                     (" Board model (probed, not recommended): das-1802hr\n");
1446                 return das1802hr;
1447                 break;
1448         case 0x7:
1449                 if (board == das1801st || board == das1802st ||
1450                     board == das1701st || board == das1702st) {
1451                         dev_dbg(dev->class_dev, "Board model: %s\n",
1452                                 das1800_boards[board].name);
1453                         return board;
1454                 }
1455                 printk
1456                     (" Board model (probed, not recommended): das-1800st series\n");
1457                 return das1801st;
1458                 break;
1459         case 0x8:
1460                 if (board == das1801hc || board == das1802hc) {
1461                         dev_dbg(dev->class_dev, "Board model: %s\n",
1462                                 das1800_boards[board].name);
1463                         return board;
1464                 }
1465                 printk
1466                     (" Board model (probed, not recommended): das-1800hc series\n");
1467                 return das1801hc;
1468                 break;
1469         default:
1470                 printk
1471                     (" Board model: probe returned 0x%x (unknown, please report)\n",
1472                      id);
1473                 return board;
1474                 break;
1475         }
1476         return -1;
1477 }
1478
1479 static int das1800_attach(struct comedi_device *dev,
1480                           struct comedi_devconfig *it)
1481 {
1482         const struct das1800_board *thisboard;
1483         struct das1800_private *devpriv;
1484         struct comedi_subdevice *s;
1485         unsigned int irq = it->options[1];
1486         unsigned int dma0 = it->options[2];
1487         unsigned int dma1 = it->options[3];
1488         int board;
1489         int ret;
1490
1491         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1492         if (!devpriv)
1493                 return -ENOMEM;
1494
1495         ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1496         if (ret)
1497                 return ret;
1498
1499         board = das1800_probe(dev);
1500         if (board < 0) {
1501                 dev_err(dev->class_dev, "unable to determine board type\n");
1502                 return -ENODEV;
1503         }
1504
1505         dev->board_ptr = das1800_boards + board;
1506         thisboard = comedi_board(dev);
1507         dev->board_name = thisboard->name;
1508
1509         /*  if it is an 'ao' board with fancy analog out then we need extra io ports */
1510         if (thisboard->ao_ability == 2) {
1511                 unsigned long iobase2 = dev->iobase + IOBASE2;
1512
1513                 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1514                 if (ret)
1515                         return ret;
1516                 devpriv->iobase2 = iobase2;
1517         }
1518
1519         if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
1520             irq == 15) {
1521                 ret = request_irq(irq, das1800_interrupt, 0,
1522                                   dev->board_name, dev);
1523                 if (ret == 0) {
1524                         dev->irq = irq;
1525
1526                         switch (irq) {
1527                         case 3:
1528                                 devpriv->irq_dma_bits |= 0x8;
1529                                 break;
1530                         case 5:
1531                                 devpriv->irq_dma_bits |= 0x10;
1532                                 break;
1533                         case 7:
1534                                 devpriv->irq_dma_bits |= 0x18;
1535                                 break;
1536                         case 10:
1537                                 devpriv->irq_dma_bits |= 0x28;
1538                                 break;
1539                         case 11:
1540                                 devpriv->irq_dma_bits |= 0x30;
1541                                 break;
1542                         case 15:
1543                                 devpriv->irq_dma_bits |= 0x38;
1544                                 break;
1545                         }
1546                 }
1547         }
1548
1549         ret = das1800_init_dma(dev, dma0, dma1);
1550         if (ret < 0)
1551                 return ret;
1552
1553         if (devpriv->ai_buf0 == NULL) {
1554                 devpriv->ai_buf0 =
1555                     kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
1556                 if (devpriv->ai_buf0 == NULL)
1557                         return -ENOMEM;
1558         }
1559
1560         ret = comedi_alloc_subdevices(dev, 4);
1561         if (ret)
1562                 return ret;
1563
1564         /* analog input subdevice */
1565         s = &dev->subdevices[0];
1566         s->type = COMEDI_SUBD_AI;
1567         s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
1568         if (thisboard->common)
1569                 s->subdev_flags |= SDF_COMMON;
1570         s->n_chan = thisboard->qram_len;
1571         s->maxdata = (1 << thisboard->resolution) - 1;
1572         s->range_table = thisboard->range_ai;
1573         s->insn_read = das1800_ai_rinsn;
1574         if (dev->irq) {
1575                 dev->read_subdev = s;
1576                 s->subdev_flags |= SDF_CMD_READ;
1577                 s->len_chanlist = s->n_chan;
1578                 s->do_cmd = das1800_ai_do_cmd;
1579                 s->do_cmdtest = das1800_ai_do_cmdtest;
1580                 s->poll = das1800_ai_poll;
1581                 s->cancel = das1800_cancel;
1582         }
1583
1584         /* analog out */
1585         s = &dev->subdevices[1];
1586         if (thisboard->ao_ability == 1) {
1587                 s->type = COMEDI_SUBD_AO;
1588                 s->subdev_flags = SDF_WRITABLE;
1589                 s->n_chan = thisboard->ao_n_chan;
1590                 s->maxdata = (1 << thisboard->resolution) - 1;
1591                 s->range_table = &range_bipolar10;
1592                 s->insn_write = das1800_ao_winsn;
1593         } else {
1594                 s->type = COMEDI_SUBD_UNUSED;
1595         }
1596
1597         /* di */
1598         s = &dev->subdevices[2];
1599         s->type = COMEDI_SUBD_DI;
1600         s->subdev_flags = SDF_READABLE;
1601         s->n_chan = 4;
1602         s->maxdata = 1;
1603         s->range_table = &range_digital;
1604         s->insn_bits = das1800_di_rbits;
1605
1606         /* do */
1607         s = &dev->subdevices[3];
1608         s->type = COMEDI_SUBD_DO;
1609         s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1610         s->n_chan = thisboard->do_n_chan;
1611         s->maxdata = 1;
1612         s->range_table = &range_digital;
1613         s->insn_bits = das1800_do_wbits;
1614
1615         das1800_cancel(dev, dev->read_subdev);
1616
1617         /*  initialize digital out channels */
1618         outb(0, dev->iobase + DAS1800_DIGITAL);
1619
1620         /*  initialize analog out channels */
1621         if (thisboard->ao_ability == 1) {
1622                 /*  select 'update' dac channel for baseAddress + 0x0 */
1623                 outb(DAC(thisboard->ao_n_chan - 1),
1624                      dev->iobase + DAS1800_SELECT);
1625                 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
1626         }
1627
1628         return 0;
1629 };
1630
1631 static void das1800_detach(struct comedi_device *dev)
1632 {
1633         struct das1800_private *devpriv = dev->private;
1634
1635         if (devpriv) {
1636                 if (devpriv->dma0)
1637                         free_dma(devpriv->dma0);
1638                 if (devpriv->dma1)
1639                         free_dma(devpriv->dma1);
1640                 kfree(devpriv->ai_buf0);
1641                 kfree(devpriv->ai_buf1);
1642                 if (devpriv->iobase2)
1643                         release_region(devpriv->iobase2, DAS1800_SIZE);
1644         }
1645         comedi_legacy_detach(dev);
1646 }
1647
1648 static struct comedi_driver das1800_driver = {
1649         .driver_name    = "das1800",
1650         .module         = THIS_MODULE,
1651         .attach         = das1800_attach,
1652         .detach         = das1800_detach,
1653         .num_names      = ARRAY_SIZE(das1800_boards),
1654         .board_name     = &das1800_boards[0].name,
1655         .offset         = sizeof(struct das1800_board),
1656 };
1657 module_comedi_driver(das1800_driver);
1658
1659 MODULE_AUTHOR("Comedi http://www.comedi.org");
1660 MODULE_DESCRIPTION("Comedi low-level driver");
1661 MODULE_LICENSE("GPL");