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