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