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