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