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