GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / comedi / drivers / das1800.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Comedi driver for Keithley DAS-1700/DAS-1800 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
10 /*
11  * Driver: das1800
12  * Description: Keithley Metrabyte DAS1800 (& compatibles)
13  * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
14  * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
15  *   DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
16  *   DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
17  *   DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
18  *   DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
19  *   DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
20  *   DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
21  *   DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
22  *   DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
23  *   DAS-1802AO (das-1802ao)
24  * Status: works
25  *
26  * Configuration options:
27  *   [0] - I/O port base address
28  *   [1] - IRQ (optional, required for analog input cmd support)
29  *   [2] - DMA0 (optional, requires irq)
30  *   [3] - DMA1 (optional, requires irq and dma0)
31  *
32  * analog input cmd triggers supported:
33  *
34  *   start_src          TRIG_NOW        command starts immediately
35  *                      TRIG_EXT        command starts on external pin TGIN
36  *
37  *   scan_begin_src     TRIG_FOLLOW     paced/external scans start immediately
38  *                      TRIG_TIMER      burst scans start periodically
39  *                      TRIG_EXT        burst scans start on external pin XPCLK
40  *
41  *   scan_end_src       TRIG_COUNT      scan ends after last channel
42  *
43  *   convert_src        TRIG_TIMER      paced/burst conversions are timed
44  *                      TRIG_EXT        conversions on external pin XPCLK
45  *                                      (requires scan_begin_src == TRIG_FOLLOW)
46  *
47  *   stop_src           TRIG_COUNT      command stops after stop_arg scans
48  *                      TRIG_EXT        command stops on external pin TGIN
49  *                      TRIG_NONE       command runs until canceled
50  *
51  * If TRIG_EXT is used for both the start_src and stop_src, the first TGIN
52  * trigger starts the command, and the second trigger will stop it. If only
53  * one is TRIG_EXT, the first trigger will either stop or start the command.
54  * The external pin TGIN is normally set for negative edge triggering. It
55  * can be set to positive edge with the CR_INVERT flag. If TRIG_EXT is used
56  * for both the start_src and stop_src they must have the same polarity.
57  *
58  * Minimum conversion speed is limited to 64 microseconds (convert_arg <= 64000)
59  * for 'burst' scans. This limitation does not apply for 'paced' scans. The
60  * maximum conversion speed is limited by the board (convert_arg >= ai_speed).
61  * Maximum conversion speeds are not always achievable depending on the
62  * board setup (see user manual).
63  *
64  * NOTES:
65  * Only the DAS-1801ST has been tested by me.
66  * Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
67  *
68  * The waveform analog output on the 'ao' cards is not supported.
69  * If you need it, send me (Frank Hess) an email.
70  */
71
72 #include <linux/module.h>
73 #include <linux/interrupt.h>
74 #include <linux/slab.h>
75 #include <linux/io.h>
76 #include <linux/comedi/comedidev.h>
77 #include <linux/comedi/comedi_8254.h>
78 #include <linux/comedi/comedi_isadma.h>
79
80 /* misc. defines */
81 #define DAS1800_SIZE           16       /* uses 16 io addresses */
82 #define FIFO_SIZE              1024     /*  1024 sample fifo */
83 #define DMA_BUF_SIZE           0x1ff00  /*  size in bytes of dma buffers */
84
85 /* Registers for the das1800 */
86 #define DAS1800_FIFO            0x0
87 #define DAS1800_QRAM            0x0
88 #define DAS1800_DAC             0x0
89 #define DAS1800_SELECT          0x2
90 #define   ADC                     0x0
91 #define   QRAM                    0x1
92 #define   DAC(a)                  (0x2 + a)
93 #define DAS1800_DIGITAL         0x3
94 #define DAS1800_CONTROL_A       0x4
95 #define   FFEN                    0x1
96 #define   CGEN                    0x4
97 #define   CGSL                    0x8
98 #define   TGEN                    0x10
99 #define   TGSL                    0x20
100 #define   TGPL                    0x40
101 #define   ATEN                    0x80
102 #define DAS1800_CONTROL_B       0x5
103 #define   DMA_CH5                 0x1
104 #define   DMA_CH6                 0x2
105 #define   DMA_CH7                 0x3
106 #define   DMA_CH5_CH6             0x5
107 #define   DMA_CH6_CH7             0x6
108 #define   DMA_CH7_CH5             0x7
109 #define   DMA_ENABLED             0x3
110 #define   DMA_DUAL                0x4
111 #define   IRQ3                    0x8
112 #define   IRQ5                    0x10
113 #define   IRQ7                    0x18
114 #define   IRQ10                   0x28
115 #define   IRQ11                   0x30
116 #define   IRQ15                   0x38
117 #define   FIMD                    0x40
118 #define DAS1800_CONTROL_C       0X6
119 #define   IPCLK                   0x1
120 #define   XPCLK                   0x3
121 #define   BMDE                    0x4
122 #define   CMEN                    0x8
123 #define   UQEN                    0x10
124 #define   SD                      0x40
125 #define   UB                      0x80
126 #define DAS1800_STATUS          0x7
127 #define   INT                     0x1
128 #define   DMATC                   0x2
129 #define   CT0TC                   0x8
130 #define   OVF                     0x10
131 #define   FHF                     0x20
132 #define   FNE                     0x40
133 #define   CVEN                    0x80
134 #define   CVEN_MASK               0x40
135 #define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
136 #define DAS1800_BURST_LENGTH    0x8
137 #define DAS1800_BURST_RATE      0x9
138 #define DAS1800_QRAM_ADDRESS    0xa
139 #define DAS1800_COUNTER         0xc
140
141 #define IOBASE2                   0x400
142
143 static const struct comedi_lrange das1801_ai_range = {
144         8, {
145                 BIP_RANGE(5),           /* bipolar gain = 1 */
146                 BIP_RANGE(1),           /* bipolar gain = 10 */
147                 BIP_RANGE(0.1),         /* bipolar gain = 50 */
148                 BIP_RANGE(0.02),        /* bipolar gain = 250 */
149                 UNI_RANGE(5),           /* unipolar gain = 1 */
150                 UNI_RANGE(1),           /* unipolar gain = 10 */
151                 UNI_RANGE(0.1),         /* unipolar gain = 50 */
152                 UNI_RANGE(0.02)         /* unipolar gain = 250 */
153         }
154 };
155
156 static const struct comedi_lrange das1802_ai_range = {
157         8, {
158                 BIP_RANGE(10),          /* bipolar gain = 1 */
159                 BIP_RANGE(5),           /* bipolar gain = 2 */
160                 BIP_RANGE(2.5),         /* bipolar gain = 4 */
161                 BIP_RANGE(1.25),        /* bipolar gain = 8 */
162                 UNI_RANGE(10),          /* unipolar gain = 1 */
163                 UNI_RANGE(5),           /* unipolar gain = 2 */
164                 UNI_RANGE(2.5),         /* unipolar gain = 4 */
165                 UNI_RANGE(1.25)         /* unipolar gain = 8 */
166         }
167 };
168
169 /*
170  * The waveform analog outputs on the 'ao' boards are not currently
171  * supported. They have a comedi_lrange of:
172  * { 2, { BIP_RANGE(10), BIP_RANGE(5) } }
173  */
174
175 enum das1800_boardid {
176         BOARD_DAS1701ST,
177         BOARD_DAS1701ST_DA,
178         BOARD_DAS1702ST,
179         BOARD_DAS1702ST_DA,
180         BOARD_DAS1702HR,
181         BOARD_DAS1702HR_DA,
182         BOARD_DAS1701AO,
183         BOARD_DAS1702AO,
184         BOARD_DAS1801ST,
185         BOARD_DAS1801ST_DA,
186         BOARD_DAS1802ST,
187         BOARD_DAS1802ST_DA,
188         BOARD_DAS1802HR,
189         BOARD_DAS1802HR_DA,
190         BOARD_DAS1801HC,
191         BOARD_DAS1802HC,
192         BOARD_DAS1801AO,
193         BOARD_DAS1802AO
194 };
195
196 /* board probe id values (hi byte of the digital input register) */
197 #define DAS1800_ID_ST_DA                0x3
198 #define DAS1800_ID_HR_DA                0x4
199 #define DAS1800_ID_AO                   0x5
200 #define DAS1800_ID_HR                   0x6
201 #define DAS1800_ID_ST                   0x7
202 #define DAS1800_ID_HC                   0x8
203
204 struct das1800_board {
205         const char *name;
206         unsigned char id;
207         unsigned int ai_speed;
208         unsigned int is_01_series:1;
209 };
210
211 static const struct das1800_board das1800_boards[] = {
212         [BOARD_DAS1701ST] = {
213                 .name           = "das-1701st",
214                 .id             = DAS1800_ID_ST,
215                 .ai_speed       = 6250,
216                 .is_01_series   = 1,
217         },
218         [BOARD_DAS1701ST_DA] = {
219                 .name           = "das-1701st-da",
220                 .id             = DAS1800_ID_ST_DA,
221                 .ai_speed       = 6250,
222                 .is_01_series   = 1,
223         },
224         [BOARD_DAS1702ST] = {
225                 .name           = "das-1702st",
226                 .id             = DAS1800_ID_ST,
227                 .ai_speed       = 6250,
228         },
229         [BOARD_DAS1702ST_DA] = {
230                 .name           = "das-1702st-da",
231                 .id             = DAS1800_ID_ST_DA,
232                 .ai_speed       = 6250,
233         },
234         [BOARD_DAS1702HR] = {
235                 .name           = "das-1702hr",
236                 .id             = DAS1800_ID_HR,
237                 .ai_speed       = 20000,
238         },
239         [BOARD_DAS1702HR_DA] = {
240                 .name           = "das-1702hr-da",
241                 .id             = DAS1800_ID_HR_DA,
242                 .ai_speed       = 20000,
243         },
244         [BOARD_DAS1701AO] = {
245                 .name           = "das-1701ao",
246                 .id             = DAS1800_ID_AO,
247                 .ai_speed       = 6250,
248                 .is_01_series   = 1,
249         },
250         [BOARD_DAS1702AO] = {
251                 .name           = "das-1702ao",
252                 .id             = DAS1800_ID_AO,
253                 .ai_speed       = 6250,
254         },
255         [BOARD_DAS1801ST] = {
256                 .name           = "das-1801st",
257                 .id             = DAS1800_ID_ST,
258                 .ai_speed       = 3000,
259                 .is_01_series   = 1,
260         },
261         [BOARD_DAS1801ST_DA] = {
262                 .name           = "das-1801st-da",
263                 .id             = DAS1800_ID_ST_DA,
264                 .ai_speed       = 3000,
265                 .is_01_series   = 1,
266         },
267         [BOARD_DAS1802ST] = {
268                 .name           = "das-1802st",
269                 .id             = DAS1800_ID_ST,
270                 .ai_speed       = 3000,
271         },
272         [BOARD_DAS1802ST_DA] = {
273                 .name           = "das-1802st-da",
274                 .id             = DAS1800_ID_ST_DA,
275                 .ai_speed       = 3000,
276         },
277         [BOARD_DAS1802HR] = {
278                 .name           = "das-1802hr",
279                 .id             = DAS1800_ID_HR,
280                 .ai_speed       = 10000,
281         },
282         [BOARD_DAS1802HR_DA] = {
283                 .name           = "das-1802hr-da",
284                 .id             = DAS1800_ID_HR_DA,
285                 .ai_speed       = 10000,
286         },
287         [BOARD_DAS1801HC] = {
288                 .name           = "das-1801hc",
289                 .id             = DAS1800_ID_HC,
290                 .ai_speed       = 3000,
291                 .is_01_series   = 1,
292         },
293         [BOARD_DAS1802HC] = {
294                 .name           = "das-1802hc",
295                 .id             = DAS1800_ID_HC,
296                 .ai_speed       = 3000,
297         },
298         [BOARD_DAS1801AO] = {
299                 .name           = "das-1801ao",
300                 .id             = DAS1800_ID_AO,
301                 .ai_speed       = 3000,
302                 .is_01_series   = 1,
303         },
304         [BOARD_DAS1802AO] = {
305                 .name           = "das-1802ao",
306                 .id             = DAS1800_ID_AO,
307                 .ai_speed       = 3000,
308         },
309 };
310
311 struct das1800_private {
312         struct comedi_isadma *dma;
313         int irq_dma_bits;
314         int dma_bits;
315         unsigned short *fifo_buf;
316         unsigned long iobase2;
317         bool ai_is_unipolar;
318 };
319
320 static void das1800_ai_munge(struct comedi_device *dev,
321                              struct comedi_subdevice *s,
322                              void *data, unsigned int num_bytes,
323                              unsigned int start_chan_index)
324 {
325         struct das1800_private *devpriv = dev->private;
326         unsigned short *array = data;
327         unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
328         unsigned int i;
329
330         if (devpriv->ai_is_unipolar)
331                 return;
332
333         for (i = 0; i < num_samples; i++)
334                 array[i] = comedi_offset_munge(s, array[i]);
335 }
336
337 static void das1800_handle_fifo_half_full(struct comedi_device *dev,
338                                           struct comedi_subdevice *s)
339 {
340         struct das1800_private *devpriv = dev->private;
341         unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
342
343         insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
344         comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
345 }
346
347 static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
348                                           struct comedi_subdevice *s)
349 {
350         struct comedi_cmd *cmd = &s->async->cmd;
351         unsigned short dpnt;
352
353         while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
354                 dpnt = inw(dev->iobase + DAS1800_FIFO);
355                 comedi_buf_write_samples(s, &dpnt, 1);
356
357                 if (cmd->stop_src == TRIG_COUNT &&
358                     s->async->scans_done >= cmd->stop_arg)
359                         break;
360         }
361 }
362
363 static void das1800_flush_dma_channel(struct comedi_device *dev,
364                                       struct comedi_subdevice *s,
365                                       struct comedi_isadma_desc *desc)
366 {
367         unsigned int residue = comedi_isadma_disable(desc->chan);
368         unsigned int nbytes = desc->size - residue;
369         unsigned int nsamples;
370
371         /*  figure out how many points to read */
372         nsamples = comedi_bytes_to_samples(s, nbytes);
373         nsamples = comedi_nsamples_left(s, nsamples);
374
375         comedi_buf_write_samples(s, desc->virt_addr, nsamples);
376 }
377
378 static void das1800_flush_dma(struct comedi_device *dev,
379                               struct comedi_subdevice *s)
380 {
381         struct das1800_private *devpriv = dev->private;
382         struct comedi_isadma *dma = devpriv->dma;
383         struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
384         const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
385
386         das1800_flush_dma_channel(dev, s, desc);
387
388         if (dual_dma) {
389                 /*  switch to other channel and flush it */
390                 dma->cur_dma = 1 - dma->cur_dma;
391                 desc = &dma->desc[dma->cur_dma];
392                 das1800_flush_dma_channel(dev, s, desc);
393         }
394
395         /*  get any remaining samples in fifo */
396         das1800_handle_fifo_not_empty(dev, s);
397 }
398
399 static void das1800_handle_dma(struct comedi_device *dev,
400                                struct comedi_subdevice *s, unsigned int status)
401 {
402         struct das1800_private *devpriv = dev->private;
403         struct comedi_isadma *dma = devpriv->dma;
404         struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
405         const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
406
407         das1800_flush_dma_channel(dev, s, desc);
408
409         /* re-enable dma channel */
410         comedi_isadma_program(desc);
411
412         if (status & DMATC) {
413                 /*  clear DMATC interrupt bit */
414                 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
415                 /*  switch dma channels for next time, if appropriate */
416                 if (dual_dma)
417                         dma->cur_dma = 1 - dma->cur_dma;
418         }
419 }
420
421 static int das1800_ai_cancel(struct comedi_device *dev,
422                              struct comedi_subdevice *s)
423 {
424         struct das1800_private *devpriv = dev->private;
425         struct comedi_isadma *dma = devpriv->dma;
426         struct comedi_isadma_desc *desc;
427         int i;
428
429         /* disable and stop conversions */
430         outb(0x0, dev->iobase + DAS1800_STATUS);
431         outb(0x0, dev->iobase + DAS1800_CONTROL_B);
432         outb(0x0, dev->iobase + DAS1800_CONTROL_A);
433
434         if (dma) {
435                 for (i = 0; i < 2; i++) {
436                         desc = &dma->desc[i];
437                         if (desc->chan)
438                                 comedi_isadma_disable(desc->chan);
439                 }
440         }
441
442         return 0;
443 }
444
445 static void das1800_ai_handler(struct comedi_device *dev)
446 {
447         struct das1800_private *devpriv = dev->private;
448         struct comedi_subdevice *s = dev->read_subdev;
449         struct comedi_async *async = s->async;
450         struct comedi_cmd *cmd = &async->cmd;
451         unsigned int status = inb(dev->iobase + DAS1800_STATUS);
452
453         /* select adc register (spinlock is already held) */
454         outb(ADC, dev->iobase + DAS1800_SELECT);
455
456         /* get samples with dma, fifo, or polled as necessary */
457         if (devpriv->irq_dma_bits & DMA_ENABLED)
458                 das1800_handle_dma(dev, s, status);
459         else if (status & FHF)
460                 das1800_handle_fifo_half_full(dev, s);
461         else if (status & FNE)
462                 das1800_handle_fifo_not_empty(dev, s);
463
464         /* if the card's fifo has overflowed */
465         if (status & OVF) {
466                 /*  clear OVF interrupt bit */
467                 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
468                 dev_err(dev->class_dev, "FIFO overflow\n");
469                 async->events |= COMEDI_CB_ERROR;
470                 comedi_handle_events(dev, s);
471                 return;
472         }
473         /*  stop taking data if appropriate */
474         /* stop_src TRIG_EXT */
475         if (status & CT0TC) {
476                 /*  clear CT0TC interrupt bit */
477                 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
478                 /* get all remaining samples before quitting */
479                 if (devpriv->irq_dma_bits & DMA_ENABLED)
480                         das1800_flush_dma(dev, s);
481                 else
482                         das1800_handle_fifo_not_empty(dev, s);
483                 async->events |= COMEDI_CB_EOA;
484         } else if (cmd->stop_src == TRIG_COUNT &&
485                    async->scans_done >= cmd->stop_arg) {
486                 async->events |= COMEDI_CB_EOA;
487         }
488
489         comedi_handle_events(dev, s);
490 }
491
492 static int das1800_ai_poll(struct comedi_device *dev,
493                            struct comedi_subdevice *s)
494 {
495         unsigned long flags;
496
497         /*
498          * Protects the indirect addressing selected by DAS1800_SELECT
499          * in das1800_ai_handler() also prevents race with das1800_interrupt().
500          */
501         spin_lock_irqsave(&dev->spinlock, flags);
502
503         das1800_ai_handler(dev);
504
505         spin_unlock_irqrestore(&dev->spinlock, flags);
506
507         return comedi_buf_n_bytes_ready(s);
508 }
509
510 static irqreturn_t das1800_interrupt(int irq, void *d)
511 {
512         struct comedi_device *dev = d;
513         unsigned int status;
514
515         if (!dev->attached) {
516                 dev_err(dev->class_dev, "premature interrupt\n");
517                 return IRQ_HANDLED;
518         }
519
520         /*
521          * Protects the indirect addressing selected by DAS1800_SELECT
522          * in das1800_ai_handler() also prevents race with das1800_ai_poll().
523          */
524         spin_lock(&dev->spinlock);
525
526         status = inb(dev->iobase + DAS1800_STATUS);
527
528         /* if interrupt was not caused by das-1800 */
529         if (!(status & INT)) {
530                 spin_unlock(&dev->spinlock);
531                 return IRQ_NONE;
532         }
533         /* clear the interrupt status bit INT */
534         outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
535         /*  handle interrupt */
536         das1800_ai_handler(dev);
537
538         spin_unlock(&dev->spinlock);
539         return IRQ_HANDLED;
540 }
541
542 static int das1800_ai_fixup_paced_timing(struct comedi_device *dev,
543                                          struct comedi_cmd *cmd)
544 {
545         unsigned int arg = cmd->convert_arg;
546
547         /*
548          * Paced mode:
549          *      scan_begin_src is TRIG_FOLLOW
550          *      convert_src is TRIG_TIMER
551          *
552          * The convert_arg sets the pacer sample acquisition time.
553          * The max acquisition speed is limited to the boards
554          * 'ai_speed' (this was already verified). The min speed is
555          * limited by the cascaded 8254 timer.
556          */
557         comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
558         return comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
559 }
560
561 static int das1800_ai_fixup_burst_timing(struct comedi_device *dev,
562                                          struct comedi_cmd *cmd)
563 {
564         unsigned int arg = cmd->convert_arg;
565         int err = 0;
566
567         /*
568          * Burst mode:
569          *      scan_begin_src is TRIG_TIMER or TRIG_EXT
570          *      convert_src is TRIG_TIMER
571          *
572          * The convert_arg sets burst sample acquisition time.
573          * The max acquisition speed is limited to the boards
574          * 'ai_speed' (this was already verified). The min speed is
575          * limiited to 64 microseconds,
576          */
577         err |= comedi_check_trigger_arg_max(&arg, 64000);
578
579         /* round to microseconds then verify */
580         switch (cmd->flags & CMDF_ROUND_MASK) {
581         case CMDF_ROUND_NEAREST:
582         default:
583                 arg = DIV_ROUND_CLOSEST(arg, 1000);
584                 break;
585         case CMDF_ROUND_DOWN:
586                 arg = arg / 1000;
587                 break;
588         case CMDF_ROUND_UP:
589                 arg = DIV_ROUND_UP(arg, 1000);
590                 break;
591         }
592         err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000);
593
594         /*
595          * The pacer can be used to set the scan sample rate. The max scan
596          * speed is limited by the conversion speed and the number of channels
597          * to convert. The min speed is limited by the cascaded 8254 timer.
598          */
599         if (cmd->scan_begin_src == TRIG_TIMER) {
600                 arg = cmd->convert_arg * cmd->chanlist_len;
601                 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
602
603                 arg = cmd->scan_begin_arg;
604                 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
605                 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
606         }
607
608         return err;
609 }
610
611 static int das1800_ai_check_chanlist(struct comedi_device *dev,
612                                      struct comedi_subdevice *s,
613                                      struct comedi_cmd *cmd)
614 {
615         unsigned int range = CR_RANGE(cmd->chanlist[0]);
616         bool unipolar0 = comedi_range_is_unipolar(s, range);
617         int i;
618
619         for (i = 1; i < cmd->chanlist_len; i++) {
620                 range = CR_RANGE(cmd->chanlist[i]);
621
622                 if (unipolar0 != comedi_range_is_unipolar(s, range)) {
623                         dev_dbg(dev->class_dev,
624                                 "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
625                         return -EINVAL;
626                 }
627         }
628
629         return 0;
630 }
631
632 static int das1800_ai_cmdtest(struct comedi_device *dev,
633                               struct comedi_subdevice *s,
634                               struct comedi_cmd *cmd)
635 {
636         const struct das1800_board *board = dev->board_ptr;
637         int err = 0;
638
639         /* Step 1 : check if triggers are trivially valid */
640
641         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
642         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
643                                         TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
644         err |= comedi_check_trigger_src(&cmd->convert_src,
645                                         TRIG_TIMER | TRIG_EXT);
646         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
647         err |= comedi_check_trigger_src(&cmd->stop_src,
648                                         TRIG_COUNT | TRIG_EXT | TRIG_NONE);
649
650         if (err)
651                 return 1;
652
653         /* Step 2a : make sure trigger sources are unique */
654
655         err |= comedi_check_trigger_is_unique(cmd->start_src);
656         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
657         err |= comedi_check_trigger_is_unique(cmd->convert_src);
658         err |= comedi_check_trigger_is_unique(cmd->stop_src);
659
660         /* Step 2b : and mutually compatible */
661
662         /* burst scans must use timed conversions */
663         if (cmd->scan_begin_src != TRIG_FOLLOW &&
664             cmd->convert_src != TRIG_TIMER)
665                 err |= -EINVAL;
666
667         /* the external pin TGIN must use the same polarity */
668         if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
669                 err |= comedi_check_trigger_arg_is(&cmd->start_arg,
670                                                    cmd->stop_arg);
671
672         if (err)
673                 return 2;
674
675         /* Step 3: check if arguments are trivially valid */
676
677         if (cmd->start_arg == TRIG_NOW)
678                 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
679
680         if (cmd->convert_src == TRIG_TIMER) {
681                 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
682                                                     board->ai_speed);
683         }
684
685         err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
686         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
687                                            cmd->chanlist_len);
688
689         switch (cmd->stop_src) {
690         case TRIG_COUNT:
691                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
692                 break;
693         case TRIG_NONE:
694                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
695                 break;
696         default:
697                 break;
698         }
699
700         if (err)
701                 return 3;
702
703         /* Step 4: fix up any arguments */
704
705         if (cmd->convert_src == TRIG_TIMER) {
706                 if (cmd->scan_begin_src == TRIG_FOLLOW)
707                         err |= das1800_ai_fixup_paced_timing(dev, cmd);
708                 else /* TRIG_TIMER or TRIG_EXT */
709                         err |= das1800_ai_fixup_burst_timing(dev, cmd);
710         }
711
712         if (err)
713                 return 4;
714
715         /* Step 5: check channel list if it exists */
716         if (cmd->chanlist && cmd->chanlist_len > 0)
717                 err |= das1800_ai_check_chanlist(dev, s, cmd);
718
719         if (err)
720                 return 5;
721
722         return 0;
723 }
724
725 static unsigned char das1800_ai_chanspec_bits(struct comedi_subdevice *s,
726                                               unsigned int chanspec)
727 {
728         unsigned int range = CR_RANGE(chanspec);
729         unsigned int aref = CR_AREF(chanspec);
730         unsigned char bits;
731
732         bits = UQEN;
733         if (aref != AREF_DIFF)
734                 bits |= SD;
735         if (aref == AREF_COMMON)
736                 bits |= CMEN;
737         if (comedi_range_is_unipolar(s, range))
738                 bits |= UB;
739
740         return bits;
741 }
742
743 static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
744                                              struct comedi_subdevice *s,
745                                              unsigned int maxbytes,
746                                              unsigned int ns)
747 {
748         struct comedi_cmd *cmd = &s->async->cmd;
749         unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
750         unsigned int samples;
751
752         samples = max_samples;
753
754         /* for timed modes, make dma buffer fill in 'ns' time */
755         switch (cmd->scan_begin_src) {
756         case TRIG_FOLLOW:       /* not in burst mode */
757                 if (cmd->convert_src == TRIG_TIMER)
758                         samples = ns / cmd->convert_arg;
759                 break;
760         case TRIG_TIMER:
761                 samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
762                 break;
763         }
764
765         /* limit samples to what is remaining in the command */
766         samples = comedi_nsamples_left(s, samples);
767
768         if (samples > max_samples)
769                 samples = max_samples;
770         if (samples < 1)
771                 samples = 1;
772
773         return comedi_samples_to_bytes(s, samples);
774 }
775
776 static void das1800_ai_setup_dma(struct comedi_device *dev,
777                                  struct comedi_subdevice *s)
778 {
779         struct das1800_private *devpriv = dev->private;
780         struct comedi_isadma *dma = devpriv->dma;
781         struct comedi_isadma_desc *desc;
782         unsigned int bytes;
783
784         if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
785                 return;
786
787         dma->cur_dma = 0;
788         desc = &dma->desc[0];
789
790         /* determine a dma transfer size to fill buffer in 0.3 sec */
791         bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
792
793         desc->size = bytes;
794         comedi_isadma_program(desc);
795
796         /* set up dual dma if appropriate */
797         if (devpriv->irq_dma_bits & DMA_DUAL) {
798                 desc = &dma->desc[1];
799                 desc->size = bytes;
800                 comedi_isadma_program(desc);
801         }
802 }
803
804 static void das1800_ai_set_chanlist(struct comedi_device *dev,
805                                     unsigned int *chanlist, unsigned int len)
806 {
807         unsigned long flags;
808         unsigned int i;
809
810         /* protects the indirect addressing selected by DAS1800_SELECT */
811         spin_lock_irqsave(&dev->spinlock, flags);
812
813         /* select QRAM register and set start address */
814         outb(QRAM, dev->iobase + DAS1800_SELECT);
815         outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
816
817         /* make channel / gain list */
818         for (i = 0; i < len; i++) {
819                 unsigned int chan = CR_CHAN(chanlist[i]);
820                 unsigned int range = CR_RANGE(chanlist[i]);
821                 unsigned short val;
822
823                 val = chan | ((range & 0x3) << 8);
824                 outw(val, dev->iobase + DAS1800_QRAM);
825         }
826
827         /* finish write to QRAM */
828         outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
829
830         spin_unlock_irqrestore(&dev->spinlock, flags);
831 }
832
833 static int das1800_ai_cmd(struct comedi_device *dev,
834                           struct comedi_subdevice *s)
835 {
836         struct das1800_private *devpriv = dev->private;
837         int control_a, control_c;
838         struct comedi_async *async = s->async;
839         const struct comedi_cmd *cmd = &async->cmd;
840         unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
841
842         /*
843          * Disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY (because dma in
844          * handler is unsafe at hard real-time priority).
845          */
846         if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY))
847                 devpriv->irq_dma_bits &= ~DMA_ENABLED;
848         else
849                 devpriv->irq_dma_bits |= devpriv->dma_bits;
850         /*  interrupt on end of conversion for CMDF_WAKE_EOS */
851         if (cmd->flags & CMDF_WAKE_EOS) {
852                 /*  interrupt fifo not empty */
853                 devpriv->irq_dma_bits &= ~FIMD;
854         } else {
855                 /*  interrupt fifo half full */
856                 devpriv->irq_dma_bits |= FIMD;
857         }
858
859         das1800_ai_cancel(dev, s);
860
861         devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0);
862
863         control_a = FFEN;
864         if (cmd->stop_src == TRIG_EXT)
865                 control_a |= ATEN;
866         if (cmd->start_src == TRIG_EXT)
867                 control_a |= TGEN | CGSL;
868         else /* TRIG_NOW */
869                 control_a |= CGEN;
870         if (control_a & (ATEN | TGEN)) {
871                 if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT))
872                         control_a |= TGPL;
873         }
874
875         control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]);
876         /* set clock source to internal or external */
877         if (cmd->scan_begin_src == TRIG_FOLLOW) {
878                 /* not in burst mode */
879                 if (cmd->convert_src == TRIG_TIMER) {
880                         /* trig on cascaded counters */
881                         control_c |= IPCLK;
882                 } else { /* TRIG_EXT */
883                         /* trig on falling edge of external trigger */
884                         control_c |= XPCLK;
885                 }
886         } else if (cmd->scan_begin_src == TRIG_TIMER) {
887                 /* burst mode with internal pacer clock */
888                 control_c |= BMDE | IPCLK;
889         } else { /* TRIG_EXT */
890                 /* burst mode with external trigger */
891                 control_c |= BMDE | XPCLK;
892         }
893
894         das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len);
895
896         /* setup cascaded counters for conversion/scan frequency */
897         if ((cmd->scan_begin_src == TRIG_FOLLOW ||
898              cmd->scan_begin_src == TRIG_TIMER) &&
899             cmd->convert_src == TRIG_TIMER) {
900                 comedi_8254_update_divisors(dev->pacer);
901                 comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
902         }
903
904         /* setup counter 0 for 'about triggering' */
905         if (cmd->stop_src == TRIG_EXT)
906                 comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY);
907
908         das1800_ai_setup_dma(dev, s);
909         outb(control_c, dev->iobase + DAS1800_CONTROL_C);
910         /*  set conversion rate and length for burst mode */
911         if (control_c & BMDE) {
912                 outb(cmd->convert_arg / 1000 - 1,       /* microseconds - 1 */
913                      dev->iobase + DAS1800_BURST_RATE);
914                 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
915         }
916
917         /* enable and start conversions */
918         outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);
919         outb(control_a, dev->iobase + DAS1800_CONTROL_A);
920         outb(CVEN, dev->iobase + DAS1800_STATUS);
921
922         return 0;
923 }
924
925 static int das1800_ai_eoc(struct comedi_device *dev,
926                           struct comedi_subdevice *s,
927                           struct comedi_insn *insn,
928                           unsigned long context)
929 {
930         unsigned char status;
931
932         status = inb(dev->iobase + DAS1800_STATUS);
933         if (status & FNE)
934                 return 0;
935         return -EBUSY;
936 }
937
938 static int das1800_ai_insn_read(struct comedi_device *dev,
939                                 struct comedi_subdevice *s,
940                                 struct comedi_insn *insn,
941                                 unsigned int *data)
942 {
943         unsigned int range = CR_RANGE(insn->chanspec);
944         bool is_unipolar = comedi_range_is_unipolar(s, range);
945         int ret = 0;
946         int n;
947         unsigned short dpnt;
948         unsigned long flags;
949
950         outb(das1800_ai_chanspec_bits(s, insn->chanspec),
951              dev->iobase + DAS1800_CONTROL_C);          /* software pacer */
952         outb(CVEN, dev->iobase + DAS1800_STATUS);       /* enable conversions */
953         outb(0x0, dev->iobase + DAS1800_CONTROL_A);     /* reset fifo */
954         outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
955
956         das1800_ai_set_chanlist(dev, &insn->chanspec, 1);
957
958         /* protects the indirect addressing selected by DAS1800_SELECT */
959         spin_lock_irqsave(&dev->spinlock, flags);
960
961         /* select ai fifo register */
962         outb(ADC, dev->iobase + DAS1800_SELECT);
963
964         for (n = 0; n < insn->n; n++) {
965                 /* trigger conversion */
966                 outb(0, dev->iobase + DAS1800_FIFO);
967
968                 ret = comedi_timeout(dev, s, insn, das1800_ai_eoc, 0);
969                 if (ret)
970                         break;
971
972                 dpnt = inw(dev->iobase + DAS1800_FIFO);
973                 if (!is_unipolar)
974                         dpnt = comedi_offset_munge(s, dpnt);
975                 data[n] = dpnt;
976         }
977         spin_unlock_irqrestore(&dev->spinlock, flags);
978
979         return ret ? ret : insn->n;
980 }
981
982 static int das1800_ao_insn_write(struct comedi_device *dev,
983                                  struct comedi_subdevice *s,
984                                  struct comedi_insn *insn,
985                                  unsigned int *data)
986 {
987         unsigned int chan = CR_CHAN(insn->chanspec);
988         unsigned int update_chan = s->n_chan - 1;
989         unsigned long flags;
990         int i;
991
992         /* protects the indirect addressing selected by DAS1800_SELECT */
993         spin_lock_irqsave(&dev->spinlock, flags);
994
995         for (i = 0; i < insn->n; i++) {
996                 unsigned int val = data[i];
997
998                 s->readback[chan] = val;
999
1000                 val = comedi_offset_munge(s, val);
1001
1002                 /* load this channel (and update if it's the last channel) */
1003                 outb(DAC(chan), dev->iobase + DAS1800_SELECT);
1004                 outw(val, dev->iobase + DAS1800_DAC);
1005
1006                 /* update all channels */
1007                 if (chan != update_chan) {
1008                         val = comedi_offset_munge(s, s->readback[update_chan]);
1009
1010                         outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
1011                         outw(val, dev->iobase + DAS1800_DAC);
1012                 }
1013         }
1014         spin_unlock_irqrestore(&dev->spinlock, flags);
1015
1016         return insn->n;
1017 }
1018
1019 static int das1800_di_insn_bits(struct comedi_device *dev,
1020                                 struct comedi_subdevice *s,
1021                                 struct comedi_insn *insn,
1022                                 unsigned int *data)
1023 {
1024         data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1025         data[0] = 0;
1026
1027         return insn->n;
1028 }
1029
1030 static int das1800_do_insn_bits(struct comedi_device *dev,
1031                                 struct comedi_subdevice *s,
1032                                 struct comedi_insn *insn,
1033                                 unsigned int *data)
1034 {
1035         if (comedi_dio_update_state(s, data))
1036                 outb(s->state, dev->iobase + DAS1800_DIGITAL);
1037
1038         data[1] = s->state;
1039
1040         return insn->n;
1041 }
1042
1043 static void das1800_init_dma(struct comedi_device *dev,
1044                              struct comedi_devconfig *it)
1045 {
1046         struct das1800_private *devpriv = dev->private;
1047         unsigned int *dma_chan;
1048
1049         /*
1050          * it->options[2] is DMA channel 0
1051          * it->options[3] is DMA channel 1
1052          *
1053          * Encode the DMA channels into 2 digit hexadecimal for switch.
1054          */
1055         dma_chan = &it->options[2];
1056
1057         switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
1058         case 0x5:       /*  dma0 == 5 */
1059                 devpriv->dma_bits = DMA_CH5;
1060                 break;
1061         case 0x6:       /*  dma0 == 6 */
1062                 devpriv->dma_bits = DMA_CH6;
1063                 break;
1064         case 0x7:       /*  dma0 == 7 */
1065                 devpriv->dma_bits = DMA_CH7;
1066                 break;
1067         case 0x65:      /*  dma0 == 5, dma1 == 6 */
1068                 devpriv->dma_bits = DMA_CH5_CH6;
1069                 break;
1070         case 0x76:      /*  dma0 == 6, dma1 == 7 */
1071                 devpriv->dma_bits = DMA_CH6_CH7;
1072                 break;
1073         case 0x57:      /*  dma0 == 7, dma1 == 5 */
1074                 devpriv->dma_bits = DMA_CH7_CH5;
1075                 break;
1076         default:
1077                 return;
1078         }
1079
1080         /* DMA can use 1 or 2 buffers, each with a separate channel */
1081         devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
1082                                            dma_chan[0], dma_chan[1],
1083                                            DMA_BUF_SIZE, COMEDI_ISADMA_READ);
1084         if (!devpriv->dma)
1085                 devpriv->dma_bits = 0;
1086 }
1087
1088 static void das1800_free_dma(struct comedi_device *dev)
1089 {
1090         struct das1800_private *devpriv = dev->private;
1091
1092         if (devpriv)
1093                 comedi_isadma_free(devpriv->dma);
1094 }
1095
1096 static int das1800_probe(struct comedi_device *dev)
1097 {
1098         const struct das1800_board *board = dev->board_ptr;
1099         unsigned char id;
1100
1101         id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
1102
1103         /*
1104          * The dev->board_ptr will be set by comedi_device_attach() if the
1105          * board name provided by the user matches a board->name in this
1106          * driver. If so, this function sanity checks the id to verify that
1107          * the board is correct.
1108          */
1109         if (board) {
1110                 if (board->id == id)
1111                         return 0;
1112                 dev_err(dev->class_dev,
1113                         "probed id does not match board id (0x%x != 0x%x)\n",
1114                         id, board->id);
1115                 return -ENODEV;
1116         }
1117
1118          /*
1119           * If the dev->board_ptr is not set, the user is trying to attach
1120           * an unspecified board to this driver. In this case the id is used
1121           * to 'probe' for the dev->board_ptr.
1122           */
1123         switch (id) {
1124         case DAS1800_ID_ST_DA:
1125                 /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
1126                 board = &das1800_boards[BOARD_DAS1801ST_DA];
1127                 break;
1128         case DAS1800_ID_HR_DA:
1129                 /* das-1702hr-da, das-1802hr-da */
1130                 board = &das1800_boards[BOARD_DAS1802HR_DA];
1131                 break;
1132         case DAS1800_ID_AO:
1133                 /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
1134                 board = &das1800_boards[BOARD_DAS1801AO];
1135                 break;
1136         case DAS1800_ID_HR:
1137                 /*  das-1702hr, das-1802hr */
1138                 board = &das1800_boards[BOARD_DAS1802HR];
1139                 break;
1140         case DAS1800_ID_ST:
1141                 /* das-1701st, das-1702st, das-1801st, das-1802st */
1142                 board = &das1800_boards[BOARD_DAS1801ST];
1143                 break;
1144         case DAS1800_ID_HC:
1145                 /* das-1801hc, das-1802hc */
1146                 board = &das1800_boards[BOARD_DAS1801HC];
1147                 break;
1148         default:
1149                 dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
1150                 return -ENODEV;
1151         }
1152         dev->board_ptr = board;
1153         dev->board_name = board->name;
1154         dev_warn(dev->class_dev,
1155                  "probed id 0x%0x: %s series (not recommended)\n",
1156                  id, board->name);
1157         return 0;
1158 }
1159
1160 static int das1800_attach(struct comedi_device *dev,
1161                           struct comedi_devconfig *it)
1162 {
1163         const struct das1800_board *board;
1164         struct das1800_private *devpriv;
1165         struct comedi_subdevice *s;
1166         unsigned int irq = it->options[1];
1167         bool is_16bit;
1168         int ret;
1169         int i;
1170
1171         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1172         if (!devpriv)
1173                 return -ENOMEM;
1174
1175         ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1176         if (ret)
1177                 return ret;
1178
1179         ret = das1800_probe(dev);
1180         if (ret)
1181                 return ret;
1182         board = dev->board_ptr;
1183
1184         is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA;
1185
1186         /* waveform 'ao' boards have additional io ports */
1187         if (board->id == DAS1800_ID_AO) {
1188                 unsigned long iobase2 = dev->iobase + IOBASE2;
1189
1190                 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1191                 if (ret)
1192                         return ret;
1193                 devpriv->iobase2 = iobase2;
1194         }
1195
1196         if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
1197             irq == 15) {
1198                 ret = request_irq(irq, das1800_interrupt, 0,
1199                                   dev->board_name, dev);
1200                 if (ret == 0) {
1201                         dev->irq = irq;
1202
1203                         switch (irq) {
1204                         case 3:
1205                                 devpriv->irq_dma_bits |= 0x8;
1206                                 break;
1207                         case 5:
1208                                 devpriv->irq_dma_bits |= 0x10;
1209                                 break;
1210                         case 7:
1211                                 devpriv->irq_dma_bits |= 0x18;
1212                                 break;
1213                         case 10:
1214                                 devpriv->irq_dma_bits |= 0x28;
1215                                 break;
1216                         case 11:
1217                                 devpriv->irq_dma_bits |= 0x30;
1218                                 break;
1219                         case 15:
1220                                 devpriv->irq_dma_bits |= 0x38;
1221                                 break;
1222                         }
1223                 }
1224         }
1225
1226         /* an irq and one dma channel is required to use dma */
1227         if (dev->irq & it->options[2])
1228                 das1800_init_dma(dev, it);
1229
1230         devpriv->fifo_buf = kmalloc_array(FIFO_SIZE,
1231                                           sizeof(*devpriv->fifo_buf),
1232                                           GFP_KERNEL);
1233         if (!devpriv->fifo_buf)
1234                 return -ENOMEM;
1235
1236         dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS1800_COUNTER,
1237                                           I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
1238         if (IS_ERR(dev->pacer))
1239                 return PTR_ERR(dev->pacer);
1240
1241         ret = comedi_alloc_subdevices(dev, 4);
1242         if (ret)
1243                 return ret;
1244
1245         /*
1246          * Analog Input subdevice
1247          *
1248          * The "hc" type boards have 64 analog input channels and a 64
1249          * entry QRAM fifo.
1250          *
1251          * All the other board types have 16 on-board channels. Each channel
1252          * can be expanded to 16 channels with the addition of an EXP-1800
1253          * expansion board for a total of 256 channels. The QRAM fifo on
1254          * these boards has 256 entries.
1255          *
1256          * From the datasheets it's not clear what the comedi channel to
1257          * actual physical channel mapping is when EXP-1800 boards are used.
1258          */
1259         s = &dev->subdevices[0];
1260         s->type         = COMEDI_SUBD_AI;
1261         s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
1262         if (board->id != DAS1800_ID_HC)
1263                 s->subdev_flags |= SDF_COMMON;
1264         s->n_chan       = (board->id == DAS1800_ID_HC) ? 64 : 256;
1265         s->maxdata      = is_16bit ? 0xffff : 0x0fff;
1266         s->range_table  = board->is_01_series ? &das1801_ai_range
1267                                               : &das1802_ai_range;
1268         s->insn_read    = das1800_ai_insn_read;
1269         if (dev->irq) {
1270                 dev->read_subdev = s;
1271                 s->subdev_flags |= SDF_CMD_READ;
1272                 s->len_chanlist = s->n_chan;
1273                 s->do_cmd       = das1800_ai_cmd;
1274                 s->do_cmdtest   = das1800_ai_cmdtest;
1275                 s->poll         = das1800_ai_poll;
1276                 s->cancel       = das1800_ai_cancel;
1277                 s->munge        = das1800_ai_munge;
1278         }
1279
1280         /* Analog Output subdevice */
1281         s = &dev->subdevices[1];
1282         if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) {
1283                 s->type         = COMEDI_SUBD_AO;
1284                 s->subdev_flags = SDF_WRITABLE;
1285                 s->n_chan       = (board->id == DAS1800_ID_ST_DA) ? 4 : 2;
1286                 s->maxdata      = is_16bit ? 0xffff : 0x0fff;
1287                 s->range_table  = &range_bipolar10;
1288                 s->insn_write   = das1800_ao_insn_write;
1289
1290                 ret = comedi_alloc_subdev_readback(s);
1291                 if (ret)
1292                         return ret;
1293
1294                 /* initialize all channels to 0V */
1295                 for (i = 0; i < s->n_chan; i++) {
1296                         /* spinlock is not necessary during the attach */
1297                         outb(DAC(i), dev->iobase + DAS1800_SELECT);
1298                         outw(0, dev->iobase + DAS1800_DAC);
1299                 }
1300         } else if (board->id == DAS1800_ID_AO) {
1301                 /*
1302                  * 'ao' boards have waveform analog outputs that are not
1303                  * currently supported.
1304                  */
1305                 s->type         = COMEDI_SUBD_UNUSED;
1306         } else {
1307                 s->type         = COMEDI_SUBD_UNUSED;
1308         }
1309
1310         /* Digital Input subdevice */
1311         s = &dev->subdevices[2];
1312         s->type         = COMEDI_SUBD_DI;
1313         s->subdev_flags = SDF_READABLE;
1314         s->n_chan       = 4;
1315         s->maxdata      = 1;
1316         s->range_table  = &range_digital;
1317         s->insn_bits    = das1800_di_insn_bits;
1318
1319         /* Digital Output subdevice */
1320         s = &dev->subdevices[3];
1321         s->type         = COMEDI_SUBD_DO;
1322         s->subdev_flags = SDF_WRITABLE;
1323         s->n_chan       = (board->id == DAS1800_ID_HC) ? 8 : 4;
1324         s->maxdata      = 1;
1325         s->range_table  = &range_digital;
1326         s->insn_bits    = das1800_do_insn_bits;
1327
1328         das1800_ai_cancel(dev, dev->read_subdev);
1329
1330         /*  initialize digital out channels */
1331         outb(0, dev->iobase + DAS1800_DIGITAL);
1332
1333         return 0;
1334 };
1335
1336 static void das1800_detach(struct comedi_device *dev)
1337 {
1338         struct das1800_private *devpriv = dev->private;
1339
1340         das1800_free_dma(dev);
1341         if (devpriv) {
1342                 kfree(devpriv->fifo_buf);
1343                 if (devpriv->iobase2)
1344                         release_region(devpriv->iobase2, DAS1800_SIZE);
1345         }
1346         comedi_legacy_detach(dev);
1347 }
1348
1349 static struct comedi_driver das1800_driver = {
1350         .driver_name    = "das1800",
1351         .module         = THIS_MODULE,
1352         .attach         = das1800_attach,
1353         .detach         = das1800_detach,
1354         .num_names      = ARRAY_SIZE(das1800_boards),
1355         .board_name     = &das1800_boards[0].name,
1356         .offset         = sizeof(struct das1800_board),
1357 };
1358 module_comedi_driver(das1800_driver);
1359
1360 MODULE_AUTHOR("Comedi https://www.comedi.org");
1361 MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
1362 MODULE_LICENSE("GPL");