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