staging: comedi, remove interrupt.h
[GitHub/mt8127/android_kernel_alcatel_ttab.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
60//#define DEBUG_INTERRUPT
61//#define DEBUG_STATUS_A
62//#define DEBUG_STATUS_B
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
34c43922 196static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 197 struct comedi_insn * insn, unsigned int * data);
34c43922 198static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 199 struct comedi_insn * insn, unsigned int * data);
34c43922 200static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
ea6d0d4c 201 struct comedi_cmd * cmd);
34c43922
BP
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);
71b5f4f1 204static void handle_cdio_interrupt(struct comedi_device * dev);
34c43922 205static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6
DS
206 unsigned int trignum);
207
34c43922 208static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 209 struct comedi_insn * insn, unsigned int * data);
34c43922 210static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6 211 unsigned char data_out, unsigned char *data_in);
34c43922 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
34c43922 215static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 216 struct comedi_insn * insn, unsigned int * data);
34c43922 217static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 218 struct comedi_insn * insn, unsigned int * data);
03aef4b6 219
34c43922 220static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 221 struct comedi_insn * insn, unsigned int * data);
71b5f4f1 222static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
90035c08 223 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
03aef4b6 224
34c43922 225static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 226 struct comedi_insn * insn, unsigned int * data);
34c43922 227static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 228 struct comedi_insn * insn, unsigned int * data);
71b5f4f1 229static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan);
03aef4b6 230
71b5f4f1 231static void ni_rtsi_init(struct comedi_device * dev);
34c43922 232static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 233 struct comedi_insn * insn, unsigned int * data);
34c43922 234static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 235 struct comedi_insn * insn, unsigned int * data);
03aef4b6 236
34c43922 237static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s);
71b5f4f1 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
34c43922 251static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s);
03aef4b6 252#ifndef PCIDMA
71b5f4f1 253static void ni_handle_fifo_half_full(struct comedi_device * dev);
34c43922 254static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s);
03aef4b6 255#endif
71b5f4f1 256static void ni_handle_fifo_dregs(struct comedi_device * dev);
34c43922 257static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6 258 unsigned int trignum);
71b5f4f1 259static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
03aef4b6 260 unsigned int *list);
71b5f4f1 261static void shutdown_ai_command(struct comedi_device * dev);
03aef4b6 262
34c43922 263static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6
DS
264 unsigned int trignum);
265
34c43922 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
34c43922 270static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 271 struct comedi_insn * insn, unsigned int * data);
34c43922 272static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 273 struct comedi_insn * insn, unsigned int * data);
34c43922 274static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 275 struct comedi_insn * insn, unsigned int * data);
34c43922
BP
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,
ea6d0d4c 278 struct comedi_cmd * cmd);
34c43922 279static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
71b5f4f1 280static void handle_gpct_interrupt(struct comedi_device * dev,
03aef4b6
DS
281 unsigned short counter_index);
282
71b5f4f1
BP
283static int init_cs5529(struct comedi_device * dev);
284static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data);
34c43922 285static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 286 struct comedi_insn * insn, unsigned int * data);
03aef4b6 287#ifdef NI_CS5529_DEBUG
71b5f4f1 288static unsigned int cs5529_config_read(struct comedi_device * dev,
03aef4b6
DS
289 unsigned int reg_select_bits);
290#endif
71b5f4f1 291static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
03aef4b6
DS
292 unsigned int reg_select_bits);
293
34c43922 294static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 295 struct comedi_insn * insn, unsigned int * data);
34c43922 296static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 297 struct comedi_insn * insn, unsigned int * data);
03aef4b6 298
71b5f4f1 299static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
03aef4b6 300 unsigned period_ns);
71b5f4f1
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
71b5f4f1 356static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
03aef4b6 357 unsigned ai_mite_status);
71b5f4f1 358static void handle_b_interrupt(struct comedi_device * dev, unsigned short status,
03aef4b6 359 unsigned ao_mite_status);
71b5f4f1
BP
360static void get_last_sample_611x(struct comedi_device * dev);
361static void get_last_sample_6143(struct comedi_device * dev);
03aef4b6 362
71b5f4f1 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",
400 __FUNCTION__);
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
71b5f4f1 409static int ni_ai_drain_dma(struct comedi_device * dev);
03aef4b6
DS
410
411/* DMA channel setup */
412
413// negative channel means no channel
71b5f4f1 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
428// negative channel means no channel
71b5f4f1 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
443// negative mite_channel means no channel
71b5f4f1 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
458// negative mite_channel means no channel
71b5f4f1 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
71b5f4f1 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
71b5f4f1 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
71b5f4f1 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
547#endif // PCIDMA
548
71b5f4f1 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);
568#endif // PCIDMA
569 return 0;
570}
571
71b5f4f1 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);
584#endif // PCIDMA
585}
586
71b5f4f1 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);
599#endif // PCIDMA
600}
601
71b5f4f1 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);
619#endif // PCIDMA
620}
621
71b5f4f1 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);
634#endif // PCIDMA
635}
636
637// e-series boards use the second irq signals to generate dma requests for their counters
638#ifdef PCIDMA
71b5f4f1 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}
668#endif // PCIDMA
669
71b5f4f1 670static void ni_clear_ai_fifo(struct comedi_device * dev)
03aef4b6
DS
671{
672 if (boardtype.reg_type == ni_reg_6143) {
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
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
71b5f4f1 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
71b5f4f1 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)
71b5f4f1 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
71b5f4f1 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
71b5f4f1 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*/
71b5f4f1 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;
779 smp_mb(); // make sure dev->attached is checked before handler does anything else.
780
781 // lock to avoid race with comedi_poll
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
71b5f4f1 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
71b5f4f1 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
870#endif //PCIDMA
34c43922 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
71b5f4f1 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
34c43922 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
71b5f4f1 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
71b5f4f1 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
71b5f4f1 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
DS
973
974 //67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt
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);
995 //mite_print_chsr(ai_mite_status);
996 s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
997 //disable_irq(dev->irq);
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 }
1055#endif // !PCIDMA
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
71b5f4f1 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
71b5f4f1 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;
03aef4b6
DS
1105 //unsigned short ack=0;
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);
1124 //mite_print_chsr(ao_mite_status);
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
34c43922 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 */
34c43922 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
34c43922 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
34c43922 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
1336 // This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed
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 */
1346 ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
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
71b5f4f1 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
71b5f4f1 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*/
71b5f4f1 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 }
1447 // Check if stranded sample is present
1448 if (ni_readl(AIFIFO_Status_6143) & 0x01) {
1449 ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
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
71b5f4f1 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
71b5f4f1 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) {
1507 ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
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
34c43922 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
71b5f4f1 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;
1551// rt_printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel);
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
71b5f4f1 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
1612#endif // PCIDMA
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
34c43922 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
34c43922 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
1706 // lock to avoid race with interrupt handler
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
34c43922 1721static int ni_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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) {
1777 ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
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
71b5f4f1 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
71b5f4f1 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
1844// offset = 1 << (boardtype.adbits - 1);
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;
1862 // don't use 2's complement encoding
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;
1902 // don't use 2's complement encoding
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 */
71b5f4f1 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]) {
1955 // ready to go.
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
1966 // Set up Calibration mode if required
1967 if (boardtype.reg_type == ni_reg_6143) {
1968 if ((list[0] & CR_ALT_SOURCE)
1969 && !devpriv->ai_calib_source_enabled) {
1970 // Strobe Relay enable bit
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;
1978 msleep_interruptible(100); // Allow relays to change
1979 } else if (!(list[0] & CR_ALT_SOURCE)
1980 && devpriv->ai_calib_source_enabled) {
1981 // Strobe Relay disable bit
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;
1989 msleep_interruptible(100); // Allow relays to change
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
71b5f4f1 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
71b5f4f1 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
71b5f4f1 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:
2088 // simultaneously-sampled inputs
2089 return boardtype.ai_speed;
2090 break;
2091 default:
2092 // multiplexed inputs
2093 break;
2094 };
2095 return boardtype.ai_speed * num_channels;
2096}
2097
34c43922 2098static int ni_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
ea6d0d4c 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
34c43922 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;
2370 start_stop_select |= AI_STOP_Select(31); // logic low
2371 start_stop_select |= AI_STOP_Sync;
2372 } else {
2373 start_stop_select |= AI_STOP_Select(19); // ai configuration memory
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) {
2384 // have to take 3 stage adc pipeline into account
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;
2399 // this is required to get the last sample for chanlist_len > 1, not sure why
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;
2443 //mode2 |= AI_SC_Reload_Mode;
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
2489 mode2 |= AI_SI2_Reload_Mode; // alternate
2490 mode2 |= AI_SI2_Initial_Load_Source; // B
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 }
2592 //mite_dump_regs(devpriv->mite);
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
34c43922 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
34c43922 2628static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 2629 struct comedi_insn * insn, unsigned int * data);
03aef4b6 2630
34c43922 2631static int ni_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 2682static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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 */
34c43922 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
71b5f4f1 2803static int ni_m_series_ao_config_chanlist(struct comedi_device * dev,
34c43922 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",
2848 __FUNCTION__);
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",
2860 __FUNCTION__);
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
34c43922 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
34c43922 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}
34c43922 2924static int ni_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 2932static int ni_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 2951static int ni_ao_insn_write_671x(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 2968static int ni_ao_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 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 }
3047 // stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears
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
34c43922 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)
3117 devpriv->ao_trigger_select |= AO_START1_Polarity; // 0=active high, 1=active low. see daq-stc 3-24 (p186)
3118 if (cmd->start_arg & CR_EDGE)
3119 devpriv->ao_trigger_select |= AO_START1_Edge; // 0=edge detection disabled, 1=enabled
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 {
3144 // this is how the NI example code does it for m-series boards, verified correct with 6259
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);
3247 // enable sending of ao dma requests
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
34c43922 3264static int ni_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
ea6d0d4c 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
34c43922 3387static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
3388{
3389 //devpriv->ao0p=0x0000;
3390 //ni_writew(devpriv->ao0p,AO_Configuration);
3391
3392 //devpriv->ao1p=AO_Channel(1);
3393 //ni_writew(devpriv->ao1p,AO_Configuration);
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
3437// digital io
3438
34c43922 3439static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 3471static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
71b5f4f1 3498static int ni_m_series_dio_insn_config(struct comedi_device * dev,
90035c08 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
34c43922 3528static int ni_m_series_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 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
34c43922 3547static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
ea6d0d4c 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
34c43922 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
34c43922 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
3721// XXX not sure what interrupt C group does
3722// ni_writeb(Interrupt_Group_C_Enable_Bit, M_Offset_Interrupt_C_Enable);
3723 //wait for dma to fill output fifo
3724 for (i = 0; i < timeout; ++i) {
3725 if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
3726 break;
3727 comedi_udelay(10);
3728 }
3729 if (i == timeout) {
3730 comedi_error(dev, "dma failed to fill cdo fifo!");
3731 ni_cdio_cancel(dev, s);
3732 return -EIO;
3733 }
3734 ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
3735 CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, M_Offset_CDIO_Command);
3736 return retval;
3737}
3738
34c43922 3739static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
3740{
3741 ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
3742 CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
3743 CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
3744 M_Offset_CDIO_Command);
3745// XXX not sure what interrupt C group does
3746// ni_writeb(0, M_Offset_Interrupt_C_Enable);
3747 ni_writel(0, M_Offset_CDO_Mask_Enable);
3748 ni_release_cdo_mite_channel(dev);
3749 return 0;
3750}
3751
71b5f4f1 3752static void handle_cdio_interrupt(struct comedi_device * dev)
03aef4b6
DS
3753{
3754 unsigned cdio_status;
34c43922 3755 struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV;
03aef4b6
DS
3756#ifdef PCIDMA
3757 unsigned long flags;
3758#endif
3759
3760 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
3761 return;
3762 }
3763#ifdef PCIDMA
3764 comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
3765 if (devpriv->cdo_mite_chan) {
3766 unsigned cdo_mite_status =
3767 mite_get_status(devpriv->cdo_mite_chan);
3768 if (cdo_mite_status & CHSR_LINKC) {
3769 writel(CHOR_CLRLC,
3770 devpriv->mite->mite_io_addr +
3771 MITE_CHOR(devpriv->cdo_mite_chan->channel));
3772 }
3773 mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
3774 }
3775 comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
3776#endif
3777
3778 cdio_status = ni_readl(M_Offset_CDIO_Status);
3779 if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
3780// rt_printk("cdio error: statux=0x%x\n", cdio_status);
3781 ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); // XXX just guessing this is needed and does something useful
3782 s->async->events |= COMEDI_CB_OVERFLOW;
3783 }
3784 if (cdio_status & CDO_FIFO_Empty_Bit) {
3785// rt_printk("cdio fifo empty\n");
3786 ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
3787 M_Offset_CDIO_Command);
3788// s->async->events |= COMEDI_CB_EOA;
3789 }
3790 ni_event(dev, s);
3791}
3792
34c43922 3793static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 3794 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
3795{
3796 int err = insn->n;
3797 unsigned char byte_out, byte_in = 0;
3798
3799 if (insn->n != 2)
3800 return -EINVAL;
3801
3802 switch (data[0]) {
3803 case INSN_CONFIG_SERIAL_CLOCK:
3804
3805#ifdef DEBUG_DIO
3806 rt_printk("SPI serial clock Config cd\n", data[1]);
3807#endif
3808 devpriv->serial_hw_mode = 1;
3809 devpriv->dio_control |= DIO_HW_Serial_Enable;
3810
3811 if (data[1] == SERIAL_DISABLED) {
3812 devpriv->serial_hw_mode = 0;
3813 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
3814 DIO_Software_Serial_Control);
3815 data[1] = SERIAL_DISABLED;
3816 devpriv->serial_interval_ns = data[1];
3817 } else if (data[1] <= SERIAL_600NS) {
3818 /* Warning: this clock speed is too fast to reliably
3819 control SCXI. */
3820 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
3821 devpriv->clock_and_fout |= Slow_Internal_Timebase;
3822 devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
3823 data[1] = SERIAL_600NS;
3824 devpriv->serial_interval_ns = data[1];
3825 } else if (data[1] <= SERIAL_1_2US) {
3826 devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
3827 devpriv->clock_and_fout |= Slow_Internal_Timebase |
3828 DIO_Serial_Out_Divide_By_2;
3829 data[1] = SERIAL_1_2US;
3830 devpriv->serial_interval_ns = data[1];
3831 } else if (data[1] <= SERIAL_10US) {
3832 devpriv->dio_control |= DIO_HW_Serial_Timebase;
3833 devpriv->clock_and_fout |= Slow_Internal_Timebase |
3834 DIO_Serial_Out_Divide_By_2;
3835 /* Note: DIO_Serial_Out_Divide_By_2 only affects
3836 600ns/1.2us. If you turn divide_by_2 off with the
3837 slow clock, you will still get 10us, except then
3838 all your delays are wrong. */
3839 data[1] = SERIAL_10US;
3840 devpriv->serial_interval_ns = data[1];
3841 } else {
3842 devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
3843 DIO_Software_Serial_Control);
3844 devpriv->serial_hw_mode = 0;
3845 data[1] = (data[1] / 1000) * 1000;
3846 devpriv->serial_interval_ns = data[1];
3847 }
3848
3849 devpriv->stc_writew(dev, devpriv->dio_control,
3850 DIO_Control_Register);
3851 devpriv->stc_writew(dev, devpriv->clock_and_fout,
3852 Clock_and_FOUT_Register);
3853 return 1;
3854
3855 break;
3856
3857 case INSN_CONFIG_BIDIRECTIONAL_DATA:
3858
3859 if (devpriv->serial_interval_ns == 0) {
3860 return -EINVAL;
3861 }
3862
3863 byte_out = data[1] & 0xFF;
3864
3865 if (devpriv->serial_hw_mode) {
3866 err = ni_serial_hw_readwrite8(dev, s, byte_out,
3867 &byte_in);
3868 } else if (devpriv->serial_interval_ns > 0) {
3869 err = ni_serial_sw_readwrite8(dev, s, byte_out,
3870 &byte_in);
3871 } else {
3872 rt_printk("ni_serial_insn_config: serial disabled!\n");
3873 return -EINVAL;
3874 }
3875 if (err < 0)
3876 return err;
3877 data[1] = byte_in & 0xFF;
3878 return insn->n;
3879
3880 break;
3881 default:
3882 return -EINVAL;
3883 }
3884
3885}
3886
34c43922 3887static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6
DS
3888 unsigned char data_out, unsigned char *data_in)
3889{
3890 unsigned int status1;
3891 int err = 0, count = 20;
3892
3893#ifdef DEBUG_DIO
3894 rt_printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
3895#endif
3896
3897 devpriv->dio_output &= ~DIO_Serial_Data_Mask;
3898 devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
3899 devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
3900
3901 status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
3902 if (status1 & DIO_Serial_IO_In_Progress_St) {
3903 err = -EBUSY;
3904 goto Error;
3905 }
3906
3907 devpriv->dio_control |= DIO_HW_Serial_Start;
3908 devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
3909 devpriv->dio_control &= ~DIO_HW_Serial_Start;
3910
3911 /* Wait until STC says we're done, but don't loop infinitely. */
3912 while ((status1 =
3913 devpriv->stc_readw(dev,
3914 Joint_Status_1_Register)) &
3915 DIO_Serial_IO_In_Progress_St) {
3916 /* Delay one bit per loop */
3917 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
3918 if (--count < 0) {
3919 rt_printk
3920 ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
3921 err = -ETIME;
3922 goto Error;
3923 }
3924 }
3925
3926 /* Delay for last bit. This delay is absolutely necessary, because
3927 DIO_Serial_IO_In_Progress_St goes high one bit too early. */
3928 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
3929
3930 if (data_in != NULL) {
3931 *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
3932#ifdef DEBUG_DIO
3933 rt_printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
3934#endif
3935 }
3936
3937 Error:
3938 devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
3939
3940 return err;
3941}
3942
34c43922 3943static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
03aef4b6
DS
3944 unsigned char data_out, unsigned char *data_in)
3945{
3946 unsigned char mask, input = 0;
3947
3948#ifdef DEBUG_DIO
3949 rt_printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
3950#endif
3951
3952 /* Wait for one bit before transfer */
3953 comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
3954
3955 for (mask = 0x80; mask; mask >>= 1) {
3956 /* Output current bit; note that we cannot touch s->state
3957 because it is a per-subdevice field, and serial is
3958 a separate subdevice from DIO. */
3959 devpriv->dio_output &= ~DIO_SDOUT;
3960 if (data_out & mask) {
3961 devpriv->dio_output |= DIO_SDOUT;
3962 }
3963 devpriv->stc_writew(dev, devpriv->dio_output,
3964 DIO_Output_Register);
3965
3966 /* Assert SDCLK (active low, inverted), wait for half of
3967 the delay, deassert SDCLK, and wait for the other half. */
3968 devpriv->dio_control |= DIO_Software_Serial_Control;
3969 devpriv->stc_writew(dev, devpriv->dio_control,
3970 DIO_Control_Register);
3971
3972 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
3973
3974 devpriv->dio_control &= ~DIO_Software_Serial_Control;
3975 devpriv->stc_writew(dev, devpriv->dio_control,
3976 DIO_Control_Register);
3977
3978 comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
3979
3980 /* Input current bit */
3981 if (devpriv->stc_readw(dev,
3982 DIO_Parallel_Input_Register) & DIO_SDIN) {
3983/* rt_printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
3984 input |= mask;
3985 }
3986 }
3987#ifdef DEBUG_DIO
3988 rt_printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
3989#endif
3990 if (data_in)
3991 *data_in = input;
3992
3993 return 0;
3994}
3995
71b5f4f1 3996static void mio_common_detach(struct comedi_device * dev)
03aef4b6
DS
3997{
3998 if (dev->private) {
3999 if (devpriv->counter_dev) {
4000 ni_gpct_device_destroy(devpriv->counter_dev);
4001 }
4002 }
4003 if (dev->subdevices && boardtype.has_8255)
4004 subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV);
4005}
4006
34c43922 4007static void init_ao_67xx(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
4008{
4009 int i;
4010
4011 for (i = 0; i < s->n_chan; i++)
4012 {
4013 ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
4014 AO_Configuration_2_67xx);
4015 }
4016 ao_win_out(0x0, AO_Later_Single_Point_Updates);
4017}
4018
4019static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
4020{
4021 unsigned stc_register;
4022 switch (reg) {
4023 case NITIO_G0_Autoincrement_Reg:
4024 stc_register = G_Autoincrement_Register(0);
4025 break;
4026 case NITIO_G1_Autoincrement_Reg:
4027 stc_register = G_Autoincrement_Register(1);
4028 break;
4029 case NITIO_G0_Command_Reg:
4030 stc_register = G_Command_Register(0);
4031 break;
4032 case NITIO_G1_Command_Reg:
4033 stc_register = G_Command_Register(1);
4034 break;
4035 case NITIO_G0_HW_Save_Reg:
4036 stc_register = G_HW_Save_Register(0);
4037 break;
4038 case NITIO_G1_HW_Save_Reg:
4039 stc_register = G_HW_Save_Register(1);
4040 break;
4041 case NITIO_G0_SW_Save_Reg:
4042 stc_register = G_Save_Register(0);
4043 break;
4044 case NITIO_G1_SW_Save_Reg:
4045 stc_register = G_Save_Register(1);
4046 break;
4047 case NITIO_G0_Mode_Reg:
4048 stc_register = G_Mode_Register(0);
4049 break;
4050 case NITIO_G1_Mode_Reg:
4051 stc_register = G_Mode_Register(1);
4052 break;
4053 case NITIO_G0_LoadA_Reg:
4054 stc_register = G_Load_A_Register(0);
4055 break;
4056 case NITIO_G1_LoadA_Reg:
4057 stc_register = G_Load_A_Register(1);
4058 break;
4059 case NITIO_G0_LoadB_Reg:
4060 stc_register = G_Load_B_Register(0);
4061 break;
4062 case NITIO_G1_LoadB_Reg:
4063 stc_register = G_Load_B_Register(1);
4064 break;
4065 case NITIO_G0_Input_Select_Reg:
4066 stc_register = G_Input_Select_Register(0);
4067 break;
4068 case NITIO_G1_Input_Select_Reg:
4069 stc_register = G_Input_Select_Register(1);
4070 break;
4071 case NITIO_G01_Status_Reg:
4072 stc_register = G_Status_Register;
4073 break;
4074 case NITIO_G01_Joint_Reset_Reg:
4075 stc_register = Joint_Reset_Register;
4076 break;
4077 case NITIO_G01_Joint_Status1_Reg:
4078 stc_register = Joint_Status_1_Register;
4079 break;
4080 case NITIO_G01_Joint_Status2_Reg:
4081 stc_register = Joint_Status_2_Register;
4082 break;
4083 case NITIO_G0_Interrupt_Acknowledge_Reg:
4084 stc_register = Interrupt_A_Ack_Register;
4085 break;
4086 case NITIO_G1_Interrupt_Acknowledge_Reg:
4087 stc_register = Interrupt_B_Ack_Register;
4088 break;
4089 case NITIO_G0_Status_Reg:
4090 stc_register = AI_Status_1_Register;
4091 break;
4092 case NITIO_G1_Status_Reg:
4093 stc_register = AO_Status_1_Register;
4094 break;
4095 case NITIO_G0_Interrupt_Enable_Reg:
4096 stc_register = Interrupt_A_Enable_Register;
4097 break;
4098 case NITIO_G1_Interrupt_Enable_Reg:
4099 stc_register = Interrupt_B_Enable_Register;
4100 break;
4101 default:
4102 rt_printk("%s: unhandled register 0x%x in switch.\n",
4103 __FUNCTION__, reg);
4104 BUG();
4105 return 0;
4106 break;
4107 }
4108 return stc_register;
4109}
4110
4111static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
4112 enum ni_gpct_register reg)
4113{
71b5f4f1 4114 struct comedi_device *dev = counter->counter_dev->dev;
03aef4b6
DS
4115 unsigned stc_register;
4116 /* bits in the join reset register which are relevant to counters */
4117 static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
4118 static const unsigned gpct_interrupt_a_enable_mask =
4119 G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
4120 static const unsigned gpct_interrupt_b_enable_mask =
4121 G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
4122
4123 switch (reg) {
4124 /* m-series-only registers */
4125 case NITIO_G0_Counting_Mode_Reg:
4126 ni_writew(bits, M_Offset_G0_Counting_Mode);
4127 break;
4128 case NITIO_G1_Counting_Mode_Reg:
4129 ni_writew(bits, M_Offset_G1_Counting_Mode);
4130 break;
4131 case NITIO_G0_Second_Gate_Reg:
4132 ni_writew(bits, M_Offset_G0_Second_Gate);
4133 break;
4134 case NITIO_G1_Second_Gate_Reg:
4135 ni_writew(bits, M_Offset_G1_Second_Gate);
4136 break;
4137 case NITIO_G0_DMA_Config_Reg:
4138 ni_writew(bits, M_Offset_G0_DMA_Config);
4139 break;
4140 case NITIO_G1_DMA_Config_Reg:
4141 ni_writew(bits, M_Offset_G1_DMA_Config);
4142 break;
4143 case NITIO_G0_ABZ_Reg:
4144 ni_writew(bits, M_Offset_G0_MSeries_ABZ);
4145 break;
4146 case NITIO_G1_ABZ_Reg:
4147 ni_writew(bits, M_Offset_G1_MSeries_ABZ);
4148 break;
4149
4150 /* 32 bit registers */
4151 case NITIO_G0_LoadA_Reg:
4152 case NITIO_G1_LoadA_Reg:
4153 case NITIO_G0_LoadB_Reg:
4154 case NITIO_G1_LoadB_Reg:
4155 stc_register = ni_gpct_to_stc_register(reg);
4156 devpriv->stc_writel(dev, bits, stc_register);
4157 break;
4158
4159 /* 16 bit registers */
4160 case NITIO_G0_Interrupt_Enable_Reg:
4161 BUG_ON(bits & ~gpct_interrupt_a_enable_mask);
4162 ni_set_bitfield(dev, Interrupt_A_Enable_Register,
4163 gpct_interrupt_a_enable_mask, bits);
4164 break;
4165 case NITIO_G1_Interrupt_Enable_Reg:
4166 BUG_ON(bits & ~gpct_interrupt_b_enable_mask);
4167 ni_set_bitfield(dev, Interrupt_B_Enable_Register,
4168 gpct_interrupt_b_enable_mask, bits);
4169 break;
4170 case NITIO_G01_Joint_Reset_Reg:
4171 BUG_ON(bits & ~gpct_joint_reset_mask);
4172 /* fall-through */
4173 default:
4174 stc_register = ni_gpct_to_stc_register(reg);
4175 devpriv->stc_writew(dev, bits, stc_register);
4176 }
4177}
4178
4179static unsigned ni_gpct_read_register(struct ni_gpct *counter,
4180 enum ni_gpct_register reg)
4181{
71b5f4f1 4182 struct comedi_device *dev = counter->counter_dev->dev;
03aef4b6
DS
4183 unsigned stc_register;
4184 switch (reg) {
4185 /* m-series only registers */
4186 case NITIO_G0_DMA_Status_Reg:
4187 return ni_readw(M_Offset_G0_DMA_Status);
4188 break;
4189 case NITIO_G1_DMA_Status_Reg:
4190 return ni_readw(M_Offset_G1_DMA_Status);
4191 break;
4192
4193 /* 32 bit registers */
4194 case NITIO_G0_HW_Save_Reg:
4195 case NITIO_G1_HW_Save_Reg:
4196 case NITIO_G0_SW_Save_Reg:
4197 case NITIO_G1_SW_Save_Reg:
4198 stc_register = ni_gpct_to_stc_register(reg);
4199 return devpriv->stc_readl(dev, stc_register);
4200 break;
4201
4202 /* 16 bit registers */
4203 default:
4204 stc_register = ni_gpct_to_stc_register(reg);
4205 return devpriv->stc_readw(dev, stc_register);
4206 break;
4207 }
4208 return 0;
4209}
4210
71b5f4f1 4211static int ni_freq_out_insn_read(struct comedi_device * dev,
90035c08 4212 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4213{
4214 data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
4215 return 1;
4216}
4217
71b5f4f1 4218static int ni_freq_out_insn_write(struct comedi_device * dev,
90035c08 4219 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4220{
4221 devpriv->clock_and_fout &= ~FOUT_Enable;
4222 devpriv->stc_writew(dev, devpriv->clock_and_fout,
4223 Clock_and_FOUT_Register);
4224 devpriv->clock_and_fout &= ~FOUT_Divider_mask;
4225 devpriv->clock_and_fout |= FOUT_Divider(data[0]);
4226 devpriv->clock_and_fout |= FOUT_Enable;
4227 devpriv->stc_writew(dev, devpriv->clock_and_fout,
4228 Clock_and_FOUT_Register);
4229 return insn->n;
4230}
4231
71b5f4f1 4232static int ni_set_freq_out_clock(struct comedi_device * dev, unsigned int clock_source)
03aef4b6
DS
4233{
4234 switch (clock_source) {
4235 case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
4236 devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
4237 break;
4238 case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
4239 devpriv->clock_and_fout |= FOUT_Timebase_Select;
4240 break;
4241 default:
4242 return -EINVAL;
4243 }
4244 devpriv->stc_writew(dev, devpriv->clock_and_fout,
4245 Clock_and_FOUT_Register);
4246 return 3;
4247}
4248
71b5f4f1 4249static void ni_get_freq_out_clock(struct comedi_device * dev, unsigned int * clock_source,
790c5541 4250 unsigned int * clock_period_ns)
03aef4b6
DS
4251{
4252 if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
4253 *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
4254 *clock_period_ns = TIMEBASE_2_NS;
4255 } else {
4256 *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
4257 *clock_period_ns = TIMEBASE_1_NS * 2;
4258 }
4259}
4260
34c43922 4261static int ni_freq_out_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4262 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4263{
4264 switch (data[0]) {
4265 case INSN_CONFIG_SET_CLOCK_SRC:
4266 return ni_set_freq_out_clock(dev, data[1]);
4267 break;
4268 case INSN_CONFIG_GET_CLOCK_SRC:
4269 ni_get_freq_out_clock(dev, &data[1], &data[2]);
4270 return 3;
4271 default:
4272 break;
4273 }
4274 return -EINVAL;
4275}
4276
71b5f4f1 4277static int ni_alloc_private(struct comedi_device * dev)
03aef4b6
DS
4278{
4279 int ret;
4280
3301cc76 4281 ret = alloc_private(dev, sizeof(struct ni_private));
03aef4b6
DS
4282 if (ret < 0)
4283 return ret;
4284
4285 spin_lock_init(&devpriv->window_lock);
4286 spin_lock_init(&devpriv->soft_reg_copy_lock);
4287 spin_lock_init(&devpriv->mite_channel_lock);
4288
4289 return 0;
4290};
4291
0707bb04 4292static int ni_E_init(struct comedi_device * dev, struct comedi_devconfig * it)
03aef4b6 4293{
34c43922 4294 struct comedi_subdevice *s;
03aef4b6
DS
4295 unsigned j;
4296 enum ni_gpct_variant counter_variant;
4297
4298 if (boardtype.n_aochan > MAX_N_AO_CHAN) {
4299 printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
4300 return -EINVAL;
4301 }
4302
4303 if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0)
4304 return -ENOMEM;
4305
4306 /* analog input subdevice */
4307
4308 s = dev->subdevices + NI_AI_SUBDEV;
4309 dev->read_subdev = s;
4310 if (boardtype.n_adchan) {
4311 s->type = COMEDI_SUBD_AI;
4312 s->subdev_flags =
4313 SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
4314 if (boardtype.reg_type != ni_reg_611x)
4315 s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
4316 if (boardtype.adbits > 16)
4317 s->subdev_flags |= SDF_LSAMPL;
4318 if (boardtype.reg_type & ni_reg_m_series_mask)
4319 s->subdev_flags |= SDF_SOFT_CALIBRATED;
4320 s->n_chan = boardtype.n_adchan;
4321 s->len_chanlist = 512;
4322 s->maxdata = (1 << boardtype.adbits) - 1;
4323 s->range_table = ni_range_lkup[boardtype.gainlkup];
4324 s->insn_read = &ni_ai_insn_read;
4325 s->insn_config = &ni_ai_insn_config;
4326 s->do_cmdtest = &ni_ai_cmdtest;
4327 s->do_cmd = &ni_ai_cmd;
4328 s->cancel = &ni_ai_reset;
4329 s->poll = &ni_ai_poll;
4330 s->munge = &ni_ai_munge;
4331#ifdef PCIDMA
4332 s->async_dma_dir = DMA_FROM_DEVICE;
4333#endif
4334 } else {
4335 s->type = COMEDI_SUBD_UNUSED;
4336 }
4337
4338 /* analog output subdevice */
4339
4340 s = dev->subdevices + NI_AO_SUBDEV;
4341 if (boardtype.n_aochan) {
4342 s->type = COMEDI_SUBD_AO;
4343 s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
4344 if (boardtype.reg_type & ni_reg_m_series_mask)
4345 s->subdev_flags |= SDF_SOFT_CALIBRATED;
4346 s->n_chan = boardtype.n_aochan;
4347 s->maxdata = (1 << boardtype.aobits) - 1;
4348 s->range_table = boardtype.ao_range_table;
4349 s->insn_read = &ni_ao_insn_read;
4350 if (boardtype.reg_type & ni_reg_6xxx_mask) {
4351 s->insn_write = &ni_ao_insn_write_671x;
4352 } else {
4353 s->insn_write = &ni_ao_insn_write;
4354 }
4355 s->insn_config = &ni_ao_insn_config;
4356#ifdef PCIDMA
4357 if (boardtype.n_aochan) {
4358 s->async_dma_dir = DMA_TO_DEVICE;
4359#else
4360 if (boardtype.ao_fifo_depth) {
4361#endif
4362 dev->write_subdev = s;
4363 s->subdev_flags |= SDF_CMD_WRITE;
4364 s->do_cmd = &ni_ao_cmd;
4365 s->do_cmdtest = &ni_ao_cmdtest;
4366 s->len_chanlist = boardtype.n_aochan;
4367 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
4368 s->munge = ni_ao_munge;
4369 }
4370 s->cancel = &ni_ao_reset;
4371 } else {
4372 s->type = COMEDI_SUBD_UNUSED;
4373 }
4374 if ((boardtype.reg_type & ni_reg_67xx_mask))
4375 init_ao_67xx(dev, s);
4376
4377 /* digital i/o subdevice */
4378
4379 s = dev->subdevices + NI_DIO_SUBDEV;
4380 s->type = COMEDI_SUBD_DIO;
4381 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
4382 s->maxdata = 1;
4383 s->io_bits = 0; /* all bits input */
4384 s->range_table = &range_digital;
4385 s->n_chan = boardtype.num_p0_dio_channels;
4386 if (boardtype.reg_type & ni_reg_m_series_mask) {
4387 s->subdev_flags |=
4388 SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
4389 s->insn_bits = &ni_m_series_dio_insn_bits;
4390 s->insn_config = &ni_m_series_dio_insn_config;
4391 s->do_cmd = &ni_cdio_cmd;
4392 s->do_cmdtest = &ni_cdio_cmdtest;
4393 s->cancel = &ni_cdio_cancel;
4394 s->async_dma_dir = DMA_BIDIRECTIONAL;
4395 s->len_chanlist = s->n_chan;
4396
4397 ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
4398 ni_writel(s->io_bits, M_Offset_DIO_Direction);
4399 } else {
4400 s->insn_bits = &ni_dio_insn_bits;
4401 s->insn_config = &ni_dio_insn_config;
4402 devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
4403 ni_writew(devpriv->dio_control, DIO_Control_Register);
4404 }
4405
4406 /* 8255 device */
4407 s = dev->subdevices + NI_8255_DIO_SUBDEV;
4408 if (boardtype.has_8255) {
4409 subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
4410 } else {
4411 s->type = COMEDI_SUBD_UNUSED;
4412 }
4413
4414 /* formerly general purpose counter/timer device, but no longer used */
4415 s = dev->subdevices + NI_UNUSED_SUBDEV;
4416 s->type = COMEDI_SUBD_UNUSED;
4417
4418 /* calibration subdevice -- ai and ao */
4419 s = dev->subdevices + NI_CALIBRATION_SUBDEV;
4420 s->type = COMEDI_SUBD_CALIB;
4421 if (boardtype.reg_type & ni_reg_m_series_mask) {
4422 // internal PWM analog output used for AI nonlinearity calibration
4423 s->subdev_flags = SDF_INTERNAL;
4424 s->insn_config = &ni_m_series_pwm_config;
4425 s->n_chan = 1;
4426 s->maxdata = 0;
4427 ni_writel(0x0, M_Offset_Cal_PWM);
4428 } else if (boardtype.reg_type == ni_reg_6143) {
4429 // internal PWM analog output used for AI nonlinearity calibration
4430 s->subdev_flags = SDF_INTERNAL;
4431 s->insn_config = &ni_6143_pwm_config;
4432 s->n_chan = 1;
4433 s->maxdata = 0;
4434 } else {
4435 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
4436 s->insn_read = &ni_calib_insn_read;
4437 s->insn_write = &ni_calib_insn_write;
4438 caldac_setup(dev, s);
4439 }
4440
4441 /* EEPROM */
4442 s = dev->subdevices + NI_EEPROM_SUBDEV;
4443 s->type = COMEDI_SUBD_MEMORY;
4444 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
4445 s->maxdata = 0xff;
4446 if (boardtype.reg_type & ni_reg_m_series_mask) {
4447 s->n_chan = M_SERIES_EEPROM_SIZE;
4448 s->insn_read = &ni_m_series_eeprom_insn_read;
4449 } else {
4450 s->n_chan = 512;
4451 s->insn_read = &ni_eeprom_insn_read;
4452 }
4453
4454 /* PFI */
4455 s = dev->subdevices + NI_PFI_DIO_SUBDEV;
4456 s->type = COMEDI_SUBD_DIO;
4457 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4458 if (boardtype.reg_type & ni_reg_m_series_mask) {
4459 unsigned i;
4460 s->n_chan = 16;
4461 ni_writew(s->state, M_Offset_PFI_DO);
4462 for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
4463 ni_writew(devpriv->pfi_output_select_reg[i],
4464 M_Offset_PFI_Output_Select(i + 1));
4465 }
4466 } else {
4467 s->n_chan = 10;
4468 }
4469 s->maxdata = 1;
4470 if (boardtype.reg_type & ni_reg_m_series_mask) {
4471 s->insn_bits = &ni_pfi_insn_bits;
4472 }
4473 s->insn_config = &ni_pfi_insn_config;
4474 ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
4475
4476 /* cs5529 calibration adc */
4477 s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV;
4478 if (boardtype.reg_type & ni_reg_67xx_mask) {
4479 s->type = COMEDI_SUBD_AI;
4480 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
4481 // one channel for each analog output channel
4482 s->n_chan = boardtype.n_aochan;
4483 s->maxdata = (1 << 16) - 1;
4484 s->range_table = &range_unknown; /* XXX */
4485 s->insn_read = cs5529_ai_insn_read;
4486 s->insn_config = NULL;
4487 init_cs5529(dev);
4488 } else {
4489 s->type = COMEDI_SUBD_UNUSED;
4490 }
4491
4492 /* Serial */
4493 s = dev->subdevices + NI_SERIAL_SUBDEV;
4494 s->type = COMEDI_SUBD_SERIAL;
4495 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4496 s->n_chan = 1;
4497 s->maxdata = 0xff;
4498 s->insn_config = ni_serial_insn_config;
4499 devpriv->serial_interval_ns = 0;
4500 devpriv->serial_hw_mode = 0;
4501
4502 /* RTSI */
4503 s = dev->subdevices + NI_RTSI_SUBDEV;
4504 s->type = COMEDI_SUBD_DIO;
4505 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
4506 s->n_chan = 8;
4507 s->maxdata = 1;
4508 s->insn_bits = ni_rtsi_insn_bits;
4509 s->insn_config = ni_rtsi_insn_config;
4510 ni_rtsi_init(dev);
4511
4512 if (boardtype.reg_type & ni_reg_m_series_mask) {
4513 counter_variant = ni_gpct_variant_m_series;
4514 } else {
4515 counter_variant = ni_gpct_variant_e_series;
4516 }
4517 devpriv->counter_dev = ni_gpct_device_construct(dev,
4518 &ni_gpct_write_register, &ni_gpct_read_register,
4519 counter_variant, NUM_GPCT);
4520 /* General purpose counters */
4521 for (j = 0; j < NUM_GPCT; ++j) {
4522 s = dev->subdevices + NI_GPCT_SUBDEV(j);
4523 s->type = COMEDI_SUBD_COUNTER;
4524 s->subdev_flags =
4525 SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
4526 /* | SDF_CMD_WRITE */ ;
4527 s->n_chan = 3;
4528 if (boardtype.reg_type & ni_reg_m_series_mask)
4529 s->maxdata = 0xffffffff;
4530 else
4531 s->maxdata = 0xffffff;
4532 s->insn_read = &ni_gpct_insn_read;
4533 s->insn_write = &ni_gpct_insn_write;
4534 s->insn_config = &ni_gpct_insn_config;
4535 s->do_cmd = &ni_gpct_cmd;
4536 s->len_chanlist = 1;
4537 s->do_cmdtest = &ni_gpct_cmdtest;
4538 s->cancel = &ni_gpct_cancel;
4539 s->async_dma_dir = DMA_BIDIRECTIONAL;
4540 s->private = &devpriv->counter_dev->counters[j];
4541
4542 devpriv->counter_dev->counters[j].chip_index = 0;
4543 devpriv->counter_dev->counters[j].counter_index = j;
4544 ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
4545 }
4546
4547 /* Frequency output */
4548 s = dev->subdevices + NI_FREQ_OUT_SUBDEV;
4549 s->type = COMEDI_SUBD_COUNTER;
4550 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
4551 s->n_chan = 1;
4552 s->maxdata = 0xf;
4553 s->insn_read = &ni_freq_out_insn_read;
4554 s->insn_write = &ni_freq_out_insn_write;
4555 s->insn_config = &ni_freq_out_insn_config;
4556
4557 /* ai configuration */
4558 ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV);
4559 if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
4560 // BEAM is this needed for PCI-6143 ??
4561 devpriv->clock_and_fout =
4562 Slow_Internal_Time_Divide_By_2 |
4563 Slow_Internal_Timebase |
4564 Clock_To_Board_Divide_By_2 |
4565 Clock_To_Board |
4566 AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
4567 } else {
4568 devpriv->clock_and_fout =
4569 Slow_Internal_Time_Divide_By_2 |
4570 Slow_Internal_Timebase |
4571 Clock_To_Board_Divide_By_2 | Clock_To_Board;
4572 }
4573 devpriv->stc_writew(dev, devpriv->clock_and_fout,
4574 Clock_and_FOUT_Register);
4575
4576 /* analog output configuration */
4577 ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV);
4578
4579 if (dev->irq) {
4580 devpriv->stc_writew(dev,
4581 (IRQ_POLARITY ? Interrupt_Output_Polarity : 0) |
4582 (Interrupt_Output_On_3_Pins & 0) | Interrupt_A_Enable |
4583 Interrupt_B_Enable |
4584 Interrupt_A_Output_Select(interrupt_pin(dev->
4585 irq)) |
4586 Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
4587 Interrupt_Control_Register);
4588 }
4589
4590 /* DMA setup */
4591 ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
4592 ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
4593
4594 if (boardtype.reg_type & ni_reg_6xxx_mask) {
4595 ni_writeb(0, Magic_611x);
4596 } else if (boardtype.reg_type & ni_reg_m_series_mask) {
4597 int channel;
4598 for (channel = 0; channel < boardtype.n_aochan; ++channel) {
4599 ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
4600 ni_writeb(0x0,
4601 M_Offset_AO_Reference_Attenuation(channel));
4602 }
4603 ni_writeb(0x0, M_Offset_AO_Calibration);
4604 }
4605
4606 printk("\n");
4607 return 0;
4608}
4609
4610static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
4611{
71b5f4f1 4612 struct comedi_device *dev = (struct comedi_device *) arg;
03aef4b6
DS
4613
4614 if (dir) {
4615 ni_writeb(data, Port_A + 2 * port);
4616 return 0;
4617 } else {
4618 return ni_readb(Port_A + 2 * port);
4619 }
4620}
4621
4622/*
4623 presents the EEPROM as a subdevice
4624*/
4625
34c43922 4626static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4627 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4628{
4629 data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
4630
4631 return 1;
4632}
4633
4634/*
4635 reads bytes out of eeprom
4636*/
4637
71b5f4f1 4638static int ni_read_eeprom(struct comedi_device * dev, int addr)
03aef4b6
DS
4639{
4640 int bit;
4641 int bitstring;
4642
4643 bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
4644 ni_writeb(0x04, Serial_Command);
4645 for (bit = 0x8000; bit; bit >>= 1) {
4646 ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
4647 Serial_Command);
4648 ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
4649 Serial_Command);
4650 }
4651 bitstring = 0;
4652 for (bit = 0x80; bit; bit >>= 1) {
4653 ni_writeb(0x04, Serial_Command);
4654 ni_writeb(0x05, Serial_Command);
4655 bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
4656 }
4657 ni_writeb(0x00, Serial_Command);
4658
4659 return bitstring;
4660}
4661
71b5f4f1 4662static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
90035c08 4663 struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4664{
4665 data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
4666
4667 return 1;
4668}
4669
71b5f4f1 4670static int ni_get_pwm_config(struct comedi_device * dev, unsigned int * data)
03aef4b6
DS
4671{
4672 data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
4673 data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
4674 return 3;
4675}
4676
34c43922 4677static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4678 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4679{
4680 unsigned up_count, down_count;
4681 switch (data[0]) {
4682 case INSN_CONFIG_PWM_OUTPUT:
4683 switch (data[1]) {
4684 case TRIG_ROUND_NEAREST:
4685 up_count =
4686 (data[2] +
4687 devpriv->clock_ns / 2) / devpriv->clock_ns;
4688 break;
4689 case TRIG_ROUND_DOWN:
4690 up_count = data[2] / devpriv->clock_ns;
4691 break;
4692 case TRIG_ROUND_UP:
4693 up_count =
4694 (data[2] + devpriv->clock_ns -
4695 1) / devpriv->clock_ns;
4696 break;
4697 default:
4698 return -EINVAL;
4699 break;
4700 }
4701 switch (data[3]) {
4702 case TRIG_ROUND_NEAREST:
4703 down_count =
4704 (data[4] +
4705 devpriv->clock_ns / 2) / devpriv->clock_ns;
4706 break;
4707 case TRIG_ROUND_DOWN:
4708 down_count = data[4] / devpriv->clock_ns;
4709 break;
4710 case TRIG_ROUND_UP:
4711 down_count =
4712 (data[4] + devpriv->clock_ns -
4713 1) / devpriv->clock_ns;
4714 break;
4715 default:
4716 return -EINVAL;
4717 break;
4718 }
4719 if (up_count * devpriv->clock_ns != data[2] ||
4720 down_count * devpriv->clock_ns != data[4]) {
4721 data[2] = up_count * devpriv->clock_ns;
4722 data[4] = down_count * devpriv->clock_ns;
4723 return -EAGAIN;
4724 }
4725 ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
4726 MSeries_Cal_PWM_Low_Time_Bits(down_count),
4727 M_Offset_Cal_PWM);
4728 devpriv->pwm_up_count = up_count;
4729 devpriv->pwm_down_count = down_count;
4730 return 5;
4731 break;
4732 case INSN_CONFIG_GET_PWM_OUTPUT:
4733 return ni_get_pwm_config(dev, data);
4734 break;
4735 default:
4736 return -EINVAL;
4737 break;
4738 }
4739 return 0;
4740}
4741
34c43922 4742static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4743 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4744{
4745 unsigned up_count, down_count;
4746 switch (data[0]) {
4747 case INSN_CONFIG_PWM_OUTPUT:
4748 switch (data[1]) {
4749 case TRIG_ROUND_NEAREST:
4750 up_count =
4751 (data[2] +
4752 devpriv->clock_ns / 2) / devpriv->clock_ns;
4753 break;
4754 case TRIG_ROUND_DOWN:
4755 up_count = data[2] / devpriv->clock_ns;
4756 break;
4757 case TRIG_ROUND_UP:
4758 up_count =
4759 (data[2] + devpriv->clock_ns -
4760 1) / devpriv->clock_ns;
4761 break;
4762 default:
4763 return -EINVAL;
4764 break;
4765 }
4766 switch (data[3]) {
4767 case TRIG_ROUND_NEAREST:
4768 down_count =
4769 (data[4] +
4770 devpriv->clock_ns / 2) / devpriv->clock_ns;
4771 break;
4772 case TRIG_ROUND_DOWN:
4773 down_count = data[4] / devpriv->clock_ns;
4774 break;
4775 case TRIG_ROUND_UP:
4776 down_count =
4777 (data[4] + devpriv->clock_ns -
4778 1) / devpriv->clock_ns;
4779 break;
4780 default:
4781 return -EINVAL;
4782 break;
4783 }
4784 if (up_count * devpriv->clock_ns != data[2] ||
4785 down_count * devpriv->clock_ns != data[4]) {
4786 data[2] = up_count * devpriv->clock_ns;
4787 data[4] = down_count * devpriv->clock_ns;
4788 return -EAGAIN;
4789 }
4790 ni_writel(up_count, Calibration_HighTime_6143);
4791 devpriv->pwm_up_count = up_count;
4792 ni_writel(down_count, Calibration_LowTime_6143);
4793 devpriv->pwm_down_count = down_count;
4794 return 5;
4795 break;
4796 case INSN_CONFIG_GET_PWM_OUTPUT:
4797 return ni_get_pwm_config(dev, data);
4798 default:
4799 return -EINVAL;
4800 break;
4801 }
4802 return 0;
4803}
4804
71b5f4f1 4805static void ni_write_caldac(struct comedi_device * dev, int addr, int val);
03aef4b6
DS
4806/*
4807 calibration subdevice
4808*/
34c43922 4809static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4810 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4811{
4812 ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
4813
4814 return 1;
4815}
4816
34c43922 4817static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 4818 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
4819{
4820 data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
4821
4822 return 1;
4823}
4824
4825static int pack_mb88341(int addr, int val, int *bitstring);
4826static int pack_dac8800(int addr, int val, int *bitstring);
4827static int pack_dac8043(int addr, int val, int *bitstring);
4828static int pack_ad8522(int addr, int val, int *bitstring);
4829static int pack_ad8804(int addr, int val, int *bitstring);
4830static int pack_ad8842(int addr, int val, int *bitstring);
4831
4832struct caldac_struct {
4833 int n_chans;
4834 int n_bits;
4835 int (*packbits) (int, int, int *);
4836};
4837
4838static struct caldac_struct caldacs[] = {
4839 [mb88341] = {12, 8, pack_mb88341},
4840 [dac8800] = {8, 8, pack_dac8800},
4841 [dac8043] = {1, 12, pack_dac8043},
4842 [ad8522] = {2, 12, pack_ad8522},
4843 [ad8804] = {12, 8, pack_ad8804},
4844 [ad8842] = {8, 8, pack_ad8842},
4845 [ad8804_debug] = {16, 8, pack_ad8804},
4846};
4847
34c43922 4848static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
4849{
4850 int i, j;
4851 int n_dacs;
4852 int n_chans = 0;
4853 int n_bits;
4854 int diffbits = 0;
4855 int type;
4856 int chan;
4857
4858 type = boardtype.caldac[0];
4859 if (type == caldac_none)
4860 return;
4861 n_bits = caldacs[type].n_bits;
4862 for (i = 0; i < 3; i++) {
4863 type = boardtype.caldac[i];
4864 if (type == caldac_none)
4865 break;
4866 if (caldacs[type].n_bits != n_bits)
4867 diffbits = 1;
4868 n_chans += caldacs[type].n_chans;
4869 }
4870 n_dacs = i;
4871 s->n_chan = n_chans;
4872
4873 if (diffbits) {
4874 unsigned int *maxdata_list;
4875
4876 if (n_chans > MAX_N_CALDACS) {
4877 printk("BUG! MAX_N_CALDACS too small\n");
4878 }
4879 s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
4880 chan = 0;
4881 for (i = 0; i < n_dacs; i++) {
4882 type = boardtype.caldac[i];
4883 for (j = 0; j < caldacs[type].n_chans; j++) {
4884 maxdata_list[chan] =
4885 (1 << caldacs[type].n_bits) - 1;
4886 chan++;
4887 }
4888 }
4889
4890 for (chan = 0; chan < s->n_chan; chan++)
4891 ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
4892 } else {
4893 type = boardtype.caldac[0];
4894 s->maxdata = (1 << caldacs[type].n_bits) - 1;
4895
4896 for (chan = 0; chan < s->n_chan; chan++)
4897 ni_write_caldac(dev, i, s->maxdata / 2);
4898 }
4899}
4900
71b5f4f1 4901static void ni_write_caldac(struct comedi_device * dev, int addr, int val)
03aef4b6
DS
4902{
4903 unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
4904 int i;
4905 int type;
4906
4907 //printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
4908 if (devpriv->caldacs[addr] == val)
4909 return;
4910 devpriv->caldacs[addr] = val;
4911
4912 for (i = 0; i < 3; i++) {
4913 type = boardtype.caldac[i];
4914 if (type == caldac_none)
4915 break;
4916 if (addr < caldacs[type].n_chans) {
4917 bits = caldacs[type].packbits(addr, val, &bitstring);
4918 loadbit = SerDacLd(i);
4919 //printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
4920 break;
4921 }
4922 addr -= caldacs[type].n_chans;
4923 }
4924
4925 for (bit = 1 << (bits - 1); bit; bit >>= 1) {
4926 ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
4927 comedi_udelay(1);
4928 ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
4929 comedi_udelay(1);
4930 }
4931 ni_writeb(loadbit, Serial_Command);
4932 comedi_udelay(1);
4933 ni_writeb(0, Serial_Command);
4934}
4935
4936static int pack_mb88341(int addr, int val, int *bitstring)
4937{
4938 /*
4939 Fujitsu MB 88341
4940 Note that address bits are reversed. Thanks to
4941 Ingo Keen for noticing this.
4942
4943 Note also that the 88341 expects address values from
4944 1-12, whereas we use channel numbers 0-11. The NI
4945 docs use 1-12, also, so be careful here.
4946 */
4947 addr++;
4948 *bitstring = ((addr & 0x1) << 11) |
4949 ((addr & 0x2) << 9) |
4950 ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
4951 return 12;
4952}
4953
4954static int pack_dac8800(int addr, int val, int *bitstring)
4955{
4956 *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
4957 return 11;
4958}
4959
4960static int pack_dac8043(int addr, int val, int *bitstring)
4961{
4962 *bitstring = val & 0xfff;
4963 return 12;
4964}
4965
4966static int pack_ad8522(int addr, int val, int *bitstring)
4967{
4968 *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
4969 return 16;
4970}
4971
4972static int pack_ad8804(int addr, int val, int *bitstring)
4973{
4974 *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
4975 return 12;
4976}
4977
4978static int pack_ad8842(int addr, int val, int *bitstring)
4979{
4980 *bitstring = ((addr + 1) << 8) | (val & 0xff);
4981 return 12;
4982}
4983
4984#if 0
4985/*
4986 * Read the GPCTs current value.
4987 */
71b5f4f1 4988static int GPCT_G_Watch(struct comedi_device * dev, int chan)
03aef4b6
DS
4989{
4990 unsigned int hi1, hi2, lo;
4991
4992 devpriv->gpct_command[chan] &= ~G_Save_Trace;
4993 devpriv->stc_writew(dev, devpriv->gpct_command[chan],
4994 G_Command_Register(chan));
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 /* This procedure is used because the two registers cannot
5001 * be read atomically. */
5002 do {
5003 hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
5004 lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
5005 hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
5006 } while (hi1 != hi2);
5007
5008 return (hi1 << 16) | lo;
5009}
5010
71b5f4f1 5011static void GPCT_Reset(struct comedi_device * dev, int chan)
03aef4b6
DS
5012{
5013 int temp_ack_reg = 0;
5014
5015 //printk("GPCT_Reset...");
5016 devpriv->gpct_cur_operation[chan] = GPCT_RESET;
5017
5018 switch (chan) {
5019 case 0:
5020 devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
5021 ni_set_bits(dev, Interrupt_A_Enable_Register,
5022 G0_TC_Interrupt_Enable, 0);
5023 ni_set_bits(dev, Interrupt_A_Enable_Register,
5024 G0_Gate_Interrupt_Enable, 0);
5025 temp_ack_reg |= G0_Gate_Error_Confirm;
5026 temp_ack_reg |= G0_TC_Error_Confirm;
5027 temp_ack_reg |= G0_TC_Interrupt_Ack;
5028 temp_ack_reg |= G0_Gate_Interrupt_Ack;
5029 devpriv->stc_writew(dev, temp_ack_reg,
5030 Interrupt_A_Ack_Register);
5031
5032 //problem...this interferes with the other ctr...
5033 devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
5034 devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
5035 Analog_Trigger_Etc_Register);
5036 break;
5037 case 1:
5038 devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
5039 ni_set_bits(dev, Interrupt_B_Enable_Register,
5040 G1_TC_Interrupt_Enable, 0);
5041 ni_set_bits(dev, Interrupt_B_Enable_Register,
5042 G0_Gate_Interrupt_Enable, 0);
5043 temp_ack_reg |= G1_Gate_Error_Confirm;
5044 temp_ack_reg |= G1_TC_Error_Confirm;
5045 temp_ack_reg |= G1_TC_Interrupt_Ack;
5046 temp_ack_reg |= G1_Gate_Interrupt_Ack;
5047 devpriv->stc_writew(dev, temp_ack_reg,
5048 Interrupt_B_Ack_Register);
5049
5050 devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
5051 devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
5052 Analog_Trigger_Etc_Register);
5053 break;
5054 };
5055
5056 devpriv->gpct_mode[chan] = 0;
5057 devpriv->gpct_input_select[chan] = 0;
5058 devpriv->gpct_command[chan] = 0;
5059
5060 devpriv->gpct_command[chan] |= G_Synchronized_Gate;
5061
5062 devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
5063 G_Mode_Register(chan));
5064 devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
5065 G_Input_Select_Register(chan));
5066 devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
5067
5068 //printk("exit GPCT_Reset\n");
5069}
5070
5071#endif
5072
34c43922 5073static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5074 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5075{
5076 struct ni_gpct *counter = s->private;
5077 return ni_tio_insn_config(counter, insn, data);
5078}
5079
34c43922 5080static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5081 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5082{
5083 struct ni_gpct *counter = s->private;
5084 return ni_tio_rinsn(counter, insn, data);
5085}
5086
34c43922 5087static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5088 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5089{
5090 struct ni_gpct *counter = s->private;
5091 return ni_tio_winsn(counter, insn, data);
5092}
5093
34c43922 5094static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
5095{
5096 int retval;
5097#ifdef PCIDMA
5098 struct ni_gpct *counter = s->private;
ea6d0d4c 5099// const struct comedi_cmd *cmd = &s->async->cmd;
03aef4b6
DS
5100
5101 retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
5102 COMEDI_INPUT);
5103 if (retval) {
5104 comedi_error(dev,
5105 "no dma channel available for use by counter");
5106 return retval;
5107 }
5108 ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
5109 ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
5110 retval = ni_tio_cmd(counter, s->async);
5111#else
5112 retval = -ENOTSUPP;
5113#endif
5114 return retval;
5115}
5116
34c43922 5117static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
ea6d0d4c 5118 struct comedi_cmd * cmd)
03aef4b6
DS
5119{
5120#ifdef PCIDMA
5121 struct ni_gpct *counter = s->private;
5122
5123 return ni_tio_cmdtest(counter, cmd);
5124#else
5125 return -ENOTSUPP;
5126#endif
5127}
5128
34c43922 5129static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
03aef4b6
DS
5130{
5131#ifdef PCIDMA
5132 struct ni_gpct *counter = s->private;
5133 int retval;
5134
5135 retval = ni_tio_cancel(counter);
5136 ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
5137 ni_release_gpct_mite_channel(dev, counter->counter_index);
5138 return retval;
5139#else
5140 return 0;
5141#endif
5142}
5143
5144/*
5145 *
5146 * Programmable Function Inputs
5147 *
5148 */
5149
71b5f4f1 5150static int ni_m_series_set_pfi_routing(struct comedi_device * dev, unsigned chan,
03aef4b6
DS
5151 unsigned source)
5152{
5153 unsigned pfi_reg_index;
5154 unsigned array_offset;
5155 if ((source & 0x1f) != source)
5156 return -EINVAL;
5157 pfi_reg_index = 1 + chan / 3;
5158 array_offset = pfi_reg_index - 1;
5159 devpriv->pfi_output_select_reg[array_offset] &=
5160 ~MSeries_PFI_Output_Select_Mask(chan);
5161 devpriv->pfi_output_select_reg[array_offset] |=
5162 MSeries_PFI_Output_Select_Bits(chan, source);
5163 ni_writew(devpriv->pfi_output_select_reg[array_offset],
5164 M_Offset_PFI_Output_Select(pfi_reg_index));
5165 return 2;
5166}
5167
71b5f4f1 5168static int ni_old_set_pfi_routing(struct comedi_device * dev, unsigned chan,
03aef4b6
DS
5169 unsigned source)
5170{
5171 // pre-m-series boards have fixed signals on pfi pins
5172 if (source != ni_old_get_pfi_routing(dev, chan))
5173 return -EINVAL;
5174 return 2;
5175}
5176
71b5f4f1 5177static int ni_set_pfi_routing(struct comedi_device * dev, unsigned chan,
03aef4b6
DS
5178 unsigned source)
5179{
5180 if (boardtype.reg_type & ni_reg_m_series_mask)
5181 return ni_m_series_set_pfi_routing(dev, chan, source);
5182 else
5183 return ni_old_set_pfi_routing(dev, chan, source);
5184}
5185
71b5f4f1 5186static unsigned ni_m_series_get_pfi_routing(struct comedi_device * dev, unsigned chan)
03aef4b6
DS
5187{
5188 const unsigned array_offset = chan / 3;
5189 return MSeries_PFI_Output_Select_Source(chan,
5190 devpriv->pfi_output_select_reg[array_offset]);
5191}
5192
71b5f4f1 5193static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan)
03aef4b6
DS
5194{
5195 // pre-m-series boards have fixed signals on pfi pins
5196 switch (chan) {
5197 case 0:
5198 return NI_PFI_OUTPUT_AI_START1;
5199 break;
5200 case 1:
5201 return NI_PFI_OUTPUT_AI_START2;
5202 break;
5203 case 2:
5204 return NI_PFI_OUTPUT_AI_CONVERT;
5205 break;
5206 case 3:
5207 return NI_PFI_OUTPUT_G_SRC1;
5208 break;
5209 case 4:
5210 return NI_PFI_OUTPUT_G_GATE1;
5211 break;
5212 case 5:
5213 return NI_PFI_OUTPUT_AO_UPDATE_N;
5214 break;
5215 case 6:
5216 return NI_PFI_OUTPUT_AO_START1;
5217 break;
5218 case 7:
5219 return NI_PFI_OUTPUT_AI_START_PULSE;
5220 break;
5221 case 8:
5222 return NI_PFI_OUTPUT_G_SRC0;
5223 break;
5224 case 9:
5225 return NI_PFI_OUTPUT_G_GATE0;
5226 break;
5227 default:
5228 rt_printk("%s: bug, unhandled case in switch.\n", __FUNCTION__);
5229 break;
5230 }
5231 return 0;
5232}
5233
71b5f4f1 5234static unsigned ni_get_pfi_routing(struct comedi_device * dev, unsigned chan)
03aef4b6
DS
5235{
5236 if (boardtype.reg_type & ni_reg_m_series_mask)
5237 return ni_m_series_get_pfi_routing(dev, chan);
5238 else
5239 return ni_old_get_pfi_routing(dev, chan);
5240}
5241
71b5f4f1 5242static int ni_config_filter(struct comedi_device * dev, unsigned pfi_channel,
03aef4b6
DS
5243 enum ni_pfi_filter_select filter)
5244{
5245 unsigned bits;
5246 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
5247 return -ENOTSUPP;
5248 }
5249 bits = ni_readl(M_Offset_PFI_Filter);
5250 bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
5251 bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
5252 ni_writel(bits, M_Offset_PFI_Filter);
5253 return 0;
5254}
5255
34c43922 5256static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5257 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5258{
5259 if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
5260 return -ENOTSUPP;
5261 }
5262 if (data[0]) {
5263 s->state &= ~data[0];
5264 s->state |= (data[0] & data[1]);
5265 ni_writew(s->state, M_Offset_PFI_DO);
5266 }
5267 data[1] = ni_readw(M_Offset_PFI_DI);
5268 return 2;
5269}
5270
34c43922 5271static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5272 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5273{
5274 unsigned int chan;
5275
5276 if (insn->n < 1)
5277 return -EINVAL;
5278
5279 chan = CR_CHAN(insn->chanspec);
5280
5281 switch (data[0]) {
5282 case COMEDI_OUTPUT:
5283 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
5284 break;
5285 case COMEDI_INPUT:
5286 ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
5287 break;
5288 case INSN_CONFIG_DIO_QUERY:
5289 data[1] =
5290 (devpriv->
5291 io_bidirection_pin_reg & (1 << chan)) ? COMEDI_OUTPUT :
5292 COMEDI_INPUT;
5293 return 0;
5294 break;
5295 case INSN_CONFIG_SET_ROUTING:
5296 return ni_set_pfi_routing(dev, chan, data[1]);
5297 break;
5298 case INSN_CONFIG_GET_ROUTING:
5299 data[1] = ni_get_pfi_routing(dev, chan);
5300 break;
5301 case INSN_CONFIG_FILTER:
5302 return ni_config_filter(dev, chan, data[1]);
5303 break;
5304 default:
5305 return -EINVAL;
5306 }
5307 return 0;
5308}
5309
5310/*
5311 *
5312 * NI RTSI Bus Functions
5313 *
5314 */
71b5f4f1 5315static void ni_rtsi_init(struct comedi_device * dev)
03aef4b6
DS
5316{
5317 // Initialises the RTSI bus signal switch to a default state
5318
5319 // Set clock mode to internal
5320 devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
5321 if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) {
5322 rt_printk("ni_set_master_clock failed, bug?");
5323 }
5324 // default internal lines routing to RTSI bus lines
5325 devpriv->rtsi_trig_a_output_reg =
5326 RTSI_Trig_Output_Bits(0,
5327 NI_RTSI_OUTPUT_ADR_START1) | RTSI_Trig_Output_Bits(1,
5328 NI_RTSI_OUTPUT_ADR_START2) | RTSI_Trig_Output_Bits(2,
5329 NI_RTSI_OUTPUT_SCLKG) | RTSI_Trig_Output_Bits(3,
5330 NI_RTSI_OUTPUT_DACUPDN);
5331 devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
5332 RTSI_Trig_A_Output_Register);
5333 devpriv->rtsi_trig_b_output_reg =
5334 RTSI_Trig_Output_Bits(4,
5335 NI_RTSI_OUTPUT_DA_START1) | RTSI_Trig_Output_Bits(5,
5336 NI_RTSI_OUTPUT_G_SRC0) | RTSI_Trig_Output_Bits(6,
5337 NI_RTSI_OUTPUT_G_GATE0);
5338 if (boardtype.reg_type & ni_reg_m_series_mask)
5339 devpriv->rtsi_trig_b_output_reg |=
5340 RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
5341 devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
5342 RTSI_Trig_B_Output_Register);
5343
5344 // Sets the source and direction of the 4 on board lines
5345// devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
5346}
5347
34c43922 5348static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5349 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5350{
5351 if (insn->n != 2)
5352 return -EINVAL;
5353
5354 data[1] = 0;
5355
5356 return 2;
5357}
5358
5359/* Find best multiplier/divider to try and get the PLL running at 80 MHz
5360 * given an arbitrary frequency input clock */
5361static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
5362 unsigned *freq_divider, unsigned *freq_multiplier,
5363 unsigned *actual_period_ns)
5364{
5365 unsigned div;
5366 unsigned best_div = 1;
5367 static const unsigned max_div = 0x10;
5368 unsigned mult;
5369 unsigned best_mult = 1;
5370 static const unsigned max_mult = 0x100;
5371 static const unsigned pico_per_nano = 1000;
5372
5373 const unsigned reference_picosec = reference_period_ns * pico_per_nano;
5374 /* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to
5375 * 20 MHz for most timing clocks */
5376 static const unsigned target_picosec = 12500;
5377 static const unsigned fudge_factor_80_to_20Mhz = 4;
5378 int best_period_picosec = 0;
5379 for (div = 1; div <= max_div; ++div) {
5380 for (mult = 1; mult <= max_mult; ++mult) {
5381 unsigned new_period_ps =
5382 (reference_picosec * div) / mult;
5383 if (abs(new_period_ps - target_picosec) <
5384 abs(best_period_picosec - target_picosec)) {
5385 best_period_picosec = new_period_ps;
5386 best_div = div;
5387 best_mult = mult;
5388 }
5389 }
5390 }
5391 if (best_period_picosec == 0) {
5392 rt_printk("%s: bug, failed to find pll parameters\n",
5393 __FUNCTION__);
5394 return -EIO;
5395 }
5396 *freq_divider = best_div;
5397 *freq_multiplier = best_mult;
5398 *actual_period_ns =
5399 (best_period_picosec * fudge_factor_80_to_20Mhz +
5400 (pico_per_nano / 2)) / pico_per_nano;
5401 return 0;
5402}
5403
71b5f4f1 5404static inline unsigned num_configurable_rtsi_channels(struct comedi_device * dev)
03aef4b6
DS
5405{
5406 if (boardtype.reg_type & ni_reg_m_series_mask)
5407 return 8;
5408 else
5409 return 7;
5410}
5411
71b5f4f1 5412static int ni_mseries_set_pll_master_clock(struct comedi_device * dev, unsigned source,
03aef4b6
DS
5413 unsigned period_ns)
5414{
5415 static const unsigned min_period_ns = 50;
5416 static const unsigned max_period_ns = 1000;
5417 static const unsigned timeout = 1000;
5418 unsigned pll_control_bits;
5419 unsigned freq_divider;
5420 unsigned freq_multiplier;
5421 unsigned i;
5422 int retval;
5423 if (source == NI_MIO_PLL_PXI10_CLOCK)
5424 period_ns = 100;
5425 // these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that
5426 if (period_ns < min_period_ns || period_ns > max_period_ns) {
5427 rt_printk
5428 ("%s: you must specify an input clock frequency between %i and %i nanosec "
5429 "for the phased-lock loop.\n", __FUNCTION__,
5430 min_period_ns, max_period_ns);
5431 return -EINVAL;
5432 }
5433 devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
5434 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
5435 RTSI_Trig_Direction_Register);
5436 pll_control_bits =
5437 MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
5438 devpriv->clock_and_fout2 |=
5439 MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
5440 devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask;
5441 switch (source) {
5442 case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
5443 devpriv->clock_and_fout2 |=
5444 MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
5445 retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
5446 &freq_multiplier, &devpriv->clock_ns);
5447 if (retval < 0)
5448 return retval;
5449 break;
5450 case NI_MIO_PLL_PXI10_CLOCK:
5451 /* pxi clock is 10MHz */
5452 devpriv->clock_and_fout2 |=
5453 MSeries_PLL_In_Source_Select_PXI_Clock10;
5454 retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
5455 &freq_multiplier, &devpriv->clock_ns);
5456 if (retval < 0)
5457 return retval;
5458 break;
5459 default:
5460 {
5461 unsigned rtsi_channel;
5462 static const unsigned max_rtsi_channel = 7;
5463 for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
5464 ++rtsi_channel) {
5465 if (source ==
5466 NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
5467 devpriv->clock_and_fout2 |=
5468 MSeries_PLL_In_Source_Select_RTSI_Bits
5469 (rtsi_channel);
5470 break;
5471 }
5472 }
5473 if (rtsi_channel > max_rtsi_channel)
5474 return -EINVAL;
5475 retval = ni_mseries_get_pll_parameters(period_ns,
5476 &freq_divider, &freq_multiplier,
5477 &devpriv->clock_ns);
5478 if (retval < 0)
5479 return retval;
5480 }
5481 break;
5482 }
5483 ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
5484 pll_control_bits |=
5485 MSeries_PLL_Divisor_Bits(freq_divider) |
5486 MSeries_PLL_Multiplier_Bits(freq_multiplier);
5487// rt_printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n", freq_divider, freq_multiplier, pll_control_bits);
5488// rt_printk("clock_ns=%d\n", devpriv->clock_ns);
5489 ni_writew(pll_control_bits, M_Offset_PLL_Control);
5490 devpriv->clock_source = source;
5491 /* it seems to typically take a few hundred microseconds for PLL to lock */
5492 for (i = 0; i < timeout; ++i) {
5493 if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) {
5494 break;
5495 }
5496 udelay(1);
5497 }
5498 if (i == timeout) {
5499 rt_printk
5500 ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
5501 __FUNCTION__, source, period_ns);
5502 return -ETIMEDOUT;
5503 }
5504 return 3;
5505}
5506
71b5f4f1 5507static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
03aef4b6
DS
5508 unsigned period_ns)
5509{
5510 if (source == NI_MIO_INTERNAL_CLOCK) {
5511 devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
5512 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
5513 RTSI_Trig_Direction_Register);
5514 devpriv->clock_ns = TIMEBASE_1_NS;
5515 if (boardtype.reg_type & ni_reg_m_series_mask) {
5516 devpriv->clock_and_fout2 &=
5517 ~(MSeries_Timebase1_Select_Bit |
5518 MSeries_Timebase3_Select_Bit);
5519 ni_writew(devpriv->clock_and_fout2,
5520 M_Offset_Clock_and_Fout2);
5521 ni_writew(0, M_Offset_PLL_Control);
5522 }
5523 devpriv->clock_source = source;
5524 } else {
5525 if (boardtype.reg_type & ni_reg_m_series_mask) {
5526 return ni_mseries_set_pll_master_clock(dev, source,
5527 period_ns);
5528 } else {
5529 if (source == NI_MIO_RTSI_CLOCK) {
5530 devpriv->rtsi_trig_direction_reg |=
5531 Use_RTSI_Clock_Bit;
5532 devpriv->stc_writew(dev,
5533 devpriv->rtsi_trig_direction_reg,
5534 RTSI_Trig_Direction_Register);
5535 if (period_ns == 0) {
5536 rt_printk
5537 ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
5538 __FUNCTION__);
5539 return -EINVAL;
5540 } else {
5541 devpriv->clock_ns = period_ns;
5542 }
5543 devpriv->clock_source = source;
5544 } else
5545 return -EINVAL;
5546 }
5547 }
5548 return 3;
5549}
5550
71b5f4f1 5551static int ni_valid_rtsi_output_source(struct comedi_device * dev, unsigned chan,
03aef4b6
DS
5552 unsigned source)
5553{
5554 if (chan >= num_configurable_rtsi_channels(dev)) {
5555 if (chan == old_RTSI_clock_channel) {
5556 if (source == NI_RTSI_OUTPUT_RTSI_OSC)
5557 return 1;
5558 else {
5559 rt_printk
5560 ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
5561 __FUNCTION__, chan,
5562 old_RTSI_clock_channel);
5563 return 0;
5564 }
5565 }
5566 return 0;
5567 }
5568 switch (source) {
5569 case NI_RTSI_OUTPUT_ADR_START1:
5570 case NI_RTSI_OUTPUT_ADR_START2:
5571 case NI_RTSI_OUTPUT_SCLKG:
5572 case NI_RTSI_OUTPUT_DACUPDN:
5573 case NI_RTSI_OUTPUT_DA_START1:
5574 case NI_RTSI_OUTPUT_G_SRC0:
5575 case NI_RTSI_OUTPUT_G_GATE0:
5576 case NI_RTSI_OUTPUT_RGOUT0:
5577 case NI_RTSI_OUTPUT_RTSI_BRD_0:
5578 return 1;
5579 break;
5580 case NI_RTSI_OUTPUT_RTSI_OSC:
5581 if (boardtype.reg_type & ni_reg_m_series_mask)
5582 return 1;
5583 else
5584 return 0;
5585 break;
5586 default:
5587 return 0;
5588 break;
5589 }
5590}
5591
71b5f4f1 5592static int ni_set_rtsi_routing(struct comedi_device * dev, unsigned chan,
03aef4b6
DS
5593 unsigned source)
5594{
5595 if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
5596 return -EINVAL;
5597 if (chan < 4) {
5598 devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
5599 devpriv->rtsi_trig_a_output_reg |=
5600 RTSI_Trig_Output_Bits(chan, source);
5601 devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
5602 RTSI_Trig_A_Output_Register);
5603 } else if (chan < 8) {
5604 devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
5605 devpriv->rtsi_trig_b_output_reg |=
5606 RTSI_Trig_Output_Bits(chan, source);
5607 devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
5608 RTSI_Trig_B_Output_Register);
5609 }
5610 return 2;
5611}
5612
71b5f4f1 5613static unsigned ni_get_rtsi_routing(struct comedi_device * dev, unsigned chan)
03aef4b6
DS
5614{
5615 if (chan < 4) {
5616 return RTSI_Trig_Output_Source(chan,
5617 devpriv->rtsi_trig_a_output_reg);
5618 } else if (chan < num_configurable_rtsi_channels(dev)) {
5619 return RTSI_Trig_Output_Source(chan,
5620 devpriv->rtsi_trig_b_output_reg);
5621 } else {
5622 if (chan == old_RTSI_clock_channel)
5623 return NI_RTSI_OUTPUT_RTSI_OSC;
5624 rt_printk("%s: bug! should never get here?\n", __FUNCTION__);
5625 return 0;
5626 }
5627}
5628
34c43922 5629static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5630 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5631{
5632 unsigned int chan = CR_CHAN(insn->chanspec);
5633 switch (data[0]) {
5634 case INSN_CONFIG_DIO_OUTPUT:
5635 if (chan < num_configurable_rtsi_channels(dev)) {
5636 devpriv->rtsi_trig_direction_reg |=
5637 RTSI_Output_Bit(chan,
5638 (boardtype.reg_type & ni_reg_m_series_mask) !=
5639 0);
5640 } else if (chan == old_RTSI_clock_channel) {
5641 devpriv->rtsi_trig_direction_reg |=
5642 Drive_RTSI_Clock_Bit;
5643 }
5644 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
5645 RTSI_Trig_Direction_Register);
5646 break;
5647 case INSN_CONFIG_DIO_INPUT:
5648 if (chan < num_configurable_rtsi_channels(dev)) {
5649 devpriv->rtsi_trig_direction_reg &=
5650 ~RTSI_Output_Bit(chan,
5651 (boardtype.reg_type & ni_reg_m_series_mask) !=
5652 0);
5653 } else if (chan == old_RTSI_clock_channel) {
5654 devpriv->rtsi_trig_direction_reg &=
5655 ~Drive_RTSI_Clock_Bit;
5656 }
5657 devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
5658 RTSI_Trig_Direction_Register);
5659 break;
5660 case INSN_CONFIG_DIO_QUERY:
5661 if (chan < num_configurable_rtsi_channels(dev)) {
5662 data[1] =
5663 (devpriv->
5664 rtsi_trig_direction_reg & RTSI_Output_Bit(chan,
5665 (boardtype.
5666 reg_type & ni_reg_m_series_mask)
5667 !=
5668 0)) ? INSN_CONFIG_DIO_OUTPUT :
5669 INSN_CONFIG_DIO_INPUT;
5670 } else if (chan == old_RTSI_clock_channel) {
5671 data[1] =
5672 (devpriv->
5673 rtsi_trig_direction_reg & Drive_RTSI_Clock_Bit)
5674 ? INSN_CONFIG_DIO_OUTPUT :
5675 INSN_CONFIG_DIO_INPUT;
5676 }
5677 return 2;
5678 break;
5679 case INSN_CONFIG_SET_CLOCK_SRC:
5680 return ni_set_master_clock(dev, data[1], data[2]);
5681 break;
5682 case INSN_CONFIG_GET_CLOCK_SRC:
5683 data[1] = devpriv->clock_source;
5684 data[2] = devpriv->clock_ns;
5685 return 3;
5686 break;
5687 case INSN_CONFIG_SET_ROUTING:
5688 return ni_set_rtsi_routing(dev, chan, data[1]);
5689 break;
5690 case INSN_CONFIG_GET_ROUTING:
5691 data[1] = ni_get_rtsi_routing(dev, chan);
5692 return 2;
5693 break;
5694 default:
5695 return -EINVAL;
5696 break;
5697 }
5698 return 1;
5699}
5700
71b5f4f1 5701static int cs5529_wait_for_idle(struct comedi_device * dev)
03aef4b6
DS
5702{
5703 unsigned short status;
5704 const int timeout = HZ;
5705 int i;
5706
5707 for (i = 0; i < timeout; i++) {
5708 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
5709 if ((status & CSS_ADC_BUSY) == 0) {
5710 break;
5711 }
5712 set_current_state(TASK_INTERRUPTIBLE);
5713 if (schedule_timeout(1)) {
5714 return -EIO;
5715 }
5716 }
5717//printk("looped %i times waiting for idle\n", i);
5718 if (i == timeout) {
5719 rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
5720 return -ETIME;
5721 }
5722 return 0;
5723}
5724
71b5f4f1 5725static void cs5529_command(struct comedi_device * dev, unsigned short value)
03aef4b6
DS
5726{
5727 static const int timeout = 100;
5728 int i;
5729
5730 ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
5731 /* give time for command to start being serially clocked into cs5529.
5732 * this insures that the CSS_ADC_BUSY bit will get properly
5733 * set before we exit this function.
5734 */
5735 for (i = 0; i < timeout; i++) {
5736 if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
5737 break;
5738 comedi_udelay(1);
5739 }
5740//printk("looped %i times writing command to cs5529\n", i);
5741 if (i == timeout) {
5742 comedi_error(dev, "possible problem - never saw adc go busy?");
5743 }
5744}
5745
5746/* write to cs5529 register */
71b5f4f1 5747static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
03aef4b6
DS
5748 unsigned int reg_select_bits)
5749{
5750 ni_ao_win_outw(dev, ((value >> 16) & 0xff),
5751 CAL_ADC_Config_Data_High_Word_67xx);
5752 ni_ao_win_outw(dev, (value & 0xffff),
5753 CAL_ADC_Config_Data_Low_Word_67xx);
5754 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
5755 cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
5756 if (cs5529_wait_for_idle(dev))
5757 comedi_error(dev, "time or signal in cs5529_config_write()");
5758}
5759
5760#ifdef NI_CS5529_DEBUG
5761/* read from cs5529 register */
71b5f4f1 5762static unsigned int cs5529_config_read(struct comedi_device * dev,
03aef4b6
DS
5763 unsigned int reg_select_bits)
5764{
5765 unsigned int value;
5766
5767 reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
5768 cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
5769 if (cs5529_wait_for_idle(dev))
5770 comedi_error(dev, "timeout or signal in cs5529_config_read()");
5771 value = (ni_ao_win_inw(dev,
5772 CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
5773 value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
5774 return value;
5775}
5776#endif
5777
71b5f4f1 5778static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data)
03aef4b6
DS
5779{
5780 int retval;
5781 unsigned short status;
5782
5783 cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
5784 retval = cs5529_wait_for_idle(dev);
5785 if (retval) {
5786 comedi_error(dev,
5787 "timeout or signal in cs5529_do_conversion()");
5788 return -ETIME;
5789 }
5790 status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
5791 if (status & CSS_OSC_DETECT) {
5792 rt_printk
5793 ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
5794 return -EIO;
5795 }
5796 if (status & CSS_OVERRANGE) {
5797 rt_printk
5798 ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
5799 }
5800 if (data) {
5801 *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
5802 /* cs5529 returns 16 bit signed data in bipolar mode */
5803 *data ^= (1 << 15);
5804 }
5805 return 0;
5806}
5807
34c43922 5808static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 5809 struct comedi_insn * insn, unsigned int * data)
03aef4b6
DS
5810{
5811 int n, retval;
5812 unsigned short sample;
5813 unsigned int channel_select;
5814 const unsigned int INTERNAL_REF = 0x1000;
5815
5816 /* Set calibration adc source. Docs lie, reference select bits 8 to 11
5817 * do nothing. bit 12 seems to chooses internal reference voltage, bit
5818 * 13 causes the adc input to go overrange (maybe reads external reference?) */
5819 if (insn->chanspec & CR_ALT_SOURCE)
5820 channel_select = INTERNAL_REF;
5821 else
5822 channel_select = CR_CHAN(insn->chanspec);
5823 ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
5824
5825 for (n = 0; n < insn->n; n++) {
5826 retval = cs5529_do_conversion(dev, &sample);
5827 if (retval < 0)
5828 return retval;
5829 data[n] = sample;
5830 }
5831 return insn->n;
5832}
5833
71b5f4f1 5834static int init_cs5529(struct comedi_device * dev)
03aef4b6
DS
5835{
5836 unsigned int config_bits =
5837 CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
5838
5839#if 1
5840 /* do self-calibration */
5841 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
5842 CSCMD_CONFIG_REGISTER);
5843 /* need to force a conversion for calibration to run */
5844 cs5529_do_conversion(dev, NULL);
5845#else
5846 /* force gain calibration to 1 */
5847 cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
5848 cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
5849 CSCMD_CONFIG_REGISTER);
5850 if (cs5529_wait_for_idle(dev))
5851 comedi_error(dev, "timeout or signal in init_cs5529()\n");
5852#endif
5853#ifdef NI_CS5529_DEBUG
5854 rt_printk("config: 0x%x\n", cs5529_config_read(dev,
5855 CSCMD_CONFIG_REGISTER));
5856 rt_printk("gain: 0x%x\n", cs5529_config_read(dev,
5857 CSCMD_GAIN_REGISTER));
5858 rt_printk("offset: 0x%x\n", cs5529_config_read(dev,
5859 CSCMD_OFFSET_REGISTER));
5860#endif
5861 return 0;
5862}