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