Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ni_at_a2150.c
Go to the documentation of this file.
1 /*
2  comedi/drivers/ni_at_a2150.c
3  Driver for National Instruments AT-A2150 boards
4  Copyright (C) 2001, 2002 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: ni_at_a2150
27 Description: National Instruments AT-A2150
28 Author: Frank Mori Hess
29 Status: works
30 Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
31 
32 If you want to ac couple the board's inputs, use AREF_OTHER.
33 
34 Configuration options:
35  [0] - I/O port base address
36  [1] - IRQ (optional, required for timed conversions)
37  [2] - DMA (optional, required for timed conversions)
38 
39 */
40 /*
41 Yet another driver for obsolete hardware brought to you by Frank Hess.
42 Testing and debugging help provided by Dave Andruczyk.
43 
44 This driver supports the boards:
45 
46 AT-A2150C
47 AT-A2150S
48 
49 The only difference is their master clock frequencies.
50 
51 Options:
52  [0] - base io address
53  [1] - irq
54  [2] - dma channel
55 
56 References (from ftp://ftp.natinst.com/support/manuals):
57 
58  320360.pdf AT-A2150 User Manual
59 
60 TODO:
61 
62 analog level triggering
63 TRIG_WAKE_EOS
64 
65 */
66 
67 #include <linux/interrupt.h>
68 #include <linux/slab.h>
69 #include "../comedidev.h"
70 
71 #include <linux/ioport.h>
72 #include <linux/io.h>
73 #include <asm/dma.h>
74 
75 #include "8253.h"
76 #include "comedi_fc.h"
77 
78 #define A2150_SIZE 28
79 #define A2150_DMA_BUFFER_SIZE 0xff00 /* size in bytes of dma buffer */
80 
81 /* #define A2150_DEBUG enable debugging code */
82 #undef A2150_DEBUG /* disable debugging code */
83 
84 /* Registers and bits */
85 #define CONFIG_REG 0x0
86 #define CHANNEL_BITS(x) ((x) & 0x7)
87 #define CHANNEL_MASK 0x7
88 #define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
89 #define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
90 #define CLOCK_MASK (0xf << 3)
91 #define ENABLE0_BIT 0x80 /* enable (don't internally ground) channels 0 and 1 */
92 #define ENABLE1_BIT 0x100 /* enable (don't internally ground) channels 2 and 3 */
93 #define AC0_BIT 0x200 /* ac couple channels 0,1 */
94 #define AC1_BIT 0x400 /* ac couple channels 2,3 */
95 #define APD_BIT 0x800 /* analog power down */
96 #define DPD_BIT 0x1000 /* digital power down */
97 #define TRIGGER_REG 0x2 /* trigger config register */
98 #define POST_TRIGGER_BITS 0x2
99 #define DELAY_TRIGGER_BITS 0x3
100 #define HW_TRIG_EN 0x10 /* enable hardware trigger */
101 #define FIFO_START_REG 0x6 /* software start aquistion trigger */
102 #define FIFO_RESET_REG 0x8 /* clears fifo + fifo flags */
103 #define FIFO_DATA_REG 0xa /* read data */
104 #define DMA_TC_CLEAR_REG 0xe /* clear dma terminal count interrupt */
105 #define STATUS_REG 0x12 /* read only */
106 #define FNE_BIT 0x1 /* fifo not empty */
107 #define OVFL_BIT 0x8 /* fifo overflow */
108 #define EDAQ_BIT 0x10 /* end of acquisition interrupt */
109 #define DCAL_BIT 0x20 /* offset calibration in progress */
110 #define INTR_BIT 0x40 /* interrupt has occurred */
111 #define DMA_TC_BIT 0x80 /* dma terminal count interrupt has occurred */
112 #define ID_BITS(x) (((x) >> 8) & 0x3)
113 #define IRQ_DMA_CNTRL_REG 0x12 /* write only */
114 #define DMA_CHAN_BITS(x) ((x) & 0x7) /* sets dma channel */
115 #define DMA_EN_BIT 0x8 /* enables dma */
116 #define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) /* sets irq level */
117 #define FIFO_INTR_EN_BIT 0x100 /* enable fifo interrupts */
118 #define FIFO_INTR_FHF_BIT 0x200 /* interrupt fifo half full */
119 #define DMA_INTR_EN_BIT 0x800 /* enable interrupt on dma terminal count */
120 #define DMA_DEM_EN_BIT 0x1000 /* enables demand mode dma */
121 #define I8253_BASE_REG 0x14
122 #define I8253_MODE_REG 0x17
123 #define HW_COUNT_DISABLE 0x30 /* disable hardware counting of conversions */
124 
125 struct a2150_board {
126  const char *name;
127  int clock[4]; /* master clock periods, in nanoseconds */
128  int num_clocks; /* number of available master clock speeds */
129  int ai_speed; /* maximum conversion rate in nanoseconds */
130 };
131 
132 /* analog input range */
133 static const struct comedi_lrange range_a2150 = {
134  1,
135  {
136  RANGE(-2.828, 2.828),
137  }
138 };
139 
140 /* enum must match board indices */
141 enum { a2150_c, a2150_s };
142 static const struct a2150_board a2150_boards[] = {
143  {
144  .name = "at-a2150c",
145  .clock = {31250, 22676, 20833, 19531},
146  .num_clocks = 4,
147  .ai_speed = 19531,
148  },
149  {
150  .name = "at-a2150s",
151  .clock = {62500, 50000, 41667, 0},
152  .num_clocks = 3,
153  .ai_speed = 41667,
154  },
155 };
156 
157 /*
158  * Useful for shorthand access to the particular board structure
159  */
160 #define thisboard ((const struct a2150_board *)dev->board_ptr)
161 
163 
164  volatile unsigned int count; /* number of data points left to be taken */
165  unsigned int dma; /* dma channel */
166  s16 *dma_buffer; /* dma buffer */
167  unsigned int dma_transfer_size; /* size in bytes of dma transfers */
168  int irq_dma_bits; /* irq/dma register bits */
169  int config_bits; /* config register bits */
170 };
171 
172 #define devpriv ((struct a2150_private *)dev->private)
173 
174 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
175 
176 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
177  int flags);
178 static int a2150_set_chanlist(struct comedi_device *dev,
179  unsigned int start_channel,
180  unsigned int num_channels);
181 #ifdef A2150_DEBUG
182 
183 static void ni_dump_regs(struct comedi_device *dev)
184 {
185  printk("config bits 0x%x\n", devpriv->config_bits);
186  printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
187  printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
188 }
189 
190 #endif
191 
192 /* interrupt service routine */
193 static irqreturn_t a2150_interrupt(int irq, void *d)
194 {
195  int i;
196  int status;
197  unsigned long flags;
198  struct comedi_device *dev = d;
199  struct comedi_subdevice *s = dev->read_subdev;
200  struct comedi_async *async;
201  struct comedi_cmd *cmd;
202  unsigned int max_points, num_points, residue, leftover;
203  short dpnt;
204  static const int sample_size = sizeof(devpriv->dma_buffer[0]);
205 
206  if (dev->attached == 0) {
207  comedi_error(dev, "premature interrupt");
208  return IRQ_HANDLED;
209  }
210  /* initialize async here to make sure s is not NULL */
211  async = s->async;
212  async->events = 0;
213  cmd = &async->cmd;
214 
215  status = inw(dev->iobase + STATUS_REG);
216 
217  if ((status & INTR_BIT) == 0) {
218  comedi_error(dev, "spurious interrupt");
219  return IRQ_NONE;
220  }
221 
222  if (status & OVFL_BIT) {
223  comedi_error(dev, "fifo overflow");
224  a2150_cancel(dev, s);
226  }
227 
228  if ((status & DMA_TC_BIT) == 0) {
229  comedi_error(dev, "caught non-dma interrupt? Aborting.");
230  a2150_cancel(dev, s);
232  comedi_event(dev, s);
233  return IRQ_HANDLED;
234  }
235 
236  flags = claim_dma_lock();
237  disable_dma(devpriv->dma);
238  /* clear flip-flop to make sure 2-byte registers for
239  * count and address get set correctly */
240  clear_dma_ff(devpriv->dma);
241 
242  /* figure out how many points to read */
243  max_points = devpriv->dma_transfer_size / sample_size;
244  /* residue is the number of points left to be done on the dma
245  * transfer. It should always be zero at this point unless
246  * the stop_src is set to external triggering.
247  */
248  residue = get_dma_residue(devpriv->dma) / sample_size;
249  num_points = max_points - residue;
250  if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
251  num_points = devpriv->count;
252 
253  /* figure out how many points will be stored next time */
254  leftover = 0;
255  if (cmd->stop_src == TRIG_NONE) {
256  leftover = devpriv->dma_transfer_size / sample_size;
257  } else if (devpriv->count > max_points) {
258  leftover = devpriv->count - max_points;
259  if (leftover > max_points)
260  leftover = max_points;
261  }
262  /* there should only be a residue if collection was stopped by having
263  * the stop_src set to an external trigger, in which case there
264  * will be no more data
265  */
266  if (residue)
267  leftover = 0;
268 
269  for (i = 0; i < num_points; i++) {
270  /* write data point to comedi buffer */
271  dpnt = devpriv->dma_buffer[i];
272  /* convert from 2's complement to unsigned coding */
273  dpnt ^= 0x8000;
274  cfc_write_to_buffer(s, dpnt);
275  if (cmd->stop_src == TRIG_COUNT) {
276  if (--devpriv->count == 0) { /* end of acquisition */
277  a2150_cancel(dev, s);
278  async->events |= COMEDI_CB_EOA;
279  break;
280  }
281  }
282  }
283  /* re-enable dma */
284  if (leftover) {
285  set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
286  set_dma_count(devpriv->dma, leftover * sample_size);
287  enable_dma(devpriv->dma);
288  }
289  release_dma_lock(flags);
290 
291  async->events |= COMEDI_CB_BLOCK;
292 
293  comedi_event(dev, s);
294 
295  /* clear interrupt */
296  outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
297 
298  return IRQ_HANDLED;
299 }
300 
301 static int a2150_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
302 {
303  /* disable dma on card */
304  devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
305  outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
306 
307  /* disable computer's dma */
308  disable_dma(devpriv->dma);
309 
310  /* clear fifo and reset triggering circuitry */
311  outw(0, dev->iobase + FIFO_RESET_REG);
312 
313  return 0;
314 }
315 
316 static int a2150_ai_cmdtest(struct comedi_device *dev,
317  struct comedi_subdevice *s, struct comedi_cmd *cmd)
318 {
319  int err = 0;
320  int tmp;
321  int startChan;
322  int i;
323 
324  /* Step 1 : check if triggers are trivially valid */
325 
326  err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
327  err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_TIMER);
328  err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
329  err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
330  err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
331 
332  if (err)
333  return 1;
334 
335  /* Step 2a : make sure trigger sources are unique */
336 
337  err |= cfc_check_trigger_is_unique(cmd->start_src);
338  err |= cfc_check_trigger_is_unique(cmd->stop_src);
339 
340  /* Step 2b : and mutually compatible */
341 
342  if (err)
343  return 2;
344 
345  /* step 3: make sure arguments are trivially compatible */
346 
347  if (cmd->start_arg != 0) {
348  cmd->start_arg = 0;
349  err++;
350  }
351  if (cmd->convert_src == TRIG_TIMER) {
352  if (cmd->convert_arg < thisboard->ai_speed) {
353  cmd->convert_arg = thisboard->ai_speed;
354  err++;
355  }
356  }
357  if (!cmd->chanlist_len) {
358  cmd->chanlist_len = 1;
359  err++;
360  }
361  if (cmd->scan_end_arg != cmd->chanlist_len) {
362  cmd->scan_end_arg = cmd->chanlist_len;
363  err++;
364  }
365  if (cmd->stop_src == TRIG_COUNT) {
366  if (!cmd->stop_arg) {
367  cmd->stop_arg = 1;
368  err++;
369  }
370  } else { /* TRIG_NONE */
371  if (cmd->stop_arg != 0) {
372  cmd->stop_arg = 0;
373  err++;
374  }
375  }
376 
377  if (err)
378  return 3;
379 
380  /* step 4: fix up any arguments */
381 
382  if (cmd->scan_begin_src == TRIG_TIMER) {
383  tmp = cmd->scan_begin_arg;
384  a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
385  if (tmp != cmd->scan_begin_arg)
386  err++;
387  }
388 
389  if (err)
390  return 4;
391 
392  /* check channel/gain list against card's limitations */
393  if (cmd->chanlist) {
394  startChan = CR_CHAN(cmd->chanlist[0]);
395  for (i = 1; i < cmd->chanlist_len; i++) {
396  if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
397  comedi_error(dev,
398  "entries in chanlist must be consecutive channels, counting upwards\n");
399  err++;
400  }
401  }
402  if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
403  comedi_error(dev,
404  "length 2 chanlist must be channels 0,1 or channels 2,3");
405  err++;
406  }
407  if (cmd->chanlist_len == 3) {
408  comedi_error(dev,
409  "chanlist must have 1,2 or 4 channels");
410  err++;
411  }
412  if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
413  CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) {
414  comedi_error(dev,
415  "channels 0/1 and 2/3 must have the same analog reference");
416  err++;
417  }
418  }
419 
420  if (err)
421  return 5;
422 
423  return 0;
424 }
425 
426 static int a2150_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
427 {
428  struct comedi_async *async = s->async;
429  struct comedi_cmd *cmd = &async->cmd;
430  unsigned long lock_flags;
431  unsigned int old_config_bits = devpriv->config_bits;
432  unsigned int trigger_bits;
433 
434  if (!dev->irq || !devpriv->dma) {
435  comedi_error(dev,
436  " irq and dma required, cannot do hardware conversions");
437  return -1;
438  }
439  if (cmd->flags & TRIG_RT) {
440  comedi_error(dev,
441  " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
442  return -1;
443  }
444  /* clear fifo and reset triggering circuitry */
445  outw(0, dev->iobase + FIFO_RESET_REG);
446 
447  /* setup chanlist */
448  if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
449  cmd->chanlist_len) < 0)
450  return -1;
451 
452  /* setup ac/dc coupling */
453  if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
454  devpriv->config_bits |= AC0_BIT;
455  else
456  devpriv->config_bits &= ~AC0_BIT;
457  if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
458  devpriv->config_bits |= AC1_BIT;
459  else
460  devpriv->config_bits &= ~AC1_BIT;
461 
462  /* setup timing */
463  a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
464 
465  /* send timing, channel, config bits */
466  outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
467 
468  /* initialize number of samples remaining */
469  devpriv->count = cmd->stop_arg * cmd->chanlist_len;
470 
471  /* enable computer's dma */
472  lock_flags = claim_dma_lock();
473  disable_dma(devpriv->dma);
474  /* clear flip-flop to make sure 2-byte registers for
475  * count and address get set correctly */
476  clear_dma_ff(devpriv->dma);
477  set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
478  /* set size of transfer to fill in 1/3 second */
479 #define ONE_THIRD_SECOND 333333333
480  devpriv->dma_transfer_size =
481  sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
482  ONE_THIRD_SECOND / cmd->scan_begin_arg;
483  if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
484  devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
485  if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
486  devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
487  devpriv->dma_transfer_size -=
488  devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
489  set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
490  enable_dma(devpriv->dma);
491  release_dma_lock(lock_flags);
492 
493  /* clear dma interrupt before enabling it, to try and get rid of that
494  * one spurious interrupt that has been happening */
495  outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
496 
497  /* enable dma on card */
498  devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
499  outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
500 
501  /* may need to wait 72 sampling periods if timing was changed */
502  i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
503 
504  /* setup start triggering */
505  trigger_bits = 0;
506  /* decide if we need to wait 72 periods for valid data */
507  if (cmd->start_src == TRIG_NOW &&
508  (old_config_bits & CLOCK_MASK) !=
509  (devpriv->config_bits & CLOCK_MASK)) {
510  /* set trigger source to delay trigger */
511  trigger_bits |= DELAY_TRIGGER_BITS;
512  } else {
513  /* otherwise no delay */
514  trigger_bits |= POST_TRIGGER_BITS;
515  }
516  /* enable external hardware trigger */
517  if (cmd->start_src == TRIG_EXT) {
518  trigger_bits |= HW_TRIG_EN;
519  } else if (cmd->start_src == TRIG_OTHER) {
520  /* XXX add support for level/slope start trigger using TRIG_OTHER */
521  comedi_error(dev, "you shouldn't see this?");
522  }
523  /* send trigger config bits */
524  outw(trigger_bits, dev->iobase + TRIGGER_REG);
525 
526  /* start acquisition for soft trigger */
527  if (cmd->start_src == TRIG_NOW)
528  outw(0, dev->iobase + FIFO_START_REG);
529 #ifdef A2150_DEBUG
530  ni_dump_regs(dev);
531 #endif
532 
533  return 0;
534 }
535 
536 static int a2150_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
537  struct comedi_insn *insn, unsigned int *data)
538 {
539  unsigned int i, n;
540  static const int timeout = 100000;
541  static const int filter_delay = 36;
542 
543  /* clear fifo and reset triggering circuitry */
544  outw(0, dev->iobase + FIFO_RESET_REG);
545 
546  /* setup chanlist */
547  if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
548  return -1;
549 
550  /* set dc coupling */
551  devpriv->config_bits &= ~AC0_BIT;
552  devpriv->config_bits &= ~AC1_BIT;
553 
554  /* send timing, channel, config bits */
555  outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
556 
557  /* disable dma on card */
558  devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
559  outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
560 
561  /* setup start triggering */
562  outw(0, dev->iobase + TRIGGER_REG);
563 
564  /* start acquisition for soft trigger */
565  outw(0, dev->iobase + FIFO_START_REG);
566 
567  /*
568  * there is a 35.6 sample delay for data to get through the
569  * antialias filter
570  */
571  for (n = 0; n < filter_delay; n++) {
572  for (i = 0; i < timeout; i++) {
573  if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
574  break;
575  udelay(1);
576  }
577  if (i == timeout) {
578  comedi_error(dev, "timeout");
579  return -ETIME;
580  }
581  inw(dev->iobase + FIFO_DATA_REG);
582  }
583 
584  /* read data */
585  for (n = 0; n < insn->n; n++) {
586  for (i = 0; i < timeout; i++) {
587  if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
588  break;
589  udelay(1);
590  }
591  if (i == timeout) {
592  comedi_error(dev, "timeout");
593  return -ETIME;
594  }
595 #ifdef A2150_DEBUG
596  ni_dump_regs(dev);
597 #endif
598  data[n] = inw(dev->iobase + FIFO_DATA_REG);
599 #ifdef A2150_DEBUG
600  printk(" data is %i\n", data[n]);
601 #endif
602  data[n] ^= 0x8000;
603  }
604 
605  /* clear fifo and reset triggering circuitry */
606  outw(0, dev->iobase + FIFO_RESET_REG);
607 
608  return n;
609 }
610 
611 /*
612  * sets bits in devpriv->clock_bits to nearest approximation of requested
613  * period, adjusts requested period to actual timing.
614  */
615 static int a2150_get_timing(struct comedi_device *dev, unsigned int *period,
616  int flags)
617 {
618  int lub, glb, temp;
619  int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
620  int i, j;
621 
622  /* initialize greatest lower and least upper bounds */
623  lub_divisor_shift = 3;
624  lub_index = 0;
625  lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
626  glb_divisor_shift = 0;
627  glb_index = thisboard->num_clocks - 1;
628  glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
629 
630  /* make sure period is in available range */
631  if (*period < glb)
632  *period = glb;
633  if (*period > lub)
634  *period = lub;
635 
636  /* we can multiply period by 1, 2, 4, or 8, using (1 << i) */
637  for (i = 0; i < 4; i++) {
638  /* there are a maximum of 4 master clocks */
639  for (j = 0; j < thisboard->num_clocks; j++) {
640  /* temp is the period in nanosec we are evaluating */
641  temp = thisboard->clock[j] * (1 << i);
642  /* if it is the best match yet */
643  if (temp < lub && temp >= *period) {
644  lub_divisor_shift = i;
645  lub_index = j;
646  lub = temp;
647  }
648  if (temp > glb && temp <= *period) {
649  glb_divisor_shift = i;
650  glb_index = j;
651  glb = temp;
652  }
653  }
654  }
655  flags &= TRIG_ROUND_MASK;
656  switch (flags) {
657  case TRIG_ROUND_NEAREST:
658  default:
659  /* if least upper bound is better approximation */
660  if (lub - *period < *period - glb)
661  *period = lub;
662  else
663  *period = glb;
664  break;
665  case TRIG_ROUND_UP:
666  *period = lub;
667  break;
668  case TRIG_ROUND_DOWN:
669  *period = glb;
670  break;
671  }
672 
673  /* set clock bits for config register appropriately */
674  devpriv->config_bits &= ~CLOCK_MASK;
675  if (*period == lub) {
676  devpriv->config_bits |=
677  CLOCK_SELECT_BITS(lub_index) |
678  CLOCK_DIVISOR_BITS(lub_divisor_shift);
679  } else {
680  devpriv->config_bits |=
681  CLOCK_SELECT_BITS(glb_index) |
682  CLOCK_DIVISOR_BITS(glb_divisor_shift);
683  }
684 
685  return 0;
686 }
687 
688 static int a2150_set_chanlist(struct comedi_device *dev,
689  unsigned int start_channel,
690  unsigned int num_channels)
691 {
692  if (start_channel + num_channels > 4)
693  return -1;
694 
695  devpriv->config_bits &= ~CHANNEL_MASK;
696 
697  switch (num_channels) {
698  case 1:
699  devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
700  break;
701  case 2:
702  if (start_channel == 0) {
703  devpriv->config_bits |= CHANNEL_BITS(0x2);
704  } else if (start_channel == 2) {
705  devpriv->config_bits |= CHANNEL_BITS(0x3);
706  } else {
707  return -1;
708  }
709  break;
710  case 4:
711  devpriv->config_bits |= CHANNEL_BITS(0x1);
712  break;
713  default:
714  return -1;
715  break;
716  }
717 
718  return 0;
719 }
720 
721 /* probes board type, returns offset */
722 static int a2150_probe(struct comedi_device *dev)
723 {
724  int status = inw(dev->iobase + STATUS_REG);
725  return ID_BITS(status);
726 }
727 
728 static int a2150_attach(struct comedi_device *dev, struct comedi_devconfig *it)
729 {
730  struct comedi_subdevice *s;
731  unsigned long iobase = it->options[0];
732  unsigned int irq = it->options[1];
733  unsigned int dma = it->options[2];
734  static const int timeout = 2000;
735  int i;
736  int ret;
737 
738  printk("comedi%d: %s: io 0x%lx", dev->minor, dev->driver->driver_name,
739  iobase);
740  if (irq) {
741  printk(", irq %u", irq);
742  } else {
743  printk(", no irq");
744  }
745  if (dma) {
746  printk(", dma %u", dma);
747  } else {
748  printk(", no dma");
749  }
750  printk("\n");
751 
752  /* allocate and initialize dev->private */
753  if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
754  return -ENOMEM;
755 
756  if (iobase == 0) {
757  printk(" io base address required\n");
758  return -EINVAL;
759  }
760 
761  /* check if io addresses are available */
762  if (!request_region(iobase, A2150_SIZE, dev->driver->driver_name)) {
763  printk(" I/O port conflict\n");
764  return -EIO;
765  }
766  dev->iobase = iobase;
767 
768  /* grab our IRQ */
769  if (irq) {
770  /* check that irq is supported */
771  if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
772  printk(" invalid irq line %u\n", irq);
773  return -EINVAL;
774  }
775  if (request_irq(irq, a2150_interrupt, 0,
776  dev->driver->driver_name, dev)) {
777  printk("unable to allocate irq %u\n", irq);
778  return -EINVAL;
779  }
780  devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
781  dev->irq = irq;
782  }
783  /* initialize dma */
784  if (dma) {
785  if (dma == 4 || dma > 7) {
786  printk(" invalid dma channel %u\n", dma);
787  return -EINVAL;
788  }
789  if (request_dma(dma, dev->driver->driver_name)) {
790  printk(" failed to allocate dma channel %u\n", dma);
791  return -EINVAL;
792  }
793  devpriv->dma = dma;
794  devpriv->dma_buffer =
796  if (devpriv->dma_buffer == NULL)
797  return -ENOMEM;
798 
799  disable_dma(dma);
801 
802  devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
803  }
804 
805  dev->board_ptr = a2150_boards + a2150_probe(dev);
806  dev->board_name = thisboard->name;
807 
808  ret = comedi_alloc_subdevices(dev, 1);
809  if (ret)
810  return ret;
811 
812  /* analog input subdevice */
813  s = &dev->subdevices[0];
814  dev->read_subdev = s;
815  s->type = COMEDI_SUBD_AI;
817  s->n_chan = 4;
818  s->len_chanlist = 4;
819  s->maxdata = 0xffff;
820  s->range_table = &range_a2150;
821  s->do_cmd = a2150_ai_cmd;
822  s->do_cmdtest = a2150_ai_cmdtest;
823  s->insn_read = a2150_ai_rinsn;
824  s->cancel = a2150_cancel;
825 
826  /* need to do this for software counting of completed conversions, to
827  * prevent hardware count from stopping acquisition */
829 
830  /* set card's irq and dma levels */
831  outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
832 
833  /* reset and sync adc clock circuitry */
835  outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
836  /* initialize configuration register */
837  devpriv->config_bits = 0;
838  outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
839  /* wait until offset calibration is done, then enable analog inputs */
840  for (i = 0; i < timeout; i++) {
841  if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
842  break;
843  udelay(1000);
844  }
845  if (i == timeout) {
846  printk
847  (" timed out waiting for offset calibration to complete\n");
848  return -ETIME;
849  }
850  devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
851  outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
852 
853  return 0;
854 };
855 
856 static void a2150_detach(struct comedi_device *dev)
857 {
858  if (dev->iobase) {
859  outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
861  }
862  if (dev->irq)
863  free_irq(dev->irq, dev);
864  if (devpriv) {
865  if (devpriv->dma)
866  free_dma(devpriv->dma);
867  kfree(devpriv->dma_buffer);
868  }
869 };
870 
871 static struct comedi_driver ni_at_a2150_driver = {
872  .driver_name = "ni_at_a2150",
873  .module = THIS_MODULE,
874  .attach = a2150_attach,
875  .detach = a2150_detach,
876 };
877 module_comedi_driver(ni_at_a2150_driver);
878 
879 MODULE_AUTHOR("Comedi http://www.comedi.org");
880 MODULE_DESCRIPTION("Comedi low-level driver");
881 MODULE_LICENSE("GPL");