Merge tag 'regmap-fix-v4.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / staging / comedi / drivers / dt282x.c
1 /*
2  * dt282x.c
3  * Comedi driver for Data Translation DT2821 series
4  *
5  * COMEDI - Linux Control and Measurement Device Interface
6  * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 /*
20  * Driver: dt282x
21  * Description: Data Translation DT2821 series (including DT-EZ)
22  * Author: ds
23  * Devices: [Data Translation] DT2821 (dt2821), DT2821-F-16SE (dt2821-f),
24  *   DT2821-F-8DI (dt2821-f), DT2821-G-16SE (dt2821-g),
25  *   DT2821-G-8DI (dt2821-g), DT2823 (dt2823), DT2824-PGH (dt2824-pgh),
26  *   DT2824-PGL (dt2824-pgl), DT2825 (dt2825), DT2827 (dt2827),
27  *   DT2828 (dt2828), DT2928 (dt2829), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
28  *   DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
29  * Status: complete
30  * Updated: Wed, 22 Aug 2001 17:11:34 -0700
31  *
32  * Configuration options:
33  *   [0] - I/O port base address
34  *   [1] - IRQ (optional, required for async command support)
35  *   [2] - DMA 1 (optional, required for async command support)
36  *   [3] - DMA 2 (optional, required for async command support)
37  *   [4] - AI jumpered for 0=single ended, 1=differential
38  *   [5] - AI jumpered for 0=straight binary, 1=2's complement
39  *   [6] - AO 0 data format (deprecated, see below)
40  *   [7] - AO 1 data format (deprecated, see below)
41  *   [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
42  *   [9] - AO channel 0 range (deprecated, see below)
43  *   [10]- AO channel 1 range (deprecated, see below)
44  *
45  * Notes:
46  *   - AO commands might be broken.
47  *   - If you try to run a command on both the AI and AO subdevices
48  *     simultaneously, bad things will happen.  The driver needs to
49  *     be fixed to check for this situation and return an error.
50  *   - AO range is not programmable. The AO subdevice has a range_table
51  *     containing all the possible analog output ranges. Use the range
52  *     that matches your board configuration to convert between data
53  *     values and physical units. The format of the data written to the
54  *     board is handled automatically based on the unipolar/bipolar
55  *     range that is selected.
56  */
57
58 #include <linux/module.h>
59 #include <linux/delay.h>
60 #include <linux/gfp.h>
61 #include <linux/interrupt.h>
62 #include <linux/io.h>
63
64 #include "../comedidev.h"
65
66 #include "comedi_isadma.h"
67
68 /*
69  * Register map
70  */
71 #define DT2821_ADCSR_REG                0x00
72 #define DT2821_ADCSR_ADERR              BIT(15)
73 #define DT2821_ADCSR_ADCLK              BIT(9)
74 #define DT2821_ADCSR_MUXBUSY            BIT(8)
75 #define DT2821_ADCSR_ADDONE             BIT(7)
76 #define DT2821_ADCSR_IADDONE            BIT(6)
77 #define DT2821_ADCSR_GS(x)              (((x) & 0x3) << 4)
78 #define DT2821_ADCSR_CHAN(x)            (((x) & 0xf) << 0)
79 #define DT2821_CHANCSR_REG              0x02
80 #define DT2821_CHANCSR_LLE              BIT(15)
81 #define DT2821_CHANCSR_TO_PRESLA(x)     (((x) >> 8) & 0xf)
82 #define DT2821_CHANCSR_NUMB(x)          ((((x) - 1) & 0xf) << 0)
83 #define DT2821_ADDAT_REG                0x04
84 #define DT2821_DACSR_REG                0x06
85 #define DT2821_DACSR_DAERR              BIT(15)
86 #define DT2821_DACSR_YSEL(x)            ((x) << 9)
87 #define DT2821_DACSR_SSEL               BIT(8)
88 #define DT2821_DACSR_DACRDY             BIT(7)
89 #define DT2821_DACSR_IDARDY             BIT(6)
90 #define DT2821_DACSR_DACLK              BIT(5)
91 #define DT2821_DACSR_HBOE               BIT(1)
92 #define DT2821_DACSR_LBOE               BIT(0)
93 #define DT2821_DADAT_REG                0x08
94 #define DT2821_DIODAT_REG               0x0a
95 #define DT2821_SUPCSR_REG               0x0c
96 #define DT2821_SUPCSR_DMAD              BIT(15)
97 #define DT2821_SUPCSR_ERRINTEN          BIT(14)
98 #define DT2821_SUPCSR_CLRDMADNE         BIT(13)
99 #define DT2821_SUPCSR_DDMA              BIT(12)
100 #define DT2821_SUPCSR_DS(x)             (((x) & 0x3) << 10)
101 #define DT2821_SUPCSR_DS_PIO            DT2821_SUPCSR_DS(0)
102 #define DT2821_SUPCSR_DS_AD_CLK         DT2821_SUPCSR_DS(1)
103 #define DT2821_SUPCSR_DS_DA_CLK         DT2821_SUPCSR_DS(2)
104 #define DT2821_SUPCSR_DS_AD_TRIG        DT2821_SUPCSR_DS(3)
105 #define DT2821_SUPCSR_BUFFB             BIT(9)
106 #define DT2821_SUPCSR_SCDN              BIT(8)
107 #define DT2821_SUPCSR_DACON             BIT(7)
108 #define DT2821_SUPCSR_ADCINIT           BIT(6)
109 #define DT2821_SUPCSR_DACINIT           BIT(5)
110 #define DT2821_SUPCSR_PRLD              BIT(4)
111 #define DT2821_SUPCSR_STRIG             BIT(3)
112 #define DT2821_SUPCSR_XTRIG             BIT(2)
113 #define DT2821_SUPCSR_XCLK              BIT(1)
114 #define DT2821_SUPCSR_BDINIT            BIT(0)
115 #define DT2821_TMRCTR_REG               0x0e
116 #define DT2821_TMRCTR_PRESCALE(x)       (((x) & 0xf) << 8)
117 #define DT2821_TMRCTR_DIVIDER(x)        ((255 - ((x) & 0xff)) << 0)
118
119 /* Pacer Clock */
120 #define DT2821_OSC_BASE         250     /* 4 MHz (in nanoseconds) */
121 #define DT2821_PRESCALE(x)      BIT(x)
122 #define DT2821_PRESCALE_MAX     15
123 #define DT2821_DIVIDER_MAX      255
124 #define DT2821_OSC_MAX          (DT2821_OSC_BASE *                      \
125                                  DT2821_PRESCALE(DT2821_PRESCALE_MAX) * \
126                                  DT2821_DIVIDER_MAX)
127
128 static const struct comedi_lrange range_dt282x_ai_lo_bipolar = {
129         4, {
130                 BIP_RANGE(10),
131                 BIP_RANGE(5),
132                 BIP_RANGE(2.5),
133                 BIP_RANGE(1.25)
134         }
135 };
136
137 static const struct comedi_lrange range_dt282x_ai_lo_unipolar = {
138         4, {
139                 UNI_RANGE(10),
140                 UNI_RANGE(5),
141                 UNI_RANGE(2.5),
142                 UNI_RANGE(1.25)
143         }
144 };
145
146 static const struct comedi_lrange range_dt282x_ai_5_bipolar = {
147         4, {
148                 BIP_RANGE(5),
149                 BIP_RANGE(2.5),
150                 BIP_RANGE(1.25),
151                 BIP_RANGE(0.625)
152         }
153 };
154
155 static const struct comedi_lrange range_dt282x_ai_5_unipolar = {
156         4, {
157                 UNI_RANGE(5),
158                 UNI_RANGE(2.5),
159                 UNI_RANGE(1.25),
160                 UNI_RANGE(0.625)
161         }
162 };
163
164 static const struct comedi_lrange range_dt282x_ai_hi_bipolar = {
165         4, {
166                 BIP_RANGE(10),
167                 BIP_RANGE(1),
168                 BIP_RANGE(0.1),
169                 BIP_RANGE(0.02)
170         }
171 };
172
173 static const struct comedi_lrange range_dt282x_ai_hi_unipolar = {
174         4, {
175                 UNI_RANGE(10),
176                 UNI_RANGE(1),
177                 UNI_RANGE(0.1),
178                 UNI_RANGE(0.02)
179         }
180 };
181
182 /*
183  * The Analog Output range is set per-channel using jumpers on the board.
184  * All of these ranges may not be available on some DT2821 series boards.
185  * The default jumper setting has both channels set for +/-10V output.
186  */
187 static const struct comedi_lrange dt282x_ao_range = {
188         5, {
189                 BIP_RANGE(10),
190                 BIP_RANGE(5),
191                 BIP_RANGE(2.5),
192                 UNI_RANGE(10),
193                 UNI_RANGE(5),
194         }
195 };
196
197 struct dt282x_board {
198         const char *name;
199         unsigned int ai_maxdata;
200         int adchan_se;
201         int adchan_di;
202         int ai_speed;
203         int ispgl;
204         int dachan;
205         unsigned int ao_maxdata;
206 };
207
208 static const struct dt282x_board boardtypes[] = {
209         {
210                 .name           = "dt2821",
211                 .ai_maxdata     = 0x0fff,
212                 .adchan_se      = 16,
213                 .adchan_di      = 8,
214                 .ai_speed       = 20000,
215                 .dachan         = 2,
216                 .ao_maxdata     = 0x0fff,
217         }, {
218                 .name           = "dt2821-f",
219                 .ai_maxdata     = 0x0fff,
220                 .adchan_se      = 16,
221                 .adchan_di      = 8,
222                 .ai_speed       = 6500,
223                 .dachan         = 2,
224                 .ao_maxdata     = 0x0fff,
225         }, {
226                 .name           = "dt2821-g",
227                 .ai_maxdata     = 0x0fff,
228                 .adchan_se      = 16,
229                 .adchan_di      = 8,
230                 .ai_speed       = 4000,
231                 .dachan         = 2,
232                 .ao_maxdata     = 0x0fff,
233         }, {
234                 .name           = "dt2823",
235                 .ai_maxdata     = 0xffff,
236                 .adchan_di      = 4,
237                 .ai_speed       = 10000,
238                 .dachan         = 2,
239                 .ao_maxdata     = 0xffff,
240         }, {
241                 .name           = "dt2824-pgh",
242                 .ai_maxdata     = 0x0fff,
243                 .adchan_se      = 16,
244                 .adchan_di      = 8,
245                 .ai_speed       = 20000,
246         }, {
247                 .name           = "dt2824-pgl",
248                 .ai_maxdata     = 0x0fff,
249                 .adchan_se      = 16,
250                 .adchan_di      = 8,
251                 .ai_speed       = 20000,
252                 .ispgl          = 1,
253         }, {
254                 .name           = "dt2825",
255                 .ai_maxdata     = 0x0fff,
256                 .adchan_se      = 16,
257                 .adchan_di      = 8,
258                 .ai_speed       = 20000,
259                 .ispgl          = 1,
260                 .dachan         = 2,
261                 .ao_maxdata     = 0x0fff,
262         }, {
263                 .name           = "dt2827",
264                 .ai_maxdata     = 0xffff,
265                 .adchan_di      = 4,
266                 .ai_speed       = 10000,
267                 .dachan         = 2,
268                 .ao_maxdata     = 0x0fff,
269         }, {
270                 .name           = "dt2828",
271                 .ai_maxdata     = 0x0fff,
272                 .adchan_se      = 4,
273                 .ai_speed       = 10000,
274                 .dachan         = 2,
275                 .ao_maxdata     = 0x0fff,
276         }, {
277                 .name           = "dt2829",
278                 .ai_maxdata     = 0xffff,
279                 .adchan_se      = 8,
280                 .ai_speed       = 33250,
281                 .dachan         = 2,
282                 .ao_maxdata     = 0xffff,
283         }, {
284                 .name           = "dt21-ez",
285                 .ai_maxdata     = 0x0fff,
286                 .adchan_se      = 16,
287                 .adchan_di      = 8,
288                 .ai_speed       = 10000,
289                 .dachan         = 2,
290                 .ao_maxdata     = 0x0fff,
291         }, {
292                 .name           = "dt23-ez",
293                 .ai_maxdata     = 0xffff,
294                 .adchan_se      = 16,
295                 .adchan_di      = 8,
296                 .ai_speed       = 10000,
297         }, {
298                 .name           = "dt24-ez",
299                 .ai_maxdata     = 0x0fff,
300                 .adchan_se      = 16,
301                 .adchan_di      = 8,
302                 .ai_speed       = 10000,
303         }, {
304                 .name           = "dt24-ez-pgl",
305                 .ai_maxdata     = 0x0fff,
306                 .adchan_se      = 16,
307                 .adchan_di      = 8,
308                 .ai_speed       = 10000,
309                 .ispgl          = 1,
310         },
311 };
312
313 struct dt282x_private {
314         struct comedi_isadma *dma;
315         unsigned int ad_2scomp:1;
316         unsigned int divisor;
317         int dacsr;      /* software copies of registers */
318         int adcsr;
319         int supcsr;
320         int ntrig;
321         int nread;
322         int dma_dir;
323 };
324
325 static int dt282x_prep_ai_dma(struct comedi_device *dev, int dma_index, int n)
326 {
327         struct dt282x_private *devpriv = dev->private;
328         struct comedi_isadma *dma = devpriv->dma;
329         struct comedi_isadma_desc *desc = &dma->desc[dma_index];
330
331         if (!devpriv->ntrig)
332                 return 0;
333
334         if (n == 0)
335                 n = desc->maxsize;
336         if (n > devpriv->ntrig * 2)
337                 n = devpriv->ntrig * 2;
338         devpriv->ntrig -= n / 2;
339
340         desc->size = n;
341         comedi_isadma_set_mode(desc, devpriv->dma_dir);
342
343         comedi_isadma_program(desc);
344
345         return n;
346 }
347
348 static int dt282x_prep_ao_dma(struct comedi_device *dev, int dma_index, int n)
349 {
350         struct dt282x_private *devpriv = dev->private;
351         struct comedi_isadma *dma = devpriv->dma;
352         struct comedi_isadma_desc *desc = &dma->desc[dma_index];
353
354         desc->size = n;
355         comedi_isadma_set_mode(desc, devpriv->dma_dir);
356
357         comedi_isadma_program(desc);
358
359         return n;
360 }
361
362 static void dt282x_disable_dma(struct comedi_device *dev)
363 {
364         struct dt282x_private *devpriv = dev->private;
365         struct comedi_isadma *dma = devpriv->dma;
366         struct comedi_isadma_desc *desc;
367         int i;
368
369         for (i = 0; i < 2; i++) {
370                 desc = &dma->desc[i];
371                 comedi_isadma_disable(desc->chan);
372         }
373 }
374
375 static unsigned int dt282x_ns_to_timer(unsigned int *ns, unsigned int flags)
376 {
377         unsigned int prescale, base, divider;
378
379         for (prescale = 0; prescale <= DT2821_PRESCALE_MAX; prescale++) {
380                 if (prescale == 1)      /* 0 and 1 are both divide by 1 */
381                         continue;
382                 base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale);
383                 switch (flags & CMDF_ROUND_MASK) {
384                 case CMDF_ROUND_NEAREST:
385                 default:
386                         divider = DIV_ROUND_CLOSEST(*ns, base);
387                         break;
388                 case CMDF_ROUND_DOWN:
389                         divider = (*ns) / base;
390                         break;
391                 case CMDF_ROUND_UP:
392                         divider = DIV_ROUND_UP(*ns, base);
393                         break;
394                 }
395                 if (divider <= DT2821_DIVIDER_MAX)
396                         break;
397         }
398         if (divider > DT2821_DIVIDER_MAX) {
399                 prescale = DT2821_PRESCALE_MAX;
400                 divider = DT2821_DIVIDER_MAX;
401                 base = DT2821_OSC_BASE * DT2821_PRESCALE(prescale);
402         }
403         *ns = divider * base;
404         return DT2821_TMRCTR_PRESCALE(prescale) |
405                DT2821_TMRCTR_DIVIDER(divider);
406 }
407
408 static void dt282x_munge(struct comedi_device *dev,
409                          struct comedi_subdevice *s,
410                          unsigned short *buf,
411                          unsigned int nbytes)
412 {
413         struct dt282x_private *devpriv = dev->private;
414         unsigned int val;
415         int i;
416
417         if (nbytes % 2)
418                 dev_err(dev->class_dev,
419                         "bug! odd number of bytes from dma xfer\n");
420
421         for (i = 0; i < nbytes / 2; i++) {
422                 val = buf[i];
423                 val &= s->maxdata;
424                 if (devpriv->ad_2scomp)
425                         val = comedi_offset_munge(s, val);
426
427                 buf[i] = val;
428         }
429 }
430
431 static unsigned int dt282x_ao_setup_dma(struct comedi_device *dev,
432                                         struct comedi_subdevice *s,
433                                         int cur_dma)
434 {
435         struct dt282x_private *devpriv = dev->private;
436         struct comedi_isadma *dma = devpriv->dma;
437         struct comedi_isadma_desc *desc = &dma->desc[cur_dma];
438         unsigned int nsamples = comedi_bytes_to_samples(s, desc->maxsize);
439         unsigned int nbytes;
440
441         nbytes = comedi_buf_read_samples(s, desc->virt_addr, nsamples);
442         if (nbytes)
443                 dt282x_prep_ao_dma(dev, cur_dma, nbytes);
444         else
445                 dev_err(dev->class_dev, "AO underrun\n");
446
447         return nbytes;
448 }
449
450 static void dt282x_ao_dma_interrupt(struct comedi_device *dev,
451                                     struct comedi_subdevice *s)
452 {
453         struct dt282x_private *devpriv = dev->private;
454         struct comedi_isadma *dma = devpriv->dma;
455         struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
456
457         outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
458              dev->iobase + DT2821_SUPCSR_REG);
459
460         comedi_isadma_disable(desc->chan);
461
462         if (!dt282x_ao_setup_dma(dev, s, dma->cur_dma))
463                 s->async->events |= COMEDI_CB_OVERFLOW;
464
465         dma->cur_dma = 1 - dma->cur_dma;
466 }
467
468 static void dt282x_ai_dma_interrupt(struct comedi_device *dev,
469                                     struct comedi_subdevice *s)
470 {
471         struct dt282x_private *devpriv = dev->private;
472         struct comedi_isadma *dma = devpriv->dma;
473         struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
474         unsigned int nsamples = comedi_bytes_to_samples(s, desc->size);
475         int ret;
476
477         outw(devpriv->supcsr | DT2821_SUPCSR_CLRDMADNE,
478              dev->iobase + DT2821_SUPCSR_REG);
479
480         comedi_isadma_disable(desc->chan);
481
482         dt282x_munge(dev, s, desc->virt_addr, desc->size);
483         ret = comedi_buf_write_samples(s, desc->virt_addr, nsamples);
484         if (ret != desc->size)
485                 return;
486
487         devpriv->nread -= nsamples;
488         if (devpriv->nread < 0) {
489                 dev_info(dev->class_dev, "nread off by one\n");
490                 devpriv->nread = 0;
491         }
492         if (!devpriv->nread) {
493                 s->async->events |= COMEDI_CB_EOA;
494                 return;
495         }
496 #if 0
497         /* clear the dual dma flag, making this the last dma segment */
498         /* XXX probably wrong */
499         if (!devpriv->ntrig) {
500                 devpriv->supcsr &= ~DT2821_SUPCSR_DDMA;
501                 outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
502         }
503 #endif
504         /* restart the channel */
505         dt282x_prep_ai_dma(dev, dma->cur_dma, 0);
506
507         dma->cur_dma = 1 - dma->cur_dma;
508 }
509
510 static irqreturn_t dt282x_interrupt(int irq, void *d)
511 {
512         struct comedi_device *dev = d;
513         struct dt282x_private *devpriv = dev->private;
514         struct comedi_subdevice *s = dev->read_subdev;
515         struct comedi_subdevice *s_ao = dev->write_subdev;
516         unsigned int supcsr, adcsr, dacsr;
517         int handled = 0;
518
519         if (!dev->attached) {
520                 dev_err(dev->class_dev, "spurious interrupt\n");
521                 return IRQ_HANDLED;
522         }
523
524         adcsr = inw(dev->iobase + DT2821_ADCSR_REG);
525         dacsr = inw(dev->iobase + DT2821_DACSR_REG);
526         supcsr = inw(dev->iobase + DT2821_SUPCSR_REG);
527         if (supcsr & DT2821_SUPCSR_DMAD) {
528                 if (devpriv->dma_dir == COMEDI_ISADMA_READ)
529                         dt282x_ai_dma_interrupt(dev, s);
530                 else
531                         dt282x_ao_dma_interrupt(dev, s_ao);
532                 handled = 1;
533         }
534         if (adcsr & DT2821_ADCSR_ADERR) {
535                 if (devpriv->nread != 0) {
536                         dev_err(dev->class_dev, "A/D error\n");
537                         s->async->events |= COMEDI_CB_ERROR;
538                 }
539                 handled = 1;
540         }
541         if (dacsr & DT2821_DACSR_DAERR) {
542                 dev_err(dev->class_dev, "D/A error\n");
543                 s_ao->async->events |= COMEDI_CB_ERROR;
544                 handled = 1;
545         }
546 #if 0
547         if (adcsr & DT2821_ADCSR_ADDONE) {
548                 unsigned short data;
549
550                 data = inw(dev->iobase + DT2821_ADDAT_REG);
551                 data &= s->maxdata;
552                 if (devpriv->ad_2scomp)
553                         data = comedi_offset_munge(s, data);
554
555                 comedi_buf_write_samples(s, &data, 1);
556
557                 devpriv->nread--;
558                 if (!devpriv->nread) {
559                         s->async->events |= COMEDI_CB_EOA;
560                 } else {
561                         if (supcsr & DT2821_SUPCSR_SCDN)
562                                 outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
563                                      dev->iobase + DT2821_SUPCSR_REG);
564                 }
565                 handled = 1;
566         }
567 #endif
568         comedi_handle_events(dev, s);
569         comedi_handle_events(dev, s_ao);
570
571         return IRQ_RETVAL(handled);
572 }
573
574 static void dt282x_load_changain(struct comedi_device *dev, int n,
575                                  unsigned int *chanlist)
576 {
577         struct dt282x_private *devpriv = dev->private;
578         int i;
579
580         outw(DT2821_CHANCSR_LLE | DT2821_CHANCSR_NUMB(n),
581              dev->iobase + DT2821_CHANCSR_REG);
582         for (i = 0; i < n; i++) {
583                 unsigned int chan = CR_CHAN(chanlist[i]);
584                 unsigned int range = CR_RANGE(chanlist[i]);
585
586                 outw(devpriv->adcsr |
587                      DT2821_ADCSR_GS(range) |
588                      DT2821_ADCSR_CHAN(chan),
589                      dev->iobase + DT2821_ADCSR_REG);
590         }
591         outw(DT2821_CHANCSR_NUMB(n), dev->iobase + DT2821_CHANCSR_REG);
592 }
593
594 static int dt282x_ai_timeout(struct comedi_device *dev,
595                              struct comedi_subdevice *s,
596                              struct comedi_insn *insn,
597                              unsigned long context)
598 {
599         unsigned int status;
600
601         status = inw(dev->iobase + DT2821_ADCSR_REG);
602         switch (context) {
603         case DT2821_ADCSR_MUXBUSY:
604                 if ((status & DT2821_ADCSR_MUXBUSY) == 0)
605                         return 0;
606                 break;
607         case DT2821_ADCSR_ADDONE:
608                 if (status & DT2821_ADCSR_ADDONE)
609                         return 0;
610                 break;
611         default:
612                 return -EINVAL;
613         }
614         return -EBUSY;
615 }
616
617 /*
618  *    Performs a single A/D conversion.
619  *      - Put channel/gain into channel-gain list
620  *      - preload multiplexer
621  *      - trigger conversion and wait for it to finish
622  */
623 static int dt282x_ai_insn_read(struct comedi_device *dev,
624                                struct comedi_subdevice *s,
625                                struct comedi_insn *insn,
626                                unsigned int *data)
627 {
628         struct dt282x_private *devpriv = dev->private;
629         unsigned int val;
630         int ret;
631         int i;
632
633         /* XXX should we really be enabling the ad clock here? */
634         devpriv->adcsr = DT2821_ADCSR_ADCLK;
635         outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
636
637         dt282x_load_changain(dev, 1, &insn->chanspec);
638
639         outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
640              dev->iobase + DT2821_SUPCSR_REG);
641         ret = comedi_timeout(dev, s, insn,
642                              dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
643         if (ret)
644                 return ret;
645
646         for (i = 0; i < insn->n; i++) {
647                 outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
648                      dev->iobase + DT2821_SUPCSR_REG);
649
650                 ret = comedi_timeout(dev, s, insn,
651                                      dt282x_ai_timeout, DT2821_ADCSR_ADDONE);
652                 if (ret)
653                         return ret;
654
655                 val = inw(dev->iobase + DT2821_ADDAT_REG);
656                 val &= s->maxdata;
657                 if (devpriv->ad_2scomp)
658                         val = comedi_offset_munge(s, val);
659
660                 data[i] = val;
661         }
662
663         return i;
664 }
665
666 static int dt282x_ai_cmdtest(struct comedi_device *dev,
667                              struct comedi_subdevice *s,
668                              struct comedi_cmd *cmd)
669 {
670         const struct dt282x_board *board = dev->board_ptr;
671         struct dt282x_private *devpriv = dev->private;
672         int err = 0;
673         unsigned int arg;
674
675         /* Step 1 : check if triggers are trivially valid */
676
677         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
678         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
679                                         TRIG_FOLLOW | TRIG_EXT);
680         err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
681         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
682         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
683
684         if (err)
685                 return 1;
686
687         /* Step 2a : make sure trigger sources are unique */
688
689         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
690         err |= comedi_check_trigger_is_unique(cmd->stop_src);
691
692         /* Step 2b : and mutually compatible */
693
694         if (err)
695                 return 2;
696
697         /* Step 3: check if arguments are trivially valid */
698
699         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
700         err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
701         err |= comedi_check_trigger_arg_max(&cmd->convert_arg, DT2821_OSC_MAX);
702         err |= comedi_check_trigger_arg_min(&cmd->convert_arg, board->ai_speed);
703         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
704                                            cmd->chanlist_len);
705
706         if (cmd->stop_src == TRIG_COUNT)
707                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
708         else    /* TRIG_EXT | TRIG_NONE */
709                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
710
711         if (err)
712                 return 3;
713
714         /* step 4: fix up any arguments */
715
716         arg = cmd->convert_arg;
717         devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
718         err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
719
720         if (err)
721                 return 4;
722
723         return 0;
724 }
725
726 static int dt282x_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
727 {
728         struct dt282x_private *devpriv = dev->private;
729         struct comedi_isadma *dma = devpriv->dma;
730         struct comedi_cmd *cmd = &s->async->cmd;
731         int ret;
732
733         dt282x_disable_dma(dev);
734
735         outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
736
737         devpriv->supcsr = DT2821_SUPCSR_ERRINTEN;
738         if (cmd->scan_begin_src == TRIG_FOLLOW)
739                 devpriv->supcsr = DT2821_SUPCSR_DS_AD_CLK;
740         else
741                 devpriv->supcsr = DT2821_SUPCSR_DS_AD_TRIG;
742         outw(devpriv->supcsr |
743              DT2821_SUPCSR_CLRDMADNE |
744              DT2821_SUPCSR_BUFFB |
745              DT2821_SUPCSR_ADCINIT,
746              dev->iobase + DT2821_SUPCSR_REG);
747
748         devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
749         devpriv->nread = devpriv->ntrig;
750
751         devpriv->dma_dir = COMEDI_ISADMA_READ;
752         dma->cur_dma = 0;
753         dt282x_prep_ai_dma(dev, 0, 0);
754         if (devpriv->ntrig) {
755                 dt282x_prep_ai_dma(dev, 1, 0);
756                 devpriv->supcsr |= DT2821_SUPCSR_DDMA;
757                 outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
758         }
759
760         devpriv->adcsr = 0;
761
762         dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
763
764         devpriv->adcsr = DT2821_ADCSR_ADCLK | DT2821_ADCSR_IADDONE;
765         outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
766
767         outw(devpriv->supcsr | DT2821_SUPCSR_PRLD,
768              dev->iobase + DT2821_SUPCSR_REG);
769         ret = comedi_timeout(dev, s, NULL,
770                              dt282x_ai_timeout, DT2821_ADCSR_MUXBUSY);
771         if (ret)
772                 return ret;
773
774         if (cmd->scan_begin_src == TRIG_FOLLOW) {
775                 outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
776                      dev->iobase + DT2821_SUPCSR_REG);
777         } else {
778                 devpriv->supcsr |= DT2821_SUPCSR_XTRIG;
779                 outw(devpriv->supcsr, dev->iobase + DT2821_SUPCSR_REG);
780         }
781
782         return 0;
783 }
784
785 static int dt282x_ai_cancel(struct comedi_device *dev,
786                             struct comedi_subdevice *s)
787 {
788         struct dt282x_private *devpriv = dev->private;
789
790         dt282x_disable_dma(dev);
791
792         devpriv->adcsr = 0;
793         outw(devpriv->adcsr, dev->iobase + DT2821_ADCSR_REG);
794
795         devpriv->supcsr = 0;
796         outw(devpriv->supcsr | DT2821_SUPCSR_ADCINIT,
797              dev->iobase + DT2821_SUPCSR_REG);
798
799         return 0;
800 }
801
802 static int dt282x_ao_insn_write(struct comedi_device *dev,
803                                 struct comedi_subdevice *s,
804                                 struct comedi_insn *insn,
805                                 unsigned int *data)
806 {
807         struct dt282x_private *devpriv = dev->private;
808         unsigned int chan = CR_CHAN(insn->chanspec);
809         unsigned int range = CR_RANGE(insn->chanspec);
810         int i;
811
812         devpriv->dacsr |= DT2821_DACSR_SSEL | DT2821_DACSR_YSEL(chan);
813
814         for (i = 0; i < insn->n; i++) {
815                 unsigned int val = data[i];
816
817                 s->readback[chan] = val;
818
819                 if (comedi_range_is_bipolar(s, range))
820                         val = comedi_offset_munge(s, val);
821
822                 outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
823
824                 outw(val, dev->iobase + DT2821_DADAT_REG);
825
826                 outw(devpriv->supcsr | DT2821_SUPCSR_DACON,
827                      dev->iobase + DT2821_SUPCSR_REG);
828         }
829
830         return insn->n;
831 }
832
833 static int dt282x_ao_cmdtest(struct comedi_device *dev,
834                              struct comedi_subdevice *s,
835                              struct comedi_cmd *cmd)
836 {
837         struct dt282x_private *devpriv = dev->private;
838         int err = 0;
839         unsigned int arg;
840
841         /* Step 1 : check if triggers are trivially valid */
842
843         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
844         err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
845         err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
846         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
847         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
848
849         if (err)
850                 return 1;
851
852         /* Step 2a : make sure trigger sources are unique */
853
854         err |= comedi_check_trigger_is_unique(cmd->stop_src);
855
856         /* Step 2b : and mutually compatible */
857
858         if (err)
859                 return 2;
860
861         /* Step 3: check if arguments are trivially valid */
862
863         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
864         err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 5000);
865         err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
866         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
867                                            cmd->chanlist_len);
868
869         if (cmd->stop_src == TRIG_COUNT)
870                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
871         else    /* TRIG_EXT | TRIG_NONE */
872                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
873
874         if (err)
875                 return 3;
876
877         /* step 4: fix up any arguments */
878
879         arg = cmd->scan_begin_arg;
880         devpriv->divisor = dt282x_ns_to_timer(&arg, cmd->flags);
881         err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
882
883         if (err)
884                 return 4;
885
886         return 0;
887 }
888
889 static int dt282x_ao_inttrig(struct comedi_device *dev,
890                              struct comedi_subdevice *s,
891                              unsigned int trig_num)
892 {
893         struct dt282x_private *devpriv = dev->private;
894         struct comedi_cmd *cmd = &s->async->cmd;
895
896         if (trig_num != cmd->start_src)
897                 return -EINVAL;
898
899         if (!dt282x_ao_setup_dma(dev, s, 0))
900                 return -EPIPE;
901
902         if (!dt282x_ao_setup_dma(dev, s, 1))
903                 return -EPIPE;
904
905         outw(devpriv->supcsr | DT2821_SUPCSR_STRIG,
906              dev->iobase + DT2821_SUPCSR_REG);
907         s->async->inttrig = NULL;
908
909         return 1;
910 }
911
912 static int dt282x_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
913 {
914         struct dt282x_private *devpriv = dev->private;
915         struct comedi_isadma *dma = devpriv->dma;
916         struct comedi_cmd *cmd = &s->async->cmd;
917
918         dt282x_disable_dma(dev);
919
920         devpriv->supcsr = DT2821_SUPCSR_ERRINTEN |
921                           DT2821_SUPCSR_DS_DA_CLK |
922                           DT2821_SUPCSR_DDMA;
923         outw(devpriv->supcsr |
924              DT2821_SUPCSR_CLRDMADNE |
925              DT2821_SUPCSR_BUFFB |
926              DT2821_SUPCSR_DACINIT,
927              dev->iobase + DT2821_SUPCSR_REG);
928
929         devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
930         devpriv->nread = devpriv->ntrig;
931
932         devpriv->dma_dir = COMEDI_ISADMA_WRITE;
933         dma->cur_dma = 0;
934
935         outw(devpriv->divisor, dev->iobase + DT2821_TMRCTR_REG);
936
937         /* clear all bits but the DIO direction bits */
938         devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
939
940         devpriv->dacsr |= (DT2821_DACSR_SSEL |
941                            DT2821_DACSR_DACLK |
942                            DT2821_DACSR_IDARDY);
943         outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
944
945         s->async->inttrig = dt282x_ao_inttrig;
946
947         return 0;
948 }
949
950 static int dt282x_ao_cancel(struct comedi_device *dev,
951                             struct comedi_subdevice *s)
952 {
953         struct dt282x_private *devpriv = dev->private;
954
955         dt282x_disable_dma(dev);
956
957         /* clear all bits but the DIO direction bits */
958         devpriv->dacsr &= (DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
959
960         outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
961
962         devpriv->supcsr = 0;
963         outw(devpriv->supcsr | DT2821_SUPCSR_DACINIT,
964              dev->iobase + DT2821_SUPCSR_REG);
965
966         return 0;
967 }
968
969 static int dt282x_dio_insn_bits(struct comedi_device *dev,
970                                 struct comedi_subdevice *s,
971                                 struct comedi_insn *insn,
972                                 unsigned int *data)
973 {
974         if (comedi_dio_update_state(s, data))
975                 outw(s->state, dev->iobase + DT2821_DIODAT_REG);
976
977         data[1] = inw(dev->iobase + DT2821_DIODAT_REG);
978
979         return insn->n;
980 }
981
982 static int dt282x_dio_insn_config(struct comedi_device *dev,
983                                   struct comedi_subdevice *s,
984                                   struct comedi_insn *insn,
985                                   unsigned int *data)
986 {
987         struct dt282x_private *devpriv = dev->private;
988         unsigned int chan = CR_CHAN(insn->chanspec);
989         unsigned int mask;
990         int ret;
991
992         if (chan < 8)
993                 mask = 0x00ff;
994         else
995                 mask = 0xff00;
996
997         ret = comedi_dio_insn_config(dev, s, insn, data, mask);
998         if (ret)
999                 return ret;
1000
1001         devpriv->dacsr &= ~(DT2821_DACSR_LBOE | DT2821_DACSR_HBOE);
1002         if (s->io_bits & 0x00ff)
1003                 devpriv->dacsr |= DT2821_DACSR_LBOE;
1004         if (s->io_bits & 0xff00)
1005                 devpriv->dacsr |= DT2821_DACSR_HBOE;
1006
1007         outw(devpriv->dacsr, dev->iobase + DT2821_DACSR_REG);
1008
1009         return insn->n;
1010 }
1011
1012 static const struct comedi_lrange *const ai_range_table[] = {
1013         &range_dt282x_ai_lo_bipolar,
1014         &range_dt282x_ai_lo_unipolar,
1015         &range_dt282x_ai_5_bipolar,
1016         &range_dt282x_ai_5_unipolar
1017 };
1018
1019 static const struct comedi_lrange *const ai_range_pgl_table[] = {
1020         &range_dt282x_ai_hi_bipolar,
1021         &range_dt282x_ai_hi_unipolar
1022 };
1023
1024 static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
1025 {
1026         if (ispgl) {
1027                 if (x < 0 || x >= 2)
1028                         x = 0;
1029                 return ai_range_pgl_table[x];
1030         }
1031
1032         if (x < 0 || x >= 4)
1033                 x = 0;
1034         return ai_range_table[x];
1035 }
1036
1037 static void dt282x_alloc_dma(struct comedi_device *dev,
1038                              struct comedi_devconfig *it)
1039 {
1040         struct dt282x_private *devpriv = dev->private;
1041         unsigned int irq_num = it->options[1];
1042         unsigned int dma_chan[2];
1043
1044         if (it->options[2] < it->options[3]) {
1045                 dma_chan[0] = it->options[2];
1046                 dma_chan[1] = it->options[3];
1047         } else {
1048                 dma_chan[0] = it->options[3];
1049                 dma_chan[1] = it->options[2];
1050         }
1051
1052         if (!irq_num || dma_chan[0] == dma_chan[1] ||
1053             dma_chan[0] < 5 || dma_chan[0] > 7 ||
1054             dma_chan[1] < 5 || dma_chan[1] > 7)
1055                 return;
1056
1057         if (request_irq(irq_num, dt282x_interrupt, 0, dev->board_name, dev))
1058                 return;
1059
1060         /* DMA uses two 4K buffers with separate DMA channels */
1061         devpriv->dma = comedi_isadma_alloc(dev, 2, dma_chan[0], dma_chan[1],
1062                                            PAGE_SIZE, 0);
1063         if (!devpriv->dma)
1064                 free_irq(irq_num, dev);
1065 }
1066
1067 static void dt282x_free_dma(struct comedi_device *dev)
1068 {
1069         struct dt282x_private *devpriv = dev->private;
1070
1071         if (devpriv)
1072                 comedi_isadma_free(devpriv->dma);
1073 }
1074
1075 static int dt282x_initialize(struct comedi_device *dev)
1076 {
1077         /* Initialize board */
1078         outw(DT2821_SUPCSR_BDINIT, dev->iobase + DT2821_SUPCSR_REG);
1079         inw(dev->iobase + DT2821_ADCSR_REG);
1080
1081         /*
1082          * At power up, some registers are in a well-known state.
1083          * Check them to see if a DT2821 series board is present.
1084          */
1085         if (((inw(dev->iobase + DT2821_ADCSR_REG) & 0xfff0) != 0x7c00) ||
1086             ((inw(dev->iobase + DT2821_CHANCSR_REG) & 0xf0f0) != 0x70f0) ||
1087             ((inw(dev->iobase + DT2821_DACSR_REG) & 0x7c93) != 0x7c90) ||
1088             ((inw(dev->iobase + DT2821_SUPCSR_REG) & 0xf8ff) != 0x0000) ||
1089             ((inw(dev->iobase + DT2821_TMRCTR_REG) & 0xff00) != 0xf000)) {
1090                 dev_err(dev->class_dev, "board not found\n");
1091                 return -EIO;
1092         }
1093         return 0;
1094 }
1095
1096 static int dt282x_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1097 {
1098         const struct dt282x_board *board = dev->board_ptr;
1099         struct dt282x_private *devpriv;
1100         struct comedi_subdevice *s;
1101         int ret;
1102
1103         ret = comedi_request_region(dev, it->options[0], 0x10);
1104         if (ret)
1105                 return ret;
1106
1107         ret = dt282x_initialize(dev);
1108         if (ret)
1109                 return ret;
1110
1111         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1112         if (!devpriv)
1113                 return -ENOMEM;
1114
1115         /* an IRQ and 2 DMA channels are required for async command support */
1116         dt282x_alloc_dma(dev, it);
1117
1118         ret = comedi_alloc_subdevices(dev, 3);
1119         if (ret)
1120                 return ret;
1121
1122         /* Analog Input subdevice */
1123         s = &dev->subdevices[0];
1124         s->type         = COMEDI_SUBD_AI;
1125         s->subdev_flags = SDF_READABLE;
1126         if ((it->options[4] && board->adchan_di) || board->adchan_se == 0) {
1127                 s->subdev_flags |= SDF_DIFF;
1128                 s->n_chan       = board->adchan_di;
1129         } else {
1130                 s->subdev_flags |= SDF_COMMON;
1131                 s->n_chan       = board->adchan_se;
1132         }
1133         s->maxdata      = board->ai_maxdata;
1134
1135         s->range_table = opt_ai_range_lkup(board->ispgl, it->options[8]);
1136         devpriv->ad_2scomp = it->options[5] ? 1 : 0;
1137
1138         s->insn_read    = dt282x_ai_insn_read;
1139         if (dev->irq) {
1140                 dev->read_subdev = s;
1141                 s->subdev_flags |= SDF_CMD_READ;
1142                 s->len_chanlist = s->n_chan;
1143                 s->do_cmdtest   = dt282x_ai_cmdtest;
1144                 s->do_cmd       = dt282x_ai_cmd;
1145                 s->cancel       = dt282x_ai_cancel;
1146         }
1147
1148         /* Analog Output subdevice */
1149         s = &dev->subdevices[1];
1150         if (board->dachan) {
1151                 s->type         = COMEDI_SUBD_AO;
1152                 s->subdev_flags = SDF_WRITABLE;
1153                 s->n_chan       = board->dachan;
1154                 s->maxdata      = board->ao_maxdata;
1155                 /* ranges are per-channel, set by jumpers on the board */
1156                 s->range_table  = &dt282x_ao_range;
1157                 s->insn_write   = dt282x_ao_insn_write;
1158                 if (dev->irq) {
1159                         dev->write_subdev = s;
1160                         s->subdev_flags |= SDF_CMD_WRITE;
1161                         s->len_chanlist = s->n_chan;
1162                         s->do_cmdtest   = dt282x_ao_cmdtest;
1163                         s->do_cmd       = dt282x_ao_cmd;
1164                         s->cancel       = dt282x_ao_cancel;
1165                 }
1166
1167                 ret = comedi_alloc_subdev_readback(s);
1168                 if (ret)
1169                         return ret;
1170         } else {
1171                 s->type         = COMEDI_SUBD_UNUSED;
1172         }
1173
1174         /* Digital I/O subdevice */
1175         s = &dev->subdevices[2];
1176         s->type         = COMEDI_SUBD_DIO;
1177         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1178         s->n_chan       = 16;
1179         s->maxdata      = 1;
1180         s->range_table  = &range_digital;
1181         s->insn_bits    = dt282x_dio_insn_bits;
1182         s->insn_config  = dt282x_dio_insn_config;
1183
1184         return 0;
1185 }
1186
1187 static void dt282x_detach(struct comedi_device *dev)
1188 {
1189         dt282x_free_dma(dev);
1190         comedi_legacy_detach(dev);
1191 }
1192
1193 static struct comedi_driver dt282x_driver = {
1194         .driver_name    = "dt282x",
1195         .module         = THIS_MODULE,
1196         .attach         = dt282x_attach,
1197         .detach         = dt282x_detach,
1198         .board_name     = &boardtypes[0].name,
1199         .num_names      = ARRAY_SIZE(boardtypes),
1200         .offset         = sizeof(struct dt282x_board),
1201 };
1202 module_comedi_driver(dt282x_driver);
1203
1204 MODULE_AUTHOR("Comedi http://www.comedi.org");
1205 MODULE_DESCRIPTION("Comedi driver for Data Translation DT2821 series");
1206 MODULE_LICENSE("GPL");