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