Staging: iio: Fix missing include <linux/sched.h>
[deliverable/linux.git] / drivers / staging / comedi / drivers / ni_mio_common.c
CommitLineData
03aef4b6
DS
1/*
2 comedi/drivers/ni_mio_common.c
3 Hardware driver for DAQ-STC based boards
4
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
7 Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
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 This file is meant to be included by another file, e.g.,
27 ni_atmio.c or ni_pcimio.c.
28
29 Interrupt support originally added by Truxton Fulton
30 <trux@truxton.com>
31
32 References (from ftp://ftp.natinst.com/support/manuals):
33
34 340747b.pdf AT-MIO E series Register Level Programmer Manual
35 341079b.pdf PCI E Series RLPM
36 340934b.pdf DAQ-STC reference manual
37 67xx and 611x registers (from http://www.ni.com/pdf/daq/us)
38 release_ni611x.pdf
39 release_ni67xx.pdf
40 Other possibly relevant info:
41
42 320517c.pdf User manual (obsolete)
43 320517f.pdf User manual (new)
44 320889a.pdf delete
45 320906c.pdf maximum signal ratings
46 321066a.pdf about 16x
47 321791a.pdf discontinuation of at-mio-16e-10 rev. c
48 321808a.pdf about at-mio-16e-10 rev P
49 321837a.pdf discontinuation of at-mio-16de-10 rev d
50 321838a.pdf about at-mio-16de-10 rev N
51
52 ISSUES:
53
54 - the interrupt routine needs to be cleaned up
55
56 2006-02-07: S-Series PCI-6143: Support has been added but is not
57 fully tested as yet. Terry Barnaby, BEAM Ltd.
58*/
59
2696fb57
BP
60/* #define DEBUG_INTERRUPT */
61/* #define DEBUG_STATUS_A */
62/* #define DEBUG_STATUS_B */
03aef4b6 63
25436dc9 64#include <linux/interrupt.h>
03aef4b6
DS
65#include "8255.h"
66#include "mite.h"
67#include "comedi_fc.h"
68
69#ifndef MDPRINTK
f7cbd7aa 70#define MDPRINTK(format, args...)
03aef4b6
DS
71#endif
72
73/* A timeout count */
74#define NI_TIMEOUT 1000
75static const unsigned old_RTSI_clock_channel = 7;
76
77/* Note: this table must match the ai_gain_* definitions */
78static const short ni_gainlkup[][16] = {
79 [ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
0a85b6f0 80 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
03aef4b6
DS
81 [ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
82 [ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
0a85b6f0 83 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
03aef4b6
DS
84 [ai_gain_4] = {0, 1, 4, 7},
85 [ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
0a85b6f0 86 0x003, 0x004, 0x005, 0x006},
03aef4b6
DS
87 [ai_gain_622x] = {0, 1, 4, 5},
88 [ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
89 [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
90};
91
9ced1de6 92static const struct comedi_lrange range_ni_E_ai = { 16, {
0a85b6f0
MT
93 RANGE(-10, 10),
94 RANGE(-5, 5),
95 RANGE(-2.5, 2.5),
96 RANGE(-1, 1),
97 RANGE(-0.5, 0.5),
98 RANGE(-0.25, 0.25),
99 RANGE(-0.1, 0.1),
100 RANGE(-0.05, 0.05),
101 RANGE(0, 20),
102 RANGE(0, 10),
103 RANGE(0, 5),
104 RANGE(0, 2),
105 RANGE(0, 1),
106 RANGE(0, 0.5),
107 RANGE(0, 0.2),
108 RANGE(0, 0.1),
109 }
03aef4b6 110};
0a85b6f0 111
9ced1de6 112static const struct comedi_lrange range_ni_E_ai_limited = { 8, {
0a85b6f0
MT
113 RANGE(-10, 10),
114 RANGE(-5, 5),
115 RANGE(-1, 1),
116 RANGE(-0.1,
117 0.1),
118 RANGE(0, 10),
119 RANGE(0, 5),
120 RANGE(0, 1),
121 RANGE(0, 0.1),
122 }
03aef4b6 123};
0a85b6f0 124
9ced1de6 125static const struct comedi_lrange range_ni_E_ai_limited14 = { 14, {
0a85b6f0
MT
126 RANGE(-10,
127 10),
128 RANGE(-5, 5),
129 RANGE(-2, 2),
130 RANGE(-1, 1),
131 RANGE(-0.5,
132 0.5),
133 RANGE(-0.2,
134 0.2),
135 RANGE(-0.1,
136 0.1),
137 RANGE(0, 10),
138 RANGE(0, 5),
139 RANGE(0, 2),
140 RANGE(0, 1),
141 RANGE(0,
142 0.5),
143 RANGE(0,
144 0.2),
145 RANGE(0,
146 0.1),
147 }
03aef4b6 148};
0a85b6f0 149
9ced1de6 150static const struct comedi_lrange range_ni_E_ai_bipolar4 = { 4, {
0a85b6f0
MT
151 RANGE(-10, 10),
152 RANGE(-5, 5),
153 RANGE(-0.5,
154 0.5),
155 RANGE(-0.05,
156 0.05),
157 }
03aef4b6 158};
0a85b6f0 159
9ced1de6 160static const struct comedi_lrange range_ni_E_ai_611x = { 8, {
0a85b6f0
MT
161 RANGE(-50, 50),
162 RANGE(-20, 20),
163 RANGE(-10, 10),
164 RANGE(-5, 5),
165 RANGE(-2, 2),
166 RANGE(-1, 1),
167 RANGE(-0.5, 0.5),
168 RANGE(-0.2, 0.2),
169 }
03aef4b6 170};
0a85b6f0 171
9ced1de6 172static const struct comedi_lrange range_ni_M_ai_622x = { 4, {
0a85b6f0
MT
173 RANGE(-10, 10),
174 RANGE(-5, 5),
175 RANGE(-1, 1),
176 RANGE(-0.2, 0.2),
177 }
03aef4b6 178};
0a85b6f0 179
9ced1de6 180static const struct comedi_lrange range_ni_M_ai_628x = { 7, {
0a85b6f0
MT
181 RANGE(-10, 10),
182 RANGE(-5, 5),
183 RANGE(-2, 2),
184 RANGE(-1, 1),
185 RANGE(-0.5, 0.5),
186 RANGE(-0.2, 0.2),
187 RANGE(-0.1, 0.1),
188 }
03aef4b6 189};
0a85b6f0 190
9ced1de6 191static const struct comedi_lrange range_ni_S_ai_6143 = { 1, {
0a85b6f0
MT
192 RANGE(-5, +5),
193 }
03aef4b6 194};
0a85b6f0 195
9ced1de6 196static const struct comedi_lrange range_ni_E_ao_ext = { 4, {
0a85b6f0
MT
197 RANGE(-10, 10),
198 RANGE(0, 10),
199 RANGE_ext(-1, 1),
200 RANGE_ext(0, 1),
201 }
03aef4b6
DS
202};
203
9ced1de6 204static const struct comedi_lrange *const ni_range_lkup[] = {
03aef4b6
DS
205 [ai_gain_16] = &range_ni_E_ai,
206 [ai_gain_8] = &range_ni_E_ai_limited,
207 [ai_gain_14] = &range_ni_E_ai_limited14,
208 [ai_gain_4] = &range_ni_E_ai_bipolar4,
209 [ai_gain_611x] = &range_ni_E_ai_611x,
210 [ai_gain_622x] = &range_ni_M_ai_622x,
211 [ai_gain_628x] = &range_ni_M_ai_628x,
212 [ai_gain_6143] = &range_ni_S_ai_6143
213};
214
0a85b6f0
MT
215static int ni_dio_insn_config(struct comedi_device *dev,
216 struct comedi_subdevice *s,
217 struct comedi_insn *insn, unsigned int *data);
218static int ni_dio_insn_bits(struct comedi_device *dev,
219 struct comedi_subdevice *s,
220 struct comedi_insn *insn, unsigned int *data);
221static int ni_cdio_cmdtest(struct comedi_device *dev,
222 struct comedi_subdevice *s, struct comedi_cmd *cmd);
da91b269 223static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
0a85b6f0
MT
224static int ni_cdio_cancel(struct comedi_device *dev,
225 struct comedi_subdevice *s);
da91b269
BP
226static void handle_cdio_interrupt(struct comedi_device *dev);
227static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
228 unsigned int trignum);
229
230static int ni_serial_insn_config(struct comedi_device *dev,
231 struct comedi_subdevice *s,
232 struct comedi_insn *insn, unsigned int *data);
233static int ni_serial_hw_readwrite8(struct comedi_device *dev,
234 struct comedi_subdevice *s,
235 unsigned char data_out,
236 unsigned char *data_in);
237static int ni_serial_sw_readwrite8(struct comedi_device *dev,
238 struct comedi_subdevice *s,
239 unsigned char data_out,
240 unsigned char *data_in);
241
242static int ni_calib_insn_read(struct comedi_device *dev,
243 struct comedi_subdevice *s,
244 struct comedi_insn *insn, unsigned int *data);
245static int ni_calib_insn_write(struct comedi_device *dev,
246 struct comedi_subdevice *s,
247 struct comedi_insn *insn, unsigned int *data);
248
249static int ni_eeprom_insn_read(struct comedi_device *dev,
250 struct comedi_subdevice *s,
251 struct comedi_insn *insn, unsigned int *data);
da91b269 252static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
0a85b6f0
MT
253 struct comedi_subdevice *s,
254 struct comedi_insn *insn,
255 unsigned int *data);
256
257static int ni_pfi_insn_bits(struct comedi_device *dev,
258 struct comedi_subdevice *s,
259 struct comedi_insn *insn, unsigned int *data);
260static int ni_pfi_insn_config(struct comedi_device *dev,
261 struct comedi_subdevice *s,
262 struct comedi_insn *insn, unsigned int *data);
263static unsigned ni_old_get_pfi_routing(struct comedi_device *dev,
264 unsigned chan);
03aef4b6 265
da91b269 266static void ni_rtsi_init(struct comedi_device *dev);
0a85b6f0
MT
267static int ni_rtsi_insn_bits(struct comedi_device *dev,
268 struct comedi_subdevice *s,
269 struct comedi_insn *insn, unsigned int *data);
270static int ni_rtsi_insn_config(struct comedi_device *dev,
271 struct comedi_subdevice *s,
272 struct comedi_insn *insn, unsigned int *data);
03aef4b6 273
da91b269
BP
274static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s);
275static int ni_read_eeprom(struct comedi_device *dev, int addr);
03aef4b6
DS
276
277#ifdef DEBUG_STATUS_A
278static void ni_mio_print_status_a(int status);
279#else
280#define ni_mio_print_status_a(a)
281#endif
282#ifdef DEBUG_STATUS_B
283static void ni_mio_print_status_b(int status);
284#else
285#define ni_mio_print_status_b(a)
286#endif
287
da91b269 288static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s);
03aef4b6 289#ifndef PCIDMA
da91b269 290static void ni_handle_fifo_half_full(struct comedi_device *dev);
0a85b6f0
MT
291static int ni_ao_fifo_half_empty(struct comedi_device *dev,
292 struct comedi_subdevice *s);
03aef4b6 293#endif
da91b269
BP
294static void ni_handle_fifo_dregs(struct comedi_device *dev);
295static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
296 unsigned int trignum);
297static void ni_load_channelgain_list(struct comedi_device *dev,
298 unsigned int n_chan, unsigned int *list);
da91b269 299static void shutdown_ai_command(struct comedi_device *dev);
03aef4b6 300
da91b269 301static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 302 unsigned int trignum);
03aef4b6 303
da91b269 304static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s);
03aef4b6
DS
305
306static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
307
0a85b6f0
MT
308static int ni_gpct_insn_write(struct comedi_device *dev,
309 struct comedi_subdevice *s,
310 struct comedi_insn *insn, unsigned int *data);
311static int ni_gpct_insn_read(struct comedi_device *dev,
312 struct comedi_subdevice *s,
313 struct comedi_insn *insn, unsigned int *data);
314static int ni_gpct_insn_config(struct comedi_device *dev,
315 struct comedi_subdevice *s,
316 struct comedi_insn *insn, unsigned int *data);
da91b269 317static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
0a85b6f0
MT
318static int ni_gpct_cmdtest(struct comedi_device *dev,
319 struct comedi_subdevice *s, struct comedi_cmd *cmd);
320static int ni_gpct_cancel(struct comedi_device *dev,
321 struct comedi_subdevice *s);
da91b269 322static void handle_gpct_interrupt(struct comedi_device *dev,
0a85b6f0 323 unsigned short counter_index);
03aef4b6 324
da91b269 325static int init_cs5529(struct comedi_device *dev);
0a85b6f0
MT
326static int cs5529_do_conversion(struct comedi_device *dev,
327 unsigned short *data);
328static int cs5529_ai_insn_read(struct comedi_device *dev,
329 struct comedi_subdevice *s,
330 struct comedi_insn *insn, unsigned int *data);
03aef4b6 331#ifdef NI_CS5529_DEBUG
da91b269 332static unsigned int cs5529_config_read(struct comedi_device *dev,
0a85b6f0 333 unsigned int reg_select_bits);
03aef4b6 334#endif
da91b269 335static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
0a85b6f0 336 unsigned int reg_select_bits);
03aef4b6 337
0a85b6f0
MT
338static int ni_m_series_pwm_config(struct comedi_device *dev,
339 struct comedi_subdevice *s,
340 struct comedi_insn *insn, unsigned int *data);
341static int ni_6143_pwm_config(struct comedi_device *dev,
342 struct comedi_subdevice *s,
343 struct comedi_insn *insn, unsigned int *data);
03aef4b6 344
da91b269 345static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
0a85b6f0 346 unsigned period_ns);
da91b269
BP
347static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status);
348static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status);
03aef4b6
DS
349
350enum aimodes {
351 AIMODE_NONE = 0,
352 AIMODE_HALF_FULL = 1,
353 AIMODE_SCAN = 2,
354 AIMODE_SAMPLE = 3,
355};
356
357enum ni_common_subdevices {
358 NI_AI_SUBDEV,
359 NI_AO_SUBDEV,
360 NI_DIO_SUBDEV,
361 NI_8255_DIO_SUBDEV,
362 NI_UNUSED_SUBDEV,
363 NI_CALIBRATION_SUBDEV,
364 NI_EEPROM_SUBDEV,
365 NI_PFI_DIO_SUBDEV,
366 NI_CS5529_CALIBRATION_SUBDEV,
367 NI_SERIAL_SUBDEV,
368 NI_RTSI_SUBDEV,
369 NI_GPCT0_SUBDEV,
370 NI_GPCT1_SUBDEV,
371 NI_FREQ_OUT_SUBDEV,
372 NI_NUM_SUBDEVICES
373};
374static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
375{
376 switch (counter_index) {
377 case 0:
378 return NI_GPCT0_SUBDEV;
379 break;
380 case 1:
381 return NI_GPCT1_SUBDEV;
382 break;
383 default:
384 break;
385 }
386 BUG();
387 return NI_GPCT0_SUBDEV;
388}
389
390enum timebase_nanoseconds {
391 TIMEBASE_1_NS = 50,
392 TIMEBASE_2_NS = 10000
393};
394
395#define SERIAL_DISABLED 0
396#define SERIAL_600NS 600
397#define SERIAL_1_2US 1200
398#define SERIAL_10US 10000
399
400static const int num_adc_stages_611x = 3;
401
da91b269 402static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
0a85b6f0 403 unsigned ai_mite_status);
da91b269 404static void handle_b_interrupt(struct comedi_device *dev, unsigned short status,
0a85b6f0 405 unsigned ao_mite_status);
da91b269
BP
406static void get_last_sample_611x(struct comedi_device *dev);
407static void get_last_sample_6143(struct comedi_device *dev);
03aef4b6 408
da91b269 409static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
0a85b6f0 410 unsigned bit_mask, unsigned bit_values)
03aef4b6
DS
411{
412 unsigned long flags;
413
5f74ea14 414 spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
03aef4b6
DS
415 switch (reg) {
416 case Interrupt_A_Enable_Register:
417 devpriv->int_a_enable_reg &= ~bit_mask;
418 devpriv->int_a_enable_reg |= bit_values & bit_mask;
419 devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
0a85b6f0 420 Interrupt_A_Enable_Register);
03aef4b6
DS
421 break;
422 case Interrupt_B_Enable_Register:
423 devpriv->int_b_enable_reg &= ~bit_mask;
424 devpriv->int_b_enable_reg |= bit_values & bit_mask;
425 devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
0a85b6f0 426 Interrupt_B_Enable_Register);
03aef4b6
DS
427 break;
428 case IO_Bidirection_Pin_Register:
429 devpriv->io_bidirection_pin_reg &= ~bit_mask;
430 devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
431 devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
0a85b6f0 432 IO_Bidirection_Pin_Register);
03aef4b6
DS
433 break;
434 case AI_AO_Select:
435 devpriv->ai_ao_select_reg &= ~bit_mask;
436 devpriv->ai_ao_select_reg |= bit_values & bit_mask;
437 ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
438 break;
439 case G0_G1_Select:
440 devpriv->g0_g1_select_reg &= ~bit_mask;
441 devpriv->g0_g1_select_reg |= bit_values & bit_mask;
442 ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
443 break;
444 default:
0a85b6f0 445 printk("Warning %s() called with invalid register\n", __func__);
5f74ea14 446 printk("reg is %d\n", reg);
03aef4b6
DS
447 break;
448 }
449 mmiowb();
5f74ea14 450 spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
03aef4b6
DS
451}
452
453#ifdef PCIDMA
da91b269 454static int ni_ai_drain_dma(struct comedi_device *dev);
03aef4b6
DS
455
456/* DMA channel setup */
457
2696fb57 458/* negative channel means no channel */
da91b269 459static inline void ni_set_ai_dma_channel(struct comedi_device *dev, int channel)
03aef4b6
DS
460{
461 unsigned bitfield;
462
463 if (channel >= 0) {
464 bitfield =
0a85b6f0
MT
465 (ni_stc_dma_channel_select_bitfield(channel) <<
466 AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
03aef4b6
DS
467 } else {
468 bitfield = 0;
469 }
470 ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield);
471}
472
2696fb57 473/* negative channel means no channel */
da91b269 474static inline void ni_set_ao_dma_channel(struct comedi_device *dev, int channel)
03aef4b6
DS
475{
476 unsigned bitfield;
477
478 if (channel >= 0) {
479 bitfield =
0a85b6f0
MT
480 (ni_stc_dma_channel_select_bitfield(channel) <<
481 AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
03aef4b6
DS
482 } else {
483 bitfield = 0;
484 }
485 ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield);
486}
487
2696fb57 488/* negative mite_channel means no channel */
da91b269 489static inline void ni_set_gpct_dma_channel(struct comedi_device *dev,
0a85b6f0
MT
490 unsigned gpct_index,
491 int mite_channel)
03aef4b6
DS
492{
493 unsigned bitfield;
494
495 if (mite_channel >= 0) {
496 bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel);
497 } else {
498 bitfield = 0;
499 }
500 ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index),
0a85b6f0 501 bitfield);
03aef4b6
DS
502}
503
2696fb57 504/* negative mite_channel means no channel */
0a85b6f0
MT
505static inline void ni_set_cdo_dma_channel(struct comedi_device *dev,
506 int mite_channel)
03aef4b6
DS
507{
508 unsigned long flags;
509
5f74ea14 510 spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
03aef4b6
DS
511 devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask;
512 if (mite_channel >= 0) {
513 /*XXX just guessing ni_stc_dma_channel_select_bitfield() returns the right bits,
514 under the assumption the cdio dma selection works just like ai/ao/gpct.
515 Definitely works for dma channels 0 and 1. */
516 devpriv->cdio_dma_select_reg |=
0a85b6f0
MT
517 (ni_stc_dma_channel_select_bitfield(mite_channel) <<
518 CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
03aef4b6
DS
519 }
520 ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
521 mmiowb();
5f74ea14 522 spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
03aef4b6
DS
523}
524
da91b269 525static int ni_request_ai_mite_channel(struct comedi_device *dev)
03aef4b6
DS
526{
527 unsigned long flags;
528
5f74ea14 529 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
530 BUG_ON(devpriv->ai_mite_chan);
531 devpriv->ai_mite_chan =
0a85b6f0 532 mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
03aef4b6 533 if (devpriv->ai_mite_chan == NULL) {
0a85b6f0 534 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6 535 comedi_error(dev,
0a85b6f0 536 "failed to reserve mite dma channel for analog input.");
03aef4b6
DS
537 return -EBUSY;
538 }
539 devpriv->ai_mite_chan->dir = COMEDI_INPUT;
540 ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel);
5f74ea14 541 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
542 return 0;
543}
544
da91b269 545static int ni_request_ao_mite_channel(struct comedi_device *dev)
03aef4b6
DS
546{
547 unsigned long flags;
548
5f74ea14 549 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
550 BUG_ON(devpriv->ao_mite_chan);
551 devpriv->ao_mite_chan =
0a85b6f0 552 mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
03aef4b6 553 if (devpriv->ao_mite_chan == NULL) {
0a85b6f0 554 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6 555 comedi_error(dev,
0a85b6f0 556 "failed to reserve mite dma channel for analog outut.");
03aef4b6
DS
557 return -EBUSY;
558 }
559 devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
560 ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel);
5f74ea14 561 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
562 return 0;
563}
564
da91b269 565static int ni_request_gpct_mite_channel(struct comedi_device *dev,
0a85b6f0
MT
566 unsigned gpct_index,
567 enum comedi_io_direction direction)
03aef4b6
DS
568{
569 unsigned long flags;
570 struct mite_channel *mite_chan;
571
572 BUG_ON(gpct_index >= NUM_GPCT);
5f74ea14 573 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
574 BUG_ON(devpriv->counter_dev->counters[gpct_index].mite_chan);
575 mite_chan =
0a85b6f0
MT
576 mite_request_channel(devpriv->mite,
577 devpriv->gpct_mite_ring[gpct_index]);
03aef4b6 578 if (mite_chan == NULL) {
0a85b6f0 579 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6 580 comedi_error(dev,
0a85b6f0 581 "failed to reserve mite dma channel for counter.");
03aef4b6
DS
582 return -EBUSY;
583 }
584 mite_chan->dir = direction;
585 ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
0a85b6f0 586 mite_chan);
03aef4b6 587 ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
5f74ea14 588 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
589 return 0;
590}
591
2696fb57 592#endif /* PCIDMA */
03aef4b6 593
da91b269 594static int ni_request_cdo_mite_channel(struct comedi_device *dev)
03aef4b6
DS
595{
596#ifdef PCIDMA
597 unsigned long flags;
598
5f74ea14 599 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
600 BUG_ON(devpriv->cdo_mite_chan);
601 devpriv->cdo_mite_chan =
0a85b6f0 602 mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
03aef4b6 603 if (devpriv->cdo_mite_chan == NULL) {
0a85b6f0 604 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6 605 comedi_error(dev,
0a85b6f0 606 "failed to reserve mite dma channel for correlated digital outut.");
03aef4b6
DS
607 return -EBUSY;
608 }
609 devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
610 ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
5f74ea14 611 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
2696fb57 612#endif /* PCIDMA */
03aef4b6
DS
613 return 0;
614}
615
da91b269 616static void ni_release_ai_mite_channel(struct comedi_device *dev)
03aef4b6
DS
617{
618#ifdef PCIDMA
619 unsigned long flags;
620
5f74ea14 621 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
622 if (devpriv->ai_mite_chan) {
623 ni_set_ai_dma_channel(dev, -1);
624 mite_release_channel(devpriv->ai_mite_chan);
625 devpriv->ai_mite_chan = NULL;
626 }
5f74ea14 627 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
2696fb57 628#endif /* PCIDMA */
03aef4b6
DS
629}
630
da91b269 631static void ni_release_ao_mite_channel(struct comedi_device *dev)
03aef4b6
DS
632{
633#ifdef PCIDMA
634 unsigned long flags;
635
5f74ea14 636 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
637 if (devpriv->ao_mite_chan) {
638 ni_set_ao_dma_channel(dev, -1);
639 mite_release_channel(devpriv->ao_mite_chan);
640 devpriv->ao_mite_chan = NULL;
641 }
5f74ea14 642 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
2696fb57 643#endif /* PCIDMA */
03aef4b6
DS
644}
645
0a85b6f0
MT
646void ni_release_gpct_mite_channel(struct comedi_device *dev,
647 unsigned gpct_index)
03aef4b6
DS
648{
649#ifdef PCIDMA
650 unsigned long flags;
651
652 BUG_ON(gpct_index >= NUM_GPCT);
5f74ea14 653 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
654 if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
655 struct mite_channel *mite_chan =
0a85b6f0 656 devpriv->counter_dev->counters[gpct_index].mite_chan;
03aef4b6
DS
657
658 ni_set_gpct_dma_channel(dev, gpct_index, -1);
0a85b6f0
MT
659 ni_tio_set_mite_channel(&devpriv->
660 counter_dev->counters[gpct_index],
661 NULL);
03aef4b6
DS
662 mite_release_channel(mite_chan);
663 }
5f74ea14 664 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
2696fb57 665#endif /* PCIDMA */
03aef4b6
DS
666}
667
da91b269 668static void ni_release_cdo_mite_channel(struct comedi_device *dev)
03aef4b6
DS
669{
670#ifdef PCIDMA
671 unsigned long flags;
672
5f74ea14 673 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
674 if (devpriv->cdo_mite_chan) {
675 ni_set_cdo_dma_channel(dev, -1);
676 mite_release_channel(devpriv->cdo_mite_chan);
677 devpriv->cdo_mite_chan = NULL;
678 }
5f74ea14 679 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
2696fb57 680#endif /* PCIDMA */
03aef4b6
DS
681}
682
2696fb57 683/* e-series boards use the second irq signals to generate dma requests for their counters */
03aef4b6 684#ifdef PCIDMA
da91b269 685static void ni_e_series_enable_second_irq(struct comedi_device *dev,
0a85b6f0 686 unsigned gpct_index, short enable)
03aef4b6
DS
687{
688 if (boardtype.reg_type & ni_reg_m_series_mask)
689 return;
690 switch (gpct_index) {
691 case 0:
692 if (enable) {
693 devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
0a85b6f0 694 Second_IRQ_A_Enable_Register);
03aef4b6
DS
695 } else {
696 devpriv->stc_writew(dev, 0,
0a85b6f0 697 Second_IRQ_A_Enable_Register);
03aef4b6
DS
698 }
699 break;
700 case 1:
701 if (enable) {
702 devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
0a85b6f0 703 Second_IRQ_B_Enable_Register);
03aef4b6
DS
704 } else {
705 devpriv->stc_writew(dev, 0,
0a85b6f0 706 Second_IRQ_B_Enable_Register);
03aef4b6
DS
707 }
708 break;
709 default:
710 BUG();
711 break;
712 }
713}
2696fb57 714#endif /* PCIDMA */
03aef4b6 715
da91b269 716static void ni_clear_ai_fifo(struct comedi_device *dev)
03aef4b6
DS
717{
718 if (boardtype.reg_type == ni_reg_6143) {
2696fb57
BP
719 /* Flush the 6143 data FIFO */
720 ni_writel(0x10, AIFIFO_Control_6143); /* Flush fifo */
721 ni_writel(0x00, AIFIFO_Control_6143); /* Flush fifo */
722 while (ni_readl(AIFIFO_Status_6143) & 0x10) ; /* Wait for complete */
03aef4b6
DS
723 } else {
724 devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
725 if (boardtype.reg_type == ni_reg_625x) {
726 ni_writeb(0, M_Offset_Static_AI_Control(0));
727 ni_writeb(1, M_Offset_Static_AI_Control(0));
728#if 0
729 /* the NI example code does 3 convert pulses for 625x boards,
730 but that appears to be wrong in practice. */
731 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 732 AI_Command_1_Register);
03aef4b6 733 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 734 AI_Command_1_Register);
03aef4b6 735 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 736 AI_Command_1_Register);
03aef4b6
DS
737#endif
738 }
739 }
740}
741
da91b269 742static void win_out2(struct comedi_device *dev, uint32_t data, int reg)
03aef4b6
DS
743{
744 devpriv->stc_writew(dev, data >> 16, reg);
745 devpriv->stc_writew(dev, data & 0xffff, reg + 1);
746}
747
da91b269 748static uint32_t win_in2(struct comedi_device *dev, int reg)
03aef4b6
DS
749{
750 uint32_t bits;
751 bits = devpriv->stc_readw(dev, reg) << 16;
752 bits |= devpriv->stc_readw(dev, reg + 1);
753 return bits;
754}
755
f7cbd7aa 756#define ao_win_out(data, addr) ni_ao_win_outw(dev, data, addr)
0a85b6f0
MT
757static inline void ni_ao_win_outw(struct comedi_device *dev, uint16_t data,
758 int addr)
03aef4b6
DS
759{
760 unsigned long flags;
761
5f74ea14 762 spin_lock_irqsave(&devpriv->window_lock, flags);
03aef4b6
DS
763 ni_writew(addr, AO_Window_Address_611x);
764 ni_writew(data, AO_Window_Data_611x);
5f74ea14 765 spin_unlock_irqrestore(&devpriv->window_lock, flags);
03aef4b6
DS
766}
767
0a85b6f0
MT
768static inline void ni_ao_win_outl(struct comedi_device *dev, uint32_t data,
769 int addr)
03aef4b6
DS
770{
771 unsigned long flags;
772
5f74ea14 773 spin_lock_irqsave(&devpriv->window_lock, flags);
03aef4b6
DS
774 ni_writew(addr, AO_Window_Address_611x);
775 ni_writel(data, AO_Window_Data_611x);
5f74ea14 776 spin_unlock_irqrestore(&devpriv->window_lock, flags);
03aef4b6
DS
777}
778
da91b269 779static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
03aef4b6
DS
780{
781 unsigned long flags;
782 unsigned short data;
783
5f74ea14 784 spin_lock_irqsave(&devpriv->window_lock, flags);
03aef4b6
DS
785 ni_writew(addr, AO_Window_Address_611x);
786 data = ni_readw(AO_Window_Data_611x);
5f74ea14 787 spin_unlock_irqrestore(&devpriv->window_lock, flags);
03aef4b6
DS
788 return data;
789}
790
791/* ni_set_bits( ) allows different parts of the ni_mio_common driver to
792* share registers (such as Interrupt_A_Register) without interfering with
793* each other.
794*
795* NOTE: the switch/case statements are optimized out for a constant argument
796* so this is actually quite fast--- If you must wrap another function around this
797* make it inline to avoid a large speed penalty.
798*
799* value should only be 1 or 0.
800*/
0a85b6f0
MT
801static inline void ni_set_bits(struct comedi_device *dev, int reg,
802 unsigned bits, unsigned value)
03aef4b6
DS
803{
804 unsigned bit_values;
805
806 if (value)
807 bit_values = bits;
808 else
809 bit_values = 0;
810 ni_set_bitfield(dev, reg, bits, bit_values);
811}
812
70265d24 813static irqreturn_t ni_E_interrupt(int irq, void *d)
03aef4b6 814{
71b5f4f1 815 struct comedi_device *dev = d;
03aef4b6
DS
816 unsigned short a_status;
817 unsigned short b_status;
818 unsigned int ai_mite_status = 0;
819 unsigned int ao_mite_status = 0;
820 unsigned long flags;
821#ifdef PCIDMA
822 struct mite_struct *mite = devpriv->mite;
823#endif
824
825 if (dev->attached == 0)
826 return IRQ_NONE;
2696fb57 827 smp_mb(); /* make sure dev->attached is checked before handler does anything else. */
03aef4b6 828
2696fb57 829 /* lock to avoid race with comedi_poll */
5f74ea14 830 spin_lock_irqsave(&dev->spinlock, flags);
03aef4b6
DS
831 a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
832 b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
833#ifdef PCIDMA
834 if (mite) {
835 unsigned long flags_too;
836
5f74ea14 837 spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
03aef4b6
DS
838 if (devpriv->ai_mite_chan) {
839 ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
840 if (ai_mite_status & CHSR_LINKC)
841 writel(CHOR_CLRLC,
0a85b6f0
MT
842 devpriv->mite->mite_io_addr +
843 MITE_CHOR(devpriv->
844 ai_mite_chan->channel));
03aef4b6
DS
845 }
846 if (devpriv->ao_mite_chan) {
847 ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
848 if (ao_mite_status & CHSR_LINKC)
849 writel(CHOR_CLRLC,
0a85b6f0
MT
850 mite->mite_io_addr +
851 MITE_CHOR(devpriv->
852 ao_mite_chan->channel));
03aef4b6 853 }
5f74ea14 854 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
03aef4b6
DS
855 }
856#endif
857 ack_a_interrupt(dev, a_status);
858 ack_b_interrupt(dev, b_status);
859 if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
860 handle_a_interrupt(dev, a_status, ai_mite_status);
861 if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
862 handle_b_interrupt(dev, b_status, ao_mite_status);
863 handle_gpct_interrupt(dev, 0);
864 handle_gpct_interrupt(dev, 1);
865 handle_cdio_interrupt(dev);
866
5f74ea14 867 spin_unlock_irqrestore(&dev->spinlock, flags);
03aef4b6
DS
868 return IRQ_HANDLED;
869}
870
871#ifdef PCIDMA
da91b269 872static void ni_sync_ai_dma(struct comedi_device *dev)
03aef4b6 873{
34c43922 874 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
03aef4b6
DS
875 unsigned long flags;
876
5f74ea14 877 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
878 if (devpriv->ai_mite_chan)
879 mite_sync_input_dma(devpriv->ai_mite_chan, s->async);
5f74ea14 880 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
881}
882
0a85b6f0
MT
883static void mite_handle_b_linkc(struct mite_struct *mite,
884 struct comedi_device *dev)
03aef4b6 885{
34c43922 886 struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
03aef4b6
DS
887 unsigned long flags;
888
5f74ea14 889 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
890 if (devpriv->ao_mite_chan) {
891 mite_sync_output_dma(devpriv->ao_mite_chan, s->async);
892 }
5f74ea14 893 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
894}
895
da91b269 896static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
03aef4b6
DS
897{
898 static const int timeout = 10000;
899 int i;
900 for (i = 0; i < timeout; i++) {
901 unsigned short b_status;
902
903 b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
904 if (b_status & AO_FIFO_Half_Full_St)
905 break;
906 /* if we poll too often, the pci bus activity seems
907 to slow the dma transfer down */
5f74ea14 908 udelay(10);
03aef4b6
DS
909 }
910 if (i == timeout) {
911 comedi_error(dev, "timed out waiting for dma load");
912 return -EPIPE;
913 }
914 return 0;
915}
916
2696fb57 917#endif /* PCIDMA */
da91b269 918static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
919{
920 if (devpriv->aimode == AIMODE_SCAN) {
921#ifdef PCIDMA
922 static const int timeout = 10;
923 int i;
924
925 for (i = 0; i < timeout; i++) {
926 ni_sync_ai_dma(dev);
927 if ((s->async->events & COMEDI_CB_EOS))
928 break;
5f74ea14 929 udelay(1);
03aef4b6
DS
930 }
931#else
932 ni_handle_fifo_dregs(dev);
933 s->async->events |= COMEDI_CB_EOS;
934#endif
935 }
936 /* handle special case of single scan using AI_End_On_End_Of_Scan */
937 if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
938 shutdown_ai_command(dev);
939 }
940}
941
da91b269 942static void shutdown_ai_command(struct comedi_device *dev)
03aef4b6 943{
34c43922 944 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
03aef4b6
DS
945
946#ifdef PCIDMA
947 ni_ai_drain_dma(dev);
948#endif
949 ni_handle_fifo_dregs(dev);
950 get_last_sample_611x(dev);
951 get_last_sample_6143(dev);
952
953 s->async->events |= COMEDI_CB_EOA;
954}
955
da91b269 956static void ni_event(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6 957{
0a85b6f0
MT
958 if (s->
959 async->events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW |
960 COMEDI_CB_EOA)) {
03aef4b6
DS
961 switch (s - dev->subdevices) {
962 case NI_AI_SUBDEV:
963 ni_ai_reset(dev, s);
964 break;
965 case NI_AO_SUBDEV:
966 ni_ao_reset(dev, s);
967 break;
968 case NI_GPCT0_SUBDEV:
969 case NI_GPCT1_SUBDEV:
970 ni_gpct_cancel(dev, s);
971 break;
972 case NI_DIO_SUBDEV:
973 ni_cdio_cancel(dev, s);
974 break;
975 default:
976 break;
977 }
978 }
979 comedi_event(dev, s);
980}
981
da91b269 982static void handle_gpct_interrupt(struct comedi_device *dev,
0a85b6f0 983 unsigned short counter_index)
03aef4b6
DS
984{
985#ifdef PCIDMA
0a85b6f0
MT
986 struct comedi_subdevice *s =
987 dev->subdevices + NI_GPCT_SUBDEV(counter_index);
03aef4b6
DS
988
989 ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
0a85b6f0 990 s);
03aef4b6
DS
991 if (s->async->events)
992 ni_event(dev, s);
993#endif
994}
995
da91b269 996static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
03aef4b6
DS
997{
998 unsigned short ack = 0;
999
1000 if (a_status & AI_SC_TC_St) {
1001 ack |= AI_SC_TC_Interrupt_Ack;
1002 }
1003 if (a_status & AI_START1_St) {
1004 ack |= AI_START1_Interrupt_Ack;
1005 }
1006 if (a_status & AI_START_St) {
1007 ack |= AI_START_Interrupt_Ack;
1008 }
1009 if (a_status & AI_STOP_St) {
1010 /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
1011 ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */ ;
1012 }
1013 if (ack)
1014 devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
1015}
1016
da91b269 1017static void handle_a_interrupt(struct comedi_device *dev, unsigned short status,
0a85b6f0 1018 unsigned ai_mite_status)
03aef4b6 1019{
34c43922 1020 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
03aef4b6 1021
2696fb57 1022 /* 67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt */
03aef4b6
DS
1023 if (s->type == COMEDI_SUBD_UNUSED)
1024 return;
1025
1026#ifdef DEBUG_INTERRUPT
5f74ea14 1027 printk
0a85b6f0
MT
1028 ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
1029 status, ai_mite_status);
03aef4b6
DS
1030 ni_mio_print_status_a(status);
1031#endif
1032#ifdef PCIDMA
1033 if (ai_mite_status & CHSR_LINKC) {
1034 ni_sync_ai_dma(dev);
1035 }
1036
1037 if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
0a85b6f0
MT
1038 CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
1039 CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
5f74ea14 1040 printk
0a85b6f0
MT
1041 ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
1042 ai_mite_status);
2696fb57 1043 /* mite_print_chsr(ai_mite_status); */
03aef4b6 1044 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
2696fb57 1045 /* disable_irq(dev->irq); */
03aef4b6
DS
1046 }
1047#endif
1048
1049 /* test for all uncommon interrupt events at the same time */
1050 if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
0a85b6f0 1051 AI_SC_TC_St | AI_START1_St)) {
03aef4b6 1052 if (status == 0xffff) {
5f74ea14 1053 printk
0a85b6f0 1054 ("ni_mio_common: a_status=0xffff. Card removed?\n");
03aef4b6
DS
1055 /* we probably aren't even running a command now,
1056 * so it's a good idea to be careful. */
1057 if (comedi_get_subdevice_runflags(s) & SRF_RUNNING) {
1058 s->async->events |=
0a85b6f0 1059 COMEDI_CB_ERROR | COMEDI_CB_EOA;
03aef4b6
DS
1060 ni_event(dev, s);
1061 }
1062 return;
1063 }
1064 if (status & (AI_Overrun_St | AI_Overflow_St |
0a85b6f0 1065 AI_SC_TC_Error_St)) {
5f74ea14 1066 printk("ni_mio_common: ai error a_status=%04x\n",
0a85b6f0 1067 status);
03aef4b6
DS
1068 ni_mio_print_status_a(status);
1069
1070 shutdown_ai_command(dev);
1071
1072 s->async->events |= COMEDI_CB_ERROR;
1073 if (status & (AI_Overrun_St | AI_Overflow_St))
1074 s->async->events |= COMEDI_CB_OVERFLOW;
1075
1076 ni_event(dev, s);
1077
1078 return;
1079 }
1080 if (status & AI_SC_TC_St) {
1081#ifdef DEBUG_INTERRUPT
5f74ea14 1082 printk("ni_mio_common: SC_TC interrupt\n");
03aef4b6
DS
1083#endif
1084 if (!devpriv->ai_continuous) {
1085 shutdown_ai_command(dev);
1086 }
1087 }
1088 }
1089#ifndef PCIDMA
1090 if (status & AI_FIFO_Half_Full_St) {
1091 int i;
1092 static const int timeout = 10;
1093 /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
1094 *fail to get the fifo less than half full, so loop to be sure.*/
1095 for (i = 0; i < timeout; ++i) {
1096 ni_handle_fifo_half_full(dev);
1097 if ((devpriv->stc_readw(dev,
1098 AI_Status_1_Register) &
0a85b6f0 1099 AI_FIFO_Half_Full_St) == 0)
03aef4b6
DS
1100 break;
1101 }
1102 }
2696fb57 1103#endif /* !PCIDMA */
03aef4b6
DS
1104
1105 if ((status & AI_STOP_St)) {
1106 ni_handle_eos(dev, s);
1107 }
1108
1109 ni_event(dev, s);
1110
1111#ifdef DEBUG_INTERRUPT
1112 status = devpriv->stc_readw(dev, AI_Status_1_Register);
1113 if (status & Interrupt_A_St) {
5f74ea14 1114 printk
0a85b6f0
MT
1115 ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
1116 status);
03aef4b6
DS
1117 }
1118#endif
1119}
1120
da91b269 1121static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
03aef4b6
DS
1122{
1123 unsigned short ack = 0;
1124 if (b_status & AO_BC_TC_St) {
1125 ack |= AO_BC_TC_Interrupt_Ack;
1126 }
1127 if (b_status & AO_Overrun_St) {
1128 ack |= AO_Error_Interrupt_Ack;
1129 }
1130 if (b_status & AO_START_St) {
1131 ack |= AO_START_Interrupt_Ack;
1132 }
1133 if (b_status & AO_START1_St) {
1134 ack |= AO_START1_Interrupt_Ack;
1135 }
1136 if (b_status & AO_UC_TC_St) {
1137 ack |= AO_UC_TC_Interrupt_Ack;
1138 }
1139 if (b_status & AO_UI2_TC_St) {
1140 ack |= AO_UI2_TC_Interrupt_Ack;
1141 }
1142 if (b_status & AO_UPDATE_St) {
1143 ack |= AO_UPDATE_Interrupt_Ack;
1144 }
1145 if (ack)
1146 devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
1147}
1148
0a85b6f0
MT
1149static void handle_b_interrupt(struct comedi_device *dev,
1150 unsigned short b_status, unsigned ao_mite_status)
03aef4b6 1151{
34c43922 1152 struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
2696fb57 1153 /* unsigned short ack=0; */
03aef4b6 1154#ifdef DEBUG_INTERRUPT
5f74ea14 1155 printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
0a85b6f0 1156 b_status, ao_mite_status);
03aef4b6
DS
1157 ni_mio_print_status_b(b_status);
1158#endif
1159
1160#ifdef PCIDMA
1161 /* Currently, mite.c requires us to handle LINKC */
1162 if (ao_mite_status & CHSR_LINKC) {
1163 mite_handle_b_linkc(devpriv->mite, dev);
1164 }
1165
1166 if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
0a85b6f0
MT
1167 CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
1168 CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
5f74ea14 1169 printk
0a85b6f0
MT
1170 ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
1171 ao_mite_status);
2696fb57 1172 /* mite_print_chsr(ao_mite_status); */
03aef4b6
DS
1173 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1174 }
1175#endif
1176
1177 if (b_status == 0xffff)
1178 return;
1179 if (b_status & AO_Overrun_St) {
5f74ea14 1180 printk
0a85b6f0
MT
1181 ("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
1182 b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
03aef4b6
DS
1183 s->async->events |= COMEDI_CB_OVERFLOW;
1184 }
1185
1186 if (b_status & AO_BC_TC_St) {
0a85b6f0
MT
1187 MDPRINTK
1188 ("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n",
1189 b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
03aef4b6
DS
1190 s->async->events |= COMEDI_CB_EOA;
1191 }
1192#ifndef PCIDMA
1193 if (b_status & AO_FIFO_Request_St) {
1194 int ret;
1195
1196 ret = ni_ao_fifo_half_empty(dev, s);
1197 if (!ret) {
5f74ea14 1198 printk("ni_mio_common: AO buffer underrun\n");
03aef4b6 1199 ni_set_bits(dev, Interrupt_B_Enable_Register,
0a85b6f0
MT
1200 AO_FIFO_Interrupt_Enable |
1201 AO_Error_Interrupt_Enable, 0);
03aef4b6
DS
1202 s->async->events |= COMEDI_CB_OVERFLOW;
1203 }
1204 }
1205#endif
1206
1207 ni_event(dev, s);
1208}
1209
1210#ifdef DEBUG_STATUS_A
1211static const char *const status_a_strings[] = {
1212 "passthru0", "fifo", "G0_gate", "G0_TC",
1213 "stop", "start", "sc_tc", "start1",
1214 "start2", "sc_tc_error", "overflow", "overrun",
1215 "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a"
1216};
1217
1218static void ni_mio_print_status_a(int status)
1219{
1220 int i;
1221
5f74ea14 1222 printk("A status:");
03aef4b6
DS
1223 for (i = 15; i >= 0; i--) {
1224 if (status & (1 << i)) {
5f74ea14 1225 printk(" %s", status_a_strings[i]);
03aef4b6
DS
1226 }
1227 }
5f74ea14 1228 printk("\n");
03aef4b6
DS
1229}
1230#endif
1231
1232#ifdef DEBUG_STATUS_B
1233static const char *const status_b_strings[] = {
1234 "passthru1", "fifo", "G1_gate", "G1_TC",
1235 "UI2_TC", "UPDATE", "UC_TC", "BC_TC",
1236 "start1", "overrun", "start", "bc_tc_error",
1237 "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b"
1238};
1239
1240static void ni_mio_print_status_b(int status)
1241{
1242 int i;
1243
5f74ea14 1244 printk("B status:");
03aef4b6
DS
1245 for (i = 15; i >= 0; i--) {
1246 if (status & (1 << i)) {
5f74ea14 1247 printk(" %s", status_b_strings[i]);
03aef4b6
DS
1248 }
1249 }
5f74ea14 1250 printk("\n");
03aef4b6
DS
1251}
1252#endif
1253
1254#ifndef PCIDMA
1255
0a85b6f0
MT
1256static void ni_ao_fifo_load(struct comedi_device *dev,
1257 struct comedi_subdevice *s, int n)
03aef4b6 1258{
d163679c 1259 struct comedi_async *async = s->async;
ea6d0d4c 1260 struct comedi_cmd *cmd = &async->cmd;
03aef4b6
DS
1261 int chan;
1262 int i;
790c5541 1263 short d;
03aef4b6
DS
1264 u32 packed_data;
1265 int range;
1266 int err = 1;
1267
1268 chan = async->cur_chan;
1269 for (i = 0; i < n; i++) {
1270 err &= comedi_buf_get(async, &d);
1271 if (err == 0)
1272 break;
1273
1274 range = CR_RANGE(cmd->chanlist[chan]);
1275
1276 if (boardtype.reg_type & ni_reg_6xxx_mask) {
1277 packed_data = d & 0xffff;
1278 /* 6711 only has 16 bit wide ao fifo */
1279 if (boardtype.reg_type != ni_reg_6711) {
1280 err &= comedi_buf_get(async, &d);
1281 if (err == 0)
1282 break;
1283 chan++;
1284 i++;
1285 packed_data |= (d << 16) & 0xffff0000;
1286 }
1287 ni_writel(packed_data, DAC_FIFO_Data_611x);
1288 } else {
1289 ni_writew(d, DAC_FIFO_Data);
1290 }
1291 chan++;
1292 chan %= cmd->chanlist_len;
1293 }
1294 async->cur_chan = chan;
1295 if (err == 0) {
1296 async->events |= COMEDI_CB_OVERFLOW;
1297 }
1298}
1299
1300/*
1301 * There's a small problem if the FIFO gets really low and we
1302 * don't have the data to fill it. Basically, if after we fill
1303 * the FIFO with all the data available, the FIFO is _still_
1304 * less than half full, we never clear the interrupt. If the
1305 * IRQ is in edge mode, we never get another interrupt, because
1306 * this one wasn't cleared. If in level mode, we get flooded
1307 * with interrupts that we can't fulfill, because nothing ever
1308 * gets put into the buffer.
1309 *
1310 * This kind of situation is recoverable, but it is easier to
1311 * just pretend we had a FIFO underrun, since there is a good
1312 * chance it will happen anyway. This is _not_ the case for
1313 * RT code, as RT code might purposely be running close to the
1314 * metal. Needs to be fixed eventually.
1315 */
0a85b6f0
MT
1316static int ni_ao_fifo_half_empty(struct comedi_device *dev,
1317 struct comedi_subdevice *s)
03aef4b6
DS
1318{
1319 int n;
1320
1321 n = comedi_buf_read_n_available(s->async);
1322 if (n == 0) {
1323 s->async->events |= COMEDI_CB_OVERFLOW;
1324 return 0;
1325 }
1326
790c5541 1327 n /= sizeof(short);
03aef4b6
DS
1328 if (n > boardtype.ao_fifo_depth / 2)
1329 n = boardtype.ao_fifo_depth / 2;
1330
1331 ni_ao_fifo_load(dev, s, n);
1332
1333 s->async->events |= COMEDI_CB_BLOCK;
1334
1335 return 1;
1336}
1337
0a85b6f0
MT
1338static int ni_ao_prep_fifo(struct comedi_device *dev,
1339 struct comedi_subdevice *s)
03aef4b6
DS
1340{
1341 int n;
1342
1343 /* reset fifo */
1344 devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
1345 if (boardtype.reg_type & ni_reg_6xxx_mask)
1346 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
1347
1348 /* load some data */
1349 n = comedi_buf_read_n_available(s->async);
1350 if (n == 0)
1351 return 0;
1352
790c5541 1353 n /= sizeof(short);
03aef4b6
DS
1354 if (n > boardtype.ao_fifo_depth)
1355 n = boardtype.ao_fifo_depth;
1356
1357 ni_ao_fifo_load(dev, s, n);
1358
1359 return n;
1360}
1361
0a85b6f0
MT
1362static void ni_ai_fifo_read(struct comedi_device *dev,
1363 struct comedi_subdevice *s, int n)
03aef4b6 1364{
d163679c 1365 struct comedi_async *async = s->async;
03aef4b6
DS
1366 int i;
1367
1368 if (boardtype.reg_type == ni_reg_611x) {
790c5541 1369 short data[2];
03aef4b6
DS
1370 u32 dl;
1371
1372 for (i = 0; i < n / 2; i++) {
1373 dl = ni_readl(ADC_FIFO_Data_611x);
1374 /* This may get the hi/lo data in the wrong order */
1375 data[0] = (dl >> 16) & 0xffff;
1376 data[1] = dl & 0xffff;
1377 cfc_write_array_to_buffer(s, data, sizeof(data));
1378 }
1379 /* Check if there's a single sample stuck in the FIFO */
1380 if (n % 2) {
1381 dl = ni_readl(ADC_FIFO_Data_611x);
1382 data[0] = dl & 0xffff;
1383 cfc_write_to_buffer(s, data[0]);
1384 }
1385 } else if (boardtype.reg_type == ni_reg_6143) {
790c5541 1386 short data[2];
03aef4b6
DS
1387 u32 dl;
1388
2696fb57 1389 /* This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed */
03aef4b6
DS
1390 for (i = 0; i < n / 2; i++) {
1391 dl = ni_readl(AIFIFO_Data_6143);
1392
1393 data[0] = (dl >> 16) & 0xffff;
1394 data[1] = dl & 0xffff;
1395 cfc_write_array_to_buffer(s, data, sizeof(data));
1396 }
1397 if (n % 2) {
1398 /* Assume there is a single sample stuck in the FIFO */
2696fb57 1399 ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
03aef4b6
DS
1400 dl = ni_readl(AIFIFO_Data_6143);
1401 data[0] = (dl >> 16) & 0xffff;
1402 cfc_write_to_buffer(s, data[0]);
1403 }
1404 } else {
1405 if (n > sizeof(devpriv->ai_fifo_buffer) /
0a85b6f0 1406 sizeof(devpriv->ai_fifo_buffer[0])) {
03aef4b6
DS
1407 comedi_error(dev, "bug! ai_fifo_buffer too small");
1408 async->events |= COMEDI_CB_ERROR;
1409 return;
1410 }
1411 for (i = 0; i < n; i++) {
1412 devpriv->ai_fifo_buffer[i] =
0a85b6f0 1413 ni_readw(ADC_FIFO_Data_Register);
03aef4b6
DS
1414 }
1415 cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
0a85b6f0
MT
1416 n *
1417 sizeof(devpriv->ai_fifo_buffer[0]));
03aef4b6
DS
1418 }
1419}
1420
da91b269 1421static void ni_handle_fifo_half_full(struct comedi_device *dev)
03aef4b6
DS
1422{
1423 int n;
34c43922 1424 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
03aef4b6
DS
1425
1426 n = boardtype.ai_fifo_depth / 2;
1427
1428 ni_ai_fifo_read(dev, s, n);
1429}
1430#endif
1431
1432#ifdef PCIDMA
da91b269 1433static int ni_ai_drain_dma(struct comedi_device *dev)
03aef4b6
DS
1434{
1435 int i;
1436 static const int timeout = 10000;
1437 unsigned long flags;
1438 int retval = 0;
1439
5f74ea14 1440 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1441 if (devpriv->ai_mite_chan) {
1442 for (i = 0; i < timeout; i++) {
1443 if ((devpriv->stc_readw(dev,
1444 AI_Status_1_Register) &
0a85b6f0
MT
1445 AI_FIFO_Empty_St)
1446 && mite_bytes_in_transit(devpriv->ai_mite_chan) ==
1447 0)
03aef4b6 1448 break;
5f74ea14 1449 udelay(5);
03aef4b6
DS
1450 }
1451 if (i == timeout) {
0a85b6f0 1452 printk("ni_mio_common: wait for dma drain timed out\n");
5f74ea14 1453 printk
0a85b6f0
MT
1454 ("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
1455 mite_bytes_in_transit(devpriv->ai_mite_chan),
1456 devpriv->stc_readw(dev, AI_Status_1_Register));
03aef4b6
DS
1457 retval = -1;
1458 }
1459 }
5f74ea14 1460 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1461
1462 ni_sync_ai_dma(dev);
1463
1464 return retval;
1465}
1466#endif
1467/*
1468 Empties the AI fifo
1469*/
da91b269 1470static void ni_handle_fifo_dregs(struct comedi_device *dev)
03aef4b6 1471{
34c43922 1472 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
790c5541 1473 short data[2];
03aef4b6
DS
1474 u32 dl;
1475 short fifo_empty;
1476 int i;
1477
1478 if (boardtype.reg_type == ni_reg_611x) {
1479 while ((devpriv->stc_readw(dev,
0a85b6f0
MT
1480 AI_Status_1_Register) &
1481 AI_FIFO_Empty_St) == 0) {
03aef4b6
DS
1482 dl = ni_readl(ADC_FIFO_Data_611x);
1483
1484 /* This may get the hi/lo data in the wrong order */
1485 data[0] = (dl >> 16);
1486 data[1] = (dl & 0xffff);
1487 cfc_write_array_to_buffer(s, data, sizeof(data));
1488 }
1489 } else if (boardtype.reg_type == ni_reg_6143) {
1490 i = 0;
1491 while (ni_readl(AIFIFO_Status_6143) & 0x04) {
1492 dl = ni_readl(AIFIFO_Data_6143);
1493
1494 /* This may get the hi/lo data in the wrong order */
1495 data[0] = (dl >> 16);
1496 data[1] = (dl & 0xffff);
1497 cfc_write_array_to_buffer(s, data, sizeof(data));
1498 i += 2;
1499 }
2696fb57 1500 /* Check if stranded sample is present */
03aef4b6 1501 if (ni_readl(AIFIFO_Status_6143) & 0x01) {
2696fb57 1502 ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
03aef4b6
DS
1503 dl = ni_readl(AIFIFO_Data_6143);
1504 data[0] = (dl >> 16) & 0xffff;
1505 cfc_write_to_buffer(s, data[0]);
1506 }
1507
1508 } else {
1509 fifo_empty =
0a85b6f0
MT
1510 devpriv->stc_readw(dev,
1511 AI_Status_1_Register) & AI_FIFO_Empty_St;
03aef4b6
DS
1512 while (fifo_empty == 0) {
1513 for (i = 0;
0a85b6f0
MT
1514 i <
1515 sizeof(devpriv->ai_fifo_buffer) /
1516 sizeof(devpriv->ai_fifo_buffer[0]); i++) {
03aef4b6 1517 fifo_empty =
0a85b6f0
MT
1518 devpriv->stc_readw(dev,
1519 AI_Status_1_Register) &
1520 AI_FIFO_Empty_St;
03aef4b6
DS
1521 if (fifo_empty)
1522 break;
1523 devpriv->ai_fifo_buffer[i] =
0a85b6f0 1524 ni_readw(ADC_FIFO_Data_Register);
03aef4b6
DS
1525 }
1526 cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
0a85b6f0
MT
1527 i *
1528 sizeof(devpriv->
1529 ai_fifo_buffer[0]));
03aef4b6
DS
1530 }
1531 }
1532}
1533
da91b269 1534static void get_last_sample_611x(struct comedi_device *dev)
03aef4b6 1535{
34c43922 1536 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
790c5541 1537 short data;
03aef4b6
DS
1538 u32 dl;
1539
1540 if (boardtype.reg_type != ni_reg_611x)
1541 return;
1542
1543 /* Check if there's a single sample stuck in the FIFO */
1544 if (ni_readb(XXX_Status) & 0x80) {
1545 dl = ni_readl(ADC_FIFO_Data_611x);
1546 data = (dl & 0xffff);
1547 cfc_write_to_buffer(s, data);
1548 }
1549}
1550
da91b269 1551static void get_last_sample_6143(struct comedi_device *dev)
03aef4b6 1552{
34c43922 1553 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
790c5541 1554 short data;
03aef4b6
DS
1555 u32 dl;
1556
1557 if (boardtype.reg_type != ni_reg_6143)
1558 return;
1559
1560 /* Check if there's a single sample stuck in the FIFO */
1561 if (ni_readl(AIFIFO_Status_6143) & 0x01) {
2696fb57 1562 ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
03aef4b6
DS
1563 dl = ni_readl(AIFIFO_Data_6143);
1564
1565 /* This may get the hi/lo data in the wrong order */
1566 data = (dl >> 16) & 0xffff;
1567 cfc_write_to_buffer(s, data);
1568 }
1569}
1570
da91b269 1571static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
1572 void *data, unsigned int num_bytes,
1573 unsigned int chan_index)
03aef4b6 1574{
d163679c 1575 struct comedi_async *async = s->async;
03aef4b6
DS
1576 unsigned int i;
1577 unsigned int length = num_bytes / bytes_per_sample(s);
790c5541
BP
1578 short *array = data;
1579 unsigned int *larray = data;
03aef4b6
DS
1580 for (i = 0; i < length; i++) {
1581#ifdef PCIDMA
1582 if (s->subdev_flags & SDF_LSAMPL)
1583 larray[i] = le32_to_cpu(larray[i]);
1584 else
1585 array[i] = le16_to_cpu(array[i]);
1586#endif
1587 if (s->subdev_flags & SDF_LSAMPL)
1588 larray[i] += devpriv->ai_offset[chan_index];
1589 else
1590 array[i] += devpriv->ai_offset[chan_index];
1591 chan_index++;
1592 chan_index %= async->cmd.chanlist_len;
1593 }
1594}
1595
1596#ifdef PCIDMA
1597
da91b269 1598static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
03aef4b6 1599{
34c43922 1600 struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
03aef4b6
DS
1601 int retval;
1602 unsigned long flags;
1603
1604 retval = ni_request_ai_mite_channel(dev);
1605 if (retval)
1606 return retval;
5f74ea14 1607/* printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel); */
03aef4b6
DS
1608
1609 /* write alloc the entire buffer */
1610 comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
1611
5f74ea14
GKH
1612 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
1613 if (devpriv->ai_mite_chan == NULL) {
1614 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1615 return -EIO;
1616 }
1617
1618 switch (boardtype.reg_type) {
1619 case ni_reg_611x:
1620 case ni_reg_6143:
1621 mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
1622 break;
1623 case ni_reg_628x:
1624 mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
1625 break;
1626 default:
1627 mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
1628 break;
1629 };
1630 /*start the MITE */
1631 mite_dma_arm(devpriv->ai_mite_chan);
5f74ea14 1632 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1633
1634 return 0;
1635}
1636
da91b269 1637static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
03aef4b6 1638{
34c43922 1639 struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
03aef4b6
DS
1640 int retval;
1641 unsigned long flags;
1642
1643 retval = ni_request_ao_mite_channel(dev);
1644 if (retval)
1645 return retval;
1646
1647 /* read alloc the entire buffer */
1648 comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
1649
5f74ea14 1650 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1651 if (devpriv->ao_mite_chan) {
1652 if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
1653 mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
1654 } else {
1655 /* doing 32 instead of 16 bit wide transfers from memory
1656 makes the mite do 32 bit pci transfers, doubling pci bandwidth. */
1657 mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
1658 }
1659 mite_dma_arm(devpriv->ao_mite_chan);
1660 } else
1661 retval = -EIO;
5f74ea14 1662 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
1663
1664 return retval;
1665}
1666
2696fb57 1667#endif /* PCIDMA */
03aef4b6
DS
1668
1669/*
1670 used for both cancel ioctl and board initialization
1671
1672 this is pretty harsh for a cancel, but it works...
1673 */
1674
da91b269 1675static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
1676{
1677 ni_release_ai_mite_channel(dev);
1678 /* ai configuration */
1679 devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
0a85b6f0 1680 Joint_Reset_Register);
03aef4b6
DS
1681
1682 ni_set_bits(dev, Interrupt_A_Enable_Register,
0a85b6f0
MT
1683 AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
1684 AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable |
1685 AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable |
1686 AI_FIFO_Interrupt_Enable, 0);
03aef4b6
DS
1687
1688 ni_clear_ai_fifo(dev);
1689
1690 if (boardtype.reg_type != ni_reg_6143)
1691 ni_writeb(0, Misc_Command);
1692
1693 devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
1694 devpriv->stc_writew(dev,
0a85b6f0
MT
1695 AI_Start_Stop | AI_Mode_1_Reserved
1696 /*| AI_Trigger_Once */ ,
1697 AI_Mode_1_Register);
03aef4b6
DS
1698 devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
1699 /* generate FIFO interrupts on non-empty */
1700 devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
1701 if (boardtype.reg_type == ni_reg_611x) {
1702 devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
0a85b6f0
MT
1703 AI_SOC_Polarity |
1704 AI_LOCALMUX_CLK_Pulse_Width,
1705 AI_Personal_Register);
1706 devpriv->stc_writew(dev,
1707 AI_SCAN_IN_PROG_Output_Select(3) |
1708 AI_EXTMUX_CLK_Output_Select(0) |
1709 AI_LOCALMUX_CLK_Output_Select(2) |
1710 AI_SC_TC_Output_Select(3) |
1711 AI_CONVERT_Output_Select
1712 (AI_CONVERT_Output_Enable_High),
1713 AI_Output_Control_Register);
03aef4b6
DS
1714 } else if (boardtype.reg_type == ni_reg_6143) {
1715 devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
0a85b6f0
MT
1716 AI_SOC_Polarity |
1717 AI_LOCALMUX_CLK_Pulse_Width,
1718 AI_Personal_Register);
1719 devpriv->stc_writew(dev,
1720 AI_SCAN_IN_PROG_Output_Select(3) |
1721 AI_EXTMUX_CLK_Output_Select(0) |
1722 AI_LOCALMUX_CLK_Output_Select(2) |
1723 AI_SC_TC_Output_Select(3) |
1724 AI_CONVERT_Output_Select
1725 (AI_CONVERT_Output_Enable_Low),
1726 AI_Output_Control_Register);
03aef4b6
DS
1727 } else {
1728 unsigned ai_output_control_bits;
1729 devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
0a85b6f0
MT
1730 AI_SOC_Polarity |
1731 AI_CONVERT_Pulse_Width |
1732 AI_LOCALMUX_CLK_Pulse_Width,
1733 AI_Personal_Register);
1734 ai_output_control_bits =
1735 AI_SCAN_IN_PROG_Output_Select(3) |
1736 AI_EXTMUX_CLK_Output_Select(0) |
1737 AI_LOCALMUX_CLK_Output_Select(2) |
1738 AI_SC_TC_Output_Select(3);
03aef4b6
DS
1739 if (boardtype.reg_type == ni_reg_622x)
1740 ai_output_control_bits |=
0a85b6f0
MT
1741 AI_CONVERT_Output_Select
1742 (AI_CONVERT_Output_Enable_High);
03aef4b6
DS
1743 else
1744 ai_output_control_bits |=
0a85b6f0
MT
1745 AI_CONVERT_Output_Select
1746 (AI_CONVERT_Output_Enable_Low);
03aef4b6 1747 devpriv->stc_writew(dev, ai_output_control_bits,
0a85b6f0 1748 AI_Output_Control_Register);
03aef4b6
DS
1749 }
1750 /* the following registers should not be changed, because there
1751 * are no backup registers in devpriv. If you want to change
1752 * any of these, add a backup register and other appropriate code:
1753 * AI_Mode_1_Register
1754 * AI_Mode_3_Register
1755 * AI_Personal_Register
1756 * AI_Output_Control_Register
1757 */
1758 devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
1759
1760 devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
1761
1762 return 0;
1763}
1764
da91b269 1765static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
1766{
1767 unsigned long flags = 0;
1768 int count;
1769
2696fb57 1770 /* lock to avoid race with interrupt handler */
03aef4b6 1771 if (in_interrupt() == 0)
5f74ea14 1772 spin_lock_irqsave(&dev->spinlock, flags);
03aef4b6
DS
1773#ifndef PCIDMA
1774 ni_handle_fifo_dregs(dev);
1775#else
1776 ni_sync_ai_dma(dev);
1777#endif
1778 count = s->async->buf_write_count - s->async->buf_read_count;
1779 if (in_interrupt() == 0)
5f74ea14 1780 spin_unlock_irqrestore(&dev->spinlock, flags);
03aef4b6
DS
1781
1782 return count;
1783}
1784
0a85b6f0
MT
1785static int ni_ai_insn_read(struct comedi_device *dev,
1786 struct comedi_subdevice *s, struct comedi_insn *insn,
1787 unsigned int *data)
03aef4b6
DS
1788{
1789 int i, n;
1790 const unsigned int mask = (1 << boardtype.adbits) - 1;
1791 unsigned signbits;
1792 unsigned short d;
1793 unsigned long dl;
1794
1795 ni_load_channelgain_list(dev, 1, &insn->chanspec);
1796
1797 ni_clear_ai_fifo(dev);
1798
1799 signbits = devpriv->ai_offset[0];
1800 if (boardtype.reg_type == ni_reg_611x) {
1801 for (n = 0; n < num_adc_stages_611x; n++) {
1802 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 1803 AI_Command_1_Register);
5f74ea14 1804 udelay(1);
03aef4b6
DS
1805 }
1806 for (n = 0; n < insn->n; n++) {
1807 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 1808 AI_Command_1_Register);
03aef4b6
DS
1809 /* The 611x has screwy 32-bit FIFOs. */
1810 d = 0;
1811 for (i = 0; i < NI_TIMEOUT; i++) {
1812 if (ni_readb(XXX_Status) & 0x80) {
1813 d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
0a85b6f0 1814 & 0xffff;
03aef4b6
DS
1815 break;
1816 }
1817 if (!(devpriv->stc_readw(dev,
0a85b6f0
MT
1818 AI_Status_1_Register) &
1819 AI_FIFO_Empty_St)) {
03aef4b6 1820 d = ni_readl(ADC_FIFO_Data_611x) &
0a85b6f0 1821 0xffff;
03aef4b6
DS
1822 break;
1823 }
1824 }
1825 if (i == NI_TIMEOUT) {
5f74ea14 1826 printk
0a85b6f0 1827 ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
03aef4b6
DS
1828 return -ETIME;
1829 }
1830 d += signbits;
1831 data[n] = d;
1832 }
1833 } else if (boardtype.reg_type == ni_reg_6143) {
1834 for (n = 0; n < insn->n; n++) {
1835 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 1836 AI_Command_1_Register);
03aef4b6
DS
1837
1838 /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
1839 dl = 0;
1840 for (i = 0; i < NI_TIMEOUT; i++) {
1841 if (ni_readl(AIFIFO_Status_6143) & 0x01) {
2696fb57 1842 ni_writel(0x01, AIFIFO_Control_6143); /* Get stranded sample into FIFO */
03aef4b6
DS
1843 dl = ni_readl(AIFIFO_Data_6143);
1844 break;
1845 }
1846 }
1847 if (i == NI_TIMEOUT) {
5f74ea14 1848 printk
0a85b6f0 1849 ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
03aef4b6
DS
1850 return -ETIME;
1851 }
1852 data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
1853 }
1854 } else {
1855 for (n = 0; n < insn->n; n++) {
1856 devpriv->stc_writew(dev, AI_CONVERT_Pulse,
0a85b6f0 1857 AI_Command_1_Register);
03aef4b6
DS
1858 for (i = 0; i < NI_TIMEOUT; i++) {
1859 if (!(devpriv->stc_readw(dev,
0a85b6f0
MT
1860 AI_Status_1_Register) &
1861 AI_FIFO_Empty_St))
03aef4b6
DS
1862 break;
1863 }
1864 if (i == NI_TIMEOUT) {
5f74ea14 1865 printk
0a85b6f0 1866 ("ni_mio_common: timeout in ni_ai_insn_read\n");
03aef4b6
DS
1867 return -ETIME;
1868 }
1869 if (boardtype.reg_type & ni_reg_m_series_mask) {
1870 data[n] =
0a85b6f0 1871 ni_readl(M_Offset_AI_FIFO_Data) & mask;
03aef4b6
DS
1872 } else {
1873 d = ni_readw(ADC_FIFO_Data_Register);
1874 d += signbits; /* subtle: needs to be short addition */
1875 data[n] = d;
1876 }
1877 }
1878 }
1879 return insn->n;
1880}
1881
da91b269 1882void ni_prime_channelgain_list(struct comedi_device *dev)
03aef4b6
DS
1883{
1884 int i;
1885 devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
1886 for (i = 0; i < NI_TIMEOUT; ++i) {
1887 if (!(devpriv->stc_readw(dev,
0a85b6f0
MT
1888 AI_Status_1_Register) &
1889 AI_FIFO_Empty_St)) {
03aef4b6
DS
1890 devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
1891 return;
1892 }
5f74ea14 1893 udelay(1);
03aef4b6 1894 }
5f74ea14 1895 printk("ni_mio_common: timeout loading channel/gain list\n");
03aef4b6
DS
1896}
1897
da91b269 1898static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
0a85b6f0
MT
1899 unsigned int n_chan,
1900 unsigned int *list)
03aef4b6
DS
1901{
1902 unsigned int chan, range, aref;
1903 unsigned int i;
1904 unsigned offset;
1905 unsigned int dither;
1906 unsigned range_code;
1907
1908 devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
1909
2696fb57 1910/* offset = 1 << (boardtype.adbits - 1); */
03aef4b6
DS
1911 if ((list[0] & CR_ALT_SOURCE)) {
1912 unsigned bypass_bits;
1913 chan = CR_CHAN(list[0]);
1914 range = CR_RANGE(list[0]);
1915 range_code = ni_gainlkup[boardtype.gainlkup][range];
1916 dither = ((list[0] & CR_ALT_FILTER) != 0);
1917 bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
1918 bypass_bits |= chan;
1919 bypass_bits |=
0a85b6f0
MT
1920 (devpriv->ai_calib_source) &
1921 (MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
1922 MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
1923 MSeries_AI_Bypass_Mode_Mux_Mask |
1924 MSeries_AO_Bypass_AO_Cal_Sel_Mask);
03aef4b6
DS
1925 bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code);
1926 if (dither)
1927 bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
2696fb57 1928 /* don't use 2's complement encoding */
03aef4b6
DS
1929 bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
1930 ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
1931 } else {
1932 ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
1933 }
1934 offset = 0;
1935 for (i = 0; i < n_chan; i++) {
1936 unsigned config_bits = 0;
1937 chan = CR_CHAN(list[i]);
1938 aref = CR_AREF(list[i]);
1939 range = CR_RANGE(list[i]);
1940 dither = ((list[i] & CR_ALT_FILTER) != 0);
1941
1942 range_code = ni_gainlkup[boardtype.gainlkup][range];
1943 devpriv->ai_offset[i] = offset;
1944 switch (aref) {
1945 case AREF_DIFF:
1946 config_bits |=
0a85b6f0 1947 MSeries_AI_Config_Channel_Type_Differential_Bits;
03aef4b6
DS
1948 break;
1949 case AREF_COMMON:
1950 config_bits |=
0a85b6f0 1951 MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
03aef4b6
DS
1952 break;
1953 case AREF_GROUND:
1954 config_bits |=
0a85b6f0 1955 MSeries_AI_Config_Channel_Type_Ground_Ref_Bits;
03aef4b6
DS
1956 break;
1957 case AREF_OTHER:
1958 break;
1959 }
1960 config_bits |= MSeries_AI_Config_Channel_Bits(chan);
1961 config_bits |=
0a85b6f0 1962 MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan);
03aef4b6
DS
1963 config_bits |= MSeries_AI_Config_Gain_Bits(range_code);
1964 if (i == n_chan - 1)
1965 config_bits |= MSeries_AI_Config_Last_Channel_Bit;
1966 if (dither)
1967 config_bits |= MSeries_AI_Config_Dither_Bit;
2696fb57 1968 /* don't use 2's complement encoding */
03aef4b6
DS
1969 config_bits |= MSeries_AI_Config_Polarity_Bit;
1970 ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
1971 }
1972 ni_prime_channelgain_list(dev);
1973}
1974
1975/*
1976 * Notes on the 6110 and 6111:
1977 * These boards a slightly different than the rest of the series, since
1978 * they have multiple A/D converters.
1979 * From the driver side, the configuration memory is a
1980 * little different.
1981 * Configuration Memory Low:
1982 * bits 15-9: same
1983 * bit 8: unipolar/bipolar (should be 0 for bipolar)
1984 * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
1985 * 1001 gain=0.1 (+/- 50)
1986 * 1010 0.2
1987 * 1011 0.1
1988 * 0001 1
1989 * 0010 2
1990 * 0011 5
1991 * 0100 10
1992 * 0101 20
1993 * 0110 50
1994 * Configuration Memory High:
1995 * bits 12-14: Channel Type
1996 * 001 for differential
1997 * 000 for calibration
1998 * bit 11: coupling (this is not currently handled)
1999 * 1 AC coupling
2000 * 0 DC coupling
2001 * bits 0-2: channel
2002 * valid channels are 0-3
2003 */
0a85b6f0
MT
2004static void ni_load_channelgain_list(struct comedi_device *dev,
2005 unsigned int n_chan, unsigned int *list)
03aef4b6
DS
2006{
2007 unsigned int chan, range, aref;
2008 unsigned int i;
2009 unsigned int hi, lo;
2010 unsigned offset;
2011 unsigned int dither;
2012
2013 if (boardtype.reg_type & ni_reg_m_series_mask) {
2014 ni_m_series_load_channelgain_list(dev, n_chan, list);
2015 return;
2016 }
2017 if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
0a85b6f0 2018 && (boardtype.reg_type != ni_reg_6143)) {
03aef4b6 2019 if (devpriv->changain_state
0a85b6f0 2020 && devpriv->changain_spec == list[0]) {
2696fb57 2021 /* ready to go. */
03aef4b6
DS
2022 return;
2023 }
2024 devpriv->changain_state = 1;
2025 devpriv->changain_spec = list[0];
2026 } else {
2027 devpriv->changain_state = 0;
2028 }
2029
2030 devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
2031
2696fb57 2032 /* Set up Calibration mode if required */
03aef4b6
DS
2033 if (boardtype.reg_type == ni_reg_6143) {
2034 if ((list[0] & CR_ALT_SOURCE)
0a85b6f0 2035 && !devpriv->ai_calib_source_enabled) {
2696fb57 2036 /* Strobe Relay enable bit */
0a85b6f0
MT
2037 ni_writew(devpriv->ai_calib_source |
2038 Calibration_Channel_6143_RelayOn,
2039 Calibration_Channel_6143);
03aef4b6 2040 ni_writew(devpriv->ai_calib_source,
0a85b6f0 2041 Calibration_Channel_6143);
03aef4b6 2042 devpriv->ai_calib_source_enabled = 1;
2696fb57 2043 msleep_interruptible(100); /* Allow relays to change */
03aef4b6 2044 } else if (!(list[0] & CR_ALT_SOURCE)
0a85b6f0 2045 && devpriv->ai_calib_source_enabled) {
2696fb57 2046 /* Strobe Relay disable bit */
0a85b6f0
MT
2047 ni_writew(devpriv->ai_calib_source |
2048 Calibration_Channel_6143_RelayOff,
2049 Calibration_Channel_6143);
03aef4b6 2050 ni_writew(devpriv->ai_calib_source,
0a85b6f0 2051 Calibration_Channel_6143);
03aef4b6 2052 devpriv->ai_calib_source_enabled = 0;
2696fb57 2053 msleep_interruptible(100); /* Allow relays to change */
03aef4b6
DS
2054 }
2055 }
2056
2057 offset = 1 << (boardtype.adbits - 1);
2058 for (i = 0; i < n_chan; i++) {
2059 if ((boardtype.reg_type != ni_reg_6143)
0a85b6f0 2060 && (list[i] & CR_ALT_SOURCE)) {
03aef4b6
DS
2061 chan = devpriv->ai_calib_source;
2062 } else {
2063 chan = CR_CHAN(list[i]);
2064 }
2065 aref = CR_AREF(list[i]);
2066 range = CR_RANGE(list[i]);
2067 dither = ((list[i] & CR_ALT_FILTER) != 0);
2068
2069 /* fix the external/internal range differences */
2070 range = ni_gainlkup[boardtype.gainlkup][range];
2071 if (boardtype.reg_type == ni_reg_611x)
2072 devpriv->ai_offset[i] = offset;
2073 else
2074 devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
2075
2076 hi = 0;
2077 if ((list[i] & CR_ALT_SOURCE)) {
2078 if (boardtype.reg_type == ni_reg_611x)
2079 ni_writew(CR_CHAN(list[i]) & 0x0003,
0a85b6f0 2080 Calibration_Channel_Select_611x);
03aef4b6
DS
2081 } else {
2082 if (boardtype.reg_type == ni_reg_611x)
2083 aref = AREF_DIFF;
2084 else if (boardtype.reg_type == ni_reg_6143)
2085 aref = AREF_OTHER;
2086 switch (aref) {
2087 case AREF_DIFF:
2088 hi |= AI_DIFFERENTIAL;
2089 break;
2090 case AREF_COMMON:
2091 hi |= AI_COMMON;
2092 break;
2093 case AREF_GROUND:
2094 hi |= AI_GROUND;
2095 break;
2096 case AREF_OTHER:
2097 break;
2098 }
2099 }
2100 hi |= AI_CONFIG_CHANNEL(chan);
2101
2102 ni_writew(hi, Configuration_Memory_High);
2103
2104 if (boardtype.reg_type != ni_reg_6143) {
2105 lo = range;
2106 if (i == n_chan - 1)
2107 lo |= AI_LAST_CHANNEL;
2108 if (dither)
2109 lo |= AI_DITHER;
2110
2111 ni_writew(lo, Configuration_Memory_Low);
2112 }
2113 }
2114
2115 /* prime the channel/gain list */
2116 if ((boardtype.reg_type != ni_reg_611x)
0a85b6f0 2117 && (boardtype.reg_type != ni_reg_6143)) {
03aef4b6
DS
2118 ni_prime_channelgain_list(dev);
2119 }
2120}
2121
da91b269 2122static int ni_ns_to_timer(const struct comedi_device *dev, unsigned nanosec,
0a85b6f0 2123 int round_mode)
03aef4b6
DS
2124{
2125 int divider;
2126 switch (round_mode) {
2127 case TRIG_ROUND_NEAREST:
2128 default:
2129 divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
2130 break;
2131 case TRIG_ROUND_DOWN:
2132 divider = (nanosec) / devpriv->clock_ns;
2133 break;
2134 case TRIG_ROUND_UP:
2135 divider = (nanosec + devpriv->clock_ns - 1) / devpriv->clock_ns;
2136 break;
2137 }
2138 return divider - 1;
2139}
2140
da91b269 2141static unsigned ni_timer_to_ns(const struct comedi_device *dev, int timer)
03aef4b6
DS
2142{
2143 return devpriv->clock_ns * (timer + 1);
2144}
2145
da91b269 2146static unsigned ni_min_ai_scan_period_ns(struct comedi_device *dev,
0a85b6f0 2147 unsigned num_channels)
03aef4b6
DS
2148{
2149 switch (boardtype.reg_type) {
2150 case ni_reg_611x:
2151 case ni_reg_6143:
2696fb57 2152 /* simultaneously-sampled inputs */
03aef4b6
DS
2153 return boardtype.ai_speed;
2154 break;
2155 default:
2696fb57 2156 /* multiplexed inputs */
03aef4b6
DS
2157 break;
2158 };
2159 return boardtype.ai_speed * num_channels;
2160}
2161
da91b269 2162static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2163 struct comedi_cmd *cmd)
03aef4b6
DS
2164{
2165 int err = 0;
2166 int tmp;
2167 int sources;
2168
2169 /* step 1: make sure trigger sources are trivially valid */
2170
2171 if ((cmd->flags & CMDF_WRITE)) {
2172 cmd->flags &= ~CMDF_WRITE;
2173 }
2174
2175 tmp = cmd->start_src;
2176 cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
2177 if (!cmd->start_src || tmp != cmd->start_src)
2178 err++;
2179
2180 tmp = cmd->scan_begin_src;
2181 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
2182 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
2183 err++;
2184
2185 tmp = cmd->convert_src;
2186 sources = TRIG_TIMER | TRIG_EXT;
2187 if ((boardtype.reg_type == ni_reg_611x)
0a85b6f0 2188 || (boardtype.reg_type == ni_reg_6143))
03aef4b6
DS
2189 sources |= TRIG_NOW;
2190 cmd->convert_src &= sources;
2191 if (!cmd->convert_src || tmp != cmd->convert_src)
2192 err++;
2193
2194 tmp = cmd->scan_end_src;
2195 cmd->scan_end_src &= TRIG_COUNT;
2196 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
2197 err++;
2198
2199 tmp = cmd->stop_src;
2200 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
2201 if (!cmd->stop_src || tmp != cmd->stop_src)
2202 err++;
2203
2204 if (err)
2205 return 1;
2206
2207 /* step 2: make sure trigger sources are unique and mutually compatible */
2208
2209 /* note that mutual compatiblity is not an issue here */
2210 if (cmd->start_src != TRIG_NOW &&
0a85b6f0 2211 cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
03aef4b6
DS
2212 err++;
2213 if (cmd->scan_begin_src != TRIG_TIMER &&
0a85b6f0
MT
2214 cmd->scan_begin_src != TRIG_EXT &&
2215 cmd->scan_begin_src != TRIG_OTHER)
03aef4b6
DS
2216 err++;
2217 if (cmd->convert_src != TRIG_TIMER &&
0a85b6f0 2218 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
03aef4b6
DS
2219 err++;
2220 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
2221 err++;
2222
2223 if (err)
2224 return 2;
2225
2226 /* step 3: make sure arguments are trivially compatible */
2227
2228 if (cmd->start_src == TRIG_EXT) {
2229 /* external trigger */
2230 unsigned int tmp = CR_CHAN(cmd->start_arg);
2231
2232 if (tmp > 16)
2233 tmp = 16;
2234 tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
2235 if (cmd->start_arg != tmp) {
2236 cmd->start_arg = tmp;
2237 err++;
2238 }
2239 } else {
2240 if (cmd->start_arg != 0) {
2241 /* true for both TRIG_NOW and TRIG_INT */
2242 cmd->start_arg = 0;
2243 err++;
2244 }
2245 }
2246 if (cmd->scan_begin_src == TRIG_TIMER) {
2247 if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
0a85b6f0
MT
2248 cmd->
2249 chanlist_len))
2250 {
03aef4b6 2251 cmd->scan_begin_arg =
0a85b6f0 2252 ni_min_ai_scan_period_ns(dev, cmd->chanlist_len);
03aef4b6
DS
2253 err++;
2254 }
2255 if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
2256 cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
2257 err++;
2258 }
2259 } else if (cmd->scan_begin_src == TRIG_EXT) {
2260 /* external trigger */
2261 unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
2262
2263 if (tmp > 16)
2264 tmp = 16;
2265 tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
2266 if (cmd->scan_begin_arg != tmp) {
2267 cmd->scan_begin_arg = tmp;
2268 err++;
2269 }
2270 } else { /* TRIG_OTHER */
2271 if (cmd->scan_begin_arg) {
2272 cmd->scan_begin_arg = 0;
2273 err++;
2274 }
2275 }
2276 if (cmd->convert_src == TRIG_TIMER) {
2277 if ((boardtype.reg_type == ni_reg_611x)
0a85b6f0 2278 || (boardtype.reg_type == ni_reg_6143)) {
03aef4b6
DS
2279 if (cmd->convert_arg != 0) {
2280 cmd->convert_arg = 0;
2281 err++;
2282 }
2283 } else {
2284 if (cmd->convert_arg < boardtype.ai_speed) {
2285 cmd->convert_arg = boardtype.ai_speed;
2286 err++;
2287 }
2288 if (cmd->convert_arg > devpriv->clock_ns * 0xffff) {
2289 cmd->convert_arg = devpriv->clock_ns * 0xffff;
2290 err++;
2291 }
2292 }
2293 } else if (cmd->convert_src == TRIG_EXT) {
2294 /* external trigger */
2295 unsigned int tmp = CR_CHAN(cmd->convert_arg);
2296
2297 if (tmp > 16)
2298 tmp = 16;
2299 tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
2300 if (cmd->convert_arg != tmp) {
2301 cmd->convert_arg = tmp;
2302 err++;
2303 }
2304 } else if (cmd->convert_src == TRIG_NOW) {
2305 if (cmd->convert_arg != 0) {
2306 cmd->convert_arg = 0;
2307 err++;
2308 }
2309 }
2310
2311 if (cmd->scan_end_arg != cmd->chanlist_len) {
2312 cmd->scan_end_arg = cmd->chanlist_len;
2313 err++;
2314 }
2315 if (cmd->stop_src == TRIG_COUNT) {
2316 unsigned int max_count = 0x01000000;
2317
2318 if (boardtype.reg_type == ni_reg_611x)
2319 max_count -= num_adc_stages_611x;
2320 if (cmd->stop_arg > max_count) {
2321 cmd->stop_arg = max_count;
2322 err++;
2323 }
2324 if (cmd->stop_arg < 1) {
2325 cmd->stop_arg = 1;
2326 err++;
2327 }
2328 } else {
2329 /* TRIG_NONE */
2330 if (cmd->stop_arg != 0) {
2331 cmd->stop_arg = 0;
2332 err++;
2333 }
2334 }
2335
2336 if (err)
2337 return 3;
2338
2339 /* step 4: fix up any arguments */
2340
2341 if (cmd->scan_begin_src == TRIG_TIMER) {
2342 tmp = cmd->scan_begin_arg;
2343 cmd->scan_begin_arg =
0a85b6f0
MT
2344 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
2345 cmd->scan_begin_arg,
2346 cmd->
2347 flags &
2348 TRIG_ROUND_MASK));
03aef4b6
DS
2349 if (tmp != cmd->scan_begin_arg)
2350 err++;
2351 }
2352 if (cmd->convert_src == TRIG_TIMER) {
2353 if ((boardtype.reg_type != ni_reg_611x)
0a85b6f0 2354 && (boardtype.reg_type != ni_reg_6143)) {
03aef4b6
DS
2355 tmp = cmd->convert_arg;
2356 cmd->convert_arg =
0a85b6f0
MT
2357 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
2358 cmd->convert_arg,
2359 cmd->
2360 flags &
2361 TRIG_ROUND_MASK));
03aef4b6
DS
2362 if (tmp != cmd->convert_arg)
2363 err++;
2364 if (cmd->scan_begin_src == TRIG_TIMER &&
0a85b6f0
MT
2365 cmd->scan_begin_arg <
2366 cmd->convert_arg * cmd->scan_end_arg) {
03aef4b6 2367 cmd->scan_begin_arg =
0a85b6f0 2368 cmd->convert_arg * cmd->scan_end_arg;
03aef4b6
DS
2369 err++;
2370 }
2371 }
2372 }
2373
2374 if (err)
2375 return 4;
2376
2377 return 0;
2378}
2379
da91b269 2380static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6 2381{
ea6d0d4c 2382 const struct comedi_cmd *cmd = &s->async->cmd;
03aef4b6
DS
2383 int timer;
2384 int mode1 = 0; /* mode1 is needed for both stop and convert */
2385 int mode2 = 0;
2386 int start_stop_select = 0;
2387 unsigned int stop_count;
2388 int interrupt_a_enable = 0;
2389
2390 MDPRINTK("ni_ai_cmd\n");
2391 if (dev->irq == 0) {
2392 comedi_error(dev, "cannot run command without an irq");
2393 return -EIO;
2394 }
2395 ni_clear_ai_fifo(dev);
2396
2397 ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
2398
2399 /* start configuration */
2400 devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
2401
2402 /* disable analog triggering for now, since it
2403 * interferes with the use of pfi0 */
2404 devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
2405 devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
0a85b6f0 2406 Analog_Trigger_Etc_Register);
03aef4b6
DS
2407
2408 switch (cmd->start_src) {
2409 case TRIG_INT:
2410 case TRIG_NOW:
2411 devpriv->stc_writew(dev, AI_START2_Select(0) |
0a85b6f0
MT
2412 AI_START1_Sync | AI_START1_Edge |
2413 AI_START1_Select(0),
2414 AI_Trigger_Select_Register);
03aef4b6
DS
2415 break;
2416 case TRIG_EXT:
2417 {
2418 int chan = CR_CHAN(cmd->start_arg);
2419 unsigned int bits = AI_START2_Select(0) |
0a85b6f0 2420 AI_START1_Sync | AI_START1_Select(chan + 1);
03aef4b6
DS
2421
2422 if (cmd->start_arg & CR_INVERT)
2423 bits |= AI_START1_Polarity;
2424 if (cmd->start_arg & CR_EDGE)
2425 bits |= AI_START1_Edge;
2426 devpriv->stc_writew(dev, bits,
0a85b6f0 2427 AI_Trigger_Select_Register);
03aef4b6
DS
2428 break;
2429 }
2430 }
2431
2432 mode2 &= ~AI_Pre_Trigger;
2433 mode2 &= ~AI_SC_Initial_Load_Source;
2434 mode2 &= ~AI_SC_Reload_Mode;
2435 devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
2436
2437 if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x)
0a85b6f0 2438 || (boardtype.reg_type == ni_reg_6143)) {
03aef4b6 2439 start_stop_select |= AI_STOP_Polarity;
2696fb57 2440 start_stop_select |= AI_STOP_Select(31); /* logic low */
03aef4b6
DS
2441 start_stop_select |= AI_STOP_Sync;
2442 } else {
2696fb57 2443 start_stop_select |= AI_STOP_Select(19); /* ai configuration memory */
03aef4b6
DS
2444 }
2445 devpriv->stc_writew(dev, start_stop_select,
0a85b6f0 2446 AI_START_STOP_Select_Register);
03aef4b6
DS
2447
2448 devpriv->ai_cmd2 = 0;
2449 switch (cmd->stop_src) {
2450 case TRIG_COUNT:
2451 stop_count = cmd->stop_arg - 1;
2452
2453 if (boardtype.reg_type == ni_reg_611x) {
2696fb57 2454 /* have to take 3 stage adc pipeline into account */
03aef4b6
DS
2455 stop_count += num_adc_stages_611x;
2456 }
2457 /* stage number of scans */
2458 devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
2459
2460 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
2461 devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
2462 /* load SC (Scan Count) */
2463 devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
2464
2465 devpriv->ai_continuous = 0;
2466 if (stop_count == 0) {
2467 devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
2468 interrupt_a_enable |= AI_STOP_Interrupt_Enable;
2696fb57 2469 /* this is required to get the last sample for chanlist_len > 1, not sure why */
03aef4b6
DS
2470 if (cmd->chanlist_len > 1)
2471 start_stop_select |=
0a85b6f0 2472 AI_STOP_Polarity | AI_STOP_Edge;
03aef4b6
DS
2473 }
2474 break;
2475 case TRIG_NONE:
2476 /* stage number of scans */
2477 devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
2478
2479 mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
2480 devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
2481
2482 /* load SC (Scan Count) */
2483 devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
2484
2485 devpriv->ai_continuous = 1;
2486
2487 break;
2488 }
2489
2490 switch (cmd->scan_begin_src) {
2491 case TRIG_TIMER:
2492 /*
2493 stop bits for non 611x boards
2494 AI_SI_Special_Trigger_Delay=0
2495 AI_Pre_Trigger=0
2496 AI_START_STOP_Select_Register:
2497 AI_START_Polarity=0 (?) rising edge
2498 AI_START_Edge=1 edge triggered
2499 AI_START_Sync=1 (?)
2500 AI_START_Select=0 SI_TC
2501 AI_STOP_Polarity=0 rising edge
2502 AI_STOP_Edge=0 level
2503 AI_STOP_Sync=1
2504 AI_STOP_Select=19 external pin (configuration mem)
2505 */
2506 start_stop_select |= AI_START_Edge | AI_START_Sync;
2507 devpriv->stc_writew(dev, start_stop_select,
0a85b6f0 2508 AI_START_STOP_Select_Register);
03aef4b6
DS
2509
2510 mode2 |= AI_SI_Reload_Mode(0);
2511 /* AI_SI_Initial_Load_Source=A */
2512 mode2 &= ~AI_SI_Initial_Load_Source;
2696fb57 2513 /* mode2 |= AI_SC_Reload_Mode; */
03aef4b6
DS
2514 devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
2515
2516 /* load SI */
2517 timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
0a85b6f0 2518 TRIG_ROUND_NEAREST);
03aef4b6
DS
2519 devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
2520 devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
2521 break;
2522 case TRIG_EXT:
2523 if (cmd->scan_begin_arg & CR_EDGE)
2524 start_stop_select |= AI_START_Edge;
2525 /* AI_START_Polarity==1 is falling edge */
2526 if (cmd->scan_begin_arg & CR_INVERT)
2527 start_stop_select |= AI_START_Polarity;
2528 if (cmd->scan_begin_src != cmd->convert_src ||
0a85b6f0
MT
2529 (cmd->scan_begin_arg & ~CR_EDGE) !=
2530 (cmd->convert_arg & ~CR_EDGE))
03aef4b6
DS
2531 start_stop_select |= AI_START_Sync;
2532 start_stop_select |=
0a85b6f0 2533 AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
03aef4b6 2534 devpriv->stc_writew(dev, start_stop_select,
0a85b6f0 2535 AI_START_STOP_Select_Register);
03aef4b6
DS
2536 break;
2537 }
2538
2539 switch (cmd->convert_src) {
2540 case TRIG_TIMER:
2541 case TRIG_NOW:
2542 if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
2543 timer = 1;
2544 else
2545 timer = ni_ns_to_timer(dev, cmd->convert_arg,
0a85b6f0 2546 TRIG_ROUND_NEAREST);
03aef4b6
DS
2547 devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */
2548 devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
2549
2550 /* AI_SI2_Reload_Mode = alternate */
2551 /* AI_SI2_Initial_Load_Source = A */
2552 mode2 &= ~AI_SI2_Initial_Load_Source;
2553 mode2 |= AI_SI2_Reload_Mode;
2554 devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
2555
2556 /* AI_SI2_Load */
2557 devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
2558
2696fb57
BP
2559 mode2 |= AI_SI2_Reload_Mode; /* alternate */
2560 mode2 |= AI_SI2_Initial_Load_Source; /* B */
03aef4b6
DS
2561
2562 devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
2563 break;
2564 case TRIG_EXT:
2565 mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
2566 if ((cmd->convert_arg & CR_INVERT) == 0)
2567 mode1 |= AI_CONVERT_Source_Polarity;
2568 devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
2569
2570 mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
2571 devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
2572
2573 break;
2574 }
2575
2576 if (dev->irq) {
2577
2578 /* interrupt on FIFO, errors, SC_TC */
2579 interrupt_a_enable |= AI_Error_Interrupt_Enable |
0a85b6f0 2580 AI_SC_TC_Interrupt_Enable;
03aef4b6
DS
2581
2582#ifndef PCIDMA
2583 interrupt_a_enable |= AI_FIFO_Interrupt_Enable;
2584#endif
2585
2586 if (cmd->flags & TRIG_WAKE_EOS
0a85b6f0 2587 || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
03aef4b6
DS
2588 /* wake on end-of-scan */
2589 devpriv->aimode = AIMODE_SCAN;
2590 } else {
2591 devpriv->aimode = AIMODE_HALF_FULL;
2592 }
2593
2594 switch (devpriv->aimode) {
2595 case AIMODE_HALF_FULL:
2596 /*generate FIFO interrupts and DMA requests on half-full */
2597#ifdef PCIDMA
2598 devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
0a85b6f0 2599 AI_Mode_3_Register);
03aef4b6
DS
2600#else
2601 devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
0a85b6f0 2602 AI_Mode_3_Register);
03aef4b6
DS
2603#endif
2604 break;
2605 case AIMODE_SAMPLE:
2606 /*generate FIFO interrupts on non-empty */
2607 devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
0a85b6f0 2608 AI_Mode_3_Register);
03aef4b6
DS
2609 break;
2610 case AIMODE_SCAN:
2611#ifdef PCIDMA
2612 devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
0a85b6f0 2613 AI_Mode_3_Register);
03aef4b6
DS
2614#else
2615 devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
0a85b6f0 2616 AI_Mode_3_Register);
03aef4b6
DS
2617#endif
2618 interrupt_a_enable |= AI_STOP_Interrupt_Enable;
2619 break;
2620 default:
2621 break;
2622 }
2623
2624 devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */
2625
2626 ni_set_bits(dev, Interrupt_A_Enable_Register,
0a85b6f0 2627 interrupt_a_enable, 1);
03aef4b6
DS
2628
2629 MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
0a85b6f0 2630 devpriv->int_a_enable_reg);
03aef4b6
DS
2631 } else {
2632 /* interrupt on nothing */
2633 ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
2634
2635 /* XXX start polling if necessary */
2636 MDPRINTK("interrupting on nothing\n");
2637 }
2638
2639 /* end configuration */
2640 devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
2641
2642 switch (cmd->scan_begin_src) {
2643 case TRIG_TIMER:
2644 devpriv->stc_writew(dev,
0a85b6f0
MT
2645 AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
2646 AI_SC_Arm, AI_Command_1_Register);
03aef4b6
DS
2647 break;
2648 case TRIG_EXT:
2649 /* XXX AI_SI_Arm? */
2650 devpriv->stc_writew(dev,
0a85b6f0
MT
2651 AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm |
2652 AI_SC_Arm, AI_Command_1_Register);
03aef4b6
DS
2653 break;
2654 }
2655
2656#ifdef PCIDMA
2657 {
2658 int retval = ni_ai_setup_MITE_dma(dev);
2659 if (retval)
2660 return retval;
2661 }
2696fb57 2662 /* mite_dump_regs(devpriv->mite); */
03aef4b6
DS
2663#endif
2664
2665 switch (cmd->start_src) {
2666 case TRIG_NOW:
2667 /* AI_START1_Pulse */
2668 devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
0a85b6f0 2669 AI_Command_2_Register);
03aef4b6
DS
2670 s->async->inttrig = NULL;
2671 break;
2672 case TRIG_EXT:
2673 s->async->inttrig = NULL;
2674 break;
2675 case TRIG_INT:
2676 s->async->inttrig = &ni_ai_inttrig;
2677 break;
2678 }
2679
2680 MDPRINTK("exit ni_ai_cmd\n");
2681
2682 return 0;
2683}
2684
da91b269 2685static int ni_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 2686 unsigned int trignum)
03aef4b6
DS
2687{
2688 if (trignum != 0)
2689 return -EINVAL;
2690
2691 devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
0a85b6f0 2692 AI_Command_2_Register);
03aef4b6
DS
2693 s->async->inttrig = NULL;
2694
2695 return 1;
2696}
2697
0a85b6f0
MT
2698static int ni_ai_config_analog_trig(struct comedi_device *dev,
2699 struct comedi_subdevice *s,
2700 struct comedi_insn *insn,
2701 unsigned int *data);
03aef4b6 2702
0a85b6f0
MT
2703static int ni_ai_insn_config(struct comedi_device *dev,
2704 struct comedi_subdevice *s,
2705 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
2706{
2707 if (insn->n < 1)
2708 return -EINVAL;
2709
2710 switch (data[0]) {
2711 case INSN_CONFIG_ANALOG_TRIG:
2712 return ni_ai_config_analog_trig(dev, s, insn, data);
2713 case INSN_CONFIG_ALT_SOURCE:
2714 if (boardtype.reg_type & ni_reg_m_series_mask) {
2715 if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
2716 MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
2717 MSeries_AI_Bypass_Mode_Mux_Mask |
2718 MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
2719 return -EINVAL;
2720 }
2721 devpriv->ai_calib_source = data[1];
2722 } else if (boardtype.reg_type == ni_reg_6143) {
2723 unsigned int calib_source;
2724
2725 calib_source = data[1] & 0xf;
2726
2727 if (calib_source > 0xF)
2728 return -EINVAL;
2729
2730 devpriv->ai_calib_source = calib_source;
2731 ni_writew(calib_source, Calibration_Channel_6143);
2732 } else {
2733 unsigned int calib_source;
2734 unsigned int calib_source_adjust;
2735
2736 calib_source = data[1] & 0xf;
2737 calib_source_adjust = (data[1] >> 4) & 0xff;
2738
2739 if (calib_source >= 8)
2740 return -EINVAL;
2741 devpriv->ai_calib_source = calib_source;
2742 if (boardtype.reg_type == ni_reg_611x) {
2743 ni_writeb(calib_source_adjust,
0a85b6f0 2744 Cal_Gain_Select_611x);
03aef4b6
DS
2745 }
2746 }
2747 return 2;
2748 default:
2749 break;
2750 }
2751
2752 return -EINVAL;
2753}
2754
0a85b6f0
MT
2755static int ni_ai_config_analog_trig(struct comedi_device *dev,
2756 struct comedi_subdevice *s,
2757 struct comedi_insn *insn,
2758 unsigned int *data)
03aef4b6
DS
2759{
2760 unsigned int a, b, modebits;
2761 int err = 0;
2762
2763 /* data[1] is flags
2764 * data[2] is analog line
2765 * data[3] is set level
2766 * data[4] is reset level */
2767 if (!boardtype.has_analog_trig)
2768 return -EINVAL;
2769 if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
2770 data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
2771 err++;
2772 }
2773 if (data[2] >= boardtype.n_adchan) {
2774 data[2] = boardtype.n_adchan - 1;
2775 err++;
2776 }
2777 if (data[3] > 255) { /* a */
2778 data[3] = 255;
2779 err++;
2780 }
2781 if (data[4] > 255) { /* b */
2782 data[4] = 255;
2783 err++;
2784 }
2785 /*
2786 * 00 ignore
2787 * 01 set
2788 * 10 reset
2789 *
2790 * modes:
2791 * 1 level: +b- +a-
2792 * high mode 00 00 01 10
2793 * low mode 00 00 10 01
2794 * 2 level: (a<b)
2795 * hysteresis low mode 10 00 00 01
2796 * hysteresis high mode 01 00 00 10
2797 * middle mode 10 01 01 10
2798 */
2799
2800 a = data[3];
2801 b = data[4];
2802 modebits = data[1] & 0xff;
2803 if (modebits & 0xf0) {
2804 /* two level mode */
2805 if (b < a) {
2806 /* swap order */
2807 a = data[4];
2808 b = data[3];
2809 modebits =
0a85b6f0 2810 ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >> 4);
03aef4b6
DS
2811 }
2812 devpriv->atrig_low = a;
2813 devpriv->atrig_high = b;
2814 switch (modebits) {
2815 case 0x81: /* low hysteresis mode */
2816 devpriv->atrig_mode = 6;
2817 break;
2818 case 0x42: /* high hysteresis mode */
2819 devpriv->atrig_mode = 3;
2820 break;
2821 case 0x96: /* middle window mode */
2822 devpriv->atrig_mode = 2;
2823 break;
2824 default:
2825 data[1] &= ~0xff;
2826 err++;
2827 }
2828 } else {
2829 /* one level mode */
2830 if (b != 0) {
2831 data[4] = 0;
2832 err++;
2833 }
2834 switch (modebits) {
2835 case 0x06: /* high window mode */
2836 devpriv->atrig_high = a;
2837 devpriv->atrig_mode = 0;
2838 break;
2839 case 0x09: /* low window mode */
2840 devpriv->atrig_low = a;
2841 devpriv->atrig_mode = 1;
2842 break;
2843 default:
2844 data[1] &= ~0xff;
2845 err++;
2846 }
2847 }
2848 if (err)
2849 return -EAGAIN;
2850 return 5;
2851}
2852
2853/* munge data from unsigned to 2's complement for analog output bipolar modes */
da91b269 2854static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
2855 void *data, unsigned int num_bytes,
2856 unsigned int chan_index)
03aef4b6 2857{
d163679c 2858 struct comedi_async *async = s->async;
03aef4b6
DS
2859 unsigned int range;
2860 unsigned int i;
2861 unsigned int offset;
790c5541
BP
2862 unsigned int length = num_bytes / sizeof(short);
2863 short *array = data;
03aef4b6
DS
2864
2865 offset = 1 << (boardtype.aobits - 1);
2866 for (i = 0; i < length; i++) {
2867 range = CR_RANGE(async->cmd.chanlist[chan_index]);
2868 if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
2869 array[i] -= offset;
2870#ifdef PCIDMA
2871 array[i] = cpu_to_le16(array[i]);
2872#endif
2873 chan_index++;
2874 chan_index %= async->cmd.chanlist_len;
2875 }
2876}
2877
da91b269 2878static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
0a85b6f0
MT
2879 struct comedi_subdevice *s,
2880 unsigned int chanspec[],
2881 unsigned int n_chans, int timed)
03aef4b6
DS
2882{
2883 unsigned int range;
2884 unsigned int chan;
2885 unsigned int conf;
2886 int i;
2887 int invert = 0;
2888
53106ae6 2889 if (timed) {
03aef4b6
DS
2890 for (i = 0; i < boardtype.n_aochan; ++i) {
2891 devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
0a85b6f0
MT
2892 ni_writeb(devpriv->ao_conf[i],
2893 M_Offset_AO_Config_Bank(i));
03aef4b6
DS
2894 ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
2895 }
2896 }
2897 for (i = 0; i < n_chans; i++) {
1f6325d6 2898 const struct comedi_krange *krange;
03aef4b6
DS
2899 chan = CR_CHAN(chanspec[i]);
2900 range = CR_RANGE(chanspec[i]);
2901 krange = s->range_table->range + range;
2902 invert = 0;
2903 conf = 0;
2904 switch (krange->max - krange->min) {
2905 case 20000000:
2906 conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
2907 ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
2908 break;
2909 case 10000000:
2910 conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
2911 ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
2912 break;
2913 case 4000000:
2914 conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
2915 ni_writeb(MSeries_Attenuate_x5_Bit,
0a85b6f0 2916 M_Offset_AO_Reference_Attenuation(chan));
03aef4b6
DS
2917 break;
2918 case 2000000:
2919 conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
2920 ni_writeb(MSeries_Attenuate_x5_Bit,
0a85b6f0 2921 M_Offset_AO_Reference_Attenuation(chan));
03aef4b6
DS
2922 break;
2923 default:
5f74ea14 2924 printk("%s: bug! unhandled ao reference voltage\n",
0a85b6f0 2925 __func__);
03aef4b6
DS
2926 break;
2927 }
2928 switch (krange->max + krange->min) {
2929 case 0:
2930 conf |= MSeries_AO_DAC_Offset_0V_Bits;
2931 break;
2932 case 10000000:
2933 conf |= MSeries_AO_DAC_Offset_5V_Bits;
2934 break;
2935 default:
5f74ea14 2936 printk("%s: bug! unhandled ao offset voltage\n",
0a85b6f0 2937 __func__);
03aef4b6
DS
2938 break;
2939 }
2940 if (timed)
2941 conf |= MSeries_AO_Update_Timed_Bit;
2942 ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
2943 devpriv->ao_conf[chan] = conf;
2944 ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
2945 }
2946 return invert;
2947}
2948
0a85b6f0
MT
2949static int ni_old_ao_config_chanlist(struct comedi_device *dev,
2950 struct comedi_subdevice *s,
2951 unsigned int chanspec[],
2952 unsigned int n_chans)
03aef4b6
DS
2953{
2954 unsigned int range;
2955 unsigned int chan;
2956 unsigned int conf;
2957 int i;
2958 int invert = 0;
2959
2960 for (i = 0; i < n_chans; i++) {
2961 chan = CR_CHAN(chanspec[i]);
2962 range = CR_RANGE(chanspec[i]);
2963 conf = AO_Channel(chan);
2964
2965 if (boardtype.ao_unipolar) {
2966 if ((range & 1) == 0) {
2967 conf |= AO_Bipolar;
2968 invert = (1 << (boardtype.aobits - 1));
2969 } else {
2970 invert = 0;
2971 }
2972 if (range & 2)
2973 conf |= AO_Ext_Ref;
2974 } else {
2975 conf |= AO_Bipolar;
2976 invert = (1 << (boardtype.aobits - 1));
2977 }
2978
2979 /* not all boards can deglitch, but this shouldn't hurt */
2980 if (chanspec[i] & CR_DEGLITCH)
2981 conf |= AO_Deglitch;
2982
2983 /* analog reference */
2984 /* AREF_OTHER connects AO ground to AI ground, i think */
2985 conf |= (CR_AREF(chanspec[i]) ==
0a85b6f0 2986 AREF_OTHER) ? AO_Ground_Ref : 0;
03aef4b6
DS
2987
2988 ni_writew(conf, AO_Configuration);
2989 devpriv->ao_conf[chan] = conf;
2990 }
2991 return invert;
2992}
2993
0a85b6f0
MT
2994static int ni_ao_config_chanlist(struct comedi_device *dev,
2995 struct comedi_subdevice *s,
2996 unsigned int chanspec[], unsigned int n_chans,
2997 int timed)
03aef4b6
DS
2998{
2999 if (boardtype.reg_type & ni_reg_m_series_mask)
3000 return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
0a85b6f0 3001 timed);
03aef4b6
DS
3002 else
3003 return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
3004}
0a85b6f0
MT
3005
3006static int ni_ao_insn_read(struct comedi_device *dev,
3007 struct comedi_subdevice *s, struct comedi_insn *insn,
3008 unsigned int *data)
03aef4b6
DS
3009{
3010 data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
3011
3012 return 1;
3013}
3014
0a85b6f0
MT
3015static int ni_ao_insn_write(struct comedi_device *dev,
3016 struct comedi_subdevice *s,
3017 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3018{
3019 unsigned int chan = CR_CHAN(insn->chanspec);
3020 unsigned int invert;
3021
3022 invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
3023
3024 devpriv->ao[chan] = data[0];
3025
3026 if (boardtype.reg_type & ni_reg_m_series_mask) {
3027 ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
3028 } else
3029 ni_writew(data[0] ^ invert,
0a85b6f0 3030 (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
03aef4b6
DS
3031
3032 return 1;
3033}
3034
0a85b6f0
MT
3035static int ni_ao_insn_write_671x(struct comedi_device *dev,
3036 struct comedi_subdevice *s,
3037 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3038{
3039 unsigned int chan = CR_CHAN(insn->chanspec);
3040 unsigned int invert;
3041
3042 ao_win_out(1 << chan, AO_Immediate_671x);
3043 invert = 1 << (boardtype.aobits - 1);
3044
3045 ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
3046
3047 devpriv->ao[chan] = data[0];
3048 ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
3049
3050 return 1;
3051}
3052
0a85b6f0
MT
3053static int ni_ao_insn_config(struct comedi_device *dev,
3054 struct comedi_subdevice *s,
3055 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3056{
3057 switch (data[0]) {
3058 case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
0a85b6f0 3059 switch (data[1]) {
03aef4b6 3060 case COMEDI_OUTPUT:
790c5541 3061 data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
0a85b6f0
MT
3062 if (devpriv->mite)
3063 data[2] += devpriv->mite->fifo_size;
03aef4b6
DS
3064 break;
3065 case COMEDI_INPUT:
3066 data[2] = 0;
3067 break;
3068 default:
3069 return -EINVAL;
3070 break;
3071 }
3072 return 0;
3073 default:
3074 break;
3075 }
3076
3077 return -EINVAL;
3078}
3079
da91b269 3080static int ni_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3081 unsigned int trignum)
03aef4b6
DS
3082{
3083 int ret;
3084 int interrupt_b_bits;
3085 int i;
3086 static const int timeout = 1000;
3087
3088 if (trignum != 0)
3089 return -EINVAL;
3090
3091 /* Null trig at beginning prevent ao start trigger from executing more than
3092 once per command (and doing things like trying to allocate the ao dma channel
3093 multiple times) */
3094 s->async->inttrig = NULL;
3095
3096 ni_set_bits(dev, Interrupt_B_Enable_Register,
0a85b6f0 3097 AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
03aef4b6
DS
3098 interrupt_b_bits = AO_Error_Interrupt_Enable;
3099#ifdef PCIDMA
3100 devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
3101 if (boardtype.reg_type & ni_reg_6xxx_mask)
3102 ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
3103 ret = ni_ao_setup_MITE_dma(dev);
3104 if (ret)
3105 return ret;
3106 ret = ni_ao_wait_for_dma_load(dev);
3107 if (ret < 0)
3108 return ret;
3109#else
3110 ret = ni_ao_prep_fifo(dev, s);
3111 if (ret == 0)
3112 return -EPIPE;
3113
3114 interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
3115#endif
3116
3117 devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
0a85b6f0 3118 AO_Mode_3_Register);
03aef4b6
DS
3119 devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
3120 /* wait for DACs to be loaded */
3121 for (i = 0; i < timeout; i++) {
5f74ea14 3122 udelay(1);
03aef4b6
DS
3123 if ((devpriv->stc_readw(dev,
3124 Joint_Status_2_Register) &
0a85b6f0 3125 AO_TMRDACWRs_In_Progress_St) == 0)
03aef4b6
DS
3126 break;
3127 }
3128 if (i == timeout) {
3129 comedi_error(dev,
0a85b6f0 3130 "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
03aef4b6
DS
3131 return -EIO;
3132 }
2696fb57 3133 /* stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears */
03aef4b6 3134 devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
0a85b6f0 3135 Interrupt_B_Ack_Register);
03aef4b6
DS
3136
3137 ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
3138
3139 devpriv->stc_writew(dev,
0a85b6f0
MT
3140 devpriv->ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm
3141 | AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
3142 AO_Command_1_Register);
03aef4b6
DS
3143
3144 devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
0a85b6f0 3145 AO_Command_2_Register);
03aef4b6
DS
3146
3147 return 0;
3148}
3149
da91b269 3150static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6 3151{
ea6d0d4c 3152 const struct comedi_cmd *cmd = &s->async->cmd;
03aef4b6
DS
3153 int bits;
3154 int i;
3155 unsigned trigvar;
3156
3157 if (dev->irq == 0) {
3158 comedi_error(dev, "cannot run command without an irq");
3159 return -EIO;
3160 }
3161
3162 devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
3163
3164 devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
3165
3166 if (boardtype.reg_type & ni_reg_6xxx_mask) {
3167 ao_win_out(CLEAR_WG, AO_Misc_611x);
3168
3169 bits = 0;
3170 for (i = 0; i < cmd->chanlist_len; i++) {
3171 int chan;
3172
3173 chan = CR_CHAN(cmd->chanlist[i]);
3174 bits |= 1 << chan;
3175 ao_win_out(chan, AO_Waveform_Generation_611x);
3176 }
3177 ao_win_out(bits, AO_Timed_611x);
3178 }
3179
3180 ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
3181
3182 if (cmd->stop_src == TRIG_NONE) {
3183 devpriv->ao_mode1 |= AO_Continuous;
3184 devpriv->ao_mode1 &= ~AO_Trigger_Once;
3185 } else {
3186 devpriv->ao_mode1 &= ~AO_Continuous;
3187 devpriv->ao_mode1 |= AO_Trigger_Once;
3188 }
3189 devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
3190 switch (cmd->start_src) {
3191 case TRIG_INT:
3192 case TRIG_NOW:
3193 devpriv->ao_trigger_select &=
0a85b6f0 3194 ~(AO_START1_Polarity | AO_START1_Select(-1));
03aef4b6
DS
3195 devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
3196 devpriv->stc_writew(dev, devpriv->ao_trigger_select,
0a85b6f0 3197 AO_Trigger_Select_Register);
03aef4b6
DS
3198 break;
3199 case TRIG_EXT:
0a85b6f0
MT
3200 devpriv->ao_trigger_select =
3201 AO_START1_Select(CR_CHAN(cmd->start_arg) + 1);
03aef4b6 3202 if (cmd->start_arg & CR_INVERT)
0a85b6f0 3203 devpriv->ao_trigger_select |= AO_START1_Polarity; /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
03aef4b6 3204 if (cmd->start_arg & CR_EDGE)
0a85b6f0
MT
3205 devpriv->ao_trigger_select |= AO_START1_Edge; /* 0=edge detection disabled, 1=enabled */
3206 devpriv->stc_writew(dev, devpriv->ao_trigger_select,
3207 AO_Trigger_Select_Register);
03aef4b6
DS
3208 break;
3209 default:
3210 BUG();
3211 break;
3212 }
3213 devpriv->ao_mode3 &= ~AO_Trigger_Length;
3214 devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
3215
3216 devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
3217 devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
3218 devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
3219 if (cmd->stop_src == TRIG_NONE) {
3220 devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
3221 } else {
3222 devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
3223 }
3224 devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
3225 devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
3226 devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
3227 switch (cmd->stop_src) {
3228 case TRIG_COUNT:
0a85b6f0 3229 if (boardtype.reg_type & ni_reg_m_series_mask) {
2696fb57 3230 /* this is how the NI example code does it for m-series boards, verified correct with 6259 */
03aef4b6 3231 devpriv->stc_writel(dev, cmd->stop_arg - 1,
0a85b6f0
MT
3232 AO_UC_Load_A_Register);
3233 devpriv->stc_writew(dev, AO_UC_Load,
3234 AO_Command_1_Register);
3235 } else {
3236 devpriv->stc_writel(dev, cmd->stop_arg,
3237 AO_UC_Load_A_Register);
3238 devpriv->stc_writew(dev, AO_UC_Load,
3239 AO_Command_1_Register);
3240 devpriv->stc_writel(dev, cmd->stop_arg - 1,
3241 AO_UC_Load_A_Register);
03aef4b6
DS
3242 }
3243 break;
3244 case TRIG_NONE:
3245 devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
3246 devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
3247 devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
3248 break;
3249 default:
3250 devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
3251 devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
3252 devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
3253 }
3254
3255 devpriv->ao_mode1 &=
0a85b6f0
MT
3256 ~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity |
3257 AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity);
03aef4b6
DS
3258 switch (cmd->scan_begin_src) {
3259 case TRIG_TIMER:
3260 devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable;
3261 trigvar =
0a85b6f0
MT
3262 ni_ns_to_timer(dev, cmd->scan_begin_arg,
3263 TRIG_ROUND_NEAREST);
03aef4b6
DS
3264 devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
3265 devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
3266 devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
3267 break;
3268 case TRIG_EXT:
3269 devpriv->ao_mode1 |=
0a85b6f0 3270 AO_UPDATE_Source_Select(cmd->scan_begin_arg);
03aef4b6
DS
3271 if (cmd->scan_begin_arg & CR_INVERT)
3272 devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity;
3273 devpriv->ao_cmd2 |= AO_BC_Gate_Enable;
3274 break;
3275 default:
3276 BUG();
3277 break;
3278 }
3279 devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
3280 devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
3281 devpriv->ao_mode2 &=
0a85b6f0 3282 ~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
03aef4b6
DS
3283 devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
3284
3285 if (cmd->scan_end_arg > 1) {
3286 devpriv->ao_mode1 |= AO_Multiple_Channels;
3287 devpriv->stc_writew(dev,
0a85b6f0
MT
3288 AO_Number_Of_Channels(cmd->scan_end_arg -
3289 1) |
3290 AO_UPDATE_Output_Select
3291 (AO_Update_Output_High_Z),
3292 AO_Output_Control_Register);
03aef4b6
DS
3293 } else {
3294 unsigned bits;
3295 devpriv->ao_mode1 &= ~AO_Multiple_Channels;
3296 bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
0a85b6f0
MT
3297 if (boardtype.
3298 reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
03aef4b6
DS
3299 bits |= AO_Number_Of_Channels(0);
3300 } else {
0a85b6f0
MT
3301 bits |=
3302 AO_Number_Of_Channels(CR_CHAN(cmd->chanlist[0]));
03aef4b6 3303 }
0a85b6f0 3304 devpriv->stc_writew(dev, bits, AO_Output_Control_Register);
03aef4b6
DS
3305 }
3306 devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
3307
3308 devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
0a85b6f0 3309 AO_Command_1_Register);
03aef4b6
DS
3310
3311 devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
3312 devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
3313
3314 devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
3315#ifdef PCIDMA
3316 devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
3317#else
3318 devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
3319#endif
3320 devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
3321 devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
3322
3323 bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
0a85b6f0 3324 AO_TMRDACWR_Pulse_Width;
03aef4b6
DS
3325 if (boardtype.ao_fifo_depth)
3326 bits |= AO_FIFO_Enable;
3327 else
3328 bits |= AO_DMA_PIO_Control;
3329#if 0
3330 /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
3331 verified with bus analyzer. */
3332 if (boardtype.reg_type & ni_reg_m_series_mask)
3333 bits |= AO_Number_Of_DAC_Packages;
3334#endif
3335 devpriv->stc_writew(dev, bits, AO_Personal_Register);
2696fb57 3336 /* enable sending of ao dma requests */
03aef4b6
DS
3337 devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
3338
3339 devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
3340
3341 if (cmd->stop_src == TRIG_COUNT) {
3342 devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
0a85b6f0 3343 Interrupt_B_Ack_Register);
03aef4b6 3344 ni_set_bits(dev, Interrupt_B_Enable_Register,
0a85b6f0 3345 AO_BC_TC_Interrupt_Enable, 1);
03aef4b6
DS
3346 }
3347
3348 s->async->inttrig = &ni_ao_inttrig;
3349
3350 return 0;
3351}
3352
da91b269 3353static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3354 struct comedi_cmd *cmd)
03aef4b6
DS
3355{
3356 int err = 0;
3357 int tmp;
3358
3359 /* step 1: make sure trigger sources are trivially valid */
3360
3361 if ((cmd->flags & CMDF_WRITE) == 0) {
3362 cmd->flags |= CMDF_WRITE;
3363 }
3364
3365 tmp = cmd->start_src;
3366 cmd->start_src &= TRIG_INT | TRIG_EXT;
3367 if (!cmd->start_src || tmp != cmd->start_src)
3368 err++;
3369
3370 tmp = cmd->scan_begin_src;
3371 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
3372 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
3373 err++;
3374
3375 tmp = cmd->convert_src;
3376 cmd->convert_src &= TRIG_NOW;
3377 if (!cmd->convert_src || tmp != cmd->convert_src)
3378 err++;
3379
3380 tmp = cmd->scan_end_src;
3381 cmd->scan_end_src &= TRIG_COUNT;
3382 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
3383 err++;
3384
3385 tmp = cmd->stop_src;
3386 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
3387 if (!cmd->stop_src || tmp != cmd->stop_src)
3388 err++;
3389
3390 if (err)
3391 return 1;
3392
3393 /* step 2: make sure trigger sources are unique and mutually compatible */
3394
3395 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
3396 err++;
3397
3398 if (err)
3399 return 2;
3400
3401 /* step 3: make sure arguments are trivially compatible */
3402
3403 if (cmd->start_src == TRIG_EXT) {
3404 /* external trigger */
3405 unsigned int tmp = CR_CHAN(cmd->start_arg);
3406
3407 if (tmp > 18)
3408 tmp = 18;
3409 tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
3410 if (cmd->start_arg != tmp) {
3411 cmd->start_arg = tmp;
3412 err++;
3413 }
3414 } else {
3415 if (cmd->start_arg != 0) {
3416 /* true for both TRIG_NOW and TRIG_INT */
3417 cmd->start_arg = 0;
3418 err++;
3419 }
3420 }
3421 if (cmd->scan_begin_src == TRIG_TIMER) {
3422 if (cmd->scan_begin_arg < boardtype.ao_speed) {
3423 cmd->scan_begin_arg = boardtype.ao_speed;
3424 err++;
3425 }
3426 if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */
3427 cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
3428 err++;
3429 }
3430 }
3431 if (cmd->convert_arg != 0) {
3432 cmd->convert_arg = 0;
3433 err++;
3434 }
3435 if (cmd->scan_end_arg != cmd->chanlist_len) {
3436 cmd->scan_end_arg = cmd->chanlist_len;
3437 err++;
3438 }
3439 if (cmd->stop_src == TRIG_COUNT) { /* XXX check */
3440 if (cmd->stop_arg > 0x00ffffff) {
3441 cmd->stop_arg = 0x00ffffff;
3442 err++;
3443 }
3444 } else {
3445 /* TRIG_NONE */
3446 if (cmd->stop_arg != 0) {
3447 cmd->stop_arg = 0;
3448 err++;
3449 }
3450 }
3451
3452 if (err)
3453 return 3;
3454
3455 /* step 4: fix up any arguments */
3456 if (cmd->scan_begin_src == TRIG_TIMER) {
3457 tmp = cmd->scan_begin_arg;
3458 cmd->scan_begin_arg =
0a85b6f0
MT
3459 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
3460 cmd->scan_begin_arg,
3461 cmd->
3462 flags &
3463 TRIG_ROUND_MASK));
03aef4b6
DS
3464 if (tmp != cmd->scan_begin_arg)
3465 err++;
3466 }
3467 if (err)
3468 return 4;
3469
3470 /* step 5: fix up chanlist */
3471
3472 if (err)
3473 return 5;
3474
3475 return 0;
3476}
3477
da91b269 3478static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6 3479{
2696fb57
BP
3480 /* devpriv->ao0p=0x0000; */
3481 /* ni_writew(devpriv->ao0p,AO_Configuration); */
03aef4b6 3482
2696fb57
BP
3483 /* devpriv->ao1p=AO_Channel(1); */
3484 /* ni_writew(devpriv->ao1p,AO_Configuration); */
03aef4b6
DS
3485
3486 ni_release_ao_mite_channel(dev);
3487
3488 devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
3489 devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
3490 ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
3491 devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
3492 devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
3493 devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
0a85b6f0 3494 AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
03aef4b6
DS
3495 devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
3496 devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
3497 devpriv->ao_cmd1 = 0;
3498 devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
3499 devpriv->ao_cmd2 = 0;
3500 devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
3501 devpriv->ao_mode1 = 0;
3502 devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
3503 devpriv->ao_mode2 = 0;
3504 devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
3505 if (boardtype.reg_type & ni_reg_m_series_mask)
3506 devpriv->ao_mode3 = AO_Last_Gate_Disable;
3507 else
3508 devpriv->ao_mode3 = 0;
3509 devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
3510 devpriv->ao_trigger_select = 0;
3511 devpriv->stc_writew(dev, devpriv->ao_trigger_select,
0a85b6f0 3512 AO_Trigger_Select_Register);
03aef4b6
DS
3513 if (boardtype.reg_type & ni_reg_6xxx_mask) {
3514 unsigned immediate_bits = 0;
3515 unsigned i;
0a85b6f0 3516 for (i = 0; i < s->n_chan; ++i) {
03aef4b6
DS
3517 immediate_bits |= 1 << i;
3518 }
3519 ao_win_out(immediate_bits, AO_Immediate_671x);
3520 ao_win_out(CLEAR_WG, AO_Misc_611x);
3521 }
3522 devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
3523
3524 return 0;
3525}
3526
2696fb57 3527/* digital io */
03aef4b6 3528
0a85b6f0
MT
3529static int ni_dio_insn_config(struct comedi_device *dev,
3530 struct comedi_subdevice *s,
3531 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3532{
3533#ifdef DEBUG_DIO
5f74ea14 3534 printk("ni_dio_insn_config() chan=%d io=%d\n",
0a85b6f0 3535 CR_CHAN(insn->chanspec), data[0]);
03aef4b6
DS
3536#endif
3537 switch (data[0]) {
3538 case INSN_CONFIG_DIO_OUTPUT:
3539 s->io_bits |= 1 << CR_CHAN(insn->chanspec);
3540 break;
3541 case INSN_CONFIG_DIO_INPUT:
3542 s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
3543 break;
3544 case INSN_CONFIG_DIO_QUERY:
3545 data[1] =
0a85b6f0
MT
3546 (s->
3547 io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
3548 COMEDI_INPUT;
03aef4b6
DS
3549 return insn->n;
3550 break;
3551 default:
3552 return -EINVAL;
3553 }
3554
3555 devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
3556 devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
3557 devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
3558
3559 return 1;
3560}
3561
0a85b6f0
MT
3562static int ni_dio_insn_bits(struct comedi_device *dev,
3563 struct comedi_subdevice *s,
3564 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3565{
3566#ifdef DEBUG_DIO
5f74ea14 3567 printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
03aef4b6
DS
3568#endif
3569 if (insn->n != 2)
3570 return -EINVAL;
3571 if (data[0]) {
3572 /* Perform check to make sure we're not using the
3573 serial part of the dio */
3574 if ((data[0] & (DIO_SDIN | DIO_SDOUT))
0a85b6f0 3575 && devpriv->serial_interval_ns)
03aef4b6
DS
3576 return -EBUSY;
3577
3578 s->state &= ~data[0];
3579 s->state |= (data[0] & data[1]);
3580 devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
3581 devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
3582 devpriv->stc_writew(dev, devpriv->dio_output,
0a85b6f0 3583 DIO_Output_Register);
03aef4b6
DS
3584 }
3585 data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
3586
3587 return 2;
3588}
3589
da91b269 3590static int ni_m_series_dio_insn_config(struct comedi_device *dev,
0a85b6f0
MT
3591 struct comedi_subdevice *s,
3592 struct comedi_insn *insn,
3593 unsigned int *data)
03aef4b6
DS
3594{
3595#ifdef DEBUG_DIO
5f74ea14 3596 printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
0a85b6f0 3597 CR_CHAN(insn->chanspec), data[0]);
03aef4b6
DS
3598#endif
3599 switch (data[0]) {
3600 case INSN_CONFIG_DIO_OUTPUT:
3601 s->io_bits |= 1 << CR_CHAN(insn->chanspec);
3602 break;
3603 case INSN_CONFIG_DIO_INPUT:
3604 s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
3605 break;
3606 case INSN_CONFIG_DIO_QUERY:
3607 data[1] =
0a85b6f0
MT
3608 (s->
3609 io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
3610 COMEDI_INPUT;
03aef4b6
DS
3611 return insn->n;
3612 break;
3613 default:
3614 return -EINVAL;
3615 }
3616
3617 ni_writel(s->io_bits, M_Offset_DIO_Direction);
3618
3619 return 1;
3620}
3621
0a85b6f0
MT
3622static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
3623 struct comedi_subdevice *s,
3624 struct comedi_insn *insn,
3625 unsigned int *data)
03aef4b6
DS
3626{
3627#ifdef DEBUG_DIO
5f74ea14 3628 printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
0a85b6f0 3629 data[1]);
03aef4b6
DS
3630#endif
3631 if (insn->n != 2)
3632 return -EINVAL;
3633 if (data[0]) {
3634 s->state &= ~data[0];
3635 s->state |= (data[0] & data[1]);
3636 ni_writel(s->state, M_Offset_Static_Digital_Output);
3637 }
3638 data[1] = ni_readl(M_Offset_Static_Digital_Input);
3639
3640 return 2;
3641}
3642
0a85b6f0
MT
3643static int ni_cdio_cmdtest(struct comedi_device *dev,
3644 struct comedi_subdevice *s, struct comedi_cmd *cmd)
03aef4b6
DS
3645{
3646 int err = 0;
3647 int tmp;
3648 int sources;
3649 unsigned i;
3650
3651 /* step 1: make sure trigger sources are trivially valid */
3652
3653 tmp = cmd->start_src;
3654 sources = TRIG_INT;
3655 cmd->start_src &= sources;
3656 if (!cmd->start_src || tmp != cmd->start_src)
3657 err++;
3658
3659 tmp = cmd->scan_begin_src;
3660 cmd->scan_begin_src &= TRIG_EXT;
3661 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
3662 err++;
3663
3664 tmp = cmd->convert_src;
3665 cmd->convert_src &= TRIG_NOW;
3666 if (!cmd->convert_src || tmp != cmd->convert_src)
3667 err++;
3668
3669 tmp = cmd->scan_end_src;
3670 cmd->scan_end_src &= TRIG_COUNT;
3671 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
3672 err++;
3673
3674 tmp = cmd->stop_src;
3675 cmd->stop_src &= TRIG_NONE;
3676 if (!cmd->stop_src || tmp != cmd->stop_src)
3677 err++;
3678
3679 if (err)
3680 return 1;
3681
3682 /* step 2: make sure trigger sources are unique... */
3683
3684 if (cmd->start_src != TRIG_INT)
3685 err++;
3686 if (cmd->scan_begin_src != TRIG_EXT)
3687 err++;
3688 if (cmd->convert_src != TRIG_NOW)
3689 err++;
3690 if (cmd->stop_src != TRIG_NONE)
3691 err++;
3692 /* ... and mutually compatible */
3693
3694 if (err)
3695 return 2;
3696
3697 /* step 3: make sure arguments are trivially compatible */
3698 if (cmd->start_src == TRIG_INT) {
3699 if (cmd->start_arg != 0) {
3700 cmd->start_arg = 0;
3701 err++;
3702 }
3703 }
3704 if (cmd->scan_begin_src == TRIG_EXT) {
3705 tmp = cmd->scan_begin_arg;
3706 tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0,
0a85b6f0 3707 CR_INVERT);
03aef4b6
DS
3708 if (tmp != cmd->scan_begin_arg) {
3709 err++;
3710 }
3711 }
3712 if (cmd->convert_src == TRIG_NOW) {
3713 if (cmd->convert_arg) {
3714 cmd->convert_arg = 0;
3715 err++;
3716 }
3717 }
3718
3719 if (cmd->scan_end_arg != cmd->chanlist_len) {
3720 cmd->scan_end_arg = cmd->chanlist_len;
3721 err++;
3722 }
3723
3724 if (cmd->stop_src == TRIG_NONE) {
3725 if (cmd->stop_arg != 0) {
3726 cmd->stop_arg = 0;
3727 err++;
3728 }
3729 }
3730
3731 if (err)
3732 return 3;
3733
3734 /* step 4: fix up any arguments */
3735
3736 if (err)
3737 return 4;
3738
3739 /* step 5: check chanlist */
3740
3741 for (i = 0; i < cmd->chanlist_len; ++i) {
3742 if (cmd->chanlist[i] != i)
3743 err = 1;
3744 }
3745
3746 if (err)
3747 return 5;
3748
3749 return 0;
3750}
3751
da91b269 3752static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6 3753{
ea6d0d4c 3754 const struct comedi_cmd *cmd = &s->async->cmd;
03aef4b6
DS
3755 unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
3756 int retval;
3757
3758 ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
3759 switch (cmd->scan_begin_src) {
3760 case TRIG_EXT:
3761 cdo_mode_bits |=
0a85b6f0
MT
3762 CR_CHAN(cmd->scan_begin_arg) &
3763 CDO_Sample_Source_Select_Mask;
03aef4b6
DS
3764 break;
3765 default:
3766 BUG();
3767 break;
3768 }
3769 if (cmd->scan_begin_arg & CR_INVERT)
3770 cdo_mode_bits |= CDO_Polarity_Bit;
3771 ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
3772 if (s->io_bits) {
3773 ni_writel(s->state, M_Offset_CDO_FIFO_Data);
3774 ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
3775 ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
3776 } else {
3777 comedi_error(dev,
0a85b6f0 3778 "attempted to run digital output command with no lines configured as outputs");
03aef4b6
DS
3779 return -EIO;
3780 }
3781 retval = ni_request_cdo_mite_channel(dev);
3782 if (retval < 0) {
3783 return retval;
3784 }
3785 s->async->inttrig = &ni_cdo_inttrig;
3786 return 0;
3787}
3788
da91b269 3789static int ni_cdo_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 3790 unsigned int trignum)
03aef4b6
DS
3791{
3792#ifdef PCIDMA
3793 unsigned long flags;
3794#endif
3795 int retval = 0;
3796 unsigned i;
3797 const unsigned timeout = 100;
3798
3799 s->async->inttrig = NULL;
3800
3801 /* read alloc the entire buffer */
3802 comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
3803
3804#ifdef PCIDMA
5f74ea14 3805 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
3806 if (devpriv->cdo_mite_chan) {
3807 mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
3808 mite_dma_arm(devpriv->cdo_mite_chan);
3809 } else {
3810 comedi_error(dev, "BUG: no cdo mite channel?");
3811 retval = -EIO;
3812 }
5f74ea14 3813 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
3814 if (retval < 0)
3815 return retval;
3816#endif
2696fb57
BP
3817/*
3818* XXX not sure what interrupt C group does
3819* ni_writeb(Interrupt_Group_C_Enable_Bit,
3820* M_Offset_Interrupt_C_Enable); wait for dma to fill output fifo
3821*/
03aef4b6
DS
3822 for (i = 0; i < timeout; ++i) {
3823 if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
3824 break;
5f74ea14 3825 udelay(10);
03aef4b6
DS
3826 }
3827 if (i == timeout) {
3828 comedi_error(dev, "dma failed to fill cdo fifo!");
3829 ni_cdio_cancel(dev, s);
3830 return -EIO;
3831 }
3832 ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
0a85b6f0
MT
3833 CDO_Empty_FIFO_Interrupt_Enable_Set_Bit,
3834 M_Offset_CDIO_Command);
03aef4b6
DS
3835 return retval;
3836}
3837
da91b269 3838static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
3839{
3840 ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
0a85b6f0
MT
3841 CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
3842 CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
3843 M_Offset_CDIO_Command);
2696fb57
BP
3844/*
3845* XXX not sure what interrupt C group does ni_writeb(0,
3846* M_Offset_Interrupt_C_Enable);
3847*/
03aef4b6
DS
3848 ni_writel(0, M_Offset_CDO_Mask_Enable);
3849 ni_release_cdo_mite_channel(dev);
3850 return 0;
3851}
3852
da91b269 3853static void handle_cdio_interrupt(struct comedi_device *dev)
03aef4b6
DS
3854{
3855 unsigned cdio_status;
34c43922 3856 struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV;
03aef4b6
DS
3857#ifdef PCIDMA
3858 unsigned long flags;
3859#endif
3860
3861 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
3862 return;
3863 }
3864#ifdef PCIDMA
5f74ea14 3865 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
3866 if (devpriv->cdo_mite_chan) {
3867 unsigned cdo_mite_status =
0a85b6f0 3868 mite_get_status(devpriv->cdo_mite_chan);
03aef4b6
DS
3869 if (cdo_mite_status & CHSR_LINKC) {
3870 writel(CHOR_CLRLC,
0a85b6f0
MT
3871 devpriv->mite->mite_io_addr +
3872 MITE_CHOR(devpriv->cdo_mite_chan->channel));
03aef4b6
DS
3873 }
3874 mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
3875 }
5f74ea14 3876 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
03aef4b6
DS
3877#endif
3878
3879 cdio_status = ni_readl(M_Offset_CDIO_Status);
3880 if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
5f74ea14 3881/* printk("cdio error: statux=0x%x\n", cdio_status); */
2696fb57 3882 ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); /* XXX just guessing this is needed and does something useful */
03aef4b6
DS
3883 s->async->events |= COMEDI_CB_OVERFLOW;
3884 }
3885 if (cdio_status & CDO_FIFO_Empty_Bit) {
5f74ea14 3886/* printk("cdio fifo empty\n"); */
03aef4b6 3887 ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
0a85b6f0 3888 M_Offset_CDIO_Command);
2696fb57 3889/* s->async->events |= COMEDI_CB_EOA; */
03aef4b6
DS
3890 }
3891 ni_event(dev, s);
3892}
3893
0a85b6f0
MT
3894static int ni_serial_insn_config(struct comedi_device *dev,
3895 struct comedi_subdevice *s,
3896 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
3897{
3898 int err = insn->n;
3899 unsigned char byte_out, byte_in = 0;
3900
3901 if (insn->n != 2)
3902 return -EINVAL;
3903
3904 switch (data[0]) {
3905 case INSN_CONFIG_SERIAL_CLOCK:
3906
3907#ifdef DEBUG_DIO
5f74ea14 3908 printk("SPI serial clock Config cd\n", data[1]);
03aef4b6
DS
3909#endif
3910 devpriv->serial_hw_mode = 1;
3911 devpriv->dio_control |= DIO_HW_Serial_Enable;
3912
3913 if (data[1] == SERIAL_DISABLED) {
3914 devpriv->serial_hw_mode = 0;
3915 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
0a85b6f0 3916 DIO_Software_Serial_Control);
03aef4b6
DS
3917 data[1] = SERIAL_DISABLED;
3918 devpriv->serial_interval_ns = data[1];
3919 } else if (data[1] <= SERIAL_600NS) {
3920 /* Warning: this clock speed is too fast to reliably
3921 control SCXI. */
3922 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
3923 devpriv->clock_and_fout |= Slow_Internal_Timebase;
3924 devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
3925 data[1] = SERIAL_600NS;
3926 devpriv->serial_interval_ns = data[1];
3927 } else if (data[1] <= SERIAL_1_2US) {
3928 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
3929 devpriv->clock_and_fout |= Slow_Internal_Timebase |
0a85b6f0 3930 DIO_Serial_Out_Divide_By_2;
03aef4b6
DS
3931 data[1] = SERIAL_1_2US;
3932 devpriv->serial_interval_ns = data[1];
3933 } else if (data[1] <= SERIAL_10US) {
3934 devpriv->dio_control |= DIO_HW_Serial_Timebase;
3935 devpriv->clock_and_fout |= Slow_Internal_Timebase |
0a85b6f0 3936 DIO_Serial_Out_Divide_By_2;
03aef4b6
DS
3937 /* Note: DIO_Serial_Out_Divide_By_2 only affects
3938 600ns/1.2us. If you turn divide_by_2 off with the
3939 slow clock, you will still get 10us, except then
3940 all your delays are wrong. */
3941 data[1] = SERIAL_10US;
3942 devpriv->serial_interval_ns = data[1];
3943 } else {
3944 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
0a85b6f0 3945 DIO_Software_Serial_Control);
03aef4b6
DS
3946 devpriv->serial_hw_mode = 0;
3947 data[1] = (data[1] / 1000) * 1000;
3948 devpriv->serial_interval_ns = data[1];
3949 }
3950
3951 devpriv->stc_writew(dev, devpriv->dio_control,
0a85b6f0 3952 DIO_Control_Register);
03aef4b6 3953 devpriv->stc_writew(dev, devpriv->clock_and_fout,
0a85b6f0 3954 Clock_and_FOUT_Register);
03aef4b6
DS
3955 return 1;
3956
3957 break;
3958
3959 case INSN_CONFIG_BIDIRECTIONAL_DATA:
3960
3961 if (devpriv->serial_interval_ns == 0) {
3962 return -EINVAL;
3963 }
3964
3965 byte_out = data[1] & 0xFF;
3966
3967 if (devpriv->serial_hw_mode) {
3968 err = ni_serial_hw_readwrite8(dev, s, byte_out,
0a85b6f0 3969 &byte_in);
03aef4b6
DS
3970 } else if (devpriv->serial_interval_ns > 0) {
3971 err = ni_serial_sw_readwrite8(dev, s, byte_out,
0a85b6f0 3972 &byte_in);
03aef4b6 3973 } else {
5f74ea14 3974 printk("ni_serial_insn_config: serial disabled!\n");
03aef4b6
DS
3975 return -EINVAL;
3976 }
3977 if (err < 0)
3978 return err;
3979 data[1] = byte_in & 0xFF;
3980 return insn->n;
3981
3982 break;
3983 default:
3984 return -EINVAL;
3985 }
3986
3987}
3988
0a85b6f0
MT
3989static int ni_serial_hw_readwrite8(struct comedi_device *dev,
3990 struct comedi_subdevice *s,
3991 unsigned char data_out,
3992 unsigned char *data_in)
03aef4b6
DS
3993{
3994 unsigned int status1;
3995 int err = 0, count = 20;
3996
3997#ifdef DEBUG_DIO
5f74ea14 3998 printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
03aef4b6
DS
3999#endif
4000
4001 devpriv->dio_output &= ~DIO_Serial_Data_Mask;
4002 devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
4003 devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
4004
4005 status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
4006 if (status1 & DIO_Serial_IO_In_Progress_St) {
4007 err = -EBUSY;
4008 goto Error;
4009 }
4010
4011 devpriv->dio_control |= DIO_HW_Serial_Start;
4012 devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
4013 devpriv->dio_control &= ~DIO_HW_Serial_Start;
4014
4015 /* Wait until STC says we're done, but don't loop infinitely. */
4016 while ((status1 =
0a85b6f0
MT
4017 devpriv->stc_readw(dev,
4018 Joint_Status_1_Register)) &
4019 DIO_Serial_IO_In_Progress_St) {
03aef4b6 4020 /* Delay one bit per loop */
5f74ea14 4021 udelay((devpriv->serial_interval_ns + 999) / 1000);
03aef4b6 4022 if (--count < 0) {
5f74ea14 4023 printk
0a85b6f0 4024 ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
03aef4b6
DS
4025 err = -ETIME;
4026 goto Error;
4027 }
4028 }
4029
4030 /* Delay for last bit. This delay is absolutely necessary, because
4031 DIO_Serial_IO_In_Progress_St goes high one bit too early. */
5f74ea14 4032 udelay((devpriv->serial_interval_ns + 999) / 1000);
03aef4b6
DS
4033
4034 if (data_in != NULL) {
4035 *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
4036#ifdef DEBUG_DIO
5f74ea14 4037 printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
03aef4b6
DS
4038#endif
4039 }
4040
0a85b6f0 4041Error:
03aef4b6
DS
4042 devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
4043
4044 return err;
4045}
4046
0a85b6f0
MT
4047static int ni_serial_sw_readwrite8(struct comedi_device *dev,
4048 struct comedi_subdevice *s,
4049 unsigned char data_out,
4050 unsigned char *data_in)
03aef4b6
DS
4051{
4052 unsigned char mask, input = 0;
4053
4054#ifdef DEBUG_DIO
5f74ea14 4055 printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
03aef4b6
DS
4056#endif
4057
4058 /* Wait for one bit before transfer */
5f74ea14 4059 udelay((devpriv->serial_interval_ns + 999) / 1000);
03aef4b6
DS
4060
4061 for (mask = 0x80; mask; mask >>= 1) {
4062 /* Output current bit; note that we cannot touch s->state
4063 because it is a per-subdevice field, and serial is
4064 a separate subdevice from DIO. */
4065 devpriv->dio_output &= ~DIO_SDOUT;
4066 if (data_out & mask) {
4067 devpriv->dio_output |= DIO_SDOUT;
4068 }
4069 devpriv->stc_writew(dev, devpriv->dio_output,
0a85b6f0 4070 DIO_Output_Register);
03aef4b6
DS
4071
4072 /* Assert SDCLK (active low, inverted), wait for half of
4073 the delay, deassert SDCLK, and wait for the other half. */
4074 devpriv->dio_control |= DIO_Software_Serial_Control;
4075 devpriv->stc_writew(dev, devpriv->dio_control,
0a85b6f0 4076 DIO_Control_Register);
03aef4b6 4077
5f74ea14 4078 udelay((devpriv->serial_interval_ns + 999) / 2000);
03aef4b6
DS
4079
4080 devpriv->dio_control &= ~DIO_Software_Serial_Control;
4081 devpriv->stc_writew(dev, devpriv->dio_control,
0a85b6f0 4082 DIO_Control_Register);
03aef4b6 4083
5f74ea14 4084 udelay((devpriv->serial_interval_ns + 999) / 2000);
03aef4b6
DS
4085
4086 /* Input current bit */
4087 if (devpriv->stc_readw(dev,
0a85b6f0
MT
4088 DIO_Parallel_Input_Register) & DIO_SDIN)
4089 {
5f74ea14 4090/* printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
03aef4b6
DS
4091 input |= mask;
4092 }
4093 }
4094#ifdef DEBUG_DIO
5f74ea14 4095 printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
03aef4b6
DS
4096#endif
4097 if (data_in)
4098 *data_in = input;
4099
4100 return 0;
4101}
4102
da91b269 4103static void mio_common_detach(struct comedi_device *dev)
03aef4b6
DS
4104{
4105 if (dev->private) {
4106 if (devpriv->counter_dev) {
4107 ni_gpct_device_destroy(devpriv->counter_dev);
4108 }
4109 }
4110 if (dev->subdevices && boardtype.has_8255)
4111 subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV);
4112}
4113
da91b269 4114static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
4115{
4116 int i;
4117
0a85b6f0 4118 for (i = 0; i < s->n_chan; i++) {
03aef4b6 4119 ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
0a85b6f0 4120 AO_Configuration_2_67xx);
03aef4b6
DS
4121 }
4122 ao_win_out(0x0, AO_Later_Single_Point_Updates);
4123}
4124
4125static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
4126{
4127 unsigned stc_register;
4128 switch (reg) {
4129 case NITIO_G0_Autoincrement_Reg:
4130 stc_register = G_Autoincrement_Register(0);
4131 break;
4132 case NITIO_G1_Autoincrement_Reg:
4133 stc_register = G_Autoincrement_Register(1);
4134 break;
4135 case NITIO_G0_Command_Reg:
4136 stc_register = G_Command_Register(0);
4137 break;
4138 case NITIO_G1_Command_Reg:
4139 stc_register = G_Command_Register(1);
4140 break;
4141 case NITIO_G0_HW_Save_Reg:
4142 stc_register = G_HW_Save_Register(0);
4143 break;
4144 case NITIO_G1_HW_Save_Reg:
4145 stc_register = G_HW_Save_Register(1);
4146 break;
4147 case NITIO_G0_SW_Save_Reg:
4148 stc_register = G_Save_Register(0);
4149 break;
4150 case NITIO_G1_SW_Save_Reg:
4151 stc_register = G_Save_Register(1);
4152 break;
4153 case NITIO_G0_Mode_Reg:
4154 stc_register = G_Mode_Register(0);
4155 break;
4156 case NITIO_G1_Mode_Reg:
4157 stc_register = G_Mode_Register(1);
4158 break;
4159 case NITIO_G0_LoadA_Reg:
4160 stc_register = G_Load_A_Register(0);
4161 break;
4162 case NITIO_G1_LoadA_Reg:
4163 stc_register = G_Load_A_Register(1);
4164 break;
4165 case NITIO_G0_LoadB_Reg:
4166 stc_register = G_Load_B_Register(0);
4167 break;
4168 case NITIO_G1_LoadB_Reg:
4169 stc_register = G_Load_B_Register(1);
4170 break;
4171 case NITIO_G0_Input_Select_Reg:
4172 stc_register = G_Input_Select_Register(0);
4173 break;
4174 case NITIO_G1_Input_Select_Reg:
4175 stc_register = G_Input_Select_Register(1);
4176 break;
4177 case NITIO_G01_Status_Reg:
4178 stc_register = G_Status_Register;
4179 break;
4180 case NITIO_G01_Joint_Reset_Reg:
4181 stc_register = Joint_Reset_Register;
4182 break;
4183 case NITIO_G01_Joint_Status1_Reg:
4184 stc_register = Joint_Status_1_Register;
4185 break;
4186 case NITIO_G01_Joint_Status2_Reg:
4187 stc_register = Joint_Status_2_Register;
4188 break;
4189 case NITIO_G0_Interrupt_Acknowledge_Reg:
4190 stc_register = Interrupt_A_Ack_Register;
4191 break;
4192 case NITIO_G1_Interrupt_Acknowledge_Reg:
4193 stc_register = Interrupt_B_Ack_Register;
4194 break;
4195 case NITIO_G0_Status_Reg:
4196 stc_register = AI_Status_1_Register;
4197 break;
4198 case NITIO_G1_Status_Reg:
4199 stc_register = AO_Status_1_Register;
4200 break;
4201 case NITIO_G0_Interrupt_Enable_Reg:
4202 stc_register = Interrupt_A_Enable_Register;
4203 break;
4204 case NITIO_G1_Interrupt_Enable_Reg:
4205 stc_register = Interrupt_B_Enable_Register;
4206 break;
4207 default:
5f74ea14 4208 printk("%s: unhandled register 0x%x in switch.\n",
0a85b6f0 4209 __func__, reg);
03aef4b6
DS
4210 BUG();
4211 return 0;
4212 break;
4213 }
4214 return stc_register;
4215}
4216
4217static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
0a85b6f0 4218 enum ni_gpct_register reg)
03aef4b6 4219{
71b5f4f1 4220 struct comedi_device *dev = counter->counter_dev->dev;
03aef4b6
DS
4221 unsigned stc_register;
4222 /* bits in the join reset register which are relevant to counters */
4223 static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
4224 static const unsigned gpct_interrupt_a_enable_mask =
0a85b6f0 4225 G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
03aef4b6 4226 static const unsigned gpct_interrupt_b_enable_mask =
0a85b6f0 4227 G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
03aef4b6
DS
4228
4229 switch (reg) {
4230 /* m-series-only registers */
4231 case NITIO_G0_Counting_Mode_Reg:
4232 ni_writew(bits, M_Offset_G0_Counting_Mode);
4233 break;
4234 case NITIO_G1_Counting_Mode_Reg:
4235 ni_writew(bits, M_Offset_G1_Counting_Mode);
4236 break;
4237 case NITIO_G0_Second_Gate_Reg:
4238 ni_writew(bits, M_Offset_G0_Second_Gate);
4239 break;
4240 case NITIO_G1_Second_Gate_Reg:
4241 ni_writew(bits, M_Offset_G1_Second_Gate);
4242 break;
4243 case NITIO_G0_DMA_Config_Reg:
4244 ni_writew(bits, M_Offset_G0_DMA_Config);
4245 break;
4246 case NITIO_G1_DMA_Config_Reg:
4247 ni_writew(bits, M_Offset_G1_DMA_Config);
4248 break;
4249 case NITIO_G0_ABZ_Reg:
4250 ni_writew(bits, M_Offset_G0_MSeries_ABZ);
4251 break;
4252 case NITIO_G1_ABZ_Reg:
4253 ni_writew(bits, M_Offset_G1_MSeries_ABZ);
4254 break;
4255
4256 /* 32 bit registers */
4257 case NITIO_G0_LoadA_Reg:
4258 case NITIO_G1_LoadA_Reg:
4259 case NITIO_G0_LoadB_Reg:
4260 case NITIO_G1_LoadB_Reg:
4261 stc_register = ni_gpct_to_stc_register(reg);
4262 devpriv->stc_writel(dev, bits, stc_register);
4263 break;
4264
4265 /* 16 bit registers */
4266 case NITIO_G0_Interrupt_Enable_Reg:
4267 BUG_ON(bits & ~gpct_interrupt_a_enable_mask);
4268 ni_set_bitfield(dev, Interrupt_A_Enable_Register,
0a85b6f0 4269 gpct_interrupt_a_enable_mask, bits);
03aef4b6
DS
4270 break;
4271 case NITIO_G1_Interrupt_Enable_Reg:
4272 BUG_ON(bits & ~gpct_interrupt_b_enable_mask);
4273 ni_set_bitfield(dev, Interrupt_B_Enable_Register,
0a85b6f0 4274 gpct_interrupt_b_enable_mask, bits);
03aef4b6
DS
4275 break;
4276 case NITIO_G01_Joint_Reset_Reg:
4277 BUG_ON(bits & ~gpct_joint_reset_mask);
4278 /* fall-through */
4279 default:
4280 stc_register = ni_gpct_to_stc_register(reg);
4281 devpriv->stc_writew(dev, bits, stc_register);
4282 }
4283}
4284
4285static unsigned ni_gpct_read_register(struct ni_gpct *counter,
0a85b6f0 4286 enum ni_gpct_register reg)
03aef4b6 4287{
71b5f4f1 4288 struct comedi_device *dev = counter->counter_dev->dev;
03aef4b6
DS
4289 unsigned stc_register;
4290 switch (reg) {
4291 /* m-series only registers */
4292 case NITIO_G0_DMA_Status_Reg:
4293 return ni_readw(M_Offset_G0_DMA_Status);
4294 break;
4295 case NITIO_G1_DMA_Status_Reg:
4296 return ni_readw(M_Offset_G1_DMA_Status);
4297 break;
4298
4299 /* 32 bit registers */
4300 case NITIO_G0_HW_Save_Reg:
4301 case NITIO_G1_HW_Save_Reg:
4302 case NITIO_G0_SW_Save_Reg:
4303 case NITIO_G1_SW_Save_Reg:
4304 stc_register = ni_gpct_to_stc_register(reg);
4305 return devpriv->stc_readl(dev, stc_register);
4306 break;
4307
4308 /* 16 bit registers */
4309 default:
4310 stc_register = ni_gpct_to_stc_register(reg);
4311 return devpriv->stc_readw(dev, stc_register);
4312 break;
4313 }
4314 return 0;
4315}
4316
da91b269 4317static int ni_freq_out_insn_read(struct comedi_device *dev,
0a85b6f0
MT
4318 struct comedi_subdevice *s,
4319 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4320{
4321 data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
4322 return 1;
4323}
4324
da91b269 4325static int ni_freq_out_insn_write(struct comedi_device *dev,
0a85b6f0
MT
4326 struct comedi_subdevice *s,
4327 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4328{
4329 devpriv->clock_and_fout &= ~FOUT_Enable;
4330 devpriv->stc_writew(dev, devpriv->clock_and_fout,
0a85b6f0 4331 Clock_and_FOUT_Register);
03aef4b6
DS
4332 devpriv->clock_and_fout &= ~FOUT_Divider_mask;
4333 devpriv->clock_and_fout |= FOUT_Divider(data[0]);
4334 devpriv->clock_and_fout |= FOUT_Enable;
4335 devpriv->stc_writew(dev, devpriv->clock_and_fout,
0a85b6f0 4336 Clock_and_FOUT_Register);
03aef4b6
DS
4337 return insn->n;
4338}
4339
0a85b6f0
MT
4340static int ni_set_freq_out_clock(struct comedi_device *dev,
4341 unsigned int clock_source)
03aef4b6
DS
4342{
4343 switch (clock_source) {
4344 case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
4345 devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
4346 break;
4347 case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
4348 devpriv->clock_and_fout |= FOUT_Timebase_Select;
4349 break;
4350 default:
4351 return -EINVAL;
4352 }
4353 devpriv->stc_writew(dev, devpriv->clock_and_fout,
0a85b6f0 4354 Clock_and_FOUT_Register);
03aef4b6
DS
4355 return 3;
4356}
4357
0a85b6f0
MT
4358static void ni_get_freq_out_clock(struct comedi_device *dev,
4359 unsigned int *clock_source,
4360 unsigned int *clock_period_ns)
03aef4b6
DS
4361{
4362 if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
4363 *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
4364 *clock_period_ns = TIMEBASE_2_NS;
4365 } else {
4366 *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
4367 *clock_period_ns = TIMEBASE_1_NS * 2;
4368 }
4369}
4370
0a85b6f0
MT
4371static int ni_freq_out_insn_config(struct comedi_device *dev,
4372 struct comedi_subdevice *s,
4373 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4374{
4375 switch (data[0]) {
4376 case INSN_CONFIG_SET_CLOCK_SRC:
4377 return ni_set_freq_out_clock(dev, data[1]);
4378 break;
4379 case INSN_CONFIG_GET_CLOCK_SRC:
4380 ni_get_freq_out_clock(dev, &data[1], &data[2]);
4381 return 3;
4382 default:
4383 break;
4384 }
4385 return -EINVAL;
4386}
4387
da91b269 4388static int ni_alloc_private(struct comedi_device *dev)
03aef4b6
DS
4389{
4390 int ret;
4391
3301cc76 4392 ret = alloc_private(dev, sizeof(struct ni_private));
03aef4b6
DS
4393 if (ret < 0)
4394 return ret;
4395
4396 spin_lock_init(&devpriv->window_lock);
4397 spin_lock_init(&devpriv->soft_reg_copy_lock);
4398 spin_lock_init(&devpriv->mite_channel_lock);
4399
4400 return 0;
4401};
4402
da91b269 4403static int ni_E_init(struct comedi_device *dev, struct comedi_devconfig *it)
03aef4b6 4404{
34c43922 4405 struct comedi_subdevice *s;
03aef4b6
DS
4406 unsigned j;
4407 enum ni_gpct_variant counter_variant;
4408
4409 if (boardtype.n_aochan > MAX_N_AO_CHAN) {
4410 printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
4411 return -EINVAL;
4412 }
4413
4414 if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0)
4415 return -ENOMEM;
4416
4417 /* analog input subdevice */
4418
4419 s = dev->subdevices + NI_AI_SUBDEV;
4420 dev->read_subdev = s;
4421 if (boardtype.n_adchan) {
4422 s->type = COMEDI_SUBD_AI;
4423 s->subdev_flags =
0a85b6f0 4424 SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
03aef4b6
DS
4425 if (boardtype.reg_type != ni_reg_611x)
4426 s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
4427 if (boardtype.adbits > 16)
4428 s->subdev_flags |= SDF_LSAMPL;
4429 if (boardtype.reg_type & ni_reg_m_series_mask)
4430 s->subdev_flags |= SDF_SOFT_CALIBRATED;
4431 s->n_chan = boardtype.n_adchan;
4432 s->len_chanlist = 512;
4433 s->maxdata = (1 << boardtype.adbits) - 1;
4434 s->range_table = ni_range_lkup[boardtype.gainlkup];
4435 s->insn_read = &ni_ai_insn_read;
4436 s->insn_config = &ni_ai_insn_config;
4437 s->do_cmdtest = &ni_ai_cmdtest;
4438 s->do_cmd = &ni_ai_cmd;
4439 s->cancel = &ni_ai_reset;
4440 s->poll = &ni_ai_poll;
4441 s->munge = &ni_ai_munge;
4442#ifdef PCIDMA
4443 s->async_dma_dir = DMA_FROM_DEVICE;
4444#endif
4445 } else {
4446 s->type = COMEDI_SUBD_UNUSED;
4447 }
4448
4449 /* analog output subdevice */
4450
4451 s = dev->subdevices + NI_AO_SUBDEV;
4452 if (boardtype.n_aochan) {
4453 s->type = COMEDI_SUBD_AO;
4454 s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
4455 if (boardtype.reg_type & ni_reg_m_series_mask)
4456 s->subdev_flags |= SDF_SOFT_CALIBRATED;
4457 s->n_chan = boardtype.n_aochan;
4458 s->maxdata = (1 << boardtype.aobits) - 1;
4459 s->range_table = boardtype.ao_range_table;
4460 s->insn_read = &ni_ao_insn_read;
4461 if (boardtype.reg_type & ni_reg_6xxx_mask) {
4462 s->insn_write = &ni_ao_insn_write_671x;
4463 } else {
4464 s->insn_write = &ni_ao_insn_write;
4465 }
4466 s->insn_config = &ni_ao_insn_config;
4467#ifdef PCIDMA
4468 if (boardtype.n_aochan) {
4469 s->async_dma_dir = DMA_TO_DEVICE;
4470#else
4471 if (boardtype.ao_fifo_depth) {
4472#endif
4473 dev->write_subdev = s;
4474 s->subdev_flags |= SDF_CMD_WRITE;
4475 s->do_cmd = &ni_ao_cmd;
4476 s->do_cmdtest = &ni_ao_cmdtest;
4477 s->len_chanlist = boardtype.n_aochan;
4478 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
4479 s->munge = ni_ao_munge;
4480 }
4481 s->cancel = &ni_ao_reset;
4482 } else {
4483 s->type = COMEDI_SUBD_UNUSED;
4484 }
4485 if ((boardtype.reg_type & ni_reg_67xx_mask))
4486 init_ao_67xx(dev, s);
4487
4488 /* digital i/o subdevice */
4489
4490 s = dev->subdevices + NI_DIO_SUBDEV;
4491 s->type = COMEDI_SUBD_DIO;
4492 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
4493 s->maxdata = 1;
4494 s->io_bits = 0; /* all bits input */
4495 s->range_table = &range_digital;
4496 s->n_chan = boardtype.num_p0_dio_channels;
4497 if (boardtype.reg_type & ni_reg_m_series_mask) {
4498 s->subdev_flags |=
0a85b6f0 4499 SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
03aef4b6
DS
4500 s->insn_bits = &ni_m_series_dio_insn_bits;
4501 s->insn_config = &ni_m_series_dio_insn_config;
4502 s->do_cmd = &ni_cdio_cmd;
4503 s->do_cmdtest = &ni_cdio_cmdtest;
4504 s->cancel = &ni_cdio_cancel;
4505 s->async_dma_dir = DMA_BIDIRECTIONAL;
4506 s->len_chanlist = s->n_chan;
4507
4508 ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
4509 ni_writel(s->io_bits, M_Offset_DIO_Direction);
4510 } else {
4511 s->insn_bits = &ni_dio_insn_bits;
4512 s->insn_config = &ni_dio_insn_config;
4513 devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
4514 ni_writew(devpriv->dio_control, DIO_Control_Register);
4515 }
4516
4517 /* 8255 device */
4518 s = dev->subdevices + NI_8255_DIO_SUBDEV;
4519 if (boardtype.has_8255) {
4520 subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
4521 } else {
4522 s->type = COMEDI_SUBD_UNUSED;
4523 }
4524
4525 /* formerly general purpose counter/timer device, but no longer used */
4526 s = dev->subdevices + NI_UNUSED_SUBDEV;
4527 s->type = COMEDI_SUBD_UNUSED;
4528
4529 /* calibration subdevice -- ai and ao */
4530 s = dev->subdevices + NI_CALIBRATION_SUBDEV;
4531 s->type = COMEDI_SUBD_CALIB;
4532 if (boardtype.reg_type & ni_reg_m_series_mask) {
2696fb57 4533 /* internal PWM analog output used for AI nonlinearity calibration */
03aef4b6
DS
4534 s->subdev_flags = SDF_INTERNAL;
4535 s->insn_config = &ni_m_series_pwm_config;
4536 s->n_chan = 1;
4537 s->maxdata = 0;
4538 ni_writel(0x0, M_Offset_Cal_PWM);
4539 } else if (boardtype.reg_type == ni_reg_6143) {
2696fb57 4540 /* internal PWM analog output used for AI nonlinearity calibration */
03aef4b6
DS
4541 s->subdev_flags = SDF_INTERNAL;
4542 s->insn_config = &ni_6143_pwm_config;
4543 s->n_chan = 1;
4544 s->maxdata = 0;
4545 } else {
4546 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
4547 s->insn_read = &ni_calib_insn_read;
4548 s->insn_write = &ni_calib_insn_write;
4549 caldac_setup(dev, s);
4550 }
4551
4552 /* EEPROM */
4553 s = dev->subdevices + NI_EEPROM_SUBDEV;
4554 s->type = COMEDI_SUBD_MEMORY;
4555 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
4556 s->maxdata = 0xff;
4557 if (boardtype.reg_type & ni_reg_m_series_mask) {
4558 s->n_chan = M_SERIES_EEPROM_SIZE;
4559 s->insn_read = &ni_m_series_eeprom_insn_read;
4560 } else {
4561 s->n_chan = 512;
4562 s->insn_read = &ni_eeprom_insn_read;
4563 }
4564
4565 /* PFI */
4566 s = dev->subdevices + NI_PFI_DIO_SUBDEV;
4567 s->type = COMEDI_SUBD_DIO;
4568 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4569 if (boardtype.reg_type & ni_reg_m_series_mask) {
4570 unsigned i;
4571 s->n_chan = 16;
4572 ni_writew(s->state, M_Offset_PFI_DO);
4573 for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
4574 ni_writew(devpriv->pfi_output_select_reg[i],
0a85b6f0 4575 M_Offset_PFI_Output_Select(i + 1));
03aef4b6
DS
4576 }
4577 } else {
4578 s->n_chan = 10;
4579 }
4580 s->maxdata = 1;
4581 if (boardtype.reg_type & ni_reg_m_series_mask) {
4582 s->insn_bits = &ni_pfi_insn_bits;
4583 }
4584 s->insn_config = &ni_pfi_insn_config;
4585 ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
4586
4587 /* cs5529 calibration adc */
4588 s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV;
4589 if (boardtype.reg_type & ni_reg_67xx_mask) {
4590 s->type = COMEDI_SUBD_AI;
4591 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
2696fb57 4592 /* one channel for each analog output channel */
03aef4b6
DS
4593 s->n_chan = boardtype.n_aochan;
4594 s->maxdata = (1 << 16) - 1;
4595 s->range_table = &range_unknown; /* XXX */
4596 s->insn_read = cs5529_ai_insn_read;
4597 s->insn_config = NULL;
4598 init_cs5529(dev);
4599 } else {
4600 s->type = COMEDI_SUBD_UNUSED;
4601 }
4602
4603 /* Serial */
4604 s = dev->subdevices + NI_SERIAL_SUBDEV;
4605 s->type = COMEDI_SUBD_SERIAL;
4606 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4607 s->n_chan = 1;
4608 s->maxdata = 0xff;
4609 s->insn_config = ni_serial_insn_config;
4610 devpriv->serial_interval_ns = 0;
4611 devpriv->serial_hw_mode = 0;
4612
4613 /* RTSI */
4614 s = dev->subdevices + NI_RTSI_SUBDEV;
4615 s->type = COMEDI_SUBD_DIO;
4616 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4617 s->n_chan = 8;
4618 s->maxdata = 1;
4619 s->insn_bits = ni_rtsi_insn_bits;
4620 s->insn_config = ni_rtsi_insn_config;
4621 ni_rtsi_init(dev);
4622
4623 if (boardtype.reg_type & ni_reg_m_series_mask) {
4624 counter_variant = ni_gpct_variant_m_series;
4625 } else {
4626 counter_variant = ni_gpct_variant_e_series;
4627 }
4628 devpriv->counter_dev = ni_gpct_device_construct(dev,
0a85b6f0
MT
4629 &ni_gpct_write_register,
4630 &ni_gpct_read_register,
4631 counter_variant,
4632 NUM_GPCT);
03aef4b6
DS
4633 /* General purpose counters */
4634 for (j = 0; j < NUM_GPCT; ++j) {
4635 s = dev->subdevices + NI_GPCT_SUBDEV(j);
4636 s->type = COMEDI_SUBD_COUNTER;
4637 s->subdev_flags =
0a85b6f0
MT
4638 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
4639 /* | SDF_CMD_WRITE */ ;
03aef4b6
DS
4640 s->n_chan = 3;
4641 if (boardtype.reg_type & ni_reg_m_series_mask)
4642 s->maxdata = 0xffffffff;
4643 else
4644 s->maxdata = 0xffffff;
4645 s->insn_read = &ni_gpct_insn_read;
4646 s->insn_write = &ni_gpct_insn_write;
4647 s->insn_config = &ni_gpct_insn_config;
4648 s->do_cmd = &ni_gpct_cmd;
4649 s->len_chanlist = 1;
4650 s->do_cmdtest = &ni_gpct_cmdtest;
4651 s->cancel = &ni_gpct_cancel;
4652 s->async_dma_dir = DMA_BIDIRECTIONAL;
4653 s->private = &devpriv->counter_dev->counters[j];
4654
4655 devpriv->counter_dev->counters[j].chip_index = 0;
4656 devpriv->counter_dev->counters[j].counter_index = j;
4657 ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
4658 }
4659
4660 /* Frequency output */
4661 s = dev->subdevices + NI_FREQ_OUT_SUBDEV;
4662 s->type = COMEDI_SUBD_COUNTER;
4663 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
4664 s->n_chan = 1;
4665 s->maxdata = 0xf;
4666 s->insn_read = &ni_freq_out_insn_read;
4667 s->insn_write = &ni_freq_out_insn_write;
4668 s->insn_config = &ni_freq_out_insn_config;
4669
4670 /* ai configuration */
4671 ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV);
4672 if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
2696fb57 4673 /* BEAM is this needed for PCI-6143 ?? */
03aef4b6 4674 devpriv->clock_and_fout =
0a85b6f0
MT
4675 Slow_Internal_Time_Divide_By_2 |
4676 Slow_Internal_Timebase |
4677 Clock_To_Board_Divide_By_2 |
4678 Clock_To_Board |
4679 AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
03aef4b6
DS
4680 } else {
4681 devpriv->clock_and_fout =
0a85b6f0
MT
4682 Slow_Internal_Time_Divide_By_2 |
4683 Slow_Internal_Timebase |
4684 Clock_To_Board_Divide_By_2 | Clock_To_Board;
03aef4b6
DS
4685 }
4686 devpriv->stc_writew(dev, devpriv->clock_and_fout,
0a85b6f0 4687 Clock_and_FOUT_Register);
03aef4b6
DS
4688
4689 /* analog output configuration */
4690 ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV);
4691
4692 if (dev->irq) {
4693 devpriv->stc_writew(dev,
0a85b6f0
MT
4694 (IRQ_POLARITY ? Interrupt_Output_Polarity :
4695 0) | (Interrupt_Output_On_3_Pins & 0) |
4696 Interrupt_A_Enable | Interrupt_B_Enable |
4697 Interrupt_A_Output_Select(interrupt_pin
4698 (dev->irq)) |
4699 Interrupt_B_Output_Select(interrupt_pin
4700 (dev->irq)),
4701 Interrupt_Control_Register);
03aef4b6
DS
4702 }
4703
4704 /* DMA setup */
4705 ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
4706 ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
4707
4708 if (boardtype.reg_type & ni_reg_6xxx_mask) {
4709 ni_writeb(0, Magic_611x);
4710 } else if (boardtype.reg_type & ni_reg_m_series_mask) {
4711 int channel;
4712 for (channel = 0; channel < boardtype.n_aochan; ++channel) {
4713 ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
4714 ni_writeb(0x0,
0a85b6f0 4715 M_Offset_AO_Reference_Attenuation(channel));
03aef4b6
DS
4716 }
4717 ni_writeb(0x0, M_Offset_AO_Calibration);
4718 }
4719
4720 printk("\n");
4721 return 0;
4722}
4723
4724static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
4725{
0a85b6f0 4726 struct comedi_device *dev = (struct comedi_device *)arg;
03aef4b6
DS
4727
4728 if (dir) {
4729 ni_writeb(data, Port_A + 2 * port);
4730 return 0;
4731 } else {
4732 return ni_readb(Port_A + 2 * port);
4733 }
4734}
4735
4736/*
4737 presents the EEPROM as a subdevice
4738*/
4739
0a85b6f0
MT
4740static int ni_eeprom_insn_read(struct comedi_device *dev,
4741 struct comedi_subdevice *s,
4742 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4743{
4744 data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
4745
4746 return 1;
4747}
4748
4749/*
4750 reads bytes out of eeprom
4751*/
4752
da91b269 4753static int ni_read_eeprom(struct comedi_device *dev, int addr)
03aef4b6
DS
4754{
4755 int bit;
4756 int bitstring;
4757
4758 bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
4759 ni_writeb(0x04, Serial_Command);
4760 for (bit = 0x8000; bit; bit >>= 1) {
4761 ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
0a85b6f0 4762 Serial_Command);
03aef4b6 4763 ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
0a85b6f0 4764 Serial_Command);
03aef4b6
DS
4765 }
4766 bitstring = 0;
4767 for (bit = 0x80; bit; bit >>= 1) {
4768 ni_writeb(0x04, Serial_Command);
4769 ni_writeb(0x05, Serial_Command);
4770 bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
4771 }
4772 ni_writeb(0x00, Serial_Command);
4773
4774 return bitstring;
4775}
4776
da91b269 4777static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
0a85b6f0
MT
4778 struct comedi_subdevice *s,
4779 struct comedi_insn *insn,
4780 unsigned int *data)
03aef4b6
DS
4781{
4782 data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
4783
4784 return 1;
4785}
4786
da91b269 4787static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
03aef4b6
DS
4788{
4789 data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
4790 data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
4791 return 3;
4792}
4793
0a85b6f0
MT
4794static int ni_m_series_pwm_config(struct comedi_device *dev,
4795 struct comedi_subdevice *s,
4796 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4797{
4798 unsigned up_count, down_count;
4799 switch (data[0]) {
4800 case INSN_CONFIG_PWM_OUTPUT:
4801 switch (data[1]) {
4802 case TRIG_ROUND_NEAREST:
4803 up_count =
0a85b6f0
MT
4804 (data[2] +
4805 devpriv->clock_ns / 2) / devpriv->clock_ns;
03aef4b6
DS
4806 break;
4807 case TRIG_ROUND_DOWN:
4808 up_count = data[2] / devpriv->clock_ns;
4809 break;
4810 case TRIG_ROUND_UP:
4811 up_count =
0a85b6f0
MT
4812 (data[2] + devpriv->clock_ns -
4813 1) / devpriv->clock_ns;
03aef4b6
DS
4814 break;
4815 default:
4816 return -EINVAL;
4817 break;
4818 }
4819 switch (data[3]) {
4820 case TRIG_ROUND_NEAREST:
4821 down_count =
0a85b6f0
MT
4822 (data[4] +
4823 devpriv->clock_ns / 2) / devpriv->clock_ns;
03aef4b6
DS
4824 break;
4825 case TRIG_ROUND_DOWN:
4826 down_count = data[4] / devpriv->clock_ns;
4827 break;
4828 case TRIG_ROUND_UP:
4829 down_count =
0a85b6f0
MT
4830 (data[4] + devpriv->clock_ns -
4831 1) / devpriv->clock_ns;
03aef4b6
DS
4832 break;
4833 default:
4834 return -EINVAL;
4835 break;
4836 }
4837 if (up_count * devpriv->clock_ns != data[2] ||
0a85b6f0 4838 down_count * devpriv->clock_ns != data[4]) {
03aef4b6
DS
4839 data[2] = up_count * devpriv->clock_ns;
4840 data[4] = down_count * devpriv->clock_ns;
4841 return -EAGAIN;
4842 }
4843 ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
0a85b6f0
MT
4844 MSeries_Cal_PWM_Low_Time_Bits(down_count),
4845 M_Offset_Cal_PWM);
03aef4b6
DS
4846 devpriv->pwm_up_count = up_count;
4847 devpriv->pwm_down_count = down_count;
4848 return 5;
4849 break;
4850 case INSN_CONFIG_GET_PWM_OUTPUT:
4851 return ni_get_pwm_config(dev, data);
4852 break;
4853 default:
4854 return -EINVAL;
4855 break;
4856 }
4857 return 0;
4858}
4859
0a85b6f0
MT
4860static int ni_6143_pwm_config(struct comedi_device *dev,
4861 struct comedi_subdevice *s,
4862 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4863{
4864 unsigned up_count, down_count;
4865 switch (data[0]) {
4866 case INSN_CONFIG_PWM_OUTPUT:
4867 switch (data[1]) {
4868 case TRIG_ROUND_NEAREST:
4869 up_count =
0a85b6f0
MT
4870 (data[2] +
4871 devpriv->clock_ns / 2) / devpriv->clock_ns;
03aef4b6
DS
4872 break;
4873 case TRIG_ROUND_DOWN:
4874 up_count = data[2] / devpriv->clock_ns;
4875 break;
4876 case TRIG_ROUND_UP:
4877 up_count =
0a85b6f0
MT
4878 (data[2] + devpriv->clock_ns -
4879 1) / devpriv->clock_ns;
03aef4b6
DS
4880 break;
4881 default:
4882 return -EINVAL;
4883 break;
4884 }
4885 switch (data[3]) {
4886 case TRIG_ROUND_NEAREST:
4887 down_count =
0a85b6f0
MT
4888 (data[4] +
4889 devpriv->clock_ns / 2) / devpriv->clock_ns;
03aef4b6
DS
4890 break;
4891 case TRIG_ROUND_DOWN:
4892 down_count = data[4] / devpriv->clock_ns;
4893 break;
4894 case TRIG_ROUND_UP:
4895 down_count =
0a85b6f0
MT
4896 (data[4] + devpriv->clock_ns -
4897 1) / devpriv->clock_ns;
03aef4b6
DS
4898 break;
4899 default:
4900 return -EINVAL;
4901 break;
4902 }
4903 if (up_count * devpriv->clock_ns != data[2] ||
0a85b6f0 4904 down_count * devpriv->clock_ns != data[4]) {
03aef4b6
DS
4905 data[2] = up_count * devpriv->clock_ns;
4906 data[4] = down_count * devpriv->clock_ns;
4907 return -EAGAIN;
4908 }
4909 ni_writel(up_count, Calibration_HighTime_6143);
4910 devpriv->pwm_up_count = up_count;
4911 ni_writel(down_count, Calibration_LowTime_6143);
4912 devpriv->pwm_down_count = down_count;
4913 return 5;
4914 break;
4915 case INSN_CONFIG_GET_PWM_OUTPUT:
4916 return ni_get_pwm_config(dev, data);
4917 default:
4918 return -EINVAL;
4919 break;
4920 }
4921 return 0;
4922}
4923
da91b269 4924static void ni_write_caldac(struct comedi_device *dev, int addr, int val);
03aef4b6
DS
4925/*
4926 calibration subdevice
4927*/
0a85b6f0
MT
4928static int ni_calib_insn_write(struct comedi_device *dev,
4929 struct comedi_subdevice *s,
4930 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4931{
4932 ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
4933
4934 return 1;
4935}
4936
0a85b6f0
MT
4937static int ni_calib_insn_read(struct comedi_device *dev,
4938 struct comedi_subdevice *s,
4939 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
4940{
4941 data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
4942
4943 return 1;
4944}
4945
4946static int pack_mb88341(int addr, int val, int *bitstring);
4947static int pack_dac8800(int addr, int val, int *bitstring);
4948static int pack_dac8043(int addr, int val, int *bitstring);
4949static int pack_ad8522(int addr, int val, int *bitstring);
4950static int pack_ad8804(int addr, int val, int *bitstring);
4951static int pack_ad8842(int addr, int val, int *bitstring);
4952
4953struct caldac_struct {
4954 int n_chans;
4955 int n_bits;
4956 int (*packbits) (int, int, int *);
4957};
4958
4959static struct caldac_struct caldacs[] = {
4960 [mb88341] = {12, 8, pack_mb88341},
4961 [dac8800] = {8, 8, pack_dac8800},
4962 [dac8043] = {1, 12, pack_dac8043},
4963 [ad8522] = {2, 12, pack_ad8522},
4964 [ad8804] = {12, 8, pack_ad8804},
4965 [ad8842] = {8, 8, pack_ad8842},
4966 [ad8804_debug] = {16, 8, pack_ad8804},
4967};
4968
da91b269 4969static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
4970{
4971 int i, j;
4972 int n_dacs;
4973 int n_chans = 0;
4974 int n_bits;
4975 int diffbits = 0;
4976 int type;
4977 int chan;
4978
4979 type = boardtype.caldac[0];
4980 if (type == caldac_none)
4981 return;
4982 n_bits = caldacs[type].n_bits;
4983 for (i = 0; i < 3; i++) {
4984 type = boardtype.caldac[i];
4985 if (type == caldac_none)
4986 break;
4987 if (caldacs[type].n_bits != n_bits)
4988 diffbits = 1;
4989 n_chans += caldacs[type].n_chans;
4990 }
4991 n_dacs = i;
4992 s->n_chan = n_chans;
4993
4994 if (diffbits) {
4995 unsigned int *maxdata_list;
4996
4997 if (n_chans > MAX_N_CALDACS) {
4998 printk("BUG! MAX_N_CALDACS too small\n");
4999 }
5000 s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
5001 chan = 0;
5002 for (i = 0; i < n_dacs; i++) {
5003 type = boardtype.caldac[i];
5004 for (j = 0; j < caldacs[type].n_chans; j++) {
5005 maxdata_list[chan] =
0a85b6f0 5006 (1 << caldacs[type].n_bits) - 1;
03aef4b6
DS
5007 chan++;
5008 }
5009 }
5010
5011 for (chan = 0; chan < s->n_chan; chan++)
5012 ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
5013 } else {
5014 type = boardtype.caldac[0];
5015 s->maxdata = (1 << caldacs[type].n_bits) - 1;
5016
5017 for (chan = 0; chan < s->n_chan; chan++)
5018 ni_write_caldac(dev, i, s->maxdata / 2);
5019 }
5020}
5021
da91b269 5022static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
03aef4b6
DS
5023{
5024 unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
5025 int i;
5026 int type;
5027
2696fb57 5028 /* printk("ni_write_caldac: chan=%d val=%d\n",addr,val); */
03aef4b6
DS
5029 if (devpriv->caldacs[addr] == val)
5030 return;
5031 devpriv->caldacs[addr] = val;
5032
5033 for (i = 0; i < 3; i++) {
5034 type = boardtype.caldac[i];
5035 if (type == caldac_none)
5036 break;
5037 if (addr < caldacs[type].n_chans) {
5038 bits = caldacs[type].packbits(addr, val, &bitstring);
5039 loadbit = SerDacLd(i);
2696fb57 5040 /* printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring); */
03aef4b6
DS
5041 break;
5042 }
5043 addr -= caldacs[type].n_chans;
5044 }
5045
5046 for (bit = 1 << (bits - 1); bit; bit >>= 1) {
5047 ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
5f74ea14 5048 udelay(1);
03aef4b6 5049 ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
5f74ea14 5050 udelay(1);
03aef4b6
DS
5051 }
5052 ni_writeb(loadbit, Serial_Command);
5f74ea14 5053 udelay(1);
03aef4b6
DS
5054 ni_writeb(0, Serial_Command);
5055}
5056
5057static int pack_mb88341(int addr, int val, int *bitstring)
5058{
5059 /*
5060 Fujitsu MB 88341
5061 Note that address bits are reversed. Thanks to
5062 Ingo Keen for noticing this.
5063
5064 Note also that the 88341 expects address values from
5065 1-12, whereas we use channel numbers 0-11. The NI
5066 docs use 1-12, also, so be careful here.
5067 */
5068 addr++;
5069 *bitstring = ((addr & 0x1) << 11) |
0a85b6f0
MT
5070 ((addr & 0x2) << 9) |
5071 ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
03aef4b6
DS
5072 return 12;
5073}
5074
5075static int pack_dac8800(int addr, int val, int *bitstring)
5076{
5077 *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
5078 return 11;
5079}
5080
5081static int pack_dac8043(int addr, int val, int *bitstring)
5082{
5083 *bitstring = val & 0xfff;
5084 return 12;
5085}
5086
5087static int pack_ad8522(int addr, int val, int *bitstring)
5088{
5089 *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
5090 return 16;
5091}
5092
5093static int pack_ad8804(int addr, int val, int *bitstring)
5094{
5095 *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
5096 return 12;
5097}
5098
5099static int pack_ad8842(int addr, int val, int *bitstring)
5100{
5101 *bitstring = ((addr + 1) << 8) | (val & 0xff);
5102 return 12;
5103}
5104
5105#if 0
5106/*
5107 * Read the GPCTs current value.
5108 */
da91b269 5109static int GPCT_G_Watch(struct comedi_device *dev, int chan)
03aef4b6
DS
5110{
5111 unsigned int hi1, hi2, lo;
5112
5113 devpriv->gpct_command[chan] &= ~G_Save_Trace;
5114 devpriv->stc_writew(dev, devpriv->gpct_command[chan],
0a85b6f0 5115 G_Command_Register(chan));
03aef4b6
DS
5116
5117 devpriv->gpct_command[chan] |= G_Save_Trace;
5118 devpriv->stc_writew(dev, devpriv->gpct_command[chan],
0a85b6f0 5119 G_Command_Register(chan));
03aef4b6
DS
5120
5121 /* This procedure is used because the two registers cannot
5122 * be read atomically. */
5123 do {
5124 hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
5125 lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
5126 hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
5127 } while (hi1 != hi2);
5128
5129 return (hi1 << 16) | lo;
5130}
5131
da91b269 5132static void GPCT_Reset(struct comedi_device *dev, int chan)
03aef4b6
DS
5133{
5134 int temp_ack_reg = 0;
5135
2696fb57 5136 /* printk("GPCT_Reset..."); */
03aef4b6
DS
5137 devpriv->gpct_cur_operation[chan] = GPCT_RESET;
5138
5139 switch (chan) {
5140 case 0:
5141 devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
5142 ni_set_bits(dev, Interrupt_A_Enable_Register,
0a85b6f0 5143 G0_TC_Interrupt_Enable, 0);
03aef4b6 5144 ni_set_bits(dev, Interrupt_A_Enable_Register,
0a85b6f0 5145 G0_Gate_Interrupt_Enable, 0);
03aef4b6
DS
5146 temp_ack_reg |= G0_Gate_Error_Confirm;
5147 temp_ack_reg |= G0_TC_Error_Confirm;
5148 temp_ack_reg |= G0_TC_Interrupt_Ack;
5149 temp_ack_reg |= G0_Gate_Interrupt_Ack;
5150 devpriv->stc_writew(dev, temp_ack_reg,
0a85b6f0 5151 Interrupt_A_Ack_Register);
03aef4b6 5152
2696fb57 5153 /* problem...this interferes with the other ctr... */
03aef4b6
DS
5154 devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
5155 devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
0a85b6f0 5156 Analog_Trigger_Etc_Register);
03aef4b6
DS
5157 break;
5158 case 1:
5159 devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
5160 ni_set_bits(dev, Interrupt_B_Enable_Register,
0a85b6f0 5161 G1_TC_Interrupt_Enable, 0);
03aef4b6 5162 ni_set_bits(dev, Interrupt_B_Enable_Register,
0a85b6f0 5163 G0_Gate_Interrupt_Enable, 0);
03aef4b6
DS
5164 temp_ack_reg |= G1_Gate_Error_Confirm;
5165 temp_ack_reg |= G1_TC_Error_Confirm;
5166 temp_ack_reg |= G1_TC_Interrupt_Ack;
5167 temp_ack_reg |= G1_Gate_Interrupt_Ack;
5168 devpriv->stc_writew(dev, temp_ack_reg,
0a85b6f0 5169 Interrupt_B_Ack_Register);
03aef4b6
DS
5170
5171 devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
5172 devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
0a85b6f0 5173 Analog_Trigger_Etc_Register);
03aef4b6
DS
5174 break;
5175 };
5176
5177 devpriv->gpct_mode[chan] = 0;
5178 devpriv->gpct_input_select[chan] = 0;
5179 devpriv->gpct_command[chan] = 0;
5180
5181 devpriv->gpct_command[chan] |= G_Synchronized_Gate;
5182
5183 devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
0a85b6f0 5184 G_Mode_Register(chan));
03aef4b6 5185 devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
0a85b6f0 5186 G_Input_Select_Register(chan));
03aef4b6
DS
5187 devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
5188
2696fb57 5189 /* printk("exit GPCT_Reset\n"); */
03aef4b6
DS
5190}
5191
5192#endif
5193
0a85b6f0
MT
5194static int ni_gpct_insn_config(struct comedi_device *dev,
5195 struct comedi_subdevice *s,
5196 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5197{
5198 struct ni_gpct *counter = s->private;
5199 return ni_tio_insn_config(counter, insn, data);
5200}
5201
0a85b6f0
MT
5202static int ni_gpct_insn_read(struct comedi_device *dev,
5203 struct comedi_subdevice *s,
5204 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5205{
5206 struct ni_gpct *counter = s->private;
5207 return ni_tio_rinsn(counter, insn, data);
5208}
5209
0a85b6f0
MT
5210static int ni_gpct_insn_write(struct comedi_device *dev,
5211 struct comedi_subdevice *s,
5212 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5213{
5214 struct ni_gpct *counter = s->private;
5215 return ni_tio_winsn(counter, insn, data);
5216}
5217
da91b269 5218static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
5219{
5220 int retval;
5221#ifdef PCIDMA
5222 struct ni_gpct *counter = s->private;
2696fb57 5223/* const struct comedi_cmd *cmd = &s->async->cmd; */
03aef4b6
DS
5224
5225 retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
0a85b6f0 5226 COMEDI_INPUT);
03aef4b6
DS
5227 if (retval) {
5228 comedi_error(dev,
0a85b6f0 5229 "no dma channel available for use by counter");
03aef4b6
DS
5230 return retval;
5231 }
5232 ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
5233 ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
5234 retval = ni_tio_cmd(counter, s->async);
5235#else
5236 retval = -ENOTSUPP;
5237#endif
5238 return retval;
5239}
5240
0a85b6f0
MT
5241static int ni_gpct_cmdtest(struct comedi_device *dev,
5242 struct comedi_subdevice *s, struct comedi_cmd *cmd)
03aef4b6
DS
5243{
5244#ifdef PCIDMA
5245 struct ni_gpct *counter = s->private;
5246
5247 return ni_tio_cmdtest(counter, cmd);
5248#else
5249 return -ENOTSUPP;
5250#endif
5251}
5252
da91b269 5253static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
03aef4b6
DS
5254{
5255#ifdef PCIDMA
5256 struct ni_gpct *counter = s->private;
5257 int retval;
5258
5259 retval = ni_tio_cancel(counter);
5260 ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
5261 ni_release_gpct_mite_channel(dev, counter->counter_index);
5262 return retval;
5263#else
5264 return 0;
5265#endif
5266}
5267
5268/*
5269 *
5270 * Programmable Function Inputs
5271 *
5272 */
5273
da91b269 5274static int ni_m_series_set_pfi_routing(struct comedi_device *dev, unsigned chan,
0a85b6f0 5275 unsigned source)
03aef4b6
DS
5276{
5277 unsigned pfi_reg_index;
5278 unsigned array_offset;
5279 if ((source & 0x1f) != source)
5280 return -EINVAL;
5281 pfi_reg_index = 1 + chan / 3;
5282 array_offset = pfi_reg_index - 1;
5283 devpriv->pfi_output_select_reg[array_offset] &=
0a85b6f0 5284 ~MSeries_PFI_Output_Select_Mask(chan);
03aef4b6 5285 devpriv->pfi_output_select_reg[array_offset] |=
0a85b6f0 5286 MSeries_PFI_Output_Select_Bits(chan, source);
03aef4b6 5287 ni_writew(devpriv->pfi_output_select_reg[array_offset],
0a85b6f0 5288 M_Offset_PFI_Output_Select(pfi_reg_index));
03aef4b6
DS
5289 return 2;
5290}
5291
da91b269 5292static int ni_old_set_pfi_routing(struct comedi_device *dev, unsigned chan,
0a85b6f0 5293 unsigned source)
03aef4b6 5294{
2696fb57 5295 /* pre-m-series boards have fixed signals on pfi pins */
03aef4b6
DS
5296 if (source != ni_old_get_pfi_routing(dev, chan))
5297 return -EINVAL;
5298 return 2;
5299}
5300
da91b269 5301static int ni_set_pfi_routing(struct comedi_device *dev, unsigned chan,
0a85b6f0 5302 unsigned source)
03aef4b6
DS
5303{
5304 if (boardtype.reg_type & ni_reg_m_series_mask)
5305 return ni_m_series_set_pfi_routing(dev, chan, source);
5306 else
5307 return ni_old_set_pfi_routing(dev, chan, source);
5308}
5309
0a85b6f0
MT
5310static unsigned ni_m_series_get_pfi_routing(struct comedi_device *dev,
5311 unsigned chan)
03aef4b6
DS
5312{
5313 const unsigned array_offset = chan / 3;
5314 return MSeries_PFI_Output_Select_Source(chan,
0a85b6f0
MT
5315 devpriv->
5316 pfi_output_select_reg
5317 [array_offset]);
03aef4b6
DS
5318}
5319
da91b269 5320static unsigned ni_old_get_pfi_routing(struct comedi_device *dev, unsigned chan)
03aef4b6 5321{
2696fb57 5322 /* pre-m-series boards have fixed signals on pfi pins */
03aef4b6
DS
5323 switch (chan) {
5324 case 0:
5325 return NI_PFI_OUTPUT_AI_START1;
5326 break;
5327 case 1:
5328 return NI_PFI_OUTPUT_AI_START2;
5329 break;
5330 case 2:
5331 return NI_PFI_OUTPUT_AI_CONVERT;
5332 break;
5333 case 3:
5334 return NI_PFI_OUTPUT_G_SRC1;
5335 break;
5336 case 4:
5337 return NI_PFI_OUTPUT_G_GATE1;
5338 break;
5339 case 5:
5340 return NI_PFI_OUTPUT_AO_UPDATE_N;
5341 break;
5342 case 6:
5343 return NI_PFI_OUTPUT_AO_START1;
5344 break;
5345 case 7:
5346 return NI_PFI_OUTPUT_AI_START_PULSE;
5347 break;
5348 case 8:
5349 return NI_PFI_OUTPUT_G_SRC0;
5350 break;
5351 case 9:
5352 return NI_PFI_OUTPUT_G_GATE0;
5353 break;
5354 default:
5f74ea14 5355 printk("%s: bug, unhandled case in switch.\n", __func__);
03aef4b6
DS
5356 break;
5357 }
5358 return 0;
5359}
5360
da91b269 5361static unsigned ni_get_pfi_routing(struct comedi_device *dev, unsigned chan)
03aef4b6
DS
5362{
5363 if (boardtype.reg_type & ni_reg_m_series_mask)
5364 return ni_m_series_get_pfi_routing(dev, chan);
5365 else
5366 return ni_old_get_pfi_routing(dev, chan);
5367}
5368
da91b269 5369static int ni_config_filter(struct comedi_device *dev, unsigned pfi_channel,
0a85b6f0 5370 enum ni_pfi_filter_select filter)
03aef4b6
DS
5371{
5372 unsigned bits;
5373 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
5374 return -ENOTSUPP;
5375 }
5376 bits = ni_readl(M_Offset_PFI_Filter);
5377 bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
5378 bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
5379 ni_writel(bits, M_Offset_PFI_Filter);
5380 return 0;
5381}
5382
0a85b6f0
MT
5383static int ni_pfi_insn_bits(struct comedi_device *dev,
5384 struct comedi_subdevice *s,
5385 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5386{
5387 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
5388 return -ENOTSUPP;
5389 }
5390 if (data[0]) {
5391 s->state &= ~data[0];
5392 s->state |= (data[0] & data[1]);
5393 ni_writew(s->state, M_Offset_PFI_DO);
5394 }
5395 data[1] = ni_readw(M_Offset_PFI_DI);
5396 return 2;
5397}
5398
0a85b6f0
MT
5399static int ni_pfi_insn_config(struct comedi_device *dev,
5400 struct comedi_subdevice *s,
5401 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5402{
5403 unsigned int chan;
5404
5405 if (insn->n < 1)
5406 return -EINVAL;
5407
5408 chan = CR_CHAN(insn->chanspec);
5409
5410 switch (data[0]) {
5411 case COMEDI_OUTPUT:
5412 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
5413 break;
5414 case COMEDI_INPUT:
5415 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
5416 break;
5417 case INSN_CONFIG_DIO_QUERY:
5418 data[1] =
0a85b6f0
MT
5419 (devpriv->io_bidirection_pin_reg & (1 << chan)) ?
5420 COMEDI_OUTPUT : COMEDI_INPUT;
03aef4b6
DS
5421 return 0;
5422 break;
5423 case INSN_CONFIG_SET_ROUTING:
5424 return ni_set_pfi_routing(dev, chan, data[1]);
5425 break;
5426 case INSN_CONFIG_GET_ROUTING:
5427 data[1] = ni_get_pfi_routing(dev, chan);
5428 break;
5429 case INSN_CONFIG_FILTER:
5430 return ni_config_filter(dev, chan, data[1]);
5431 break;
5432 default:
5433 return -EINVAL;
5434 }
5435 return 0;
5436}
5437
5438/*
5439 *
5440 * NI RTSI Bus Functions
5441 *
5442 */
da91b269 5443static void ni_rtsi_init(struct comedi_device *dev)
03aef4b6 5444{
2696fb57 5445 /* Initialises the RTSI bus signal switch to a default state */
03aef4b6 5446
2696fb57 5447 /* Set clock mode to internal */
03aef4b6
DS
5448 devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
5449 if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) {
5f74ea14 5450 printk("ni_set_master_clock failed, bug?");
03aef4b6 5451 }
2696fb57 5452 /* default internal lines routing to RTSI bus lines */
03aef4b6 5453 devpriv->rtsi_trig_a_output_reg =
0a85b6f0
MT
5454 RTSI_Trig_Output_Bits(0,
5455 NI_RTSI_OUTPUT_ADR_START1) |
5456 RTSI_Trig_Output_Bits(1,
5457 NI_RTSI_OUTPUT_ADR_START2) |
5458 RTSI_Trig_Output_Bits(2,
5459 NI_RTSI_OUTPUT_SCLKG) |
5460 RTSI_Trig_Output_Bits(3, NI_RTSI_OUTPUT_DACUPDN);
03aef4b6 5461 devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
0a85b6f0 5462 RTSI_Trig_A_Output_Register);
03aef4b6 5463 devpriv->rtsi_trig_b_output_reg =
0a85b6f0
MT
5464 RTSI_Trig_Output_Bits(4,
5465 NI_RTSI_OUTPUT_DA_START1) |
5466 RTSI_Trig_Output_Bits(5,
5467 NI_RTSI_OUTPUT_G_SRC0) |
5468 RTSI_Trig_Output_Bits(6, NI_RTSI_OUTPUT_G_GATE0);
03aef4b6
DS
5469 if (boardtype.reg_type & ni_reg_m_series_mask)
5470 devpriv->rtsi_trig_b_output_reg |=
0a85b6f0 5471 RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
03aef4b6 5472 devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
0a85b6f0 5473 RTSI_Trig_B_Output_Register);
03aef4b6 5474
2696fb57
BP
5475/*
5476* Sets the source and direction of the 4 on board lines
5477* devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
5478*/
03aef4b6
DS
5479}
5480
0a85b6f0
MT
5481static int ni_rtsi_insn_bits(struct comedi_device *dev,
5482 struct comedi_subdevice *s,
5483 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5484{
5485 if (insn->n != 2)
5486 return -EINVAL;
5487
5488 data[1] = 0;
5489
5490 return 2;
5491}
5492
5493/* Find best multiplier/divider to try and get the PLL running at 80 MHz
5494 * given an arbitrary frequency input clock */
5495static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
0a85b6f0
MT
5496 unsigned *freq_divider,
5497 unsigned *freq_multiplier,
5498 unsigned *actual_period_ns)
03aef4b6
DS
5499{
5500 unsigned div;
5501 unsigned best_div = 1;
5502 static const unsigned max_div = 0x10;
5503 unsigned mult;
5504 unsigned best_mult = 1;
5505 static const unsigned max_mult = 0x100;
5506 static const unsigned pico_per_nano = 1000;
5507
5508 const unsigned reference_picosec = reference_period_ns * pico_per_nano;
5509 /* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to
5510 * 20 MHz for most timing clocks */
5511 static const unsigned target_picosec = 12500;
5512 static const unsigned fudge_factor_80_to_20Mhz = 4;
5513 int best_period_picosec = 0;
5514 for (div = 1; div <= max_div; ++div) {
5515 for (mult = 1; mult <= max_mult; ++mult) {
5516 unsigned new_period_ps =
0a85b6f0 5517 (reference_picosec * div) / mult;
03aef4b6 5518 if (abs(new_period_ps - target_picosec) <
0a85b6f0 5519 abs(best_period_picosec - target_picosec)) {
03aef4b6
DS
5520 best_period_picosec = new_period_ps;
5521 best_div = div;
5522 best_mult = mult;
5523 }
5524 }
5525 }
5526 if (best_period_picosec == 0) {
0a85b6f0 5527 printk("%s: bug, failed to find pll parameters\n", __func__);
03aef4b6
DS
5528 return -EIO;
5529 }
5530 *freq_divider = best_div;
5531 *freq_multiplier = best_mult;
5532 *actual_period_ns =
0a85b6f0
MT
5533 (best_period_picosec * fudge_factor_80_to_20Mhz +
5534 (pico_per_nano / 2)) / pico_per_nano;
03aef4b6
DS
5535 return 0;
5536}
5537
da91b269 5538static inline unsigned num_configurable_rtsi_channels(struct comedi_device *dev)
03aef4b6
DS
5539{
5540 if (boardtype.reg_type & ni_reg_m_series_mask)
5541 return 8;
5542 else
5543 return 7;
5544}
5545
0a85b6f0
MT
5546static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
5547 unsigned source, unsigned period_ns)
03aef4b6
DS
5548{
5549 static const unsigned min_period_ns = 50;
5550 static const unsigned max_period_ns = 1000;
5551 static const unsigned timeout = 1000;
5552 unsigned pll_control_bits;
5553 unsigned freq_divider;
5554 unsigned freq_multiplier;
5555 unsigned i;
5556 int retval;
5557 if (source == NI_MIO_PLL_PXI10_CLOCK)
5558 period_ns = 100;
2696fb57 5559 /* these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that */
03aef4b6 5560 if (period_ns < min_period_ns || period_ns > max_period_ns) {
5f74ea14 5561 printk
0a85b6f0
MT
5562 ("%s: you must specify an input clock frequency between %i and %i nanosec "
5563 "for the phased-lock loop.\n", __func__,
5564 min_period_ns, max_period_ns);
03aef4b6
DS
5565 return -EINVAL;
5566 }
5567 devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
5568 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
0a85b6f0 5569 RTSI_Trig_Direction_Register);
03aef4b6 5570 pll_control_bits =
0a85b6f0 5571 MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
03aef4b6 5572 devpriv->clock_and_fout2 |=
0a85b6f0 5573 MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
03aef4b6
DS
5574 devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask;
5575 switch (source) {
5576 case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
5577 devpriv->clock_and_fout2 |=
0a85b6f0 5578 MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
03aef4b6 5579 retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
0a85b6f0
MT
5580 &freq_multiplier,
5581 &devpriv->clock_ns);
03aef4b6
DS
5582 if (retval < 0)
5583 return retval;
5584 break;
5585 case NI_MIO_PLL_PXI10_CLOCK:
5586 /* pxi clock is 10MHz */
5587 devpriv->clock_and_fout2 |=
0a85b6f0 5588 MSeries_PLL_In_Source_Select_PXI_Clock10;
03aef4b6 5589 retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
0a85b6f0
MT
5590 &freq_multiplier,
5591 &devpriv->clock_ns);
03aef4b6
DS
5592 if (retval < 0)
5593 return retval;
5594 break;
5595 default:
5596 {
5597 unsigned rtsi_channel;
5598 static const unsigned max_rtsi_channel = 7;
5599 for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
0a85b6f0 5600 ++rtsi_channel) {
03aef4b6 5601 if (source ==
0a85b6f0 5602 NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
03aef4b6 5603 devpriv->clock_and_fout2 |=
0a85b6f0
MT
5604 MSeries_PLL_In_Source_Select_RTSI_Bits
5605 (rtsi_channel);
03aef4b6
DS
5606 break;
5607 }
5608 }
5609 if (rtsi_channel > max_rtsi_channel)
5610 return -EINVAL;
5611 retval = ni_mseries_get_pll_parameters(period_ns,
0a85b6f0
MT
5612 &freq_divider,
5613 &freq_multiplier,
5614 &devpriv->
5615 clock_ns);
03aef4b6
DS
5616 if (retval < 0)
5617 return retval;
5618 }
5619 break;
5620 }
5621 ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
5622 pll_control_bits |=
0a85b6f0
MT
5623 MSeries_PLL_Divisor_Bits(freq_divider) |
5624 MSeries_PLL_Multiplier_Bits(freq_multiplier);
2696fb57 5625
5f74ea14 5626 /* printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n",
2696fb57 5627 * freq_divider, freq_multiplier, pll_control_bits); */
5f74ea14 5628 /* printk("clock_ns=%d\n", devpriv->clock_ns); */
03aef4b6
DS
5629 ni_writew(pll_control_bits, M_Offset_PLL_Control);
5630 devpriv->clock_source = source;
5631 /* it seems to typically take a few hundred microseconds for PLL to lock */
5632 for (i = 0; i < timeout; ++i) {
5633 if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) {
5634 break;
5635 }
5636 udelay(1);
5637 }
5638 if (i == timeout) {
5f74ea14 5639 printk
0a85b6f0
MT
5640 ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
5641 __func__, source, period_ns);
03aef4b6
DS
5642 return -ETIMEDOUT;
5643 }
5644 return 3;
5645}
5646
da91b269 5647static int ni_set_master_clock(struct comedi_device *dev, unsigned source,
0a85b6f0 5648 unsigned period_ns)
03aef4b6
DS
5649{
5650 if (source == NI_MIO_INTERNAL_CLOCK) {
5651 devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
5652 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
0a85b6f0 5653 RTSI_Trig_Direction_Register);
03aef4b6
DS
5654 devpriv->clock_ns = TIMEBASE_1_NS;
5655 if (boardtype.reg_type & ni_reg_m_series_mask) {
5656 devpriv->clock_and_fout2 &=
0a85b6f0
MT
5657 ~(MSeries_Timebase1_Select_Bit |
5658 MSeries_Timebase3_Select_Bit);
03aef4b6 5659 ni_writew(devpriv->clock_and_fout2,
0a85b6f0 5660 M_Offset_Clock_and_Fout2);
03aef4b6
DS
5661 ni_writew(0, M_Offset_PLL_Control);
5662 }
5663 devpriv->clock_source = source;
5664 } else {
5665 if (boardtype.reg_type & ni_reg_m_series_mask) {
5666 return ni_mseries_set_pll_master_clock(dev, source,
0a85b6f0 5667 period_ns);
03aef4b6
DS
5668 } else {
5669 if (source == NI_MIO_RTSI_CLOCK) {
5670 devpriv->rtsi_trig_direction_reg |=
0a85b6f0 5671 Use_RTSI_Clock_Bit;
03aef4b6 5672 devpriv->stc_writew(dev,
0a85b6f0
MT
5673 devpriv->
5674 rtsi_trig_direction_reg,
5675 RTSI_Trig_Direction_Register);
03aef4b6 5676 if (period_ns == 0) {
5f74ea14 5677 printk
0a85b6f0
MT
5678 ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
5679 __func__);
03aef4b6
DS
5680 return -EINVAL;
5681 } else {
5682 devpriv->clock_ns = period_ns;
5683 }
5684 devpriv->clock_source = source;
5685 } else
5686 return -EINVAL;
5687 }
5688 }
5689 return 3;
5690}
5691
da91b269 5692static int ni_valid_rtsi_output_source(struct comedi_device *dev, unsigned chan,
0a85b6f0 5693 unsigned source)
03aef4b6
DS
5694{
5695 if (chan >= num_configurable_rtsi_channels(dev)) {
5696 if (chan == old_RTSI_clock_channel) {
5697 if (source == NI_RTSI_OUTPUT_RTSI_OSC)
5698 return 1;
5699 else {
5f74ea14 5700 printk
0a85b6f0
MT
5701 ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
5702 __func__, chan, old_RTSI_clock_channel);
03aef4b6
DS
5703 return 0;
5704 }
5705 }
5706 return 0;
5707 }
5708 switch (source) {
5709 case NI_RTSI_OUTPUT_ADR_START1:
5710 case NI_RTSI_OUTPUT_ADR_START2:
5711 case NI_RTSI_OUTPUT_SCLKG:
5712 case NI_RTSI_OUTPUT_DACUPDN:
5713 case NI_RTSI_OUTPUT_DA_START1:
5714 case NI_RTSI_OUTPUT_G_SRC0:
5715 case NI_RTSI_OUTPUT_G_GATE0:
5716 case NI_RTSI_OUTPUT_RGOUT0:
5717 case NI_RTSI_OUTPUT_RTSI_BRD_0:
5718 return 1;
5719 break;
5720 case NI_RTSI_OUTPUT_RTSI_OSC:
5721 if (boardtype.reg_type & ni_reg_m_series_mask)
5722 return 1;
5723 else
5724 return 0;
5725 break;
5726 default:
5727 return 0;
5728 break;
5729 }
5730}
5731
da91b269 5732static int ni_set_rtsi_routing(struct comedi_device *dev, unsigned chan,
0a85b6f0 5733 unsigned source)
03aef4b6
DS
5734{
5735 if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
5736 return -EINVAL;
5737 if (chan < 4) {
5738 devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
5739 devpriv->rtsi_trig_a_output_reg |=
0a85b6f0 5740 RTSI_Trig_Output_Bits(chan, source);
03aef4b6 5741 devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
0a85b6f0 5742 RTSI_Trig_A_Output_Register);
03aef4b6
DS
5743 } else if (chan < 8) {
5744 devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
5745 devpriv->rtsi_trig_b_output_reg |=
0a85b6f0 5746 RTSI_Trig_Output_Bits(chan, source);
03aef4b6 5747 devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
0a85b6f0 5748 RTSI_Trig_B_Output_Register);
03aef4b6
DS
5749 }
5750 return 2;
5751}
5752
da91b269 5753static unsigned ni_get_rtsi_routing(struct comedi_device *dev, unsigned chan)
03aef4b6
DS
5754{
5755 if (chan < 4) {
5756 return RTSI_Trig_Output_Source(chan,
0a85b6f0 5757 devpriv->rtsi_trig_a_output_reg);
03aef4b6
DS
5758 } else if (chan < num_configurable_rtsi_channels(dev)) {
5759 return RTSI_Trig_Output_Source(chan,
0a85b6f0 5760 devpriv->rtsi_trig_b_output_reg);
03aef4b6
DS
5761 } else {
5762 if (chan == old_RTSI_clock_channel)
5763 return NI_RTSI_OUTPUT_RTSI_OSC;
5f74ea14 5764 printk("%s: bug! should never get here?\n", __func__);
03aef4b6
DS
5765 return 0;
5766 }
5767}
5768
0a85b6f0
MT
5769static int ni_rtsi_insn_config(struct comedi_device *dev,
5770 struct comedi_subdevice *s,
5771 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5772{
5773 unsigned int chan = CR_CHAN(insn->chanspec);
5774 switch (data[0]) {
5775 case INSN_CONFIG_DIO_OUTPUT:
5776 if (chan < num_configurable_rtsi_channels(dev)) {
5777 devpriv->rtsi_trig_direction_reg |=
0a85b6f0
MT
5778 RTSI_Output_Bit(chan,
5779 (boardtype.
5780 reg_type & ni_reg_m_series_mask) !=
5781 0);
03aef4b6
DS
5782 } else if (chan == old_RTSI_clock_channel) {
5783 devpriv->rtsi_trig_direction_reg |=
0a85b6f0 5784 Drive_RTSI_Clock_Bit;
03aef4b6
DS
5785 }
5786 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
0a85b6f0 5787 RTSI_Trig_Direction_Register);
03aef4b6
DS
5788 break;
5789 case INSN_CONFIG_DIO_INPUT:
5790 if (chan < num_configurable_rtsi_channels(dev)) {
5791 devpriv->rtsi_trig_direction_reg &=
0a85b6f0
MT
5792 ~RTSI_Output_Bit(chan,
5793 (boardtype.
5794 reg_type & ni_reg_m_series_mask)
5795 != 0);
03aef4b6
DS
5796 } else if (chan == old_RTSI_clock_channel) {
5797 devpriv->rtsi_trig_direction_reg &=
0a85b6f0 5798 ~Drive_RTSI_Clock_Bit;
03aef4b6
DS
5799 }
5800 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
0a85b6f0 5801 RTSI_Trig_Direction_Register);
03aef4b6
DS
5802 break;
5803 case INSN_CONFIG_DIO_QUERY:
5804 if (chan < num_configurable_rtsi_channels(dev)) {
5805 data[1] =
0a85b6f0
MT
5806 (devpriv->rtsi_trig_direction_reg &
5807 RTSI_Output_Bit(chan,
5808 (boardtype.reg_type &
5809 ni_reg_m_series_mask)
5810 != 0)) ? INSN_CONFIG_DIO_OUTPUT :
5811 INSN_CONFIG_DIO_INPUT;
03aef4b6
DS
5812 } else if (chan == old_RTSI_clock_channel) {
5813 data[1] =
0a85b6f0
MT
5814 (devpriv->rtsi_trig_direction_reg &
5815 Drive_RTSI_Clock_Bit)
5816 ? INSN_CONFIG_DIO_OUTPUT : INSN_CONFIG_DIO_INPUT;
03aef4b6
DS
5817 }
5818 return 2;
5819 break;
5820 case INSN_CONFIG_SET_CLOCK_SRC:
5821 return ni_set_master_clock(dev, data[1], data[2]);
5822 break;
5823 case INSN_CONFIG_GET_CLOCK_SRC:
5824 data[1] = devpriv->clock_source;
5825 data[2] = devpriv->clock_ns;
5826 return 3;
5827 break;
5828 case INSN_CONFIG_SET_ROUTING:
5829 return ni_set_rtsi_routing(dev, chan, data[1]);
5830 break;
5831 case INSN_CONFIG_GET_ROUTING:
5832 data[1] = ni_get_rtsi_routing(dev, chan);
5833 return 2;
5834 break;
5835 default:
5836 return -EINVAL;
5837 break;
5838 }
5839 return 1;
5840}
5841
da91b269 5842static int cs5529_wait_for_idle(struct comedi_device *dev)
03aef4b6
DS
5843{
5844 unsigned short status;
5845 const int timeout = HZ;
5846 int i;
5847
5848 for (i = 0; i < timeout; i++) {
5849 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
5850 if ((status & CSS_ADC_BUSY) == 0) {
5851 break;
5852 }
5853 set_current_state(TASK_INTERRUPTIBLE);
5854 if (schedule_timeout(1)) {
5855 return -EIO;
5856 }
5857 }
2696fb57 5858/* printk("looped %i times waiting for idle\n", i); */
03aef4b6 5859 if (i == timeout) {
5f74ea14 5860 printk("%s: %s: timeout\n", __FILE__, __func__);
03aef4b6
DS
5861 return -ETIME;
5862 }
5863 return 0;
5864}
5865
da91b269 5866static void cs5529_command(struct comedi_device *dev, unsigned short value)
03aef4b6
DS
5867{
5868 static const int timeout = 100;
5869 int i;
5870
5871 ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
5872 /* give time for command to start being serially clocked into cs5529.
5873 * this insures that the CSS_ADC_BUSY bit will get properly
5874 * set before we exit this function.
5875 */
5876 for (i = 0; i < timeout; i++) {
5877 if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
5878 break;
5f74ea14 5879 udelay(1);
03aef4b6 5880 }
2696fb57 5881/* printk("looped %i times writing command to cs5529\n", i); */
03aef4b6
DS
5882 if (i == timeout) {
5883 comedi_error(dev, "possible problem - never saw adc go busy?");
5884 }
5885}
5886
5887/* write to cs5529 register */
da91b269 5888static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
0a85b6f0 5889 unsigned int reg_select_bits)
03aef4b6
DS
5890{
5891 ni_ao_win_outw(dev, ((value >> 16) & 0xff),
0a85b6f0 5892 CAL_ADC_Config_Data_High_Word_67xx);
03aef4b6 5893 ni_ao_win_outw(dev, (value & 0xffff),
0a85b6f0 5894 CAL_ADC_Config_Data_Low_Word_67xx);
03aef4b6
DS
5895 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
5896 cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
5897 if (cs5529_wait_for_idle(dev))
5898 comedi_error(dev, "time or signal in cs5529_config_write()");
5899}
5900
5901#ifdef NI_CS5529_DEBUG
5902/* read from cs5529 register */
da91b269 5903static unsigned int cs5529_config_read(struct comedi_device *dev,
0a85b6f0 5904 unsigned int reg_select_bits)
03aef4b6
DS
5905{
5906 unsigned int value;
5907
5908 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
5909 cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
5910 if (cs5529_wait_for_idle(dev))
5911 comedi_error(dev, "timeout or signal in cs5529_config_read()");
5912 value = (ni_ao_win_inw(dev,
0a85b6f0
MT
5913 CAL_ADC_Config_Data_High_Word_67xx) << 16) &
5914 0xff0000;
03aef4b6
DS
5915 value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
5916 return value;
5917}
5918#endif
5919
da91b269 5920static int cs5529_do_conversion(struct comedi_device *dev, unsigned short *data)
03aef4b6
DS
5921{
5922 int retval;
5923 unsigned short status;
5924
5925 cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
5926 retval = cs5529_wait_for_idle(dev);
5927 if (retval) {
5928 comedi_error(dev,
0a85b6f0 5929 "timeout or signal in cs5529_do_conversion()");
03aef4b6
DS
5930 return -ETIME;
5931 }
5932 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
5933 if (status & CSS_OSC_DETECT) {
5f74ea14 5934 printk
0a85b6f0 5935 ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
03aef4b6
DS
5936 return -EIO;
5937 }
5938 if (status & CSS_OVERRANGE) {
5f74ea14 5939 printk
0a85b6f0 5940 ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
03aef4b6
DS
5941 }
5942 if (data) {
5943 *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
5944 /* cs5529 returns 16 bit signed data in bipolar mode */
5945 *data ^= (1 << 15);
5946 }
5947 return 0;
5948}
5949
0a85b6f0
MT
5950static int cs5529_ai_insn_read(struct comedi_device *dev,
5951 struct comedi_subdevice *s,
5952 struct comedi_insn *insn, unsigned int *data)
03aef4b6
DS
5953{
5954 int n, retval;
5955 unsigned short sample;
5956 unsigned int channel_select;
5957 const unsigned int INTERNAL_REF = 0x1000;
5958
5959 /* Set calibration adc source. Docs lie, reference select bits 8 to 11
5960 * do nothing. bit 12 seems to chooses internal reference voltage, bit
5961 * 13 causes the adc input to go overrange (maybe reads external reference?) */
5962 if (insn->chanspec & CR_ALT_SOURCE)
5963 channel_select = INTERNAL_REF;
5964 else
5965 channel_select = CR_CHAN(insn->chanspec);
5966 ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
5967
5968 for (n = 0; n < insn->n; n++) {
5969 retval = cs5529_do_conversion(dev, &sample);
5970 if (retval < 0)
5971 return retval;
5972 data[n] = sample;
5973 }
5974 return insn->n;
5975}
5976
da91b269 5977static int init_cs5529(struct comedi_device *dev)
03aef4b6
DS
5978{
5979 unsigned int config_bits =
0a85b6f0 5980 CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
03aef4b6
DS
5981
5982#if 1
5983 /* do self-calibration */
5984 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
0a85b6f0 5985 CSCMD_CONFIG_REGISTER);
03aef4b6
DS
5986 /* need to force a conversion for calibration to run */
5987 cs5529_do_conversion(dev, NULL);
5988#else
5989 /* force gain calibration to 1 */
5990 cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
5991 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
0a85b6f0 5992 CSCMD_CONFIG_REGISTER);
03aef4b6
DS
5993 if (cs5529_wait_for_idle(dev))
5994 comedi_error(dev, "timeout or signal in init_cs5529()\n");
5995#endif
5996#ifdef NI_CS5529_DEBUG
5f74ea14 5997 printk("config: 0x%x\n", cs5529_config_read(dev,
0a85b6f0
MT
5998 CSCMD_CONFIG_REGISTER));
5999 printk("gain: 0x%x\n", cs5529_config_read(dev, CSCMD_GAIN_REGISTER));
5f74ea14 6000 printk("offset: 0x%x\n", cs5529_config_read(dev,
0a85b6f0 6001 CSCMD_OFFSET_REGISTER));
03aef4b6
DS
6002#endif
6003 return 0;
6004}
This page took 0.610662 seconds and 5 git commands to generate.