Merge branch 'for-2.6.31' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
[pandora-kernel.git] / drivers / staging / comedi / drivers / das16.c
1 /*
2     comedi/drivers/das16.c
3     DAS16 driver
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2000 David A. Schleef <ds@schleef.org>
7     Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
8     Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
9
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 ************************************************************************
25 */
26 /*
27 Driver: das16
28 Description: DAS16 compatible boards
29 Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
30 Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
31   DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
32   DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
33   DAS-1602 (das-1602),
34   [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
35   PC104-DAS16JR/16 (pc104-das16jr/16),
36   CIO-DAS16JR/16 (cio-das16jr/16),
37   CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
38   CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
39   CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
40   CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
41 Status: works
42 Updated: 2003-10-12
43
44 A rewrite of the das16 and das1600 drivers.
45 Options:
46         [0] - base io address
47         [1] - irq (does nothing, irq is not used anymore)
48         [2] - dma (optional, required for comedi_command support)
49         [3] - master clock speed in MHz (optional, 1 or 10, ignored if
50                 board can probe clock, defaults to 1)
51         [4] - analog input range lowest voltage in microvolts (optional,
52                 only useful if your board does not have software
53                 programmable gain)
54         [5] - analog input range highest voltage in microvolts (optional,
55                 only useful if board does not have software programmable
56                 gain)
57         [6] - analog output range lowest voltage in microvolts (optional)
58         [7] - analog output range highest voltage in microvolts (optional)
59         [8] - use timer mode for DMA.  Timer mode is needed e.g. for
60                 buggy DMA controllers in NS CS5530A (Geode Companion), and for
61                 'jr' cards that lack a hardware fifo.  This option is no
62                 longer needed, since timer mode is _always_ used.
63
64 Passing a zero for an option is the same as leaving it unspecified.
65
66 */
67 /*
68
69 Testing and debugging help provided by Daniel Koch.
70
71 Keithley Manuals:
72         2309.PDF (das16)
73         4919.PDF (das1400, 1600)
74         4922.PDF (das-1400)
75         4923.PDF (das1200, 1400, 1600)
76
77 Computer boards manuals also available from their website www.measurementcomputing.com
78
79 */
80
81 #include <linux/pci.h>
82 #include <linux/interrupt.h>
83 #include <asm/dma.h>
84 #include "../comedidev.h"
85
86 #include "8253.h"
87 #include "8255.h"
88 #include "comedi_fc.h"
89
90 #undef DEBUG
91 /* #define DEBUG */
92
93 #ifdef DEBUG
94 #define DEBUG_PRINT(format, args...) printk("das16: " format, ## args)
95 #else
96 #define DEBUG_PRINT(format, args...)
97 #endif
98
99 #define DAS16_SIZE 20           /*  number of ioports */
100 #define DAS16_DMA_SIZE 0xff00   /*  size in bytes of allocated dma buffer */
101
102 /*
103     cio-das16.pdf
104
105     "das16"
106     "das16/f"
107
108   0     a/d bits 0-3            start 12 bit
109   1     a/d bits 4-11           unused
110   2     mux read                mux set
111   3     di 4 bit                do 4 bit
112   4     unused                  ao0_lsb
113   5     unused                  ao0_msb
114   6     unused                  ao1_lsb
115   7     unused                  ao1_msb
116   8     status eoc uni/bip      interrupt reset
117   9     dma, int, trig ctrl     set dma, int
118   a     pacer control           unused
119   b     reserved                reserved
120   cdef  8254
121   0123  8255
122
123 */
124
125 /*
126     cio-das16jr.pdf
127
128     "das16jr"
129
130   0     a/d bits 0-3            start 12 bit
131   1     a/d bits 4-11           unused
132   2     mux read                mux set
133   3     di 4 bit                do 4 bit
134   4567  unused                  unused
135   8     status eoc uni/bip      interrupt reset
136   9     dma, int, trig ctrl     set dma, int
137   a     pacer control           unused
138   b     gain status             gain control
139   cdef  8254
140
141 */
142
143 /*
144     cio-das16jr_16.pdf
145
146     "das16jr_16"
147
148   0     a/d bits 0-7            start 16 bit
149   1     a/d bits 8-15           unused
150   2     mux read                mux set
151   3     di 4 bit                do 4 bit
152   4567  unused                  unused
153   8     status eoc uni/bip      interrupt reset
154   9     dma, int, trig ctrl     set dma, int
155   a     pacer control           unused
156   b     gain status             gain control
157   cdef  8254
158
159 */
160 /*
161     cio-das160x-1x.pdf
162
163     "das1601/12"
164     "das1602/12"
165     "das1602/16"
166
167   0     a/d bits 0-3            start 12 bit
168   1     a/d bits 4-11           unused
169   2     mux read                mux set
170   3     di 4 bit                do 4 bit
171   4     unused                  ao0_lsb
172   5     unused                  ao0_msb
173   6     unused                  ao1_lsb
174   7     unused                  ao1_msb
175   8     status eoc uni/bip      interrupt reset
176   9     dma, int, trig ctrl     set dma, int
177   a     pacer control           unused
178   b     gain status             gain control
179   cdef  8254
180   400   8255
181   404   unused                  conversion enable
182   405   unused                  burst enable
183   406   unused                  das1600 enable
184   407   status
185
186 */
187
188 static const int sample_size = 2;       /*  size in bytes of a sample from board */
189
190 #define DAS16_TRIG              0
191 #define DAS16_AI_LSB            0
192 #define DAS16_AI_MSB            1
193 #define DAS16_MUX               2
194 #define DAS16_DIO               3
195 #define DAS16_AO_LSB(x) ((x)?6:4)
196 #define DAS16_AO_MSB(x) ((x)?7:5)
197 #define DAS16_STATUS            8
198 #define   BUSY                  (1<<7)
199 #define   UNIPOLAR                      (1<<6)
200 #define   DAS16_MUXBIT                  (1<<5)
201 #define   DAS16_INT                     (1<<4)
202 #define DAS16_CONTROL           9
203 #define   DAS16_INTE                    (1<<7)
204 #define   DAS16_IRQ(x)                  (((x) & 0x7) << 4)
205 #define   DMA_ENABLE                    (1<<2)
206 #define   PACING_MASK   0x3
207 #define   INT_PACER             0x03
208 #define   EXT_PACER                     0x02
209 #define   DAS16_SOFT            0x00
210 #define DAS16_PACER             0x0A
211 #define   DAS16_CTR0                    (1<<1)
212 #define   DAS16_TRIG0                   (1<<0)
213 #define   BURST_LEN_BITS(x)                     (((x) & 0xf) << 4)
214 #define DAS16_GAIN              0x0B
215 #define DAS16_CNTR0_DATA                0x0C
216 #define DAS16_CNTR1_DATA                0x0D
217 #define DAS16_CNTR2_DATA                0x0E
218 #define DAS16_CNTR_CONTROL      0x0F
219 #define   DAS16_TERM_CNT        0x00
220 #define   DAS16_ONE_SHOT        0x02
221 #define   DAS16_RATE_GEN        0x04
222 #define   DAS16_CNTR_LSB_MSB    0x30
223 #define   DAS16_CNTR0           0x00
224 #define   DAS16_CNTR1           0x40
225 #define   DAS16_CNTR2           0x80
226
227 #define DAS1600_CONV            0x404
228 #define   DAS1600_CONV_DISABLE          0x40
229 #define DAS1600_BURST           0x405
230 #define   DAS1600_BURST_VAL             0x40
231 #define DAS1600_ENABLE          0x406
232 #define   DAS1600_ENABLE_VAL            0x40
233 #define DAS1600_STATUS_B        0x407
234 #define   DAS1600_BME           0x40
235 #define   DAS1600_ME            0x20
236 #define   DAS1600_CD                    0x10
237 #define   DAS1600_WS                    0x02
238 #define   DAS1600_CLK_10MHZ             0x01
239
240 static const struct comedi_lrange range_das1x01_bip = { 4, {
241                         BIP_RANGE(10),
242                         BIP_RANGE(1),
243                         BIP_RANGE(0.1),
244                         BIP_RANGE(0.01),
245         }
246 };
247 static const struct comedi_lrange range_das1x01_unip = { 4, {
248                         UNI_RANGE(10),
249                         UNI_RANGE(1),
250                         UNI_RANGE(0.1),
251                         UNI_RANGE(0.01),
252         }
253 };
254 static const struct comedi_lrange range_das1x02_bip = { 4, {
255                         BIP_RANGE(10),
256                         BIP_RANGE(5),
257                         BIP_RANGE(2.5),
258                         BIP_RANGE(1.25),
259         }
260 };
261 static const struct comedi_lrange range_das1x02_unip = { 4, {
262                         UNI_RANGE(10),
263                         UNI_RANGE(5),
264                         UNI_RANGE(2.5),
265                         UNI_RANGE(1.25),
266         }
267 };
268 static const struct comedi_lrange range_das16jr = { 9, {
269                         /*  also used by 16/330 */
270                         BIP_RANGE(10),
271                         BIP_RANGE(5),
272                         BIP_RANGE(2.5),
273                         BIP_RANGE(1.25),
274                         BIP_RANGE(0.625),
275                         UNI_RANGE(10),
276                         UNI_RANGE(5),
277                         UNI_RANGE(2.5),
278                         UNI_RANGE(1.25),
279         }
280 };
281 static const struct comedi_lrange range_das16jr_16 = { 8, {
282                         BIP_RANGE(10),
283                         BIP_RANGE(5),
284                         BIP_RANGE(2.5),
285                         BIP_RANGE(1.25),
286                         UNI_RANGE(10),
287                         UNI_RANGE(5),
288                         UNI_RANGE(2.5),
289                         UNI_RANGE(1.25),
290         }
291 };
292
293 static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
294 static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
295 static const int das1600_gainlist[] = { 0, 1, 2, 3 };
296 enum {
297         das16_pg_none = 0,
298         das16_pg_16jr,
299         das16_pg_16jr_16,
300         das16_pg_1601,
301         das16_pg_1602,
302 };
303 static const int *const das16_gainlists[] = {
304         NULL,
305         das16jr_gainlist,
306         das16jr_16_gainlist,
307         das1600_gainlist,
308         das1600_gainlist,
309 };
310 static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
311         &range_unknown,
312         &range_das16jr,
313         &range_das16jr_16,
314         &range_das1x01_unip,
315         &range_das1x02_unip,
316 };
317 static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
318         &range_unknown,
319         &range_das16jr,
320         &range_das16jr_16,
321         &range_das1x01_bip,
322         &range_das1x02_bip,
323 };
324
325 struct munge_info {
326         uint8_t byte;
327         unsigned have_byte:1;
328 };
329
330 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
331         struct comedi_insn *insn, unsigned int *data);
332 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
333         struct comedi_insn *insn, unsigned int *data);
334 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
335         struct comedi_insn *insn, unsigned int *data);
336 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
337         struct comedi_insn *insn, unsigned int *data);
338
339 static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
340         struct comedi_cmd *cmd);
341 static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s);
342 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
343 static void das16_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
344         void *array, unsigned int num_bytes, unsigned int start_chan_index);
345
346 static void das16_reset(struct comedi_device *dev);
347 static irqreturn_t das16_dma_interrupt(int irq, void *d);
348 static void das16_timer_interrupt(unsigned long arg);
349 static void das16_interrupt(struct comedi_device *dev);
350
351 static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
352         int flags);
353 static int das1600_mode_detect(struct comedi_device *dev);
354 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
355         struct comedi_cmd cmd);
356
357 static void reg_dump(struct comedi_device *dev);
358
359 struct das16_board {
360         const char *name;
361         void *ai;
362         unsigned int ai_nbits;
363         unsigned int ai_speed;  /*  max conversion speed in nanosec */
364         unsigned int ai_pg;
365         void *ao;
366         unsigned int ao_nbits;
367         void *di;
368         void *do_;
369
370         unsigned int i8255_offset;
371         unsigned int i8254_offset;
372
373         unsigned int size;
374         unsigned int id;
375 };
376
377 static const struct das16_board das16_boards[] = {
378         {
379         .name = "das-16",
380         .ai = das16_ai_rinsn,
381         .ai_nbits = 12,
382         .ai_speed = 15000,
383         .ai_pg = das16_pg_none,
384         .ao = das16_ao_winsn,
385         .ao_nbits = 12,
386         .di = das16_di_rbits,
387         .do_ = das16_do_wbits,
388         .i8255_offset = 0x10,
389         .i8254_offset = 0x0c,
390         .size = 0x14,
391         .id = 0x00,
392                 },
393         {
394         .name = "das-16g",
395         .ai = das16_ai_rinsn,
396         .ai_nbits = 12,
397         .ai_speed = 15000,
398         .ai_pg = das16_pg_none,
399         .ao = das16_ao_winsn,
400         .ao_nbits = 12,
401         .di = das16_di_rbits,
402         .do_ = das16_do_wbits,
403         .i8255_offset = 0x10,
404         .i8254_offset = 0x0c,
405         .size = 0x14,
406         .id = 0x00,
407                 },
408         {
409         .name = "das-16f",
410         .ai = das16_ai_rinsn,
411         .ai_nbits = 12,
412         .ai_speed = 8500,
413         .ai_pg = das16_pg_none,
414         .ao = das16_ao_winsn,
415         .ao_nbits = 12,
416         .di = das16_di_rbits,
417         .do_ = das16_do_wbits,
418         .i8255_offset = 0x10,
419         .i8254_offset = 0x0c,
420         .size = 0x14,
421         .id = 0x00,
422                 },
423         {
424         .name = "cio-das16",    /*  cio-das16.pdf */
425         .ai = das16_ai_rinsn,
426         .ai_nbits = 12,
427         .ai_speed = 20000,
428         .ai_pg = das16_pg_none,
429         .ao = das16_ao_winsn,
430         .ao_nbits = 12,
431         .di = das16_di_rbits,
432         .do_ = das16_do_wbits,
433         .i8255_offset = 0x10,
434         .i8254_offset = 0x0c,
435         .size = 0x14,
436         .id = 0x80,
437                 },
438         {
439         .name = "cio-das16/f",  /*  das16.pdf */
440         .ai = das16_ai_rinsn,
441         .ai_nbits = 12,
442         .ai_speed = 10000,
443         .ai_pg = das16_pg_none,
444         .ao = das16_ao_winsn,
445         .ao_nbits = 12,
446         .di = das16_di_rbits,
447         .do_ = das16_do_wbits,
448         .i8255_offset = 0x10,
449         .i8254_offset = 0x0c,
450         .size = 0x14,
451         .id = 0x80,
452                 },
453         {
454         .name = "cio-das16/jr", /*  cio-das16jr.pdf */
455         .ai = das16_ai_rinsn,
456         .ai_nbits = 12,
457         .ai_speed = 7692,
458         .ai_pg = das16_pg_16jr,
459         .ao = NULL,
460         .di = das16_di_rbits,
461         .do_ = das16_do_wbits,
462         .i8255_offset = 0,
463         .i8254_offset = 0x0c,
464         .size = 0x10,
465         .id = 0x00,
466                 },
467         {
468         .name = "pc104-das16jr",        /*  pc104-das16jr_xx.pdf */
469         .ai = das16_ai_rinsn,
470         .ai_nbits = 12,
471         .ai_speed = 3300,
472         .ai_pg = das16_pg_16jr,
473         .ao = NULL,
474         .di = das16_di_rbits,
475         .do_ = das16_do_wbits,
476         .i8255_offset = 0,
477         .i8254_offset = 0x0c,
478         .size = 0x10,
479         .id = 0x00,
480                 },
481         {
482         .name = "cio-das16jr/16",       /*  cio-das16jr_16.pdf */
483         .ai = das16_ai_rinsn,
484         .ai_nbits = 16,
485         .ai_speed = 10000,
486         .ai_pg = das16_pg_16jr_16,
487         .ao = NULL,
488         .di = das16_di_rbits,
489         .do_ = das16_do_wbits,
490         .i8255_offset = 0,
491         .i8254_offset = 0x0c,
492         .size = 0x10,
493         .id = 0x00,
494                 },
495         {
496         .name = "pc104-das16jr/16",     /*  pc104-das16jr_xx.pdf */
497         .ai = das16_ai_rinsn,
498         .ai_nbits = 16,
499         .ai_speed = 10000,
500         .ai_pg = das16_pg_16jr_16,
501         .ao = NULL,
502         .di = das16_di_rbits,
503         .do_ = das16_do_wbits,
504         .i8255_offset = 0,
505         .i8254_offset = 0x0c,
506         .size = 0x10,
507         .id = 0x00,
508                 },
509         {
510         .name = "das-1201",     /*  4924.pdf (keithley user's manual) */
511         .ai = das16_ai_rinsn,
512         .ai_nbits = 12,
513         .ai_speed = 20000,
514         .ai_pg = das16_pg_none,
515         .ao = NULL,
516         .di = das16_di_rbits,
517         .do_ = das16_do_wbits,
518         .i8255_offset = 0x400,
519         .i8254_offset = 0x0c,
520         .size = 0x408,
521         .id = 0x20,
522                 },
523         {
524         .name = "das-1202",     /*  4924.pdf (keithley user's manual) */
525         .ai = das16_ai_rinsn,
526         .ai_nbits = 12,
527         .ai_speed = 10000,
528         .ai_pg = das16_pg_none,
529         .ao = NULL,
530         .di = das16_di_rbits,
531         .do_ = das16_do_wbits,
532         .i8255_offset = 0x400,
533         .i8254_offset = 0x0c,
534         .size = 0x408,
535         .id = 0x20,
536                 },
537         {
538         .name = "das-1401",     /*  4919.pdf and 4922.pdf (keithley user's manual) */
539         .ai = das16_ai_rinsn,
540         .ai_nbits = 12,
541         .ai_speed = 10000,
542         .ai_pg = das16_pg_1601,
543         .ao = NULL,
544         .di = das16_di_rbits,
545         .do_ = das16_do_wbits,
546         .i8255_offset = 0x0,
547         .i8254_offset = 0x0c,
548         .size = 0x408,
549         .id = 0xc0      /*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
550                 },
551         {
552         .name = "das-1402",     /*  4919.pdf and 4922.pdf (keithley user's manual) */
553         .ai = das16_ai_rinsn,
554         .ai_nbits = 12,
555         .ai_speed = 10000,
556         .ai_pg = das16_pg_1602,
557         .ao = NULL,
558         .di = das16_di_rbits,
559         .do_ = das16_do_wbits,
560         .i8255_offset = 0x0,
561         .i8254_offset = 0x0c,
562         .size = 0x408,
563         .id = 0xc0      /*  4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */
564                 },
565         {
566         .name = "das-1601",     /*  4919.pdf */
567         .ai = das16_ai_rinsn,
568         .ai_nbits = 12,
569         .ai_speed = 10000,
570         .ai_pg = das16_pg_1601,
571         .ao = das16_ao_winsn,
572         .ao_nbits = 12,
573         .di = das16_di_rbits,
574         .do_ = das16_do_wbits,
575         .i8255_offset = 0x400,
576         .i8254_offset = 0x0c,
577         .size = 0x408,
578         .id = 0xc0},
579         {
580         .name = "das-1602",     /*  4919.pdf */
581         .ai = das16_ai_rinsn,
582         .ai_nbits = 12,
583         .ai_speed = 10000,
584         .ai_pg = das16_pg_1602,
585         .ao = das16_ao_winsn,
586         .ao_nbits = 12,
587         .di = das16_di_rbits,
588         .do_ = das16_do_wbits,
589         .i8255_offset = 0x400,
590         .i8254_offset = 0x0c,
591         .size = 0x408,
592         .id = 0xc0},
593         {
594         .name = "cio-das1401/12",       /*  cio-das1400_series.pdf */
595         .ai = das16_ai_rinsn,
596         .ai_nbits = 12,
597         .ai_speed = 6250,
598         .ai_pg = das16_pg_1601,
599         .ao = NULL,
600         .di = das16_di_rbits,
601         .do_ = das16_do_wbits,
602         .i8255_offset = 0,
603         .i8254_offset = 0x0c,
604         .size = 0x408,
605         .id = 0xc0},
606         {
607         .name = "cio-das1402/12",       /*  cio-das1400_series.pdf */
608         .ai = das16_ai_rinsn,
609         .ai_nbits = 12,
610         .ai_speed = 6250,
611         .ai_pg = das16_pg_1602,
612         .ao = NULL,
613         .di = das16_di_rbits,
614         .do_ = das16_do_wbits,
615         .i8255_offset = 0,
616         .i8254_offset = 0x0c,
617         .size = 0x408,
618         .id = 0xc0},
619         {
620         .name = "cio-das1402/16",       /*  cio-das1400_series.pdf */
621         .ai = das16_ai_rinsn,
622         .ai_nbits = 16,
623         .ai_speed = 10000,
624         .ai_pg = das16_pg_1602,
625         .ao = NULL,
626         .di = das16_di_rbits,
627         .do_ = das16_do_wbits,
628         .i8255_offset = 0,
629         .i8254_offset = 0x0c,
630         .size = 0x408,
631         .id = 0xc0},
632         {
633         .name = "cio-das1601/12",       /*  cio-das160x-1x.pdf */
634         .ai = das16_ai_rinsn,
635         .ai_nbits = 12,
636         .ai_speed = 6250,
637         .ai_pg = das16_pg_1601,
638         .ao = das16_ao_winsn,
639         .ao_nbits = 12,
640         .di = das16_di_rbits,
641         .do_ = das16_do_wbits,
642         .i8255_offset = 0x400,
643         .i8254_offset = 0x0c,
644         .size = 0x408,
645         .id = 0xc0},
646         {
647         .name = "cio-das1602/12",       /*  cio-das160x-1x.pdf */
648         .ai = das16_ai_rinsn,
649         .ai_nbits = 12,
650         .ai_speed = 10000,
651         .ai_pg = das16_pg_1602,
652         .ao = das16_ao_winsn,
653         .ao_nbits = 12,
654         .di = das16_di_rbits,
655         .do_ = das16_do_wbits,
656         .i8255_offset = 0x400,
657         .i8254_offset = 0x0c,
658         .size = 0x408,
659         .id = 0xc0},
660         {
661         .name = "cio-das1602/16",       /*  cio-das160x-1x.pdf */
662         .ai = das16_ai_rinsn,
663         .ai_nbits = 16,
664         .ai_speed = 10000,
665         .ai_pg = das16_pg_1602,
666         .ao = das16_ao_winsn,
667         .ao_nbits = 12,
668         .di = das16_di_rbits,
669         .do_ = das16_do_wbits,
670         .i8255_offset = 0x400,
671         .i8254_offset = 0x0c,
672         .size = 0x408,
673         .id = 0xc0},
674         {
675         .name = "cio-das16/330",        /*  ? */
676         .ai = das16_ai_rinsn,
677         .ai_nbits = 12,
678         .ai_speed = 3030,
679         .ai_pg = das16_pg_16jr,
680         .ao = NULL,
681         .di = das16_di_rbits,
682         .do_ = das16_do_wbits,
683         .i8255_offset = 0,
684         .i8254_offset = 0x0c,
685         .size = 0x14,
686         .id = 0xf0},
687 #if 0
688         {
689         .name = "das16/330i",   /*  ? */
690                 },
691         {
692         .name = "das16/jr/ctr5",        /*  ? */
693                 },
694         {
695         .name = "cio-das16/m1/16",      /*  cio-das16_m1_16.pdf, this board is a bit quirky, no dma */
696                 },
697 #endif
698 };
699
700 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it);
701 static int das16_detach(struct comedi_device *dev);
702 static struct comedi_driver driver_das16 = {
703         .driver_name = "das16",
704         .module = THIS_MODULE,
705         .attach = das16_attach,
706         .detach = das16_detach,
707         .board_name = &das16_boards[0].name,
708         .num_names = ARRAY_SIZE(das16_boards),
709         .offset = sizeof(das16_boards[0]),
710 };
711
712 #define DAS16_TIMEOUT 1000
713
714 /* Period for timer interrupt in jiffies.  It's a function
715  * to deal with possibility of dynamic HZ patches  */
716 static inline int timer_period(void)
717 {
718         return HZ / 20;
719 }
720 struct das16_private_struct {
721         unsigned int ai_unipolar;       /*  unipolar flag */
722         unsigned int ai_singleended;    /*  single ended flag */
723         unsigned int clockbase; /*  master clock speed in ns */
724         volatile unsigned int control_state;    /*  dma, interrupt and trigger control bits */
725         volatile unsigned long adc_byte_count;  /*  number of bytes remaining */
726         unsigned int divisor1;  /*  divisor dividing master clock to get conversion frequency */
727         unsigned int divisor2;  /*  divisor dividing master clock to get conversion frequency */
728         unsigned int dma_chan;  /*  dma channel */
729         uint16_t *dma_buffer[2];
730         dma_addr_t dma_buffer_addr[2];
731         unsigned int current_buffer;
732         volatile unsigned int dma_transfer_size;        /*  target number of bytes to transfer per dma shot */
733         /*  user-defined analog input and output ranges defined from config options */
734         struct comedi_lrange *user_ai_range_table;
735         struct comedi_lrange *user_ao_range_table;
736
737         struct timer_list timer;        /*  for timed interrupt */
738         volatile short timer_running;
739         volatile short timer_mode;      /*  true if using timer mode */
740 };
741 #define devpriv ((struct das16_private_struct *)(dev->private))
742 #define thisboard ((struct das16_board *)(dev->board_ptr))
743
744 static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
745         struct comedi_cmd *cmd)
746 {
747         int err = 0, tmp;
748         int gain, start_chan, i;
749         int mask;
750
751         /* make sure triggers are valid */
752         tmp = cmd->start_src;
753         cmd->start_src &= TRIG_NOW;
754         if (!cmd->start_src || tmp != cmd->start_src)
755                 err++;
756
757         tmp = cmd->scan_begin_src;
758         mask = TRIG_FOLLOW;
759         /*  if board supports burst mode */
760         if (thisboard->size > 0x400)
761                 mask |= TRIG_TIMER | TRIG_EXT;
762         cmd->scan_begin_src &= mask;
763         if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
764                 err++;
765
766         tmp = cmd->convert_src;
767         mask = TRIG_TIMER | TRIG_EXT;
768         /*  if board supports burst mode */
769         if (thisboard->size > 0x400)
770                 mask |= TRIG_NOW;
771         cmd->convert_src &= mask;
772         if (!cmd->convert_src || tmp != cmd->convert_src)
773                 err++;
774
775         tmp = cmd->scan_end_src;
776         cmd->scan_end_src &= TRIG_COUNT;
777         if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
778                 err++;
779
780         tmp = cmd->stop_src;
781         cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
782         if (!cmd->stop_src || tmp != cmd->stop_src)
783                 err++;
784
785         if (err)
786                 return 1;
787
788         /* step 2: make sure trigger sources are unique and mutually compatible */
789         if (cmd->scan_begin_src != TRIG_TIMER &&
790                 cmd->scan_begin_src != TRIG_EXT &&
791                 cmd->scan_begin_src != TRIG_FOLLOW)
792                 err++;
793         if (cmd->convert_src != TRIG_TIMER &&
794                 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
795                 err++;
796         if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
797                 err++;
798
799         /*  make sure scan_begin_src and convert_src dont conflict */
800         if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
801                 err++;
802         if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
803                 err++;
804
805         if (err)
806                 return 2;
807
808         /* step 3: make sure arguments are trivially compatible */
809         if (cmd->start_arg != 0) {
810                 cmd->start_arg = 0;
811                 err++;
812         }
813
814         if (cmd->scan_begin_src == TRIG_FOLLOW) {
815                 /* internal trigger */
816                 if (cmd->scan_begin_arg != 0) {
817                         cmd->scan_begin_arg = 0;
818                         err++;
819                 }
820         }
821
822         if (cmd->scan_end_arg != cmd->chanlist_len) {
823                 cmd->scan_end_arg = cmd->chanlist_len;
824                 err++;
825         }
826         /*  check against maximum frequency */
827         if (cmd->scan_begin_src == TRIG_TIMER) {
828                 if (cmd->scan_begin_arg <
829                         thisboard->ai_speed * cmd->chanlist_len) {
830                         cmd->scan_begin_arg =
831                                 thisboard->ai_speed * cmd->chanlist_len;
832                         err++;
833                 }
834         }
835         if (cmd->convert_src == TRIG_TIMER) {
836                 if (cmd->convert_arg < thisboard->ai_speed) {
837                         cmd->convert_arg = thisboard->ai_speed;
838                         err++;
839                 }
840         }
841
842         if (cmd->stop_src == TRIG_NONE) {
843                 if (cmd->stop_arg != 0) {
844                         cmd->stop_arg = 0;
845                         err++;
846                 }
847         }
848         if (err)
849                 return 3;
850
851         /*  step 4: fix up arguments */
852         if (cmd->scan_begin_src == TRIG_TIMER) {
853                 unsigned int tmp = cmd->scan_begin_arg;
854                 /*  set divisors, correct timing arguments */
855                 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
856                         &(devpriv->divisor1), &(devpriv->divisor2),
857                         &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
858                 err += (tmp != cmd->scan_begin_arg);
859         }
860         if (cmd->convert_src == TRIG_TIMER) {
861                 unsigned int tmp = cmd->convert_arg;
862                 /*  set divisors, correct timing arguments */
863                 i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
864                         &(devpriv->divisor1), &(devpriv->divisor2),
865                         &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
866                 err += (tmp != cmd->convert_arg);
867         }
868         if (err)
869                 return 4;
870
871         /*  check channel/gain list against card's limitations */
872         if (cmd->chanlist) {
873                 gain = CR_RANGE(cmd->chanlist[0]);
874                 start_chan = CR_CHAN(cmd->chanlist[0]);
875                 for (i = 1; i < cmd->chanlist_len; i++) {
876                         if (CR_CHAN(cmd->chanlist[i]) !=
877                                 (start_chan + i) % s->n_chan) {
878                                 comedi_error(dev,
879                                         "entries in chanlist must be consecutive channels, counting upwards\n");
880                                 err++;
881                         }
882                         if (CR_RANGE(cmd->chanlist[i]) != gain) {
883                                 comedi_error(dev,
884                                         "entries in chanlist must all have the same gain\n");
885                                 err++;
886                         }
887                 }
888         }
889         if (err)
890                 return 5;
891
892         return 0;
893 }
894
895 static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s)
896 {
897         struct comedi_async *async = s->async;
898         struct comedi_cmd *cmd = &async->cmd;
899         unsigned int byte;
900         unsigned long flags;
901         int range;
902
903         if (devpriv->dma_chan == 0 || (dev->irq == 0
904                         && devpriv->timer_mode == 0)) {
905                 comedi_error(dev,
906                         "irq (or use of 'timer mode') dma required to execute comedi_cmd");
907                 return -1;
908         }
909         if (cmd->flags & TRIG_RT) {
910                 comedi_error(dev,
911                         "isa dma transfers cannot be performed with TRIG_RT, aborting");
912                 return -1;
913         }
914
915         devpriv->adc_byte_count =
916                 cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
917
918         /*  disable conversions for das1600 mode */
919         if (thisboard->size > 0x400) {
920                 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
921         }
922         /*  set scan limits */
923         byte = CR_CHAN(cmd->chanlist[0]);
924         byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
925         outb(byte, dev->iobase + DAS16_MUX);
926
927         /* set gain (this is also burst rate register but according to
928          * computer boards manual, burst rate does nothing, even on keithley cards) */
929         if (thisboard->ai_pg != das16_pg_none) {
930                 range = CR_RANGE(cmd->chanlist[0]);
931                 outb((das16_gainlists[thisboard->ai_pg])[range],
932                         dev->iobase + DAS16_GAIN);
933         }
934
935         /* set counter mode and counts */
936         cmd->convert_arg =
937                 das16_set_pacer(dev, cmd->convert_arg,
938                 cmd->flags & TRIG_ROUND_MASK);
939         DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
940
941         /* enable counters */
942         byte = 0;
943         /* Enable burst mode if appropriate. */
944         if (thisboard->size > 0x400) {
945                 if (cmd->convert_src == TRIG_NOW) {
946                         outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
947                         /*  set burst length */
948                         byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
949                 } else {
950                         outb(0, dev->iobase + DAS1600_BURST);
951                 }
952         }
953         outb(byte, dev->iobase + DAS16_PACER);
954
955         /*  set up dma transfer */
956         flags = claim_dma_lock();
957         disable_dma(devpriv->dma_chan);
958         /* clear flip-flop to make sure 2-byte registers for
959          * count and address get set correctly */
960         clear_dma_ff(devpriv->dma_chan);
961         devpriv->current_buffer = 0;
962         set_dma_addr(devpriv->dma_chan,
963                 devpriv->dma_buffer_addr[devpriv->current_buffer]);
964         /*  set appropriate size of transfer */
965         devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
966         set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
967         enable_dma(devpriv->dma_chan);
968         release_dma_lock(flags);
969
970         /*  set up interrupt */
971         if (devpriv->timer_mode) {
972                 devpriv->timer_running = 1;
973                 devpriv->timer.expires = jiffies + timer_period();
974                 add_timer(&devpriv->timer);
975                 devpriv->control_state &= ~DAS16_INTE;
976         } else {
977                 /* clear interrupt bit */
978                 outb(0x00, dev->iobase + DAS16_STATUS);
979                 /* enable interrupts */
980                 devpriv->control_state |= DAS16_INTE;
981         }
982         devpriv->control_state |= DMA_ENABLE;
983         devpriv->control_state &= ~PACING_MASK;
984         if (cmd->convert_src == TRIG_EXT)
985                 devpriv->control_state |= EXT_PACER;
986         else
987                 devpriv->control_state |= INT_PACER;
988         outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
989
990         /* Enable conversions if using das1600 mode */
991         if (thisboard->size > 0x400) {
992                 outb(0, dev->iobase + DAS1600_CONV);
993         }
994
995         return 0;
996 }
997
998 static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
999 {
1000         unsigned long flags;
1001
1002         spin_lock_irqsave(&dev->spinlock, flags);
1003         /* disable interrupts, dma and pacer clocked conversions */
1004         devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
1005         outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1006         if (devpriv->dma_chan)
1007                 disable_dma(devpriv->dma_chan);
1008
1009         /*  disable SW timer */
1010         if (devpriv->timer_mode && devpriv->timer_running) {
1011                 devpriv->timer_running = 0;
1012                 del_timer(&devpriv->timer);
1013         }
1014
1015         /* disable burst mode */
1016         if (thisboard->size > 0x400) {
1017                 outb(0, dev->iobase + DAS1600_BURST);
1018         }
1019
1020         spin_unlock_irqrestore(&dev->spinlock, flags);
1021
1022         return 0;
1023 }
1024
1025 static void das16_reset(struct comedi_device *dev)
1026 {
1027         outb(0, dev->iobase + DAS16_STATUS);
1028         outb(0, dev->iobase + DAS16_CONTROL);
1029         outb(0, dev->iobase + DAS16_PACER);
1030         outb(0, dev->iobase + DAS16_CNTR_CONTROL);
1031 }
1032
1033 static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
1034         struct comedi_insn *insn, unsigned int *data)
1035 {
1036         int i, n;
1037         int range;
1038         int chan;
1039         int msb, lsb;
1040
1041         /*  disable interrupts and pacing */
1042         devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
1043         outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1044
1045         /* set multiplexer */
1046         chan = CR_CHAN(insn->chanspec);
1047         chan |= CR_CHAN(insn->chanspec) << 4;
1048         outb(chan, dev->iobase + DAS16_MUX);
1049
1050         /* set gain */
1051         if (thisboard->ai_pg != das16_pg_none) {
1052                 range = CR_RANGE(insn->chanspec);
1053                 outb((das16_gainlists[thisboard->ai_pg])[range],
1054                         dev->iobase + DAS16_GAIN);
1055         }
1056
1057         for (n = 0; n < insn->n; n++) {
1058                 /* trigger conversion */
1059                 outb_p(0, dev->iobase + DAS16_TRIG);
1060
1061                 for (i = 0; i < DAS16_TIMEOUT; i++) {
1062                         if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
1063                                 break;
1064                 }
1065                 if (i == DAS16_TIMEOUT) {
1066                         printk("das16: timeout\n");
1067                         return -ETIME;
1068                 }
1069                 msb = inb(dev->iobase + DAS16_AI_MSB);
1070                 lsb = inb(dev->iobase + DAS16_AI_LSB);
1071                 if (thisboard->ai_nbits == 12) {
1072                         data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
1073                 } else {
1074                         data[n] = lsb | (msb << 8);
1075                 }
1076         }
1077
1078         return n;
1079 }
1080
1081 static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s,
1082         struct comedi_insn *insn, unsigned int *data)
1083 {
1084         unsigned int bits;
1085
1086         bits = inb(dev->iobase + DAS16_DIO) & 0xf;
1087         data[1] = bits;
1088         data[0] = 0;
1089
1090         return 2;
1091 }
1092
1093 static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s,
1094         struct comedi_insn *insn, unsigned int *data)
1095 {
1096         unsigned int wbits;
1097
1098         /*  only set bits that have been masked */
1099         data[0] &= 0xf;
1100         wbits = s->state;
1101         /*  zero bits that have been masked */
1102         wbits &= ~data[0];
1103         /*  set masked bits */
1104         wbits |= data[0] & data[1];
1105         s->state = wbits;
1106         data[1] = wbits;
1107
1108         outb(s->state, dev->iobase + DAS16_DIO);
1109
1110         return 2;
1111 }
1112
1113 static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
1114         struct comedi_insn *insn, unsigned int *data)
1115 {
1116         int i;
1117         int lsb, msb;
1118         int chan;
1119
1120         chan = CR_CHAN(insn->chanspec);
1121
1122         for (i = 0; i < insn->n; i++) {
1123                 if (thisboard->ao_nbits == 12) {
1124                         lsb = (data[i] << 4) & 0xff;
1125                         msb = (data[i] >> 4) & 0xff;
1126                 } else {
1127                         lsb = data[i] & 0xff;
1128                         msb = (data[i] >> 8) & 0xff;
1129                 }
1130                 outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
1131                 outb(msb, dev->iobase + DAS16_AO_MSB(chan));
1132         }
1133
1134         return i;
1135 }
1136
1137 static irqreturn_t das16_dma_interrupt(int irq, void *d)
1138 {
1139         int status;
1140         struct comedi_device *dev = d;
1141
1142         status = inb(dev->iobase + DAS16_STATUS);
1143
1144         if ((status & DAS16_INT) == 0) {
1145                 DEBUG_PRINT("spurious interrupt\n");
1146                 return IRQ_NONE;
1147         }
1148
1149         /* clear interrupt */
1150         outb(0x00, dev->iobase + DAS16_STATUS);
1151         das16_interrupt(dev);
1152         return IRQ_HANDLED;
1153 }
1154
1155 static void das16_timer_interrupt(unsigned long arg)
1156 {
1157         struct comedi_device *dev = (struct comedi_device *) arg;
1158
1159         das16_interrupt(dev);
1160
1161         if (devpriv->timer_running)
1162                 mod_timer(&devpriv->timer, jiffies + timer_period());
1163 }
1164
1165 /* the pc104-das16jr (at least) has problems if the dma
1166         transfer is interrupted in the middle of transferring
1167         a 16 bit sample, so this function takes care to get
1168         an even transfer count after disabling dma
1169         channel.
1170 */
1171 static int disable_dma_on_even(struct comedi_device *dev)
1172 {
1173         int residue;
1174         int i;
1175         static const int disable_limit = 100;
1176         static const int enable_timeout = 100;
1177         disable_dma(devpriv->dma_chan);
1178         residue = get_dma_residue(devpriv->dma_chan);
1179         for (i = 0; i < disable_limit && (residue % 2); ++i) {
1180                 int j;
1181                 enable_dma(devpriv->dma_chan);
1182                 for (j = 0; j < enable_timeout; ++j) {
1183                         int new_residue;
1184                         udelay(2);
1185                         new_residue = get_dma_residue(devpriv->dma_chan);
1186                         if (new_residue != residue)
1187                                 break;
1188                 }
1189                 disable_dma(devpriv->dma_chan);
1190                 residue = get_dma_residue(devpriv->dma_chan);
1191         }
1192         if (i == disable_limit) {
1193                 comedi_error(dev,
1194                         "failed to get an even dma transfer, could be trouble.");
1195         }
1196         return residue;
1197 }
1198
1199 static void das16_interrupt(struct comedi_device *dev)
1200 {
1201         unsigned long dma_flags, spin_flags;
1202         struct comedi_subdevice *s = dev->read_subdev;
1203         struct comedi_async *async;
1204         struct comedi_cmd *cmd;
1205         int num_bytes, residue;
1206         int buffer_index;
1207
1208         if (dev->attached == 0) {
1209                 comedi_error(dev, "premature interrupt");
1210                 return;
1211         }
1212         /*  initialize async here to make sure it is not NULL */
1213         async = s->async;
1214         cmd = &async->cmd;
1215
1216         if (devpriv->dma_chan == 0) {
1217                 comedi_error(dev, "interrupt with no dma channel?");
1218                 return;
1219         }
1220
1221         spin_lock_irqsave(&dev->spinlock, spin_flags);
1222         if ((devpriv->control_state & DMA_ENABLE) == 0) {
1223                 spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1224                 DEBUG_PRINT("interrupt while dma disabled?\n");
1225                 return;
1226         }
1227
1228         dma_flags = claim_dma_lock();
1229         clear_dma_ff(devpriv->dma_chan);
1230         residue = disable_dma_on_even(dev);
1231
1232         /*  figure out how many points to read */
1233         if (residue > devpriv->dma_transfer_size) {
1234                 comedi_error(dev, "residue > transfer size!\n");
1235                 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1236                 num_bytes = 0;
1237         } else
1238                 num_bytes = devpriv->dma_transfer_size - residue;
1239
1240         if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) {
1241                 num_bytes = devpriv->adc_byte_count;
1242                 async->events |= COMEDI_CB_EOA;
1243         }
1244
1245         buffer_index = devpriv->current_buffer;
1246         devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
1247         devpriv->adc_byte_count -= num_bytes;
1248
1249         /*  figure out how many bytes for next transfer */
1250         if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
1251                 devpriv->dma_transfer_size > devpriv->adc_byte_count)
1252                 devpriv->dma_transfer_size = devpriv->adc_byte_count;
1253
1254         /*  re-enable  dma */
1255         if ((async->events & COMEDI_CB_EOA) == 0) {
1256                 set_dma_addr(devpriv->dma_chan,
1257                         devpriv->dma_buffer_addr[devpriv->current_buffer]);
1258                 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
1259                 enable_dma(devpriv->dma_chan);
1260                 /* reenable conversions for das1600 mode, (stupid hardware) */
1261                 if (thisboard->size > 0x400 && devpriv->timer_mode == 0) {
1262                         outb(0x00, dev->iobase + DAS1600_CONV);
1263                 }
1264         }
1265         release_dma_lock(dma_flags);
1266
1267         spin_unlock_irqrestore(&dev->spinlock, spin_flags);
1268
1269         cfc_write_array_to_buffer(s,
1270                 devpriv->dma_buffer[buffer_index], num_bytes);
1271
1272         cfc_handle_events(dev, s);
1273 }
1274
1275 static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns,
1276         int rounding_flags)
1277 {
1278         i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
1279                 &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
1280
1281         /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
1282         i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
1283         i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
1284
1285         return ns;
1286 }
1287
1288 static void reg_dump(struct comedi_device *dev)
1289 {
1290         DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
1291         DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
1292         DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
1293         DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
1294         DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
1295         DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
1296         DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
1297         DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
1298                 inb(dev->iobase + DAS16_CNTR_CONTROL));
1299         DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
1300         DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
1301         DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
1302         DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
1303                 inb(dev->iobase + DAS1600_STATUS_B));
1304 }
1305
1306 static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it)
1307 {
1308         int status;
1309         int diobits;
1310
1311         /* status is available on all boards */
1312
1313         status = inb(dev->iobase + DAS16_STATUS);
1314
1315         if ((status & UNIPOLAR)) {
1316                 devpriv->ai_unipolar = 1;
1317         } else {
1318                 devpriv->ai_unipolar = 0;
1319         }
1320
1321         if ((status & DAS16_MUXBIT)) {
1322                 devpriv->ai_singleended = 1;
1323         } else {
1324                 devpriv->ai_singleended = 0;
1325         }
1326
1327         /* diobits indicates boards */
1328
1329         diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
1330
1331         printk(" id bits are 0x%02x\n", diobits);
1332         if (thisboard->id != diobits) {
1333                 printk(" requested board's id bits are 0x%x (ignore)\n",
1334                         thisboard->id);
1335         }
1336
1337         return 0;
1338 }
1339
1340 static int das1600_mode_detect(struct comedi_device *dev)
1341 {
1342         int status = 0;
1343
1344         status = inb(dev->iobase + DAS1600_STATUS_B);
1345
1346         if (status & DAS1600_CLK_10MHZ) {
1347                 devpriv->clockbase = 100;
1348                 printk(" 10MHz pacer clock\n");
1349         } else {
1350                 devpriv->clockbase = 1000;
1351                 printk(" 1MHz pacer clock\n");
1352         }
1353
1354         reg_dump(dev);
1355
1356         return 0;
1357 }
1358
1359 /*
1360  *
1361  * Options list:
1362  *   0  I/O base
1363  *   1  IRQ
1364  *   2  DMA
1365  *   3  Clock speed (in MHz)
1366  */
1367
1368 static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1369 {
1370         struct comedi_subdevice *s;
1371         int ret;
1372         unsigned int irq;
1373         unsigned long iobase;
1374         unsigned int dma_chan;
1375         int timer_mode;
1376         unsigned long flags;
1377         struct comedi_krange *user_ai_range, *user_ao_range;
1378
1379         iobase = it->options[0];
1380 #if 0
1381         irq = it->options[1];
1382         timer_mode = it->options[8];
1383 #endif
1384         /* always use time_mode since using irq can drop samples while
1385          * waiting for dma done interrupt (due to hardware limitations) */
1386         irq = 0;
1387         timer_mode = 1;
1388         if (timer_mode)
1389                 irq = 0;
1390
1391         printk("comedi%d: das16:", dev->minor);
1392
1393         /*  check that clock setting is valid */
1394         if (it->options[3]) {
1395                 if (it->options[3] != 0 &&
1396                         it->options[3] != 1 && it->options[3] != 10) {
1397                         printk("\n Invalid option.  Master clock must be set to 1 or 10 (MHz)\n");
1398                         return -EINVAL;
1399                 }
1400         }
1401
1402         ret = alloc_private(dev, sizeof(struct das16_private_struct));
1403         if (ret < 0)
1404                 return ret;
1405
1406         if (thisboard->size < 0x400) {
1407                 printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
1408                 if (!request_region(iobase, thisboard->size, "das16")) {
1409                         printk(" I/O port conflict\n");
1410                         return -EIO;
1411                 }
1412         } else {
1413                 printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
1414                         iobase, iobase + 0x0f,
1415                         iobase + 0x400,
1416                         iobase + 0x400 + (thisboard->size & 0x3ff));
1417                 if (!request_region(iobase, 0x10, "das16")) {
1418                         printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
1419                                 iobase, iobase + 0x0f);
1420                         return -EIO;
1421                 }
1422                 if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
1423                                 "das16")) {
1424                         release_region(iobase, 0x10);
1425                         printk(" I/O port conflict:  0x%04lx-0x%04lx\n",
1426                                 iobase + 0x400,
1427                                 iobase + 0x400 + (thisboard->size & 0x3ff));
1428                         return -EIO;
1429                 }
1430         }
1431
1432         dev->iobase = iobase;
1433
1434         /*  probe id bits to make sure they are consistent */
1435         if (das16_probe(dev, it)) {
1436                 printk(" id bits do not match selected board, aborting\n");
1437                 return -EINVAL;
1438         }
1439         dev->board_name = thisboard->name;
1440
1441         /*  get master clock speed */
1442         if (thisboard->size < 0x400) {
1443                 if (it->options[3])
1444                         devpriv->clockbase = 1000 / it->options[3];
1445                 else
1446                         devpriv->clockbase = 1000;      /*  1 MHz default */
1447         } else {
1448                 das1600_mode_detect(dev);
1449         }
1450
1451         /* now for the irq */
1452         if (irq > 1 && irq < 8) {
1453                 ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev);
1454
1455                 if (ret < 0)
1456                         return ret;
1457                 dev->irq = irq;
1458                 printk(" ( irq = %u )", irq);
1459         } else if (irq == 0) {
1460                 printk(" ( no irq )");
1461         } else {
1462                 printk(" invalid irq\n");
1463                 return -EINVAL;
1464         }
1465
1466         /*  initialize dma */
1467         dma_chan = it->options[2];
1468         if (dma_chan == 1 || dma_chan == 3) {
1469                 /*  allocate dma buffers */
1470                 int i;
1471                 for (i = 0; i < 2; i++) {
1472                         devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
1473                                 DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
1474                         if (devpriv->dma_buffer[i] == NULL)
1475                                 return -ENOMEM;
1476                 }
1477                 if (request_dma(dma_chan, "das16")) {
1478                         printk(" failed to allocate dma channel %i\n",
1479                                 dma_chan);
1480                         return -EINVAL;
1481                 }
1482                 devpriv->dma_chan = dma_chan;
1483                 flags = claim_dma_lock();
1484                 disable_dma(devpriv->dma_chan);
1485                 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
1486                 release_dma_lock(flags);
1487                 printk(" ( dma = %u)\n", dma_chan);
1488         } else if (dma_chan == 0) {
1489                 printk(" ( no dma )\n");
1490         } else {
1491                 printk(" invalid dma channel\n");
1492                 return -EINVAL;
1493         }
1494
1495         /*  get any user-defined input range */
1496         if (thisboard->ai_pg == das16_pg_none &&
1497                 (it->options[4] || it->options[5])) {
1498                 /*  allocate single-range range table */
1499                 devpriv->user_ai_range_table =
1500                         kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
1501                         GFP_KERNEL);
1502                 /*  initialize ai range */
1503                 devpriv->user_ai_range_table->length = 1;
1504                 user_ai_range = devpriv->user_ai_range_table->range;
1505                 user_ai_range->min = it->options[4];
1506                 user_ai_range->max = it->options[5];
1507                 user_ai_range->flags = UNIT_volt;
1508         }
1509         /*  get any user-defined output range */
1510         if (it->options[6] || it->options[7]) {
1511                 /*  allocate single-range range table */
1512                 devpriv->user_ao_range_table =
1513                         kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
1514                         GFP_KERNEL);
1515                 /*  initialize ao range */
1516                 devpriv->user_ao_range_table->length = 1;
1517                 user_ao_range = devpriv->user_ao_range_table->range;
1518                 user_ao_range->min = it->options[6];
1519                 user_ao_range->max = it->options[7];
1520                 user_ao_range->flags = UNIT_volt;
1521         }
1522
1523         if (timer_mode) {
1524                 init_timer(&(devpriv->timer));
1525                 devpriv->timer.function = das16_timer_interrupt;
1526                 devpriv->timer.data = (unsigned long)dev;
1527         }
1528         devpriv->timer_mode = timer_mode ? 1 : 0;
1529
1530         ret = alloc_subdevices(dev, 5);
1531         if (ret < 0)
1532                 return ret;
1533
1534         s = dev->subdevices + 0;
1535         dev->read_subdev = s;
1536         /* ai */
1537         if (thisboard->ai) {
1538                 s->type = COMEDI_SUBD_AI;
1539                 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1540                 if (devpriv->ai_singleended) {
1541                         s->n_chan = 16;
1542                         s->len_chanlist = 16;
1543                         s->subdev_flags |= SDF_GROUND;
1544                 } else {
1545                         s->n_chan = 8;
1546                         s->len_chanlist = 8;
1547                         s->subdev_flags |= SDF_DIFF;
1548                 }
1549                 s->maxdata = (1 << thisboard->ai_nbits) - 1;
1550                 if (devpriv->user_ai_range_table) {     /*  user defined ai range */
1551                         s->range_table = devpriv->user_ai_range_table;
1552                 } else if (devpriv->ai_unipolar) {
1553                         s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
1554                 } else {
1555                         s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
1556                 }
1557                 s->insn_read = thisboard->ai;
1558                 s->do_cmdtest = das16_cmd_test;
1559                 s->do_cmd = das16_cmd_exec;
1560                 s->cancel = das16_cancel;
1561                 s->munge = das16_ai_munge;
1562         } else {
1563                 s->type = COMEDI_SUBD_UNUSED;
1564         }
1565
1566         s = dev->subdevices + 1;
1567         /* ao */
1568         if (thisboard->ao) {
1569                 s->type = COMEDI_SUBD_AO;
1570                 s->subdev_flags = SDF_WRITABLE;
1571                 s->n_chan = 2;
1572                 s->maxdata = (1 << thisboard->ao_nbits) - 1;
1573                 if (devpriv->user_ao_range_table) {     /*  user defined ao range */
1574                         s->range_table = devpriv->user_ao_range_table;
1575                 } else {
1576                         s->range_table = &range_unknown;
1577                 }
1578                 s->insn_write = thisboard->ao;
1579         } else {
1580                 s->type = COMEDI_SUBD_UNUSED;
1581         }
1582
1583         s = dev->subdevices + 2;
1584         /* di */
1585         if (thisboard->di) {
1586                 s->type = COMEDI_SUBD_DI;
1587                 s->subdev_flags = SDF_READABLE;
1588                 s->n_chan = 4;
1589                 s->maxdata = 1;
1590                 s->range_table = &range_digital;
1591                 s->insn_bits = thisboard->di;
1592         } else {
1593                 s->type = COMEDI_SUBD_UNUSED;
1594         }
1595
1596         s = dev->subdevices + 3;
1597         /* do */
1598         if (thisboard->do_) {
1599                 s->type = COMEDI_SUBD_DO;
1600                 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1601                 s->n_chan = 4;
1602                 s->maxdata = 1;
1603                 s->range_table = &range_digital;
1604                 s->insn_bits = thisboard->do_;
1605                 /*  initialize digital output lines */
1606                 outb(s->state, dev->iobase + DAS16_DIO);
1607         } else {
1608                 s->type = COMEDI_SUBD_UNUSED;
1609         }
1610
1611         s = dev->subdevices + 4;
1612         /* 8255 */
1613         if (thisboard->i8255_offset != 0) {
1614                 subdev_8255_init(dev, s, NULL, (dev->iobase +
1615                                 thisboard->i8255_offset));
1616         } else {
1617                 s->type = COMEDI_SUBD_UNUSED;
1618         }
1619
1620         das16_reset(dev);
1621         /* set the interrupt level */
1622         devpriv->control_state = DAS16_IRQ(dev->irq);
1623         outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
1624
1625         /*  turn on das1600 mode if available */
1626         if (thisboard->size > 0x400) {
1627                 outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
1628                 outb(0, dev->iobase + DAS1600_CONV);
1629                 outb(0, dev->iobase + DAS1600_BURST);
1630         }
1631
1632         return 0;
1633 }
1634
1635 static int das16_detach(struct comedi_device *dev)
1636 {
1637         printk("comedi%d: das16: remove\n", dev->minor);
1638
1639         das16_reset(dev);
1640
1641         if (dev->subdevices)
1642                 subdev_8255_cleanup(dev, dev->subdevices + 4);
1643
1644         if (devpriv) {
1645                 int i;
1646                 for (i = 0; i < 2; i++) {
1647                         if (devpriv->dma_buffer[i])
1648                                 pci_free_consistent(NULL, DAS16_DMA_SIZE,
1649                                         devpriv->dma_buffer[i],
1650                                         devpriv->dma_buffer_addr[i]);
1651                 }
1652                 if (devpriv->dma_chan)
1653                         free_dma(devpriv->dma_chan);
1654                 if (devpriv->user_ai_range_table)
1655                         kfree(devpriv->user_ai_range_table);
1656                 if (devpriv->user_ao_range_table)
1657                         kfree(devpriv->user_ao_range_table);
1658         }
1659
1660         if (dev->irq)
1661                 free_irq(dev->irq, dev);
1662
1663         if (dev->iobase) {
1664                 if (thisboard->size < 0x400) {
1665                         release_region(dev->iobase, thisboard->size);
1666                 } else {
1667                         release_region(dev->iobase, 0x10);
1668                         release_region(dev->iobase + 0x400,
1669                                 thisboard->size & 0x3ff);
1670                 }
1671         }
1672
1673         return 0;
1674 }
1675
1676 COMEDI_INITCLEANUP(driver_das16);
1677
1678 /* utility function that suggests a dma transfer size in bytes */
1679 static unsigned int das16_suggest_transfer_size(struct comedi_device *dev,
1680         struct comedi_cmd cmd)
1681 {
1682         unsigned int size;
1683         unsigned int freq;
1684
1685         /* if we are using timer interrupt, we don't care how long it
1686          * will take to complete transfer since it will be interrupted
1687          * by timer interrupt */
1688         if (devpriv->timer_mode)
1689                 return DAS16_DMA_SIZE;
1690
1691         /* otherwise, we are relying on dma terminal count interrupt,
1692          * so pick a reasonable size */
1693         if (cmd.convert_src == TRIG_TIMER)
1694                 freq = 1000000000 / cmd.convert_arg;
1695         else if (cmd.scan_begin_src == TRIG_TIMER)
1696                 freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
1697         /*  return some default value */
1698         else
1699                 freq = 0xffffffff;
1700
1701         if (cmd.flags & TRIG_WAKE_EOS) {
1702                 size = sample_size * cmd.chanlist_len;
1703         } else {
1704                 /*  make buffer fill in no more than 1/3 second */
1705                 size = (freq / 3) * sample_size;
1706         }
1707
1708         /*  set a minimum and maximum size allowed */
1709         if (size > DAS16_DMA_SIZE)
1710                 size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
1711         else if (size < sample_size)
1712                 size = sample_size;
1713
1714         if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
1715                 size = devpriv->adc_byte_count;
1716
1717         return size;
1718 }
1719
1720 static void das16_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
1721         void *array, unsigned int num_bytes, unsigned int start_chan_index)
1722 {
1723         unsigned int i, num_samples = num_bytes / sizeof(short);
1724         short *data = array;
1725
1726         for (i = 0; i < num_samples; i++) {
1727                 data[i] = le16_to_cpu(data[i]);
1728                 if (thisboard->ai_nbits == 12) {
1729                         data[i] = (data[i] >> 4) & 0xfff;
1730                 }
1731         }
1732 }