blob: a574885ffba9f5937b1514719f10428052537436 [file] [log] [blame]
David Schleef03aef4b2009-02-17 17:04:22 -08001/*
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07002 * Hardware driver for DAQ-STC based boards
3 *
4 * COMEDI - Linux Control and Measurement Device Interface
5 * Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
6 * Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
David Schleef03aef4b2009-02-17 17:04:22 -080018
19/*
H Hartley Sweetenbd474a02016-04-14 09:57:55 -070020 * This file is meant to be included by another file, e.g.,
21 * ni_atmio.c or ni_pcimio.c.
22 *
23 * Interrupt support originally added by Truxton Fulton <trux@truxton.com>
24 *
25 * References (ftp://ftp.natinst.com/support/manuals):
26 * 340747b.pdf AT-MIO E series Register Level Programmer Manual
27 * 341079b.pdf PCI E Series RLPM
28 * 340934b.pdf DAQ-STC reference manual
29 *
30 * 67xx and 611x registers (ftp://ftp.ni.com/support/daq/mhddk/documentation/)
31 * release_ni611x.pdf
32 * release_ni67xx.pdf
33 *
34 * Other possibly relevant info:
35 * 320517c.pdf User manual (obsolete)
36 * 320517f.pdf User manual (new)
37 * 320889a.pdf delete
38 * 320906c.pdf maximum signal ratings
39 * 321066a.pdf about 16x
40 * 321791a.pdf discontinuation of at-mio-16e-10 rev. c
41 * 321808a.pdf about at-mio-16e-10 rev P
42 * 321837a.pdf discontinuation of at-mio-16de-10 rev d
43 * 321838a.pdf about at-mio-16de-10 rev N
44 *
45 * ISSUES:
46 * - the interrupt routine needs to be cleaned up
47 *
48 * 2006-02-07: S-Series PCI-6143: Support has been added but is not
49 * fully tested as yet. Terry Barnaby, BEAM Ltd.
50 */
David Schleef03aef4b2009-02-17 17:04:22 -080051
Greg Kroah-Hartman25436dc2009-04-27 15:14:34 -070052#include <linux/interrupt.h>
Greg Kroah-Hartman4377a022009-10-12 14:58:16 -070053#include <linux/sched.h>
H Hartley Sweeten305591a2013-07-24 09:55:00 -070054#include <linux/delay.h>
David Schleef03aef4b2009-02-17 17:04:22 -080055#include "8255.h"
56#include "mite.h"
David Schleef03aef4b2009-02-17 17:04:22 -080057
David Schleef03aef4b2009-02-17 17:04:22 -080058/* A timeout count */
59#define NI_TIMEOUT 1000
David Schleef03aef4b2009-02-17 17:04:22 -080060
61/* Note: this table must match the ai_gain_* definitions */
62static const short ni_gainlkup[][16] = {
63 [ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +053064 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
David Schleef03aef4b2009-02-17 17:04:22 -080065 [ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
66 [ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +053067 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
David Schleef03aef4b2009-02-17 17:04:22 -080068 [ai_gain_4] = {0, 1, 4, 7},
69 [ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +053070 0x003, 0x004, 0x005, 0x006},
David Schleef03aef4b2009-02-17 17:04:22 -080071 [ai_gain_622x] = {0, 1, 4, 5},
72 [ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
73 [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
74};
75
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -070076static const struct comedi_lrange range_ni_E_ai = {
77 16, {
78 BIP_RANGE(10),
79 BIP_RANGE(5),
80 BIP_RANGE(2.5),
81 BIP_RANGE(1),
82 BIP_RANGE(0.5),
83 BIP_RANGE(0.25),
84 BIP_RANGE(0.1),
85 BIP_RANGE(0.05),
86 UNI_RANGE(20),
87 UNI_RANGE(10),
88 UNI_RANGE(5),
89 UNI_RANGE(2),
90 UNI_RANGE(1),
91 UNI_RANGE(0.5),
92 UNI_RANGE(0.2),
93 UNI_RANGE(0.1)
94 }
David Schleef03aef4b2009-02-17 17:04:22 -080095};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +053096
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -070097static const struct comedi_lrange range_ni_E_ai_limited = {
98 8, {
99 BIP_RANGE(10),
100 BIP_RANGE(5),
101 BIP_RANGE(1),
102 BIP_RANGE(0.1),
103 UNI_RANGE(10),
104 UNI_RANGE(5),
105 UNI_RANGE(1),
106 UNI_RANGE(0.1)
107 }
David Schleef03aef4b2009-02-17 17:04:22 -0800108};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530109
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700110static const struct comedi_lrange range_ni_E_ai_limited14 = {
111 14, {
112 BIP_RANGE(10),
113 BIP_RANGE(5),
114 BIP_RANGE(2),
115 BIP_RANGE(1),
116 BIP_RANGE(0.5),
117 BIP_RANGE(0.2),
118 BIP_RANGE(0.1),
119 UNI_RANGE(10),
120 UNI_RANGE(5),
121 UNI_RANGE(2),
122 UNI_RANGE(1),
123 UNI_RANGE(0.5),
124 UNI_RANGE(0.2),
125 UNI_RANGE(0.1)
126 }
David Schleef03aef4b2009-02-17 17:04:22 -0800127};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530128
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700129static const struct comedi_lrange range_ni_E_ai_bipolar4 = {
130 4, {
131 BIP_RANGE(10),
132 BIP_RANGE(5),
133 BIP_RANGE(0.5),
134 BIP_RANGE(0.05)
135 }
David Schleef03aef4b2009-02-17 17:04:22 -0800136};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530137
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700138static const struct comedi_lrange range_ni_E_ai_611x = {
139 8, {
140 BIP_RANGE(50),
141 BIP_RANGE(20),
142 BIP_RANGE(10),
143 BIP_RANGE(5),
144 BIP_RANGE(2),
145 BIP_RANGE(1),
146 BIP_RANGE(0.5),
147 BIP_RANGE(0.2)
148 }
David Schleef03aef4b2009-02-17 17:04:22 -0800149};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530150
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700151static const struct comedi_lrange range_ni_M_ai_622x = {
152 4, {
153 BIP_RANGE(10),
154 BIP_RANGE(5),
155 BIP_RANGE(1),
156 BIP_RANGE(0.2)
157 }
David Schleef03aef4b2009-02-17 17:04:22 -0800158};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530159
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700160static const struct comedi_lrange range_ni_M_ai_628x = {
161 7, {
162 BIP_RANGE(10),
163 BIP_RANGE(5),
164 BIP_RANGE(2),
165 BIP_RANGE(1),
166 BIP_RANGE(0.5),
167 BIP_RANGE(0.2),
168 BIP_RANGE(0.1)
169 }
David Schleef03aef4b2009-02-17 17:04:22 -0800170};
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530171
H Hartley Sweetendaed6c7282013-12-09 17:30:59 -0700172static const struct comedi_lrange range_ni_E_ao_ext = {
173 4, {
174 BIP_RANGE(10),
175 UNI_RANGE(10),
176 RANGE_ext(-1, 1),
177 RANGE_ext(0, 1)
178 }
David Schleef03aef4b2009-02-17 17:04:22 -0800179};
180
Bill Pemberton9ced1de2009-03-16 22:05:31 -0400181static const struct comedi_lrange *const ni_range_lkup[] = {
David Schleef03aef4b2009-02-17 17:04:22 -0800182 [ai_gain_16] = &range_ni_E_ai,
183 [ai_gain_8] = &range_ni_E_ai_limited,
184 [ai_gain_14] = &range_ni_E_ai_limited14,
185 [ai_gain_4] = &range_ni_E_ai_bipolar4,
186 [ai_gain_611x] = &range_ni_E_ai_611x,
187 [ai_gain_622x] = &range_ni_M_ai_622x,
188 [ai_gain_628x] = &range_ni_M_ai_628x,
H Hartley Sweeten50708d92013-04-03 13:39:34 -0700189 [ai_gain_6143] = &range_bipolar5
David Schleef03aef4b2009-02-17 17:04:22 -0800190};
191
David Schleef03aef4b2009-02-17 17:04:22 -0800192enum aimodes {
193 AIMODE_NONE = 0,
194 AIMODE_HALF_FULL = 1,
195 AIMODE_SCAN = 2,
196 AIMODE_SAMPLE = 3,
197};
198
199enum ni_common_subdevices {
200 NI_AI_SUBDEV,
201 NI_AO_SUBDEV,
202 NI_DIO_SUBDEV,
203 NI_8255_DIO_SUBDEV,
204 NI_UNUSED_SUBDEV,
205 NI_CALIBRATION_SUBDEV,
206 NI_EEPROM_SUBDEV,
207 NI_PFI_DIO_SUBDEV,
208 NI_CS5529_CALIBRATION_SUBDEV,
209 NI_SERIAL_SUBDEV,
210 NI_RTSI_SUBDEV,
211 NI_GPCT0_SUBDEV,
212 NI_GPCT1_SUBDEV,
213 NI_FREQ_OUT_SUBDEV,
214 NI_NUM_SUBDEVICES
215};
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700216
H Hartley Sweeten0b235d52016-04-14 09:57:59 -0700217#define NI_GPCT_SUBDEV(x) (NI_GPCT0_SUBDEV + (x))
David Schleef03aef4b2009-02-17 17:04:22 -0800218
219enum timebase_nanoseconds {
220 TIMEBASE_1_NS = 50,
221 TIMEBASE_2_NS = 10000
222};
223
224#define SERIAL_DISABLED 0
225#define SERIAL_600NS 600
226#define SERIAL_1_2US 1200
227#define SERIAL_10US 10000
228
229static const int num_adc_stages_611x = 3;
230
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700231static void ni_writel(struct comedi_device *dev, unsigned int data, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700232{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700233 if (dev->mmio)
234 writel(data, dev->mmio + reg);
H Hartley Sweetenbd3a3cd2016-03-22 10:04:48 -0700235 else
236 outl(data, dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700237}
238
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700239static void ni_writew(struct comedi_device *dev, unsigned int data, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700240{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700241 if (dev->mmio)
242 writew(data, dev->mmio + reg);
H Hartley Sweetenbd3a3cd2016-03-22 10:04:48 -0700243 else
244 outw(data, dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700245}
246
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700247static void ni_writeb(struct comedi_device *dev, unsigned int data, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700248{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700249 if (dev->mmio)
250 writeb(data, dev->mmio + reg);
H Hartley Sweetenbd3a3cd2016-03-22 10:04:48 -0700251 else
252 outb(data, dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700253}
254
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700255static unsigned int ni_readl(struct comedi_device *dev, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700256{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700257 if (dev->mmio)
258 return readl(dev->mmio + reg);
H Hartley Sweeten0953ee42014-07-16 10:43:34 -0700259
260 return inl(dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700261}
262
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700263static unsigned int ni_readw(struct comedi_device *dev, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700264{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700265 if (dev->mmio)
266 return readw(dev->mmio + reg);
H Hartley Sweeten0953ee42014-07-16 10:43:34 -0700267
268 return inw(dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700269}
270
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700271static unsigned int ni_readb(struct comedi_device *dev, int reg)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700272{
H Hartley Sweeten5f8a5f42014-07-29 15:01:38 -0700273 if (dev->mmio)
274 return readb(dev->mmio + reg);
H Hartley Sweeten0953ee42014-07-16 10:43:34 -0700275
276 return inb(dev->iobase + reg);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -0700277}
278
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700279/*
280 * We automatically take advantage of STC registers that can be
281 * read/written directly in the I/O space of the board.
282 *
283 * The AT-MIO and DAQCard devices map the low 8 STC registers to
284 * iobase+reg*2.
285 *
286 * Most PCIMIO devices also map the low 8 STC registers but the
287 * 611x devices map the read registers to iobase+(addr-1)*2.
288 * For now non-windowed STC access is disabled if a PCIMIO device
289 * is detected (devpriv->mite has been initialized).
290 *
291 * The M series devices do not used windowed registers for the
292 * STC registers. The functions below handle the mapping of the
293 * windowed STC registers to the m series register offsets.
294 */
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700295
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700296struct mio_regmap {
297 unsigned int mio_reg;
298 int size;
299};
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700300
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700301static const struct mio_regmap m_series_stc_write_regmap[] = {
H Hartley Sweeten480456d2015-05-01 14:58:54 -0700302 [NISTC_INTA_ACK_REG] = { 0x104, 2 },
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -0700303 [NISTC_INTB_ACK_REG] = { 0x106, 2 },
H Hartley Sweetena1da35a2015-05-01 14:58:56 -0700304 [NISTC_AI_CMD2_REG] = { 0x108, 2 },
H Hartley Sweeten382b3c42015-05-01 14:58:57 -0700305 [NISTC_AO_CMD2_REG] = { 0x10a, 2 },
H Hartley Sweeten5fa2fa42015-05-01 14:58:58 -0700306 [NISTC_G0_CMD_REG] = { 0x10c, 2 },
307 [NISTC_G1_CMD_REG] = { 0x10e, 2 },
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -0700308 [NISTC_AI_CMD1_REG] = { 0x110, 2 },
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -0700309 [NISTC_AO_CMD1_REG] = { 0x112, 2 },
H Hartley Sweeten975b6d22015-05-01 14:58:34 -0700310 /*
H Hartley Sweeten05aafee2015-05-01 14:59:01 -0700311 * NISTC_DIO_OUT_REG maps to:
H Hartley Sweeten975b6d22015-05-01 14:58:34 -0700312 * { NI_M_DIO_REG, 4 } and { NI_M_SCXI_SER_DO_REG, 1 }
313 */
H Hartley Sweeten05aafee2015-05-01 14:59:01 -0700314 [NISTC_DIO_OUT_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */
H Hartley Sweeten59a97c32015-05-01 14:59:02 -0700315 [NISTC_DIO_CTRL_REG] = { 0, 0 }, /* DOES NOT MAP CLEANLY */
H Hartley Sweetenbd358f52015-05-01 14:59:03 -0700316 [NISTC_AI_MODE1_REG] = { 0x118, 2 },
H Hartley Sweetenb134cc52015-05-01 14:59:04 -0700317 [NISTC_AI_MODE2_REG] = { 0x11a, 2 },
H Hartley Sweetena2c53732015-05-01 14:59:05 -0700318 [NISTC_AI_SI_LOADA_REG] = { 0x11c, 4 },
319 [NISTC_AI_SI_LOADB_REG] = { 0x120, 4 },
320 [NISTC_AI_SC_LOADA_REG] = { 0x124, 4 },
321 [NISTC_AI_SC_LOADB_REG] = { 0x128, 4 },
322 [NISTC_AI_SI2_LOADA_REG] = { 0x12c, 4 },
323 [NISTC_AI_SI2_LOADB_REG] = { 0x130, 4 },
H Hartley Sweetenaff27002015-05-01 14:59:06 -0700324 [NISTC_G0_MODE_REG] = { 0x134, 2 },
325 [NISTC_G1_MODE_REG] = { 0x136, 2 },
326 [NISTC_G0_LOADA_REG] = { 0x138, 4 },
327 [NISTC_G0_LOADB_REG] = { 0x13c, 4 },
328 [NISTC_G1_LOADA_REG] = { 0x140, 4 },
329 [NISTC_G1_LOADB_REG] = { 0x144, 4 },
330 [NISTC_G0_INPUT_SEL_REG] = { 0x148, 2 },
331 [NISTC_G1_INPUT_SEL_REG] = { 0x14a, 2 },
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -0700332 [NISTC_AO_MODE1_REG] = { 0x14c, 2 },
H Hartley Sweetenec8bf722015-05-01 14:59:08 -0700333 [NISTC_AO_MODE2_REG] = { 0x14e, 2 },
H Hartley Sweeten37e0ece2015-05-01 14:59:09 -0700334 [NISTC_AO_UI_LOADA_REG] = { 0x150, 4 },
335 [NISTC_AO_UI_LOADB_REG] = { 0x154, 4 },
336 [NISTC_AO_BC_LOADA_REG] = { 0x158, 4 },
337 [NISTC_AO_BC_LOADB_REG] = { 0x15c, 4 },
338 [NISTC_AO_UC_LOADA_REG] = { 0x160, 4 },
339 [NISTC_AO_UC_LOADB_REG] = { 0x164, 4 },
H Hartley Sweetena47fc022015-05-01 14:59:10 -0700340 [NISTC_CLK_FOUT_REG] = { 0x170, 2 },
H Hartley Sweeten5ecadf82015-05-01 14:59:12 -0700341 [NISTC_IO_BIDIR_PIN_REG] = { 0x172, 2 },
H Hartley Sweetena4f18b12015-05-01 14:59:14 -0700342 [NISTC_RTSI_TRIG_DIR_REG] = { 0x174, 2 },
H Hartley Sweetend8f62c42015-05-01 14:59:15 -0700343 [NISTC_INT_CTRL_REG] = { 0x176, 2 },
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -0700344 [NISTC_AI_OUT_CTRL_REG] = { 0x178, 2 },
H Hartley Sweeten27cf6c02015-05-01 14:59:17 -0700345 [NISTC_ATRIG_ETC_REG] = { 0x17a, 2 },
H Hartley Sweeten3e908892015-05-01 14:59:18 -0700346 [NISTC_AI_START_STOP_REG] = { 0x17c, 2 },
H Hartley Sweetenf8780712015-05-01 14:59:19 -0700347 [NISTC_AI_TRIG_SEL_REG] = { 0x17e, 2 },
H Hartley Sweetenaf5102a2015-05-01 14:59:20 -0700348 [NISTC_AI_DIV_LOADA_REG] = { 0x180, 4 },
H Hartley Sweeten2b6285da2015-05-01 14:59:21 -0700349 [NISTC_AO_START_SEL_REG] = { 0x184, 2 },
H Hartley Sweetenf21844d2015-05-01 14:59:22 -0700350 [NISTC_AO_TRIG_SEL_REG] = { 0x186, 2 },
H Hartley Sweeten38aba4c2015-05-01 14:59:23 -0700351 [NISTC_G0_AUTOINC_REG] = { 0x188, 2 },
352 [NISTC_G1_AUTOINC_REG] = { 0x18a, 2 },
H Hartley Sweeten72bca4f2015-05-01 14:59:24 -0700353 [NISTC_AO_MODE3_REG] = { 0x18c, 2 },
H Hartley Sweeten707502f2015-05-01 14:59:25 -0700354 [NISTC_RESET_REG] = { 0x190, 2 },
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -0700355 [NISTC_INTA_ENA_REG] = { 0x192, 2 },
H Hartley Sweetend84e9c32015-05-01 14:59:27 -0700356 [NISTC_INTA2_ENA_REG] = { 0, 0 }, /* E-Series only */
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -0700357 [NISTC_INTB_ENA_REG] = { 0x196, 2 },
H Hartley Sweeten04b68462015-05-01 14:59:29 -0700358 [NISTC_INTB2_ENA_REG] = { 0, 0 }, /* E-Series only */
H Hartley Sweetenc1b74032015-05-01 14:59:30 -0700359 [NISTC_AI_PERSONAL_REG] = { 0x19a, 2 },
H Hartley Sweeten63ff3f22015-05-01 14:59:31 -0700360 [NISTC_AO_PERSONAL_REG] = { 0x19c, 2 },
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -0700361 [NISTC_RTSI_TRIGA_OUT_REG] = { 0x19e, 2 },
362 [NISTC_RTSI_TRIGB_OUT_REG] = { 0x1a0, 2 },
H Hartley Sweeten24a11ba2015-05-01 14:59:33 -0700363 [NISTC_RTSI_BOARD_REG] = { 0, 0 }, /* Unknown */
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -0700364 [NISTC_CFG_MEM_CLR_REG] = { 0x1a4, 2 },
365 [NISTC_ADC_FIFO_CLR_REG] = { 0x1a6, 2 },
366 [NISTC_DAC_FIFO_CLR_REG] = { 0x1a8, 2 },
H Hartley Sweeten5bd1c722015-05-01 14:59:35 -0700367 [NISTC_AO_OUT_CTRL_REG] = { 0x1ac, 2 },
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -0700368 [NISTC_AI_MODE3_REG] = { 0x1ae, 2 },
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700369};
370
371static void m_series_stc_write(struct comedi_device *dev,
372 unsigned int data, unsigned int reg)
373{
374 const struct mio_regmap *regmap;
375
376 if (reg < ARRAY_SIZE(m_series_stc_write_regmap)) {
377 regmap = &m_series_stc_write_regmap[reg];
378 } else {
379 dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700380 __func__, reg);
381 return;
382 }
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700383
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700384 switch (regmap->size) {
385 case 4:
386 ni_writel(dev, data, regmap->mio_reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700387 break;
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700388 case 2:
389 ni_writew(dev, data, regmap->mio_reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700390 break;
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700391 default:
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700392 dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n",
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700393 __func__, reg);
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700394 break;
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700395 }
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700396}
397
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700398static const struct mio_regmap m_series_stc_read_regmap[] = {
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -0700399 [NISTC_AI_STATUS1_REG] = { 0x104, 2 },
H Hartley Sweetend123ee32015-05-01 14:59:38 -0700400 [NISTC_AO_STATUS1_REG] = { 0x106, 2 },
H Hartley Sweeten7f0e1ba2015-05-01 14:59:39 -0700401 [NISTC_G01_STATUS_REG] = { 0x108, 2 },
H Hartley Sweeten3ca18fe2015-05-01 14:59:40 -0700402 [NISTC_AI_STATUS2_REG] = { 0, 0 }, /* Unknown */
H Hartley Sweeten63b2bb02015-05-01 14:59:41 -0700403 [NISTC_AO_STATUS2_REG] = { 0x10c, 2 },
H Hartley Sweeten6f764a42015-05-01 14:59:42 -0700404 [NISTC_DIO_IN_REG] = { 0, 0 }, /* Unknown */
H Hartley Sweeten27650d92015-05-01 14:59:43 -0700405 [NISTC_G0_HW_SAVE_REG] = { 0x110, 4 },
406 [NISTC_G1_HW_SAVE_REG] = { 0x114, 4 },
H Hartley Sweetend9c41152015-05-01 14:59:44 -0700407 [NISTC_G0_SAVE_REG] = { 0x118, 4 },
408 [NISTC_G1_SAVE_REG] = { 0x11c, 4 },
H Hartley Sweeten2c090ac2015-05-01 14:59:45 -0700409 [NISTC_AO_UI_SAVE_REG] = { 0x120, 4 },
410 [NISTC_AO_BC_SAVE_REG] = { 0x124, 4 },
411 [NISTC_AO_UC_SAVE_REG] = { 0x128, 4 },
H Hartley Sweetend3fed082015-05-01 14:59:46 -0700412 [NISTC_STATUS1_REG] = { 0x136, 2 },
H Hartley Sweeten8fbb0152015-05-01 14:59:47 -0700413 [NISTC_DIO_SERIAL_IN_REG] = { 0x009, 1 },
H Hartley Sweetenbab382e2015-05-01 14:59:48 -0700414 [NISTC_STATUS2_REG] = { 0x13a, 2 },
H Hartley Sweeten549835c2015-05-01 14:59:49 -0700415 [NISTC_AI_SI_SAVE_REG] = { 0x180, 4 },
416 [NISTC_AI_SC_SAVE_REG] = { 0x184, 4 },
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700417};
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700418
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700419static unsigned int m_series_stc_read(struct comedi_device *dev,
420 unsigned int reg)
421{
422 const struct mio_regmap *regmap;
423
424 if (reg < ARRAY_SIZE(m_series_stc_read_regmap)) {
425 regmap = &m_series_stc_read_regmap[reg];
426 } else {
427 dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700428 __func__, reg);
429 return 0;
430 }
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700431
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700432 switch (regmap->size) {
433 case 4:
434 return ni_readl(dev, regmap->mio_reg);
435 case 2:
436 return ni_readw(dev, regmap->mio_reg);
437 case 1:
438 return ni_readb(dev, regmap->mio_reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700439 default:
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700440 dev_warn(dev->class_dev, "%s: unmapped register=0x%x\n",
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700441 __func__, reg);
442 return 0;
443 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700444}
445
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700446static void ni_stc_writew(struct comedi_device *dev,
447 unsigned int data, int reg)
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700448{
449 struct ni_private *devpriv = dev->private;
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700450 unsigned long flags;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700451
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700452 if (devpriv->is_m_series) {
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700453 m_series_stc_write(dev, data, reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700454 } else {
455 spin_lock_irqsave(&devpriv->window_lock, flags);
456 if (!devpriv->mite && reg < 8) {
457 ni_writew(dev, data, reg * 2);
458 } else {
H Hartley Sweeten4f809ff2015-05-01 14:59:51 -0700459 ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG);
460 ni_writew(dev, data, NI_E_STC_WINDOW_DATA_REG);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700461 }
462 spin_unlock_irqrestore(&devpriv->window_lock, flags);
463 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700464}
465
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700466static void ni_stc_writel(struct comedi_device *dev,
467 unsigned int data, int reg)
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700468{
469 struct ni_private *devpriv = dev->private;
470
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700471 if (devpriv->is_m_series) {
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700472 m_series_stc_write(dev, data, reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700473 } else {
474 ni_stc_writew(dev, data >> 16, reg);
475 ni_stc_writew(dev, data & 0xffff, reg + 1);
476 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700477}
478
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700479static unsigned int ni_stc_readw(struct comedi_device *dev, int reg)
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700480{
481 struct ni_private *devpriv = dev->private;
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700482 unsigned long flags;
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700483 unsigned int val;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700484
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700485 if (devpriv->is_m_series) {
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700486 val = m_series_stc_read(dev, reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700487 } else {
488 spin_lock_irqsave(&devpriv->window_lock, flags);
489 if (!devpriv->mite && reg < 8) {
490 val = ni_readw(dev, reg * 2);
491 } else {
H Hartley Sweeten4f809ff2015-05-01 14:59:51 -0700492 ni_writew(dev, reg, NI_E_STC_WINDOW_ADDR_REG);
493 val = ni_readw(dev, NI_E_STC_WINDOW_DATA_REG);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700494 }
495 spin_unlock_irqrestore(&devpriv->window_lock, flags);
496 }
497 return val;
498}
499
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700500static unsigned int ni_stc_readl(struct comedi_device *dev, int reg)
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700501{
502 struct ni_private *devpriv = dev->private;
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700503 unsigned int val;
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700504
505 if (devpriv->is_m_series) {
H Hartley Sweeten05dd0c92015-05-01 14:58:26 -0700506 val = m_series_stc_read(dev, reg);
H Hartley Sweetenb30f0d02014-06-19 10:20:37 -0700507 } else {
508 val = ni_stc_readw(dev, reg) << 16;
509 val |= ni_stc_readw(dev, reg + 1);
510 }
511 return val;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700512}
513
Bill Pembertonda91b262009-04-09 16:07:03 -0400514static inline void ni_set_bitfield(struct comedi_device *dev, int reg,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700515 unsigned int bit_mask,
516 unsigned int bit_values)
David Schleef03aef4b2009-02-17 17:04:22 -0800517{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700518 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800519 unsigned long flags;
520
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700521 spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800522 switch (reg) {
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -0700523 case NISTC_INTA_ENA_REG:
David Schleef03aef4b2009-02-17 17:04:22 -0800524 devpriv->int_a_enable_reg &= ~bit_mask;
525 devpriv->int_a_enable_reg |= bit_values & bit_mask;
H Hartley Sweetenf1618db2015-05-01 14:59:11 -0700526 ni_stc_writew(dev, devpriv->int_a_enable_reg, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800527 break;
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -0700528 case NISTC_INTB_ENA_REG:
David Schleef03aef4b2009-02-17 17:04:22 -0800529 devpriv->int_b_enable_reg &= ~bit_mask;
530 devpriv->int_b_enable_reg |= bit_values & bit_mask;
H Hartley Sweetenf1618db2015-05-01 14:59:11 -0700531 ni_stc_writew(dev, devpriv->int_b_enable_reg, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800532 break;
H Hartley Sweeten5ecadf82015-05-01 14:59:12 -0700533 case NISTC_IO_BIDIR_PIN_REG:
David Schleef03aef4b2009-02-17 17:04:22 -0800534 devpriv->io_bidirection_pin_reg &= ~bit_mask;
535 devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
H Hartley Sweetenf1618db2015-05-01 14:59:11 -0700536 ni_stc_writew(dev, devpriv->io_bidirection_pin_reg, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800537 break;
H Hartley Sweetena4b7ef92015-05-01 15:00:03 -0700538 case NI_E_DMA_AI_AO_SEL_REG:
David Schleef03aef4b2009-02-17 17:04:22 -0800539 devpriv->ai_ao_select_reg &= ~bit_mask;
540 devpriv->ai_ao_select_reg |= bit_values & bit_mask;
H Hartley Sweetenf1618db2015-05-01 14:59:11 -0700541 ni_writeb(dev, devpriv->ai_ao_select_reg, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800542 break;
H Hartley Sweeten7d6f3aa2015-05-01 15:00:04 -0700543 case NI_E_DMA_G0_G1_SEL_REG:
David Schleef03aef4b2009-02-17 17:04:22 -0800544 devpriv->g0_g1_select_reg &= ~bit_mask;
545 devpriv->g0_g1_select_reg |= bit_values & bit_mask;
H Hartley Sweetenf1618db2015-05-01 14:59:11 -0700546 ni_writeb(dev, devpriv->g0_g1_select_reg, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800547 break;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700548 case NI_M_CDIO_DMA_SEL_REG:
549 devpriv->cdio_dma_select_reg &= ~bit_mask;
550 devpriv->cdio_dma_select_reg |= bit_values & bit_mask;
551 ni_writeb(dev, devpriv->cdio_dma_select_reg, reg);
552 break;
David Schleef03aef4b2009-02-17 17:04:22 -0800553 default:
Haneen Mohammedce824102015-03-06 22:01:38 +0300554 dev_err(dev->class_dev, "called with invalid register %d\n",
555 reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800556 break;
557 }
558 mmiowb();
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700559 spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800560}
561
562#ifdef PCIDMA
David Schleef03aef4b2009-02-17 17:04:22 -0800563
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700564/* selects the MITE channel to use for DMA */
565#define NI_STC_DMA_CHAN_SEL(x) (((x) < 4) ? BIT(x) : \
566 ((x) == 4) ? 0x3 : \
567 ((x) == 5) ? 0x5 : 0x0)
568
569/* DMA channel setup */
Bill Pembertonda91b262009-04-09 16:07:03 -0400570static int ni_request_ai_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800571{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700572 struct ni_private *devpriv = dev->private;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700573 struct mite_channel *mite_chan;
David Schleef03aef4b2009-02-17 17:04:22 -0800574 unsigned long flags;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700575 unsigned int bits;
David Schleef03aef4b2009-02-17 17:04:22 -0800576
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700577 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700578 mite_chan = mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
579 if (!mite_chan) {
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530580 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700581 dev_err(dev->class_dev,
582 "failed to reserve mite dma channel for analog input\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800583 return -EBUSY;
584 }
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700585 mite_chan->dir = COMEDI_INPUT;
586 devpriv->ai_mite_chan = mite_chan;
587
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700588 bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700589 ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
590 NI_E_DMA_AI_SEL_MASK, NI_E_DMA_AI_SEL(bits));
591
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700592 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800593 return 0;
594}
595
Bill Pembertonda91b262009-04-09 16:07:03 -0400596static int ni_request_ao_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800597{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700598 struct ni_private *devpriv = dev->private;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700599 struct mite_channel *mite_chan;
David Schleef03aef4b2009-02-17 17:04:22 -0800600 unsigned long flags;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700601 unsigned int bits;
David Schleef03aef4b2009-02-17 17:04:22 -0800602
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700603 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700604 mite_chan = mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
605 if (!mite_chan) {
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530606 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700607 dev_err(dev->class_dev,
608 "failed to reserve mite dma channel for analog outut\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800609 return -EBUSY;
610 }
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700611 mite_chan->dir = COMEDI_OUTPUT;
612 devpriv->ao_mite_chan = mite_chan;
613
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700614 bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700615 ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
616 NI_E_DMA_AO_SEL_MASK, NI_E_DMA_AO_SEL(bits));
617
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700618 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800619 return 0;
620}
621
Bill Pembertonda91b262009-04-09 16:07:03 -0400622static int ni_request_gpct_mite_channel(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700623 unsigned int gpct_index,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530624 enum comedi_io_direction direction)
David Schleef03aef4b2009-02-17 17:04:22 -0800625{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700626 struct ni_private *devpriv = dev->private;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700627 struct ni_gpct *counter = &devpriv->counter_dev->counters[gpct_index];
David Schleef03aef4b2009-02-17 17:04:22 -0800628 struct mite_channel *mite_chan;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700629 unsigned long flags;
630 unsigned int bits;
David Schleef03aef4b2009-02-17 17:04:22 -0800631
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700632 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700633 mite_chan = mite_request_channel(devpriv->mite,
634 devpriv->gpct_mite_ring[gpct_index]);
H Hartley Sweetenc6be1542015-03-04 12:15:40 -0700635 if (!mite_chan) {
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530636 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700637 dev_err(dev->class_dev,
638 "failed to reserve mite dma channel for counter\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800639 return -EBUSY;
640 }
641 mite_chan->dir = direction;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700642 ni_tio_set_mite_channel(counter, mite_chan);
643
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700644 bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700645 ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
646 NI_E_DMA_G0_G1_SEL_MASK(gpct_index),
647 NI_E_DMA_G0_G1_SEL(gpct_index, bits));
648
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700649 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800650 return 0;
651}
652
Bill Pembertonda91b262009-04-09 16:07:03 -0400653static int ni_request_cdo_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800654{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700655 struct ni_private *devpriv = dev->private;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700656 struct mite_channel *mite_chan;
David Schleef03aef4b2009-02-17 17:04:22 -0800657 unsigned long flags;
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700658 unsigned int bits;
David Schleef03aef4b2009-02-17 17:04:22 -0800659
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700660 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700661 mite_chan = mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
662 if (!mite_chan) {
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530663 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700664 dev_err(dev->class_dev,
665 "failed to reserve mite dma channel for correlated digital output\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800666 return -EBUSY;
667 }
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700668 mite_chan->dir = COMEDI_OUTPUT;
669 devpriv->cdo_mite_chan = mite_chan;
670
671 /*
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700672 * XXX just guessing NI_STC_DMA_CHAN_SEL()
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700673 * returns the right bits, under the assumption the cdio dma
674 * selection works just like ai/ao/gpct.
675 * Definitely works for dma channels 0 and 1.
676 */
H Hartley Sweeten6f7fa702016-04-14 09:58:07 -0700677 bits = NI_STC_DMA_CHAN_SEL(mite_chan->channel);
H Hartley Sweeten38b81a72016-04-14 09:57:50 -0700678 ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
679 NI_M_CDIO_DMA_SEL_CDO_MASK,
680 NI_M_CDIO_DMA_SEL_CDO(bits));
681
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700682 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800683 return 0;
684}
H Hartley Sweetencf122bb2016-04-14 09:57:52 -0700685#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -0800686
Bill Pembertonda91b262009-04-09 16:07:03 -0400687static void ni_release_ai_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800688{
689#ifdef PCIDMA
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700690 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800691 unsigned long flags;
692
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700693 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800694 if (devpriv->ai_mite_chan) {
H Hartley Sweetenb7cd3f62016-04-14 09:57:51 -0700695 ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
696 NI_E_DMA_AI_SEL_MASK, 0);
David Schleef03aef4b2009-02-17 17:04:22 -0800697 mite_release_channel(devpriv->ai_mite_chan);
698 devpriv->ai_mite_chan = NULL;
699 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700700 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
Bill Pemberton2696fb52009-03-27 11:29:34 -0400701#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -0800702}
703
Bill Pembertonda91b262009-04-09 16:07:03 -0400704static void ni_release_ao_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800705{
706#ifdef PCIDMA
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700707 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800708 unsigned long flags;
709
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700710 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800711 if (devpriv->ao_mite_chan) {
H Hartley Sweetenb7cd3f62016-04-14 09:57:51 -0700712 ni_set_bitfield(dev, NI_E_DMA_AI_AO_SEL_REG,
713 NI_E_DMA_AO_SEL_MASK, 0);
David Schleef03aef4b2009-02-17 17:04:22 -0800714 mite_release_channel(devpriv->ao_mite_chan);
715 devpriv->ao_mite_chan = NULL;
716 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700717 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
Bill Pemberton2696fb52009-03-27 11:29:34 -0400718#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -0800719}
720
David Schleef03aef4b2009-02-17 17:04:22 -0800721#ifdef PCIDMA
H Hartley Sweeten29aba7632012-09-17 13:13:32 -0700722static void ni_release_gpct_mite_channel(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700723 unsigned int gpct_index)
H Hartley Sweeten29aba7632012-09-17 13:13:32 -0700724{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700725 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800726 unsigned long flags;
727
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700728 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800729 if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
730 struct mite_channel *mite_chan =
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530731 devpriv->counter_dev->counters[gpct_index].mite_chan;
David Schleef03aef4b2009-02-17 17:04:22 -0800732
H Hartley Sweetenb7cd3f62016-04-14 09:57:51 -0700733 ni_set_bitfield(dev, NI_E_DMA_G0_G1_SEL_REG,
734 NI_E_DMA_G0_G1_SEL_MASK(gpct_index), 0);
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530735 ni_tio_set_mite_channel(&devpriv->
736 counter_dev->counters[gpct_index],
737 NULL);
David Schleef03aef4b2009-02-17 17:04:22 -0800738 mite_release_channel(mite_chan);
739 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700740 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800741}
742
Bill Pembertonda91b262009-04-09 16:07:03 -0400743static void ni_release_cdo_mite_channel(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800744{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700745 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800746 unsigned long flags;
747
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700748 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800749 if (devpriv->cdo_mite_chan) {
H Hartley Sweetenb7cd3f62016-04-14 09:57:51 -0700750 ni_set_bitfield(dev, NI_M_CDIO_DMA_SEL_REG,
751 NI_M_CDIO_DMA_SEL_CDO_MASK, 0);
David Schleef03aef4b2009-02-17 17:04:22 -0800752 mite_release_channel(devpriv->cdo_mite_chan);
753 devpriv->cdo_mite_chan = NULL;
754 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700755 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800756}
757
Bill Pembertonda91b262009-04-09 16:07:03 -0400758static void ni_e_series_enable_second_irq(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700759 unsigned int gpct_index, short enable)
David Schleef03aef4b2009-02-17 17:04:22 -0800760{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700761 struct ni_private *devpriv = dev->private;
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700762 unsigned int val = 0;
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700763 int reg;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700764
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700765 if (devpriv->is_m_series || gpct_index > 1)
David Schleef03aef4b2009-02-17 17:04:22 -0800766 return;
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700767
768 /*
769 * e-series boards use the second irq signals to generate
770 * dma requests for their counters
771 */
772 if (gpct_index == 0) {
H Hartley Sweetend84e9c32015-05-01 14:59:27 -0700773 reg = NISTC_INTA2_ENA_REG;
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700774 if (enable)
H Hartley Sweetend84e9c32015-05-01 14:59:27 -0700775 val = NISTC_INTA_ENA_G0_GATE;
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700776 } else {
H Hartley Sweeten04b68462015-05-01 14:59:29 -0700777 reg = NISTC_INTB2_ENA_REG;
H Hartley Sweeten5f315522014-06-19 10:20:33 -0700778 if (enable)
H Hartley Sweeten04b68462015-05-01 14:59:29 -0700779 val = NISTC_INTB_ENA_G1_GATE;
David Schleef03aef4b2009-02-17 17:04:22 -0800780 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -0700781 ni_stc_writew(dev, val, reg);
David Schleef03aef4b2009-02-17 17:04:22 -0800782}
Bill Pemberton2696fb52009-03-27 11:29:34 -0400783#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -0800784
Bill Pembertonda91b262009-04-09 16:07:03 -0400785static void ni_clear_ai_fifo(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800786{
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700787 struct ni_private *devpriv = dev->private;
Chase Southwood60738f62014-01-16 12:27:29 -0600788 static const int timeout = 10000;
789 int i;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700790
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700791 if (devpriv->is_6143) {
Bill Pemberton2696fb52009-03-27 11:29:34 -0400792 /* Flush the 6143 data FIFO */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -0700793 ni_writel(dev, 0x10, NI6143_AI_FIFO_CTRL_REG);
794 ni_writel(dev, 0x00, NI6143_AI_FIFO_CTRL_REG);
Chase Southwood60738f62014-01-16 12:27:29 -0600795 /* Wait for complete */
796 for (i = 0; i < timeout; i++) {
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -0700797 if (!(ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x10))
Chase Southwood60738f62014-01-16 12:27:29 -0600798 break;
799 udelay(1);
800 }
H Hartley Sweetena6266972014-07-16 11:22:56 -0700801 if (i == timeout)
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700802 dev_err(dev->class_dev, "FIFO flush timeout\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800803 } else {
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -0700804 ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700805 if (devpriv->is_625x) {
H Hartley Sweeten975b6d22015-05-01 14:58:34 -0700806 ni_writeb(dev, 0, NI_M_STATIC_AI_CTRL_REG(0));
807 ni_writeb(dev, 1, NI_M_STATIC_AI_CTRL_REG(0));
David Schleef03aef4b2009-02-17 17:04:22 -0800808#if 0
H Hartley Sweetenbd474a02016-04-14 09:57:55 -0700809 /*
810 * The NI example code does 3 convert pulses for 625x
811 * boards, But that appears to be wrong in practice.
812 */
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -0700813 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
814 NISTC_AI_CMD1_REG);
815 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
816 NISTC_AI_CMD1_REG);
817 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
818 NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -0800819#endif
820 }
821 }
822}
823
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700824static inline void ni_ao_win_outw(struct comedi_device *dev,
825 unsigned int data, int addr)
David Schleef03aef4b2009-02-17 17:04:22 -0800826{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700827 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800828 unsigned long flags;
829
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700830 spin_lock_irqsave(&devpriv->window_lock, flags);
H Hartley Sweeten0418da52015-05-01 15:00:07 -0700831 ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
832 ni_writew(dev, data, NI611X_AO_WINDOW_DATA_REG);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700833 spin_unlock_irqrestore(&devpriv->window_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800834}
835
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700836static inline void ni_ao_win_outl(struct comedi_device *dev,
837 unsigned int data, int addr)
David Schleef03aef4b2009-02-17 17:04:22 -0800838{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700839 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800840 unsigned long flags;
841
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700842 spin_lock_irqsave(&devpriv->window_lock, flags);
H Hartley Sweeten0418da52015-05-01 15:00:07 -0700843 ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
844 ni_writel(dev, data, NI611X_AO_WINDOW_DATA_REG);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700845 spin_unlock_irqrestore(&devpriv->window_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800846}
847
Bill Pembertonda91b262009-04-09 16:07:03 -0400848static inline unsigned short ni_ao_win_inw(struct comedi_device *dev, int addr)
David Schleef03aef4b2009-02-17 17:04:22 -0800849{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700850 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -0800851 unsigned long flags;
852 unsigned short data;
853
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700854 spin_lock_irqsave(&devpriv->window_lock, flags);
H Hartley Sweeten0418da52015-05-01 15:00:07 -0700855 ni_writew(dev, addr, NI611X_AO_WINDOW_ADDR_REG);
856 data = ni_readw(dev, NI611X_AO_WINDOW_DATA_REG);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700857 spin_unlock_irqrestore(&devpriv->window_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800858 return data;
859}
860
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -0700861/*
862 * ni_set_bits( ) allows different parts of the ni_mio_common driver to
863 * share registers (such as Interrupt_A_Register) without interfering with
864 * each other.
865 *
866 * NOTE: the switch/case statements are optimized out for a constant argument
867 * so this is actually quite fast--- If you must wrap another function around
868 * this make it inline to avoid a large speed penalty.
869 *
870 * value should only be 1 or 0.
871 */
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +0530872static inline void ni_set_bits(struct comedi_device *dev, int reg,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700873 unsigned int bits, unsigned int value)
David Schleef03aef4b2009-02-17 17:04:22 -0800874{
H Hartley Sweetenfe20a342016-04-14 09:57:53 -0700875 unsigned int bit_values;
David Schleef03aef4b2009-02-17 17:04:22 -0800876
877 if (value)
878 bit_values = bits;
879 else
880 bit_values = 0;
881 ni_set_bitfield(dev, reg, bits, bit_values);
882}
883
David Schleef03aef4b2009-02-17 17:04:22 -0800884#ifdef PCIDMA
Bill Pembertonda91b262009-04-09 16:07:03 -0400885static void ni_sync_ai_dma(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800886{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -0700887 struct ni_private *devpriv = dev->private;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -0700888 struct comedi_subdevice *s = dev->read_subdev;
David Schleef03aef4b2009-02-17 17:04:22 -0800889 unsigned long flags;
890
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700891 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800892 if (devpriv->ai_mite_chan)
H Hartley Sweeten51d43002016-04-20 10:36:39 -0700893 mite_sync_dma(devpriv->ai_mite_chan, s);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -0700894 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -0800895}
896
H Hartley Sweeten2655c8a2014-05-28 16:26:41 -0700897static int ni_ai_drain_dma(struct comedi_device *dev)
898{
899 struct ni_private *devpriv = dev->private;
900 int i;
901 static const int timeout = 10000;
902 unsigned long flags;
903 int retval = 0;
904
905 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
906 if (devpriv->ai_mite_chan) {
907 for (i = 0; i < timeout; i++) {
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -0700908 if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
H Hartley Sweeten73894982016-04-14 09:57:58 -0700909 NISTC_AI_STATUS1_FIFO_E) &&
910 mite_bytes_in_transit(devpriv->ai_mite_chan) == 0)
H Hartley Sweeten2655c8a2014-05-28 16:26:41 -0700911 break;
912 udelay(5);
913 }
914 if (i == timeout) {
Haneen Mohammedcd255032015-03-05 13:01:49 +0300915 dev_err(dev->class_dev, "timed out\n");
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -0700916 dev_err(dev->class_dev,
917 "mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
918 mite_bytes_in_transit(devpriv->ai_mite_chan),
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -0700919 ni_stc_readw(dev, NISTC_AI_STATUS1_REG));
H Hartley Sweeten2655c8a2014-05-28 16:26:41 -0700920 retval = -1;
921 }
922 }
923 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
924
925 ni_sync_ai_dma(dev);
926
927 return retval;
928}
929
Bill Pembertonda91b262009-04-09 16:07:03 -0400930static int ni_ao_wait_for_dma_load(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -0800931{
932 static const int timeout = 10000;
933 int i;
H Hartley Sweetenf7401972014-07-16 11:02:08 -0700934
David Schleef03aef4b2009-02-17 17:04:22 -0800935 for (i = 0; i < timeout; i++) {
936 unsigned short b_status;
937
H Hartley Sweetend123ee32015-05-01 14:59:38 -0700938 b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG);
939 if (b_status & NISTC_AO_STATUS1_FIFO_HF)
David Schleef03aef4b2009-02-17 17:04:22 -0800940 break;
H Hartley Sweetenbd474a02016-04-14 09:57:55 -0700941 /*
942 * If we poll too often, the pci bus activity seems
943 * to slow the dma transfer down.
944 */
H Hartley Sweeten8a5b8172016-04-14 09:58:03 -0700945 usleep_range(10, 100);
David Schleef03aef4b2009-02-17 17:04:22 -0800946 }
947 if (i == timeout) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -0700948 dev_err(dev->class_dev, "timed out waiting for dma load\n");
David Schleef03aef4b2009-02-17 17:04:22 -0800949 return -EPIPE;
950 }
951 return 0;
952}
Bill Pemberton2696fb52009-03-27 11:29:34 -0400953#endif /* PCIDMA */
H Hartley Sweetenf8246df2014-05-28 16:26:37 -0700954
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700955#ifndef PCIDMA
956
957static void ni_ao_fifo_load(struct comedi_device *dev,
958 struct comedi_subdevice *s, int n)
959{
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700960 struct ni_private *devpriv = dev->private;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700961 int i;
962 unsigned short d;
H Hartley Sweeten546615f2016-04-14 09:57:54 -0700963 unsigned int packed_data;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700964
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700965 for (i = 0; i < n; i++) {
H Hartley Sweetene14c6a62014-10-22 14:36:43 -0700966 comedi_buf_read_samples(s, &d, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700967
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700968 if (devpriv->is_6xxx) {
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700969 packed_data = d & 0xffff;
970 /* 6711 only has 16 bit wide ao fifo */
H Hartley Sweetena52b53e2014-07-14 12:23:44 -0700971 if (!devpriv->is_6711) {
H Hartley Sweetene14c6a62014-10-22 14:36:43 -0700972 comedi_buf_read_samples(s, &d, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700973 i++;
974 packed_data |= (d << 16) & 0xffff0000;
975 }
H Hartley Sweeten0418da52015-05-01 15:00:07 -0700976 ni_writel(dev, packed_data, NI611X_AO_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700977 } else {
H Hartley Sweeten9e0ad6f2015-05-01 15:00:00 -0700978 ni_writew(dev, d, NI_E_AO_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700979 }
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700980 }
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -0700981}
982
983/*
984 * There's a small problem if the FIFO gets really low and we
985 * don't have the data to fill it. Basically, if after we fill
986 * the FIFO with all the data available, the FIFO is _still_
987 * less than half full, we never clear the interrupt. If the
988 * IRQ is in edge mode, we never get another interrupt, because
989 * this one wasn't cleared. If in level mode, we get flooded
990 * with interrupts that we can't fulfill, because nothing ever
991 * gets put into the buffer.
992 *
993 * This kind of situation is recoverable, but it is easier to
994 * just pretend we had a FIFO underrun, since there is a good
995 * chance it will happen anyway. This is _not_ the case for
996 * RT code, as RT code might purposely be running close to the
997 * metal. Needs to be fixed eventually.
998 */
999static int ni_ao_fifo_half_empty(struct comedi_device *dev,
1000 struct comedi_subdevice *s)
1001{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001002 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001003 unsigned int nbytes;
1004 unsigned int nsamples;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001005
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001006 nbytes = comedi_buf_read_n_available(s);
1007 if (nbytes == 0) {
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001008 s->async->events |= COMEDI_CB_OVERFLOW;
1009 return 0;
1010 }
1011
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001012 nsamples = comedi_bytes_to_samples(s, nbytes);
1013 if (nsamples > board->ao_fifo_depth / 2)
1014 nsamples = board->ao_fifo_depth / 2;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001015
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001016 ni_ao_fifo_load(dev, s, nsamples);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001017
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001018 return 1;
1019}
1020
1021static int ni_ao_prep_fifo(struct comedi_device *dev,
1022 struct comedi_subdevice *s)
1023{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001024 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001025 struct ni_private *devpriv = dev->private;
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001026 unsigned int nbytes;
1027 unsigned int nsamples;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001028
1029 /* reset fifo */
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -07001030 ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001031 if (devpriv->is_6xxx)
H Hartley Sweetenef391542015-05-01 15:00:11 -07001032 ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001033
1034 /* load some data */
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001035 nbytes = comedi_buf_read_n_available(s);
1036 if (nbytes == 0)
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001037 return 0;
1038
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001039 nsamples = comedi_bytes_to_samples(s, nbytes);
1040 if (nsamples > board->ao_fifo_depth)
1041 nsamples = board->ao_fifo_depth;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001042
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001043 ni_ao_fifo_load(dev, s, nsamples);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001044
H Hartley Sweeten836b5712014-10-31 12:04:29 -07001045 return nsamples;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001046}
1047
1048static void ni_ai_fifo_read(struct comedi_device *dev,
1049 struct comedi_subdevice *s, int n)
1050{
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001051 struct ni_private *devpriv = dev->private;
1052 struct comedi_async *async = s->async;
H Hartley Sweeten546615f2016-04-14 09:57:54 -07001053 unsigned int dl;
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001054 unsigned short data;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001055 int i;
1056
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001057 if (devpriv->is_611x) {
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001058 for (i = 0; i < n / 2; i++) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001059 dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001060 /* This may get the hi/lo data in the wrong order */
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001061 data = (dl >> 16) & 0xffff;
1062 comedi_buf_write_samples(s, &data, 1);
1063 data = dl & 0xffff;
1064 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001065 }
1066 /* Check if there's a single sample stuck in the FIFO */
1067 if (n % 2) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001068 dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001069 data = dl & 0xffff;
1070 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001071 }
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001072 } else if (devpriv->is_6143) {
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001073 /*
1074 * This just reads the FIFO assuming the data is present,
1075 * no checks on the FIFO status are performed.
1076 */
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001077 for (i = 0; i < n / 2; i++) {
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001078 dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001079
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001080 data = (dl >> 16) & 0xffff;
1081 comedi_buf_write_samples(s, &data, 1);
1082 data = dl & 0xffff;
1083 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001084 }
1085 if (n % 2) {
1086 /* Assume there is a single sample stuck in the FIFO */
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001087 /* Get stranded sample into FIFO */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001088 ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
1089 dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001090 data = (dl >> 16) & 0xffff;
1091 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001092 }
1093 } else {
Janani Ravichandrane5636372016-02-11 19:07:48 -05001094 if (n > ARRAY_SIZE(devpriv->ai_fifo_buffer)) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07001095 dev_err(dev->class_dev,
1096 "bug! ai_fifo_buffer too small\n");
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001097 async->events |= COMEDI_CB_ERROR;
1098 return;
1099 }
1100 for (i = 0; i < n; i++) {
1101 devpriv->ai_fifo_buffer[i] =
H Hartley Sweeten363f5702015-05-01 14:59:56 -07001102 ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001103 }
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001104 comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, n);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001105 }
1106}
1107
1108static void ni_handle_fifo_half_full(struct comedi_device *dev)
1109{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001110 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001111 struct comedi_subdevice *s = dev->read_subdev;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001112 int n;
1113
1114 n = board->ai_fifo_depth / 2;
1115
1116 ni_ai_fifo_read(dev, s, n);
1117}
1118#endif
1119
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07001120/* Empties the AI fifo */
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001121static void ni_handle_fifo_dregs(struct comedi_device *dev)
1122{
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001123 struct ni_private *devpriv = dev->private;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001124 struct comedi_subdevice *s = dev->read_subdev;
H Hartley Sweeten546615f2016-04-14 09:57:54 -07001125 unsigned int dl;
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001126 unsigned short data;
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001127 int i;
1128
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001129 if (devpriv->is_611x) {
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001130 while ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1131 NISTC_AI_STATUS1_FIFO_E) == 0) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001132 dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001133
1134 /* This may get the hi/lo data in the wrong order */
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001135 data = dl >> 16;
1136 comedi_buf_write_samples(s, &data, 1);
1137 data = dl & 0xffff;
1138 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001139 }
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001140 } else if (devpriv->is_6143) {
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001141 i = 0;
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001142 while (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x04) {
1143 dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001144
1145 /* This may get the hi/lo data in the wrong order */
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001146 data = dl >> 16;
1147 comedi_buf_write_samples(s, &data, 1);
1148 data = dl & 0xffff;
1149 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001150 i += 2;
1151 }
1152 /* Check if stranded sample is present */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001153 if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) {
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001154 /* Get stranded sample into FIFO */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001155 ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
1156 dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001157 data = (dl >> 16) & 0xffff;
1158 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001159 }
1160
1161 } else {
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001162 unsigned short fe; /* fifo empty */
1163
1164 fe = ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1165 NISTC_AI_STATUS1_FIFO_E;
1166 while (fe == 0) {
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001167 for (i = 0;
Janani Ravichandrane5636372016-02-11 19:07:48 -05001168 i < ARRAY_SIZE(devpriv->ai_fifo_buffer); i++) {
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001169 fe = ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1170 NISTC_AI_STATUS1_FIFO_E;
1171 if (fe)
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001172 break;
1173 devpriv->ai_fifo_buffer[i] =
H Hartley Sweeten363f5702015-05-01 14:59:56 -07001174 ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001175 }
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001176 comedi_buf_write_samples(s, devpriv->ai_fifo_buffer, i);
H Hartley Sweeten2ffb2472014-05-28 16:26:47 -07001177 }
1178 }
1179}
1180
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001181static void get_last_sample_611x(struct comedi_device *dev)
1182{
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001183 struct ni_private *devpriv = dev->private;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001184 struct comedi_subdevice *s = dev->read_subdev;
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001185 unsigned short data;
H Hartley Sweeten546615f2016-04-14 09:57:54 -07001186 unsigned int dl;
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001187
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001188 if (!devpriv->is_611x)
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001189 return;
1190
1191 /* Check if there's a single sample stuck in the FIFO */
H Hartley Sweeten906170b2015-05-01 14:59:52 -07001192 if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001193 dl = ni_readl(dev, NI611X_AI_FIFO_DATA_REG);
Haneen Mohammedf0dff422015-03-13 14:29:30 +03001194 data = dl & 0xffff;
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001195 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001196 }
1197}
1198
1199static void get_last_sample_6143(struct comedi_device *dev)
1200{
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001201 struct ni_private *devpriv = dev->private;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001202 struct comedi_subdevice *s = dev->read_subdev;
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001203 unsigned short data;
H Hartley Sweeten546615f2016-04-14 09:57:54 -07001204 unsigned int dl;
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001205
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001206 if (!devpriv->is_6143)
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001207 return;
1208
1209 /* Check if there's a single sample stuck in the FIFO */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001210 if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) & 0x01) {
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001211 /* Get stranded sample into FIFO */
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001212 ni_writel(dev, 0x01, NI6143_AI_FIFO_CTRL_REG);
1213 dl = ni_readl(dev, NI6143_AI_FIFO_DATA_REG);
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001214
1215 /* This may get the hi/lo data in the wrong order */
1216 data = (dl >> 16) & 0xffff;
H Hartley Sweeten9caba322014-10-22 15:36:36 -07001217 comedi_buf_write_samples(s, &data, 1);
H Hartley Sweetenf8f6d912014-05-28 16:26:40 -07001218 }
1219}
1220
H Hartley Sweetenf8246df2014-05-28 16:26:37 -07001221static void shutdown_ai_command(struct comedi_device *dev)
1222{
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001223 struct comedi_subdevice *s = dev->read_subdev;
H Hartley Sweetenf8246df2014-05-28 16:26:37 -07001224
1225#ifdef PCIDMA
1226 ni_ai_drain_dma(dev);
1227#endif
1228 ni_handle_fifo_dregs(dev);
1229 get_last_sample_611x(dev);
1230 get_last_sample_6143(dev);
1231
1232 s->async->events |= COMEDI_CB_EOA;
1233}
1234
Bill Pembertonda91b262009-04-09 16:07:03 -04001235static void ni_handle_eos(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08001236{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001237 struct ni_private *devpriv = dev->private;
1238
David Schleef03aef4b2009-02-17 17:04:22 -08001239 if (devpriv->aimode == AIMODE_SCAN) {
1240#ifdef PCIDMA
1241 static const int timeout = 10;
1242 int i;
1243
1244 for (i = 0; i < timeout; i++) {
1245 ni_sync_ai_dma(dev);
1246 if ((s->async->events & COMEDI_CB_EOS))
1247 break;
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001248 udelay(1);
David Schleef03aef4b2009-02-17 17:04:22 -08001249 }
1250#else
1251 ni_handle_fifo_dregs(dev);
1252 s->async->events |= COMEDI_CB_EOS;
1253#endif
1254 }
H Hartley Sweetena1da35a2015-05-01 14:58:56 -07001255 /* handle special case of single scan */
1256 if (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS)
David Schleef03aef4b2009-02-17 17:04:22 -08001257 shutdown_ai_command(dev);
David Schleef03aef4b2009-02-17 17:04:22 -08001258}
1259
Bill Pembertonda91b262009-04-09 16:07:03 -04001260static void handle_gpct_interrupt(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301261 unsigned short counter_index)
David Schleef03aef4b2009-02-17 17:04:22 -08001262{
1263#ifdef PCIDMA
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001264 struct ni_private *devpriv = dev->private;
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07001265 struct comedi_subdevice *s;
1266
1267 s = &dev->subdevices[NI_GPCT_SUBDEV(counter_index)];
David Schleef03aef4b2009-02-17 17:04:22 -08001268
1269 ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301270 s);
H Hartley Sweetenb9a69a12014-09-18 11:11:30 -07001271 comedi_handle_events(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08001272#endif
1273}
1274
Bill Pembertonda91b262009-04-09 16:07:03 -04001275static void ack_a_interrupt(struct comedi_device *dev, unsigned short a_status)
David Schleef03aef4b2009-02-17 17:04:22 -08001276{
1277 unsigned short ack = 0;
1278
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001279 if (a_status & NISTC_AI_STATUS1_SC_TC)
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001280 ack |= NISTC_INTA_ACK_AI_SC_TC;
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001281 if (a_status & NISTC_AI_STATUS1_START1)
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001282 ack |= NISTC_INTA_ACK_AI_START1;
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001283 if (a_status & NISTC_AI_STATUS1_START)
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001284 ack |= NISTC_INTA_ACK_AI_START;
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001285 if (a_status & NISTC_AI_STATUS1_STOP)
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001286 ack |= NISTC_INTA_ACK_AI_STOP;
David Schleef03aef4b2009-02-17 17:04:22 -08001287 if (ack)
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001288 ni_stc_writew(dev, ack, NISTC_INTA_ACK_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001289}
1290
H Hartley Sweetenba5c0da2016-04-21 12:04:41 -07001291static void handle_a_interrupt(struct comedi_device *dev,
1292 struct comedi_subdevice *s,
H Hartley Sweeten3da088c2016-04-21 12:04:43 -07001293 unsigned short status)
David Schleef03aef4b2009-02-17 17:04:22 -08001294{
H Hartley Sweeten93fac792014-07-14 12:23:49 -07001295 struct comedi_cmd *cmd = &s->async->cmd;
David Schleef03aef4b2009-02-17 17:04:22 -08001296
David Schleef03aef4b2009-02-17 17:04:22 -08001297 /* test for all uncommon interrupt events at the same time */
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001298 if (status & (NISTC_AI_STATUS1_ERR |
1299 NISTC_AI_STATUS1_SC_TC | NISTC_AI_STATUS1_START1)) {
David Schleef03aef4b2009-02-17 17:04:22 -08001300 if (status == 0xffff) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07001301 dev_err(dev->class_dev, "Card removed?\n");
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07001302 /*
1303 * We probably aren't even running a command now,
1304 * so it's a good idea to be careful.
1305 */
H Hartley Sweeten3da088c2016-04-21 12:04:43 -07001306 if (comedi_is_subdevice_running(s))
H Hartley Sweeten3e6cb742015-01-20 12:06:02 -07001307 s->async->events |= COMEDI_CB_ERROR;
David Schleef03aef4b2009-02-17 17:04:22 -08001308 return;
1309 }
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001310 if (status & NISTC_AI_STATUS1_ERR) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07001311 dev_err(dev->class_dev, "ai error a_status=%04x\n",
1312 status);
David Schleef03aef4b2009-02-17 17:04:22 -08001313
1314 shutdown_ai_command(dev);
1315
1316 s->async->events |= COMEDI_CB_ERROR;
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001317 if (status & NISTC_AI_STATUS1_OVER)
David Schleef03aef4b2009-02-17 17:04:22 -08001318 s->async->events |= COMEDI_CB_OVERFLOW;
David Schleef03aef4b2009-02-17 17:04:22 -08001319 return;
1320 }
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001321 if (status & NISTC_AI_STATUS1_SC_TC) {
H Hartley Sweeten93fac792014-07-14 12:23:49 -07001322 if (cmd->stop_src == TRIG_COUNT)
David Schleef03aef4b2009-02-17 17:04:22 -08001323 shutdown_ai_command(dev);
David Schleef03aef4b2009-02-17 17:04:22 -08001324 }
1325 }
1326#ifndef PCIDMA
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001327 if (status & NISTC_AI_STATUS1_FIFO_HF) {
David Schleef03aef4b2009-02-17 17:04:22 -08001328 int i;
1329 static const int timeout = 10;
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07001330 /*
1331 * PCMCIA cards (at least 6036) seem to stop producing
1332 * interrupts if we fail to get the fifo less than half
1333 * full, so loop to be sure.
1334 */
David Schleef03aef4b2009-02-17 17:04:22 -08001335 for (i = 0; i < timeout; ++i) {
1336 ni_handle_fifo_half_full(dev);
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001337 if ((ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1338 NISTC_AI_STATUS1_FIFO_HF) == 0)
David Schleef03aef4b2009-02-17 17:04:22 -08001339 break;
1340 }
1341 }
Bill Pemberton2696fb52009-03-27 11:29:34 -04001342#endif /* !PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -08001343
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001344 if (status & NISTC_AI_STATUS1_STOP)
David Schleef03aef4b2009-02-17 17:04:22 -08001345 ni_handle_eos(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08001346}
1347
Bill Pembertonda91b262009-04-09 16:07:03 -04001348static void ack_b_interrupt(struct comedi_device *dev, unsigned short b_status)
David Schleef03aef4b2009-02-17 17:04:22 -08001349{
1350 unsigned short ack = 0;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001351
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001352 if (b_status & NISTC_AO_STATUS1_BC_TC)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001353 ack |= NISTC_INTB_ACK_AO_BC_TC;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001354 if (b_status & NISTC_AO_STATUS1_OVERRUN)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001355 ack |= NISTC_INTB_ACK_AO_ERR;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001356 if (b_status & NISTC_AO_STATUS1_START)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001357 ack |= NISTC_INTB_ACK_AO_START;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001358 if (b_status & NISTC_AO_STATUS1_START1)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001359 ack |= NISTC_INTB_ACK_AO_START1;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001360 if (b_status & NISTC_AO_STATUS1_UC_TC)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001361 ack |= NISTC_INTB_ACK_AO_UC_TC;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001362 if (b_status & NISTC_AO_STATUS1_UI2_TC)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001363 ack |= NISTC_INTB_ACK_AO_UI2_TC;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001364 if (b_status & NISTC_AO_STATUS1_UPDATE)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001365 ack |= NISTC_INTB_ACK_AO_UPDATE;
David Schleef03aef4b2009-02-17 17:04:22 -08001366 if (ack)
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07001367 ni_stc_writew(dev, ack, NISTC_INTB_ACK_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001368}
1369
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301370static void handle_b_interrupt(struct comedi_device *dev,
H Hartley Sweeten7ef17452016-04-21 12:04:39 -07001371 struct comedi_subdevice *s,
H Hartley Sweeten4b2d7382016-04-21 12:04:40 -07001372 unsigned short b_status)
David Schleef03aef4b2009-02-17 17:04:22 -08001373{
David Schleef03aef4b2009-02-17 17:04:22 -08001374 if (b_status == 0xffff)
1375 return;
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001376 if (b_status & NISTC_AO_STATUS1_OVERRUN) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07001377 dev_err(dev->class_dev,
1378 "AO FIFO underrun status=0x%04x status2=0x%04x\n",
H Hartley Sweeten63b2bb02015-05-01 14:59:41 -07001379 b_status, ni_stc_readw(dev, NISTC_AO_STATUS2_REG));
David Schleef03aef4b2009-02-17 17:04:22 -08001380 s->async->events |= COMEDI_CB_OVERFLOW;
1381 }
1382
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07001383 if (s->async->cmd.stop_src != TRIG_NONE &&
1384 b_status & NISTC_AO_STATUS1_BC_TC)
David Schleef03aef4b2009-02-17 17:04:22 -08001385 s->async->events |= COMEDI_CB_EOA;
H Hartley Sweetena7866a62013-11-26 10:21:16 -07001386
David Schleef03aef4b2009-02-17 17:04:22 -08001387#ifndef PCIDMA
H Hartley Sweetend123ee32015-05-01 14:59:38 -07001388 if (b_status & NISTC_AO_STATUS1_FIFO_REQ) {
David Schleef03aef4b2009-02-17 17:04:22 -08001389 int ret;
1390
1391 ret = ni_ao_fifo_half_empty(dev, s);
1392 if (!ret) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07001393 dev_err(dev->class_dev, "AO buffer underrun\n");
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07001394 ni_set_bits(dev, NISTC_INTB_ENA_REG,
1395 NISTC_INTB_ENA_AO_FIFO |
1396 NISTC_INTB_ENA_AO_ERR, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08001397 s->async->events |= COMEDI_CB_OVERFLOW;
1398 }
1399 }
1400#endif
David Schleef03aef4b2009-02-17 17:04:22 -08001401}
1402
Bill Pembertonda91b262009-04-09 16:07:03 -04001403static void ni_ai_munge(struct comedi_device *dev, struct comedi_subdevice *s,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301404 void *data, unsigned int num_bytes,
1405 unsigned int chan_index)
David Schleef03aef4b2009-02-17 17:04:22 -08001406{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001407 struct ni_private *devpriv = dev->private;
Bill Pembertond1636792009-03-16 22:05:20 -04001408 struct comedi_async *async = s->async;
H Hartley Sweeten9663ab12014-05-27 10:31:00 -07001409 struct comedi_cmd *cmd = &async->cmd;
H Hartley Sweetenc39e0502014-10-31 12:04:28 -07001410 unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
Ian Abbott3a2b1012013-10-16 14:40:26 +01001411 unsigned short *array = data;
Bill Pemberton790c5542009-03-16 22:05:02 -04001412 unsigned int *larray = data;
H Hartley Sweeten9663ab12014-05-27 10:31:00 -07001413 unsigned int i;
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07001414#ifdef PCIDMA
1415 __le16 *barray = data;
1416 __le32 *blarray = data;
1417#endif
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001418
H Hartley Sweetenc39e0502014-10-31 12:04:28 -07001419 for (i = 0; i < nsamples; i++) {
David Schleef03aef4b2009-02-17 17:04:22 -08001420#ifdef PCIDMA
1421 if (s->subdev_flags & SDF_LSAMPL)
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07001422 larray[i] = le32_to_cpu(blarray[i]);
David Schleef03aef4b2009-02-17 17:04:22 -08001423 else
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07001424 array[i] = le16_to_cpu(barray[i]);
David Schleef03aef4b2009-02-17 17:04:22 -08001425#endif
1426 if (s->subdev_flags & SDF_LSAMPL)
1427 larray[i] += devpriv->ai_offset[chan_index];
1428 else
1429 array[i] += devpriv->ai_offset[chan_index];
1430 chan_index++;
H Hartley Sweeten9663ab12014-05-27 10:31:00 -07001431 chan_index %= cmd->chanlist_len;
David Schleef03aef4b2009-02-17 17:04:22 -08001432 }
1433}
1434
1435#ifdef PCIDMA
1436
Bill Pembertonda91b262009-04-09 16:07:03 -04001437static int ni_ai_setup_MITE_dma(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -08001438{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001439 struct ni_private *devpriv = dev->private;
H Hartley Sweeten5dce16e2014-05-28 16:26:50 -07001440 struct comedi_subdevice *s = dev->read_subdev;
David Schleef03aef4b2009-02-17 17:04:22 -08001441 int retval;
1442 unsigned long flags;
1443
1444 retval = ni_request_ai_mite_channel(dev);
1445 if (retval)
1446 return retval;
David Schleef03aef4b2009-02-17 17:04:22 -08001447
1448 /* write alloc the entire buffer */
Ian Abbott24e894b2014-05-06 13:12:04 +01001449 comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
David Schleef03aef4b2009-02-17 17:04:22 -08001450
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001451 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweetenc6be1542015-03-04 12:15:40 -07001452 if (!devpriv->ai_mite_chan) {
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001453 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001454 return -EIO;
1455 }
1456
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001457 if (devpriv->is_611x || devpriv->is_6143)
David Schleef03aef4b2009-02-17 17:04:22 -08001458 mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001459 else if (devpriv->is_628x)
David Schleef03aef4b2009-02-17 17:04:22 -08001460 mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001461 else
David Schleef03aef4b2009-02-17 17:04:22 -08001462 mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001463
David Schleef03aef4b2009-02-17 17:04:22 -08001464 /*start the MITE */
1465 mite_dma_arm(devpriv->ai_mite_chan);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001466 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001467
1468 return 0;
1469}
1470
Bill Pembertonda91b262009-04-09 16:07:03 -04001471static int ni_ao_setup_MITE_dma(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -08001472{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001473 struct ni_private *devpriv = dev->private;
H Hartley Sweetene879c312014-05-28 16:26:51 -07001474 struct comedi_subdevice *s = dev->write_subdev;
David Schleef03aef4b2009-02-17 17:04:22 -08001475 int retval;
1476 unsigned long flags;
1477
1478 retval = ni_request_ao_mite_channel(dev);
1479 if (retval)
1480 return retval;
1481
1482 /* read alloc the entire buffer */
Ian Abbottd13be552014-05-06 13:12:07 +01001483 comedi_buf_read_alloc(s, s->async->prealloc_bufsz);
David Schleef03aef4b2009-02-17 17:04:22 -08001484
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001485 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001486 if (devpriv->ao_mite_chan) {
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001487 if (devpriv->is_611x || devpriv->is_6713) {
David Schleef03aef4b2009-02-17 17:04:22 -08001488 mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
1489 } else {
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07001490 /*
1491 * Doing 32 instead of 16 bit wide transfers from
1492 * memory makes the mite do 32 bit pci transfers,
1493 * doubling pci bandwidth.
1494 */
David Schleef03aef4b2009-02-17 17:04:22 -08001495 mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
1496 }
1497 mite_dma_arm(devpriv->ao_mite_chan);
H Hartley Sweeten6ac986d02015-03-05 13:21:18 -07001498 } else {
David Schleef03aef4b2009-02-17 17:04:22 -08001499 retval = -EIO;
H Hartley Sweeten6ac986d02015-03-05 13:21:18 -07001500 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001501 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001502
1503 return retval;
1504}
1505
Bill Pemberton2696fb52009-03-27 11:29:34 -04001506#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -08001507
1508/*
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07001509 * used for both cancel ioctl and board initialization
1510 *
1511 * this is pretty harsh for a cancel, but it works...
David Schleef03aef4b2009-02-17 17:04:22 -08001512 */
Bill Pembertonda91b262009-04-09 16:07:03 -04001513static int ni_ai_reset(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08001514{
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001515 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001516 unsigned int ai_personal;
1517 unsigned int ai_out_ctrl;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001518
David Schleef03aef4b2009-02-17 17:04:22 -08001519 ni_release_ai_mite_channel(dev);
1520 /* ai configuration */
H Hartley Sweeten707502f2015-05-01 14:59:25 -07001521 ni_stc_writew(dev, NISTC_RESET_AI_CFG_START | NISTC_RESET_AI,
1522 NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001523
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07001524 ni_set_bits(dev, NISTC_INTA_ENA_REG, NISTC_INTA_ENA_AI_MASK, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08001525
1526 ni_clear_ai_fifo(dev);
1527
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001528 if (!devpriv->is_6143)
H Hartley Sweeten68885d92015-05-01 14:59:54 -07001529 ni_writeb(dev, NI_E_MISC_CMD_EXT_ATRIG, NI_E_MISC_CMD_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001530
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001531 ni_stc_writew(dev, NISTC_AI_CMD1_DISARM, NISTC_AI_CMD1_REG);
H Hartley Sweetenbd358f52015-05-01 14:59:03 -07001532 ni_stc_writew(dev, NISTC_AI_MODE1_START_STOP |
1533 NISTC_AI_MODE1_RSVD
1534 /*| NISTC_AI_MODE1_TRIGGER_ONCE */,
1535 NISTC_AI_MODE1_REG);
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07001536 ni_stc_writew(dev, 0, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001537 /* generate FIFO interrupts on non-empty */
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07001538 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
1539 NISTC_AI_MODE3_REG);
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001540
H Hartley Sweetenc1b74032015-05-01 14:59:30 -07001541 ai_personal = NISTC_AI_PERSONAL_SHIFTIN_PW |
1542 NISTC_AI_PERSONAL_SOC_POLARITY |
1543 NISTC_AI_PERSONAL_LOCALMUX_CLK_PW;
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001544 ai_out_ctrl = NISTC_AI_OUT_CTRL_SCAN_IN_PROG_SEL(3) |
1545 NISTC_AI_OUT_CTRL_EXTMUX_CLK_SEL(0) |
1546 NISTC_AI_OUT_CTRL_LOCALMUX_CLK_SEL(2) |
1547 NISTC_AI_OUT_CTRL_SC_TC_SEL(3);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001548 if (devpriv->is_611x) {
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001549 ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001550 } else if (devpriv->is_6143) {
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001551 ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW;
David Schleef03aef4b2009-02-17 17:04:22 -08001552 } else {
H Hartley Sweetenc1b74032015-05-01 14:59:30 -07001553 ai_personal |= NISTC_AI_PERSONAL_CONVERT_PW;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001554 if (devpriv->is_622x)
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001555 ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_HIGH;
David Schleef03aef4b2009-02-17 17:04:22 -08001556 else
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001557 ai_out_ctrl |= NISTC_AI_OUT_CTRL_CONVERT_LOW;
David Schleef03aef4b2009-02-17 17:04:22 -08001558 }
H Hartley Sweetenc1b74032015-05-01 14:59:30 -07001559 ni_stc_writew(dev, ai_personal, NISTC_AI_PERSONAL_REG);
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001560 ni_stc_writew(dev, ai_out_ctrl, NISTC_AI_OUT_CTRL_REG);
1561
David Schleef03aef4b2009-02-17 17:04:22 -08001562 /* the following registers should not be changed, because there
1563 * are no backup registers in devpriv. If you want to change
1564 * any of these, add a backup register and other appropriate code:
H Hartley Sweetenbd358f52015-05-01 14:59:03 -07001565 * NISTC_AI_MODE1_REG
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07001566 * NISTC_AI_MODE3_REG
H Hartley Sweetenc1b74032015-05-01 14:59:30 -07001567 * NISTC_AI_PERSONAL_REG
H Hartley Sweetenaa9d73b2015-05-01 14:59:16 -07001568 * NISTC_AI_OUT_CTRL_REG
David Schleef03aef4b2009-02-17 17:04:22 -08001569 */
H Hartley Sweeten480456d2015-05-01 14:58:54 -07001570
1571 /* clear interrupts */
1572 ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001573
H Hartley Sweeten707502f2015-05-01 14:59:25 -07001574 ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001575
1576 return 0;
1577}
1578
Bill Pembertonda91b262009-04-09 16:07:03 -04001579static int ni_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08001580{
Ian Abbott3cd73bc2012-09-24 16:27:59 +01001581 unsigned long flags;
David Schleef03aef4b2009-02-17 17:04:22 -08001582 int count;
1583
Bill Pemberton2696fb52009-03-27 11:29:34 -04001584 /* lock to avoid race with interrupt handler */
Ian Abbott3cd73bc2012-09-24 16:27:59 +01001585 spin_lock_irqsave(&dev->spinlock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001586#ifndef PCIDMA
1587 ni_handle_fifo_dregs(dev);
1588#else
1589 ni_sync_ai_dma(dev);
1590#endif
H Hartley Sweetenf4f3f7c2014-06-20 10:58:28 -07001591 count = comedi_buf_n_bytes_ready(s);
Ian Abbott3cd73bc2012-09-24 16:27:59 +01001592 spin_unlock_irqrestore(&dev->spinlock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08001593
1594 return count;
1595}
1596
H Hartley Sweeten29aba7632012-09-17 13:13:32 -07001597static void ni_prime_channelgain_list(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -08001598{
1599 int i;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001600
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001601 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE, NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001602 for (i = 0; i < NI_TIMEOUT; ++i) {
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001603 if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1604 NISTC_AI_STATUS1_FIFO_E)) {
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -07001605 ni_stc_writew(dev, 1, NISTC_ADC_FIFO_CLR_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001606 return;
1607 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07001608 udelay(1);
David Schleef03aef4b2009-02-17 17:04:22 -08001609 }
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07001610 dev_err(dev->class_dev, "timeout loading channel/gain list\n");
David Schleef03aef4b2009-02-17 17:04:22 -08001611}
1612
Bill Pembertonda91b262009-04-09 16:07:03 -04001613static void ni_m_series_load_channelgain_list(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301614 unsigned int n_chan,
1615 unsigned int *list)
David Schleef03aef4b2009-02-17 17:04:22 -08001616{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001617 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001618 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08001619 unsigned int chan, range, aref;
1620 unsigned int i;
David Schleef03aef4b2009-02-17 17:04:22 -08001621 unsigned int dither;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001622 unsigned int range_code;
David Schleef03aef4b2009-02-17 17:04:22 -08001623
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -07001624 ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001625
David Schleef03aef4b2009-02-17 17:04:22 -08001626 if ((list[0] & CR_ALT_SOURCE)) {
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001627 unsigned int bypass_bits;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07001628
David Schleef03aef4b2009-02-17 17:04:22 -08001629 chan = CR_CHAN(list[0]);
1630 range = CR_RANGE(list[0]);
H Hartley Sweeten6293e352013-03-05 10:20:41 -07001631 range_code = ni_gainlkup[board->gainlkup][range];
Haneen Mohammedf0dff422015-03-13 14:29:30 +03001632 dither = (list[0] & CR_ALT_FILTER) != 0;
H Hartley Sweeten41f9f0b2015-05-01 14:58:39 -07001633 bypass_bits = NI_M_CFG_BYPASS_FIFO |
1634 NI_M_CFG_BYPASS_AI_CHAN(chan) |
1635 NI_M_CFG_BYPASS_AI_GAIN(range_code) |
1636 devpriv->ai_calib_source;
David Schleef03aef4b2009-02-17 17:04:22 -08001637 if (dither)
H Hartley Sweeten41f9f0b2015-05-01 14:58:39 -07001638 bypass_bits |= NI_M_CFG_BYPASS_AI_DITHER;
Bill Pemberton2696fb52009-03-27 11:29:34 -04001639 /* don't use 2's complement encoding */
H Hartley Sweeten41f9f0b2015-05-01 14:58:39 -07001640 bypass_bits |= NI_M_CFG_BYPASS_AI_POLARITY;
1641 ni_writel(dev, bypass_bits, NI_M_CFG_BYPASS_FIFO_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001642 } else {
H Hartley Sweeten41f9f0b2015-05-01 14:58:39 -07001643 ni_writel(dev, 0, NI_M_CFG_BYPASS_FIFO_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001644 }
David Schleef03aef4b2009-02-17 17:04:22 -08001645 for (i = 0; i < n_chan; i++) {
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001646 unsigned int config_bits = 0;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07001647
David Schleef03aef4b2009-02-17 17:04:22 -08001648 chan = CR_CHAN(list[i]);
1649 aref = CR_AREF(list[i]);
1650 range = CR_RANGE(list[i]);
Haneen Mohammedf0dff422015-03-13 14:29:30 +03001651 dither = (list[i] & CR_ALT_FILTER) != 0;
David Schleef03aef4b2009-02-17 17:04:22 -08001652
H Hartley Sweeten6293e352013-03-05 10:20:41 -07001653 range_code = ni_gainlkup[board->gainlkup][range];
H Hartley Sweeten817144a2014-07-14 12:23:51 -07001654 devpriv->ai_offset[i] = 0;
David Schleef03aef4b2009-02-17 17:04:22 -08001655 switch (aref) {
1656 case AREF_DIFF:
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001657 config_bits |= NI_M_AI_CFG_CHAN_TYPE_DIFF;
David Schleef03aef4b2009-02-17 17:04:22 -08001658 break;
1659 case AREF_COMMON:
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001660 config_bits |= NI_M_AI_CFG_CHAN_TYPE_COMMON;
David Schleef03aef4b2009-02-17 17:04:22 -08001661 break;
1662 case AREF_GROUND:
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001663 config_bits |= NI_M_AI_CFG_CHAN_TYPE_GROUND;
David Schleef03aef4b2009-02-17 17:04:22 -08001664 break;
1665 case AREF_OTHER:
1666 break;
1667 }
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001668 config_bits |= NI_M_AI_CFG_CHAN_SEL(chan);
1669 config_bits |= NI_M_AI_CFG_BANK_SEL(chan);
1670 config_bits |= NI_M_AI_CFG_GAIN(range_code);
David Schleef03aef4b2009-02-17 17:04:22 -08001671 if (i == n_chan - 1)
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001672 config_bits |= NI_M_AI_CFG_LAST_CHAN;
David Schleef03aef4b2009-02-17 17:04:22 -08001673 if (dither)
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001674 config_bits |= NI_M_AI_CFG_DITHER;
Bill Pemberton2696fb52009-03-27 11:29:34 -04001675 /* don't use 2's complement encoding */
H Hartley Sweeten67d2d052015-05-01 14:58:35 -07001676 config_bits |= NI_M_AI_CFG_POLARITY;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07001677 ni_writew(dev, config_bits, NI_M_AI_CFG_FIFO_DATA_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001678 }
1679 ni_prime_channelgain_list(dev);
1680}
1681
1682/*
1683 * Notes on the 6110 and 6111:
1684 * These boards a slightly different than the rest of the series, since
1685 * they have multiple A/D converters.
1686 * From the driver side, the configuration memory is a
1687 * little different.
1688 * Configuration Memory Low:
1689 * bits 15-9: same
1690 * bit 8: unipolar/bipolar (should be 0 for bipolar)
1691 * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
1692 * 1001 gain=0.1 (+/- 50)
1693 * 1010 0.2
1694 * 1011 0.1
1695 * 0001 1
1696 * 0010 2
1697 * 0011 5
1698 * 0100 10
1699 * 0101 20
1700 * 0110 50
1701 * Configuration Memory High:
1702 * bits 12-14: Channel Type
1703 * 001 for differential
1704 * 000 for calibration
1705 * bit 11: coupling (this is not currently handled)
1706 * 1 AC coupling
1707 * 0 DC coupling
1708 * bits 0-2: channel
1709 * valid channels are 0-3
1710 */
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301711static void ni_load_channelgain_list(struct comedi_device *dev,
H Hartley Sweeten817144a2014-07-14 12:23:51 -07001712 struct comedi_subdevice *s,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05301713 unsigned int n_chan, unsigned int *list)
David Schleef03aef4b2009-02-17 17:04:22 -08001714{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001715 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001716 struct ni_private *devpriv = dev->private;
H Hartley Sweeten817144a2014-07-14 12:23:51 -07001717 unsigned int offset = (s->maxdata + 1) >> 1;
David Schleef03aef4b2009-02-17 17:04:22 -08001718 unsigned int chan, range, aref;
1719 unsigned int i;
1720 unsigned int hi, lo;
David Schleef03aef4b2009-02-17 17:04:22 -08001721 unsigned int dither;
1722
H Hartley Sweeten17733212014-06-19 10:20:32 -07001723 if (devpriv->is_m_series) {
David Schleef03aef4b2009-02-17 17:04:22 -08001724 ni_m_series_load_channelgain_list(dev, n_chan, list);
1725 return;
1726 }
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001727 if (n_chan == 1 && !devpriv->is_611x && !devpriv->is_6143) {
H Hartley Sweeten73894982016-04-14 09:57:58 -07001728 if (devpriv->changain_state &&
1729 devpriv->changain_spec == list[0]) {
Bill Pemberton2696fb52009-03-27 11:29:34 -04001730 /* ready to go. */
David Schleef03aef4b2009-02-17 17:04:22 -08001731 return;
1732 }
1733 devpriv->changain_state = 1;
1734 devpriv->changain_spec = list[0];
1735 } else {
1736 devpriv->changain_state = 0;
1737 }
1738
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -07001739 ni_stc_writew(dev, 1, NISTC_CFG_MEM_CLR_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001740
Bill Pemberton2696fb52009-03-27 11:29:34 -04001741 /* Set up Calibration mode if required */
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001742 if (devpriv->is_6143) {
H Hartley Sweeten73894982016-04-14 09:57:58 -07001743 if ((list[0] & CR_ALT_SOURCE) &&
1744 !devpriv->ai_calib_source_enabled) {
Bill Pemberton2696fb52009-03-27 11:29:34 -04001745 /* Strobe Relay enable bit */
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001746 ni_writew(dev, devpriv->ai_calib_source |
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001747 NI6143_CALIB_CHAN_RELAY_ON,
1748 NI6143_CALIB_CHAN_REG);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001749 ni_writew(dev, devpriv->ai_calib_source,
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001750 NI6143_CALIB_CHAN_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001751 devpriv->ai_calib_source_enabled = 1;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001752 /* Allow relays to change */
1753 msleep_interruptible(100);
H Hartley Sweeten73894982016-04-14 09:57:58 -07001754 } else if (!(list[0] & CR_ALT_SOURCE) &&
1755 devpriv->ai_calib_source_enabled) {
Bill Pemberton2696fb52009-03-27 11:29:34 -04001756 /* Strobe Relay disable bit */
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001757 ni_writew(dev, devpriv->ai_calib_source |
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001758 NI6143_CALIB_CHAN_RELAY_OFF,
1759 NI6143_CALIB_CHAN_REG);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001760 ni_writew(dev, devpriv->ai_calib_source,
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001761 NI6143_CALIB_CHAN_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001762 devpriv->ai_calib_source_enabled = 0;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001763 /* Allow relays to change */
1764 msleep_interruptible(100);
David Schleef03aef4b2009-02-17 17:04:22 -08001765 }
1766 }
1767
David Schleef03aef4b2009-02-17 17:04:22 -08001768 for (i = 0; i < n_chan; i++) {
H Hartley Sweetena6266972014-07-16 11:22:56 -07001769 if (!devpriv->is_6143 && (list[i] & CR_ALT_SOURCE))
David Schleef03aef4b2009-02-17 17:04:22 -08001770 chan = devpriv->ai_calib_source;
H Hartley Sweetena6266972014-07-16 11:22:56 -07001771 else
David Schleef03aef4b2009-02-17 17:04:22 -08001772 chan = CR_CHAN(list[i]);
David Schleef03aef4b2009-02-17 17:04:22 -08001773 aref = CR_AREF(list[i]);
1774 range = CR_RANGE(list[i]);
Haneen Mohammedf0dff422015-03-13 14:29:30 +03001775 dither = (list[i] & CR_ALT_FILTER) != 0;
David Schleef03aef4b2009-02-17 17:04:22 -08001776
1777 /* fix the external/internal range differences */
H Hartley Sweeten6293e352013-03-05 10:20:41 -07001778 range = ni_gainlkup[board->gainlkup][range];
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001779 if (devpriv->is_611x)
David Schleef03aef4b2009-02-17 17:04:22 -08001780 devpriv->ai_offset[i] = offset;
1781 else
1782 devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
1783
1784 hi = 0;
1785 if ((list[i] & CR_ALT_SOURCE)) {
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001786 if (devpriv->is_611x)
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001787 ni_writew(dev, CR_CHAN(list[i]) & 0x0003,
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001788 NI611X_CALIB_CHAN_SEL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001789 } else {
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001790 if (devpriv->is_611x)
David Schleef03aef4b2009-02-17 17:04:22 -08001791 aref = AREF_DIFF;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001792 else if (devpriv->is_6143)
David Schleef03aef4b2009-02-17 17:04:22 -08001793 aref = AREF_OTHER;
1794 switch (aref) {
1795 case AREF_DIFF:
H Hartley Sweetend504a6e2015-05-01 14:59:58 -07001796 hi |= NI_E_AI_CFG_HI_TYPE_DIFF;
David Schleef03aef4b2009-02-17 17:04:22 -08001797 break;
1798 case AREF_COMMON:
H Hartley Sweetend504a6e2015-05-01 14:59:58 -07001799 hi |= NI_E_AI_CFG_HI_TYPE_COMMON;
David Schleef03aef4b2009-02-17 17:04:22 -08001800 break;
1801 case AREF_GROUND:
H Hartley Sweetend504a6e2015-05-01 14:59:58 -07001802 hi |= NI_E_AI_CFG_HI_TYPE_GROUND;
David Schleef03aef4b2009-02-17 17:04:22 -08001803 break;
1804 case AREF_OTHER:
1805 break;
1806 }
1807 }
H Hartley Sweetend504a6e2015-05-01 14:59:58 -07001808 hi |= NI_E_AI_CFG_HI_CHAN(chan);
David Schleef03aef4b2009-02-17 17:04:22 -08001809
H Hartley Sweetend504a6e2015-05-01 14:59:58 -07001810 ni_writew(dev, hi, NI_E_AI_CFG_HI_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001811
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001812 if (!devpriv->is_6143) {
H Hartley Sweeten76efac72015-05-01 14:59:57 -07001813 lo = NI_E_AI_CFG_LO_GAIN(range);
David Schleef03aef4b2009-02-17 17:04:22 -08001814
H Hartley Sweeten76efac72015-05-01 14:59:57 -07001815 if (i == n_chan - 1)
1816 lo |= NI_E_AI_CFG_LO_LAST_CHAN;
1817 if (dither)
1818 lo |= NI_E_AI_CFG_LO_DITHER;
1819
1820 ni_writew(dev, lo, NI_E_AI_CFG_LO_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08001821 }
1822 }
1823
1824 /* prime the channel/gain list */
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001825 if (!devpriv->is_611x && !devpriv->is_6143)
David Schleef03aef4b2009-02-17 17:04:22 -08001826 ni_prime_channelgain_list(dev);
David Schleef03aef4b2009-02-17 17:04:22 -08001827}
1828
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001829static int ni_ai_insn_read(struct comedi_device *dev,
1830 struct comedi_subdevice *s,
1831 struct comedi_insn *insn,
1832 unsigned int *data)
1833{
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001834 struct ni_private *devpriv = dev->private;
Ian Abbottbd1692b2016-11-14 20:16:21 +00001835 unsigned int mask = s->maxdata;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001836 int i, n;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001837 unsigned int signbits;
H Hartley Sweeten05573442014-08-25 15:23:50 -07001838 unsigned int d;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001839 unsigned long dl;
1840
H Hartley Sweeten817144a2014-07-14 12:23:51 -07001841 ni_load_channelgain_list(dev, s, 1, &insn->chanspec);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001842
1843 ni_clear_ai_fifo(dev);
1844
1845 signbits = devpriv->ai_offset[0];
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001846 if (devpriv->is_611x) {
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001847 for (n = 0; n < num_adc_stages_611x; n++) {
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001848 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
1849 NISTC_AI_CMD1_REG);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001850 udelay(1);
1851 }
1852 for (n = 0; n < insn->n; n++) {
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001853 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
1854 NISTC_AI_CMD1_REG);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001855 /* The 611x has screwy 32-bit FIFOs. */
1856 d = 0;
1857 for (i = 0; i < NI_TIMEOUT; i++) {
H Hartley Sweeten906170b2015-05-01 14:59:52 -07001858 if (ni_readb(dev, NI_E_STATUS_REG) & 0x80) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001859 d = ni_readl(dev,
1860 NI611X_AI_FIFO_DATA_REG);
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001861 d >>= 16;
1862 d &= 0xffff;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001863 break;
1864 }
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001865 if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1866 NISTC_AI_STATUS1_FIFO_E)) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07001867 d = ni_readl(dev,
1868 NI611X_AI_FIFO_DATA_REG);
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001869 d &= 0xffff;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001870 break;
1871 }
1872 }
1873 if (i == NI_TIMEOUT) {
Haneen Mohammedcd255032015-03-05 13:01:49 +03001874 dev_err(dev->class_dev, "timeout\n");
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001875 return -ETIME;
1876 }
1877 d += signbits;
Ian Abbott745f7d02016-11-14 20:16:22 +00001878 data[n] = d & 0xffff;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001879 }
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001880 } else if (devpriv->is_6143) {
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001881 for (n = 0; n < insn->n; n++) {
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001882 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
1883 NISTC_AI_CMD1_REG);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001884
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001885 /*
1886 * The 6143 has 32-bit FIFOs. You need to strobe a
1887 * bit to move a single 16bit stranded sample into
1888 * the FIFO.
1889 */
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001890 dl = 0;
1891 for (i = 0; i < NI_TIMEOUT; i++) {
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001892 if (ni_readl(dev, NI6143_AI_FIFO_STATUS_REG) &
1893 0x01) {
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001894 /* Get stranded sample into FIFO */
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07001895 ni_writel(dev, 0x01,
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07001896 NI6143_AI_FIFO_CTRL_REG);
1897 dl = ni_readl(dev,
1898 NI6143_AI_FIFO_DATA_REG);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001899 break;
1900 }
1901 }
1902 if (i == NI_TIMEOUT) {
Haneen Mohammedcd255032015-03-05 13:01:49 +03001903 dev_err(dev->class_dev, "timeout\n");
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001904 return -ETIME;
1905 }
1906 data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
1907 }
1908 } else {
1909 for (n = 0; n < insn->n; n++) {
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07001910 ni_stc_writew(dev, NISTC_AI_CMD1_CONVERT_PULSE,
1911 NISTC_AI_CMD1_REG);
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001912 for (i = 0; i < NI_TIMEOUT; i++) {
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07001913 if (!(ni_stc_readw(dev, NISTC_AI_STATUS1_REG) &
1914 NISTC_AI_STATUS1_FIFO_E))
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001915 break;
1916 }
1917 if (i == NI_TIMEOUT) {
Haneen Mohammedcd255032015-03-05 13:01:49 +03001918 dev_err(dev->class_dev, "timeout\n");
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001919 return -ETIME;
1920 }
H Hartley Sweeten17733212014-06-19 10:20:32 -07001921 if (devpriv->is_m_series) {
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07001922 dl = ni_readl(dev, NI_M_AI_FIFO_DATA_REG);
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07001923 dl &= mask;
1924 data[n] = dl;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001925 } else {
H Hartley Sweeten363f5702015-05-01 14:59:56 -07001926 d = ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07001927 d += signbits;
Ian Abbott745f7d02016-11-14 20:16:22 +00001928 data[n] = d & 0xffff;
H Hartley Sweeten3d129c32014-05-28 16:26:43 -07001929 }
1930 }
1931 }
1932 return insn->n;
1933}
1934
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001935static int ni_ns_to_timer(const struct comedi_device *dev,
1936 unsigned int nanosec, unsigned int flags)
David Schleef03aef4b2009-02-17 17:04:22 -08001937{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001938 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08001939 int divider;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001940
Ian Abbott3280c2d2014-09-03 13:45:57 +01001941 switch (flags & CMDF_ROUND_MASK) {
1942 case CMDF_ROUND_NEAREST:
David Schleef03aef4b2009-02-17 17:04:22 -08001943 default:
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05301944 divider = DIV_ROUND_CLOSEST(nanosec, devpriv->clock_ns);
David Schleef03aef4b2009-02-17 17:04:22 -08001945 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01001946 case CMDF_ROUND_DOWN:
David Schleef03aef4b2009-02-17 17:04:22 -08001947 divider = (nanosec) / devpriv->clock_ns;
1948 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01001949 case CMDF_ROUND_UP:
Bhaktipriya Shridhar7f9d2b12016-03-10 00:05:16 +05301950 divider = DIV_ROUND_UP(nanosec, devpriv->clock_ns);
David Schleef03aef4b2009-02-17 17:04:22 -08001951 break;
1952 }
1953 return divider - 1;
1954}
1955
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001956static unsigned int ni_timer_to_ns(const struct comedi_device *dev, int timer)
David Schleef03aef4b2009-02-17 17:04:22 -08001957{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07001958 struct ni_private *devpriv = dev->private;
1959
David Schleef03aef4b2009-02-17 17:04:22 -08001960 return devpriv->clock_ns * (timer + 1);
1961}
1962
H Hartley Sweeten19d92122016-05-02 10:11:36 -07001963static void ni_cmd_set_mite_transfer(struct mite_ring *ring,
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07001964 struct comedi_subdevice *sdev,
1965 const struct comedi_cmd *cmd,
1966 unsigned int max_count) {
1967#ifdef PCIDMA
1968 unsigned int nbytes = max_count;
1969
1970 if (cmd->stop_arg > 0 && cmd->stop_arg < max_count)
1971 nbytes = cmd->stop_arg;
1972 nbytes *= comedi_bytes_per_scan(sdev);
1973
1974 if (nbytes > sdev->async->prealloc_bufsz) {
1975 if (cmd->stop_arg > 0)
1976 dev_err(sdev->device->class_dev,
1977 "ni_cmd_set_mite_transfer: tried exact data transfer limits greater than buffer size\n");
1978
1979 /*
1980 * we can only transfer up to the size of the buffer. In this
1981 * case, the user is expected to continue to write into the
1982 * comedi buffer (already implemented as a ring buffer).
1983 */
1984 nbytes = sdev->async->prealloc_bufsz;
1985 }
1986
1987 mite_init_ring_descriptors(ring, sdev, nbytes);
1988#else
1989 dev_err(sdev->device->class_dev,
1990 "ni_cmd_set_mite_transfer: exact data transfer limits not implemented yet without DMA\n");
1991#endif
1992}
1993
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07001994static unsigned int ni_min_ai_scan_period_ns(struct comedi_device *dev,
1995 unsigned int num_channels)
David Schleef03aef4b2009-02-17 17:04:22 -08001996{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01001997 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07001998 struct ni_private *devpriv = dev->private;
H Hartley Sweeten6293e352013-03-05 10:20:41 -07001999
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002000 /* simultaneously-sampled inputs */
2001 if (devpriv->is_611x || devpriv->is_6143)
H Hartley Sweeten6293e352013-03-05 10:20:41 -07002002 return board->ai_speed;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002003
2004 /* multiplexed inputs */
H Hartley Sweeten6293e352013-03-05 10:20:41 -07002005 return board->ai_speed * num_channels;
David Schleef03aef4b2009-02-17 17:04:22 -08002006}
2007
Bill Pembertonda91b262009-04-09 16:07:03 -04002008static int ni_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302009 struct comedi_cmd *cmd)
David Schleef03aef4b2009-02-17 17:04:22 -08002010{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01002011 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002012 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08002013 int err = 0;
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002014 unsigned int tmp;
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002015 unsigned int sources;
David Schleef03aef4b2009-02-17 17:04:22 -08002016
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002017 /* Step 1 : check if triggers are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08002018
Ian Abbott311fd9b2015-03-27 19:14:24 +00002019 err |= comedi_check_trigger_src(&cmd->start_src,
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002020 TRIG_NOW | TRIG_INT | TRIG_EXT);
Ian Abbott311fd9b2015-03-27 19:14:24 +00002021 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002022 TRIG_TIMER | TRIG_EXT);
David Schleef03aef4b2009-02-17 17:04:22 -08002023
David Schleef03aef4b2009-02-17 17:04:22 -08002024 sources = TRIG_TIMER | TRIG_EXT;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002025 if (devpriv->is_611x || devpriv->is_6143)
David Schleef03aef4b2009-02-17 17:04:22 -08002026 sources |= TRIG_NOW;
Ian Abbott311fd9b2015-03-27 19:14:24 +00002027 err |= comedi_check_trigger_src(&cmd->convert_src, sources);
David Schleef03aef4b2009-02-17 17:04:22 -08002028
Ian Abbott311fd9b2015-03-27 19:14:24 +00002029 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
2030 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
David Schleef03aef4b2009-02-17 17:04:22 -08002031
2032 if (err)
2033 return 1;
2034
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002035 /* Step 2a : make sure trigger sources are unique */
David Schleef03aef4b2009-02-17 17:04:22 -08002036
Ian Abbott311fd9b2015-03-27 19:14:24 +00002037 err |= comedi_check_trigger_is_unique(cmd->start_src);
2038 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
2039 err |= comedi_check_trigger_is_unique(cmd->convert_src);
2040 err |= comedi_check_trigger_is_unique(cmd->stop_src);
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07002041
2042 /* Step 2b : and mutually compatible */
David Schleef03aef4b2009-02-17 17:04:22 -08002043
2044 if (err)
2045 return 2;
2046
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07002047 /* Step 3: check if arguments are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08002048
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002049 switch (cmd->start_src) {
2050 case TRIG_NOW:
2051 case TRIG_INT:
Ian Abbott311fd9b2015-03-27 19:14:24 +00002052 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002053 break;
2054 case TRIG_EXT:
2055 tmp = CR_CHAN(cmd->start_arg);
David Schleef03aef4b2009-02-17 17:04:22 -08002056
2057 if (tmp > 16)
2058 tmp = 16;
2059 tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
Ian Abbott311fd9b2015-03-27 19:14:24 +00002060 err |= comedi_check_trigger_arg_is(&cmd->start_arg, tmp);
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002061 break;
David Schleef03aef4b2009-02-17 17:04:22 -08002062 }
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07002063
David Schleef03aef4b2009-02-17 17:04:22 -08002064 if (cmd->scan_begin_src == TRIG_TIMER) {
Ian Abbott311fd9b2015-03-27 19:14:24 +00002065 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07002066 ni_min_ai_scan_period_ns(dev, cmd->chanlist_len));
Ian Abbott311fd9b2015-03-27 19:14:24 +00002067 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
2068 devpriv->clock_ns *
2069 0xffffff);
David Schleef03aef4b2009-02-17 17:04:22 -08002070 } else if (cmd->scan_begin_src == TRIG_EXT) {
2071 /* external trigger */
2072 unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
2073
2074 if (tmp > 16)
2075 tmp = 16;
2076 tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
Ian Abbott311fd9b2015-03-27 19:14:24 +00002077 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, tmp);
David Schleef03aef4b2009-02-17 17:04:22 -08002078 } else { /* TRIG_OTHER */
Ian Abbott311fd9b2015-03-27 19:14:24 +00002079 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002080 }
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07002081
David Schleef03aef4b2009-02-17 17:04:22 -08002082 if (cmd->convert_src == TRIG_TIMER) {
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002083 if (devpriv->is_611x || devpriv->is_6143) {
Ian Abbott311fd9b2015-03-27 19:14:24 +00002084 err |= comedi_check_trigger_arg_is(&cmd->convert_arg,
2085 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002086 } else {
Ian Abbott311fd9b2015-03-27 19:14:24 +00002087 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
2088 board->ai_speed);
2089 err |= comedi_check_trigger_arg_max(&cmd->convert_arg,
2090 devpriv->clock_ns *
2091 0xffff);
David Schleef03aef4b2009-02-17 17:04:22 -08002092 }
2093 } else if (cmd->convert_src == TRIG_EXT) {
2094 /* external trigger */
2095 unsigned int tmp = CR_CHAN(cmd->convert_arg);
2096
2097 if (tmp > 16)
2098 tmp = 16;
2099 tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
Ian Abbott311fd9b2015-03-27 19:14:24 +00002100 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, tmp);
David Schleef03aef4b2009-02-17 17:04:22 -08002101 } else if (cmd->convert_src == TRIG_NOW) {
Ian Abbott311fd9b2015-03-27 19:14:24 +00002102 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002103 }
2104
Ian Abbott311fd9b2015-03-27 19:14:24 +00002105 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
2106 cmd->chanlist_len);
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07002107
David Schleef03aef4b2009-02-17 17:04:22 -08002108 if (cmd->stop_src == TRIG_COUNT) {
2109 unsigned int max_count = 0x01000000;
2110
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002111 if (devpriv->is_611x)
David Schleef03aef4b2009-02-17 17:04:22 -08002112 max_count -= num_adc_stages_611x;
Ian Abbott311fd9b2015-03-27 19:14:24 +00002113 err |= comedi_check_trigger_arg_max(&cmd->stop_arg, max_count);
2114 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
David Schleef03aef4b2009-02-17 17:04:22 -08002115 } else {
2116 /* TRIG_NONE */
Ian Abbott311fd9b2015-03-27 19:14:24 +00002117 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002118 }
2119
2120 if (err)
2121 return 3;
2122
2123 /* step 4: fix up any arguments */
2124
2125 if (cmd->scan_begin_src == TRIG_TIMER) {
2126 tmp = cmd->scan_begin_arg;
2127 cmd->scan_begin_arg =
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302128 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
2129 cmd->scan_begin_arg,
H Hartley Sweetena207c122014-07-18 17:01:16 -07002130 cmd->flags));
David Schleef03aef4b2009-02-17 17:04:22 -08002131 if (tmp != cmd->scan_begin_arg)
2132 err++;
2133 }
2134 if (cmd->convert_src == TRIG_TIMER) {
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002135 if (!devpriv->is_611x && !devpriv->is_6143) {
David Schleef03aef4b2009-02-17 17:04:22 -08002136 tmp = cmd->convert_arg;
2137 cmd->convert_arg =
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302138 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
2139 cmd->convert_arg,
H Hartley Sweetena207c122014-07-18 17:01:16 -07002140 cmd->flags));
David Schleef03aef4b2009-02-17 17:04:22 -08002141 if (tmp != cmd->convert_arg)
2142 err++;
2143 if (cmd->scan_begin_src == TRIG_TIMER &&
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302144 cmd->scan_begin_arg <
2145 cmd->convert_arg * cmd->scan_end_arg) {
David Schleef03aef4b2009-02-17 17:04:22 -08002146 cmd->scan_begin_arg =
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302147 cmd->convert_arg * cmd->scan_end_arg;
David Schleef03aef4b2009-02-17 17:04:22 -08002148 err++;
2149 }
2150 }
2151 }
2152
2153 if (err)
2154 return 4;
2155
2156 return 0;
2157}
2158
H Hartley Sweeten8511b852014-05-28 16:26:38 -07002159static int ni_ai_inttrig(struct comedi_device *dev,
2160 struct comedi_subdevice *s,
2161 unsigned int trig_num)
2162{
2163 struct ni_private *devpriv = dev->private;
2164 struct comedi_cmd *cmd = &s->async->cmd;
2165
2166 if (trig_num != cmd->start_arg)
2167 return -EINVAL;
2168
H Hartley Sweetena1da35a2015-05-01 14:58:56 -07002169 ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE | devpriv->ai_cmd2,
2170 NISTC_AI_CMD2_REG);
H Hartley Sweeten8511b852014-05-28 16:26:38 -07002171 s->async->inttrig = NULL;
2172
2173 return 1;
2174}
2175
Bill Pembertonda91b262009-04-09 16:07:03 -04002176static int ni_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08002177{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002178 struct ni_private *devpriv = dev->private;
Bill Pembertonea6d0d42009-03-16 22:05:47 -04002179 const struct comedi_cmd *cmd = &s->async->cmd;
David Schleef03aef4b2009-02-17 17:04:22 -08002180 int timer;
2181 int mode1 = 0; /* mode1 is needed for both stop and convert */
2182 int mode2 = 0;
2183 int start_stop_select = 0;
2184 unsigned int stop_count;
2185 int interrupt_a_enable = 0;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07002186 unsigned int ai_trig;
David Schleef03aef4b2009-02-17 17:04:22 -08002187
David Schleef03aef4b2009-02-17 17:04:22 -08002188 if (dev->irq == 0) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07002189 dev_err(dev->class_dev, "cannot run command without an irq\n");
David Schleef03aef4b2009-02-17 17:04:22 -08002190 return -EIO;
2191 }
2192 ni_clear_ai_fifo(dev);
2193
H Hartley Sweeten817144a2014-07-14 12:23:51 -07002194 ni_load_channelgain_list(dev, s, cmd->chanlist_len, cmd->chanlist);
David Schleef03aef4b2009-02-17 17:04:22 -08002195
2196 /* start configuration */
H Hartley Sweeten707502f2015-05-01 14:59:25 -07002197 ni_stc_writew(dev, NISTC_RESET_AI_CFG_START, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002198
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07002199 /*
2200 * Disable analog triggering for now, since it interferes
2201 * with the use of pfi0.
2202 */
H Hartley Sweeten27cf6c02015-05-01 14:59:17 -07002203 devpriv->an_trig_etc_reg &= ~NISTC_ATRIG_ETC_ENA;
2204 ni_stc_writew(dev, devpriv->an_trig_etc_reg, NISTC_ATRIG_ETC_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002205
H Hartley Sweetenf8780712015-05-01 14:59:19 -07002206 ai_trig = NISTC_AI_TRIG_START2_SEL(0) | NISTC_AI_TRIG_START1_SYNC;
David Schleef03aef4b2009-02-17 17:04:22 -08002207 switch (cmd->start_src) {
2208 case TRIG_INT:
2209 case TRIG_NOW:
H Hartley Sweetenf8780712015-05-01 14:59:19 -07002210 ai_trig |= NISTC_AI_TRIG_START1_EDGE |
H Hartley Sweeten1645b552015-05-11 10:22:45 -07002211 NISTC_AI_TRIG_START1_SEL(0);
David Schleef03aef4b2009-02-17 17:04:22 -08002212 break;
2213 case TRIG_EXT:
H Hartley Sweetenf8780712015-05-01 14:59:19 -07002214 ai_trig |= NISTC_AI_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) +
2215 1);
David Schleef03aef4b2009-02-17 17:04:22 -08002216
H Hartley Sweetenf8780712015-05-01 14:59:19 -07002217 if (cmd->start_arg & CR_INVERT)
2218 ai_trig |= NISTC_AI_TRIG_START1_POLARITY;
2219 if (cmd->start_arg & CR_EDGE)
2220 ai_trig |= NISTC_AI_TRIG_START1_EDGE;
2221 break;
David Schleef03aef4b2009-02-17 17:04:22 -08002222 }
H Hartley Sweetenf8780712015-05-01 14:59:19 -07002223 ni_stc_writew(dev, ai_trig, NISTC_AI_TRIG_SEL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002224
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07002225 mode2 &= ~NISTC_AI_MODE2_PRE_TRIGGER;
2226 mode2 &= ~NISTC_AI_MODE2_SC_INIT_LOAD_SRC;
2227 mode2 &= ~NISTC_AI_MODE2_SC_RELOAD_MODE;
2228 ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002229
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002230 if (cmd->chanlist_len == 1 || devpriv->is_611x || devpriv->is_6143) {
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002231 /* logic low */
2232 start_stop_select |= NISTC_AI_STOP_POLARITY |
2233 NISTC_AI_STOP_SEL(31) |
2234 NISTC_AI_STOP_SYNC;
David Schleef03aef4b2009-02-17 17:04:22 -08002235 } else {
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002236 /* ai configuration memory */
2237 start_stop_select |= NISTC_AI_STOP_SEL(19);
David Schleef03aef4b2009-02-17 17:04:22 -08002238 }
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002239 ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002240
2241 devpriv->ai_cmd2 = 0;
2242 switch (cmd->stop_src) {
2243 case TRIG_COUNT:
2244 stop_count = cmd->stop_arg - 1;
2245
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002246 if (devpriv->is_611x) {
Bill Pemberton2696fb52009-03-27 11:29:34 -04002247 /* have to take 3 stage adc pipeline into account */
David Schleef03aef4b2009-02-17 17:04:22 -08002248 stop_count += num_adc_stages_611x;
2249 }
2250 /* stage number of scans */
H Hartley Sweetena2c53732015-05-01 14:59:05 -07002251 ni_stc_writel(dev, stop_count, NISTC_AI_SC_LOADA_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002252
H Hartley Sweetenbd358f52015-05-01 14:59:03 -07002253 mode1 |= NISTC_AI_MODE1_START_STOP |
2254 NISTC_AI_MODE1_RSVD |
2255 NISTC_AI_MODE1_TRIGGER_ONCE;
2256 ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002257 /* load SC (Scan Count) */
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002258 ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002259
David Schleef03aef4b2009-02-17 17:04:22 -08002260 if (stop_count == 0) {
H Hartley Sweetena1da35a2015-05-01 14:58:56 -07002261 devpriv->ai_cmd2 |= NISTC_AI_CMD2_END_ON_EOS;
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002262 interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07002263 /*
2264 * This is required to get the last sample for
2265 * chanlist_len > 1, not sure why.
2266 */
David Schleef03aef4b2009-02-17 17:04:22 -08002267 if (cmd->chanlist_len > 1)
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002268 start_stop_select |= NISTC_AI_STOP_POLARITY |
2269 NISTC_AI_STOP_EDGE;
David Schleef03aef4b2009-02-17 17:04:22 -08002270 }
2271 break;
2272 case TRIG_NONE:
2273 /* stage number of scans */
H Hartley Sweetena2c53732015-05-01 14:59:05 -07002274 ni_stc_writel(dev, 0, NISTC_AI_SC_LOADA_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002275
H Hartley Sweetenbd358f52015-05-01 14:59:03 -07002276 mode1 |= NISTC_AI_MODE1_START_STOP |
2277 NISTC_AI_MODE1_RSVD |
2278 NISTC_AI_MODE1_CONTINUOUS;
2279 ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002280
2281 /* load SC (Scan Count) */
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002282 ni_stc_writew(dev, NISTC_AI_CMD1_SC_LOAD, NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002283 break;
2284 }
2285
2286 switch (cmd->scan_begin_src) {
2287 case TRIG_TIMER:
2288 /*
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002289 * stop bits for non 611x boards
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002290 * NISTC_AI_MODE3_SI_TRIG_DELAY=0
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002291 * NISTC_AI_MODE2_PRE_TRIGGER=0
2292 * NISTC_AI_START_STOP_REG:
2293 * NISTC_AI_START_POLARITY=0 (?) rising edge
2294 * NISTC_AI_START_EDGE=1 edge triggered
2295 * NISTC_AI_START_SYNC=1 (?)
2296 * NISTC_AI_START_SEL=0 SI_TC
2297 * NISTC_AI_STOP_POLARITY=0 rising edge
2298 * NISTC_AI_STOP_EDGE=0 level
2299 * NISTC_AI_STOP_SYNC=1
2300 * NISTC_AI_STOP_SEL=19 external pin (configuration mem)
David Schleef03aef4b2009-02-17 17:04:22 -08002301 */
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002302 start_stop_select |= NISTC_AI_START_EDGE | NISTC_AI_START_SYNC;
2303 ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002304
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07002305 mode2 &= ~NISTC_AI_MODE2_SI_INIT_LOAD_SRC; /* A */
2306 mode2 |= NISTC_AI_MODE2_SI_RELOAD_MODE(0);
2307 /* mode2 |= NISTC_AI_MODE2_SC_RELOAD_MODE; */
2308 ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002309
2310 /* load SI */
2311 timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
Ian Abbott3280c2d2014-09-03 13:45:57 +01002312 CMDF_ROUND_NEAREST);
H Hartley Sweetena2c53732015-05-01 14:59:05 -07002313 ni_stc_writel(dev, timer, NISTC_AI_SI_LOADA_REG);
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002314 ni_stc_writew(dev, NISTC_AI_CMD1_SI_LOAD, NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002315 break;
2316 case TRIG_EXT:
2317 if (cmd->scan_begin_arg & CR_EDGE)
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002318 start_stop_select |= NISTC_AI_START_EDGE;
2319 if (cmd->scan_begin_arg & CR_INVERT) /* falling edge */
2320 start_stop_select |= NISTC_AI_START_POLARITY;
David Schleef03aef4b2009-02-17 17:04:22 -08002321 if (cmd->scan_begin_src != cmd->convert_src ||
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302322 (cmd->scan_begin_arg & ~CR_EDGE) !=
2323 (cmd->convert_arg & ~CR_EDGE))
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002324 start_stop_select |= NISTC_AI_START_SYNC;
David Schleef03aef4b2009-02-17 17:04:22 -08002325 start_stop_select |=
H Hartley Sweeten3e908892015-05-01 14:59:18 -07002326 NISTC_AI_START_SEL(1 + CR_CHAN(cmd->scan_begin_arg));
2327 ni_stc_writew(dev, start_stop_select, NISTC_AI_START_STOP_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002328 break;
2329 }
2330
2331 switch (cmd->convert_src) {
2332 case TRIG_TIMER:
2333 case TRIG_NOW:
2334 if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
2335 timer = 1;
2336 else
2337 timer = ni_ns_to_timer(dev, cmd->convert_arg,
Ian Abbott3280c2d2014-09-03 13:45:57 +01002338 CMDF_ROUND_NEAREST);
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07002339 /* 0,0 does not work */
H Hartley Sweetena2c53732015-05-01 14:59:05 -07002340 ni_stc_writew(dev, 1, NISTC_AI_SI2_LOADA_REG);
2341 ni_stc_writew(dev, timer, NISTC_AI_SI2_LOADB_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002342
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07002343 mode2 &= ~NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* A */
2344 mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */
2345 ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002346
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002347 ni_stc_writew(dev, NISTC_AI_CMD1_SI2_LOAD, NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002348
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07002349 mode2 |= NISTC_AI_MODE2_SI2_INIT_LOAD_SRC; /* B */
2350 mode2 |= NISTC_AI_MODE2_SI2_RELOAD_MODE; /* alternate */
2351 ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002352 break;
2353 case TRIG_EXT:
Spencer E. Olsonf08a28e2016-01-12 11:05:10 -07002354 mode1 |= NISTC_AI_MODE1_CONVERT_SRC(1 +
2355 CR_CHAN(cmd->convert_arg));
David Schleef03aef4b2009-02-17 17:04:22 -08002356 if ((cmd->convert_arg & CR_INVERT) == 0)
H Hartley Sweetenbd358f52015-05-01 14:59:03 -07002357 mode1 |= NISTC_AI_MODE1_CONVERT_POLARITY;
2358 ni_stc_writew(dev, mode1, NISTC_AI_MODE1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002359
H Hartley Sweetenb134cc52015-05-01 14:59:04 -07002360 mode2 |= NISTC_AI_MODE2_SC_GATE_ENA |
2361 NISTC_AI_MODE2_START_STOP_GATE_ENA;
2362 ni_stc_writew(dev, mode2, NISTC_AI_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002363
2364 break;
2365 }
2366
2367 if (dev->irq) {
David Schleef03aef4b2009-02-17 17:04:22 -08002368 /* interrupt on FIFO, errors, SC_TC */
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002369 interrupt_a_enable |= NISTC_INTA_ENA_AI_ERR |
2370 NISTC_INTA_ENA_AI_SC_TC;
David Schleef03aef4b2009-02-17 17:04:22 -08002371
2372#ifndef PCIDMA
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002373 interrupt_a_enable |= NISTC_INTA_ENA_AI_FIFO;
David Schleef03aef4b2009-02-17 17:04:22 -08002374#endif
2375
H Hartley Sweetena1da35a2015-05-01 14:58:56 -07002376 if ((cmd->flags & CMDF_WAKE_EOS) ||
2377 (devpriv->ai_cmd2 & NISTC_AI_CMD2_END_ON_EOS)) {
David Schleef03aef4b2009-02-17 17:04:22 -08002378 /* wake on end-of-scan */
2379 devpriv->aimode = AIMODE_SCAN;
2380 } else {
2381 devpriv->aimode = AIMODE_HALF_FULL;
2382 }
2383
2384 switch (devpriv->aimode) {
2385 case AIMODE_HALF_FULL:
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07002386 /* FIFO interrupts and DMA requests on half-full */
David Schleef03aef4b2009-02-17 17:04:22 -08002387#ifdef PCIDMA
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002388 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF_E,
2389 NISTC_AI_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002390#else
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002391 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF,
2392 NISTC_AI_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002393#endif
2394 break;
2395 case AIMODE_SAMPLE:
2396 /*generate FIFO interrupts on non-empty */
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002397 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
2398 NISTC_AI_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002399 break;
2400 case AIMODE_SCAN:
2401#ifdef PCIDMA
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002402 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_NE,
2403 NISTC_AI_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002404#else
H Hartley Sweetenc7edadc2015-05-01 14:59:36 -07002405 ni_stc_writew(dev, NISTC_AI_MODE3_FIFO_MODE_HF,
2406 NISTC_AI_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002407#endif
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002408 interrupt_a_enable |= NISTC_INTA_ENA_AI_STOP;
David Schleef03aef4b2009-02-17 17:04:22 -08002409 break;
2410 default:
2411 break;
2412 }
2413
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07002414 /* clear interrupts */
H Hartley Sweeten480456d2015-05-01 14:58:54 -07002415 ni_stc_writew(dev, NISTC_INTA_ACK_AI_ALL, NISTC_INTA_ACK_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002416
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002417 ni_set_bits(dev, NISTC_INTA_ENA_REG, interrupt_a_enable, 1);
David Schleef03aef4b2009-02-17 17:04:22 -08002418 } else {
2419 /* interrupt on nothing */
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07002420 ni_set_bits(dev, NISTC_INTA_ENA_REG, ~0, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002421
2422 /* XXX start polling if necessary */
David Schleef03aef4b2009-02-17 17:04:22 -08002423 }
2424
2425 /* end configuration */
H Hartley Sweeten707502f2015-05-01 14:59:25 -07002426 ni_stc_writew(dev, NISTC_RESET_AI_CFG_END, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002427
2428 switch (cmd->scan_begin_src) {
2429 case TRIG_TIMER:
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002430 ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM |
2431 NISTC_AI_CMD1_SI_ARM |
2432 NISTC_AI_CMD1_DIV_ARM |
2433 NISTC_AI_CMD1_SC_ARM,
2434 NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002435 break;
2436 case TRIG_EXT:
H Hartley Sweeten4c4d7152015-05-01 14:58:59 -07002437 ni_stc_writew(dev, NISTC_AI_CMD1_SI2_ARM |
2438 NISTC_AI_CMD1_SI_ARM | /* XXX ? */
2439 NISTC_AI_CMD1_DIV_ARM |
2440 NISTC_AI_CMD1_SC_ARM,
2441 NISTC_AI_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002442 break;
2443 }
2444
2445#ifdef PCIDMA
2446 {
2447 int retval = ni_ai_setup_MITE_dma(dev);
H Hartley Sweetenf7401972014-07-16 11:02:08 -07002448
David Schleef03aef4b2009-02-17 17:04:22 -08002449 if (retval)
2450 return retval;
2451 }
David Schleef03aef4b2009-02-17 17:04:22 -08002452#endif
2453
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002454 if (cmd->start_src == TRIG_NOW) {
H Hartley Sweetena1da35a2015-05-01 14:58:56 -07002455 ni_stc_writew(dev, NISTC_AI_CMD2_START1_PULSE |
2456 devpriv->ai_cmd2,
2457 NISTC_AI_CMD2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002458 s->async->inttrig = NULL;
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002459 } else if (cmd->start_src == TRIG_EXT) {
David Schleef03aef4b2009-02-17 17:04:22 -08002460 s->async->inttrig = NULL;
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002461 } else { /* TRIG_INT */
2462 s->async->inttrig = ni_ai_inttrig;
David Schleef03aef4b2009-02-17 17:04:22 -08002463 }
2464
David Schleef03aef4b2009-02-17 17:04:22 -08002465 return 0;
2466}
2467
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002468static int ni_ai_insn_config(struct comedi_device *dev,
2469 struct comedi_subdevice *s,
2470 struct comedi_insn *insn, unsigned int *data)
2471{
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002472 struct ni_private *devpriv = dev->private;
2473
2474 if (insn->n < 1)
2475 return -EINVAL;
2476
2477 switch (data[0]) {
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002478 case INSN_CONFIG_ALT_SOURCE:
H Hartley Sweeten17733212014-06-19 10:20:32 -07002479 if (devpriv->is_m_series) {
H Hartley Sweeten41f9f0b2015-05-01 14:58:39 -07002480 if (data[1] & ~NI_M_CFG_BYPASS_AI_CAL_MASK)
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002481 return -EINVAL;
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002482 devpriv->ai_calib_source = data[1];
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002483 } else if (devpriv->is_6143) {
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002484 unsigned int calib_source;
2485
2486 calib_source = data[1] & 0xf;
2487
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002488 devpriv->ai_calib_source = calib_source;
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07002489 ni_writew(dev, calib_source, NI6143_CALIB_CHAN_REG);
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002490 } else {
2491 unsigned int calib_source;
2492 unsigned int calib_source_adjust;
2493
2494 calib_source = data[1] & 0xf;
2495 calib_source_adjust = (data[1] >> 4) & 0xff;
2496
2497 if (calib_source >= 8)
2498 return -EINVAL;
2499 devpriv->ai_calib_source = calib_source;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002500 if (devpriv->is_611x) {
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07002501 ni_writeb(dev, calib_source_adjust,
H Hartley Sweeten0418da52015-05-01 15:00:07 -07002502 NI611X_CAL_GAIN_SEL_REG);
H Hartley Sweetend2a577c2014-05-28 16:26:39 -07002503 }
2504 }
2505 return 2;
2506 default:
2507 break;
2508 }
2509
2510 return -EINVAL;
2511}
2512
Bill Pembertonda91b262009-04-09 16:07:03 -04002513static void ni_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302514 void *data, unsigned int num_bytes,
2515 unsigned int chan_index)
David Schleef03aef4b2009-02-17 17:04:22 -08002516{
H Hartley Sweetena10817d2014-07-14 12:23:45 -07002517 struct comedi_cmd *cmd = &s->async->cmd;
H Hartley Sweetenc39e0502014-10-31 12:04:28 -07002518 unsigned int nsamples = comedi_bytes_to_samples(s, num_bytes);
H Hartley Sweeten9663ab12014-05-27 10:31:00 -07002519 unsigned short *array = data;
David Schleef03aef4b2009-02-17 17:04:22 -08002520 unsigned int i;
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07002521#ifdef PCIDMA
2522 __le16 buf, *barray = data;
2523#endif
David Schleef03aef4b2009-02-17 17:04:22 -08002524
H Hartley Sweetenc39e0502014-10-31 12:04:28 -07002525 for (i = 0; i < nsamples; i++) {
H Hartley Sweetena10817d2014-07-14 12:23:45 -07002526 unsigned int range = CR_RANGE(cmd->chanlist[chan_index]);
2527 unsigned short val = array[i];
H Hartley Sweetenfed3c232014-07-14 12:23:40 -07002528
H Hartley Sweetena10817d2014-07-14 12:23:45 -07002529 /*
2530 * Munge data from unsigned to two's complement for
2531 * bipolar ranges.
2532 */
H Hartley Sweetenfed3c232014-07-14 12:23:40 -07002533 if (comedi_range_is_bipolar(s, range))
H Hartley Sweetena10817d2014-07-14 12:23:45 -07002534 val = comedi_offset_munge(s, val);
David Schleef03aef4b2009-02-17 17:04:22 -08002535#ifdef PCIDMA
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07002536 buf = cpu_to_le16(val);
2537 barray[i] = buf;
2538#else
H Hartley Sweetena10817d2014-07-14 12:23:45 -07002539 array[i] = val;
Ksenija Stanojevic212efdb2015-10-31 06:34:29 -07002540#endif
David Schleef03aef4b2009-02-17 17:04:22 -08002541 chan_index++;
H Hartley Sweeten9663ab12014-05-27 10:31:00 -07002542 chan_index %= cmd->chanlist_len;
David Schleef03aef4b2009-02-17 17:04:22 -08002543 }
2544}
2545
Bill Pembertonda91b262009-04-09 16:07:03 -04002546static int ni_m_series_ao_config_chanlist(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302547 struct comedi_subdevice *s,
2548 unsigned int chanspec[],
2549 unsigned int n_chans, int timed)
David Schleef03aef4b2009-02-17 17:04:22 -08002550{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002551 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08002552 unsigned int range;
2553 unsigned int chan;
2554 unsigned int conf;
2555 int i;
2556 int invert = 0;
2557
Bill Pemberton53106ae2009-04-09 16:07:21 -04002558 if (timed) {
H Hartley Sweeten47277362014-07-14 12:23:47 -07002559 for (i = 0; i < s->n_chan; ++i) {
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002560 devpriv->ao_conf[i] &= ~NI_M_AO_CFG_BANK_UPDATE_TIMED;
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07002561 ni_writeb(dev, devpriv->ao_conf[i],
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002562 NI_M_AO_CFG_BANK_REG(i));
2563 ni_writeb(dev, 0xf, NI_M_AO_WAVEFORM_ORDER_REG(i));
David Schleef03aef4b2009-02-17 17:04:22 -08002564 }
2565 }
2566 for (i = 0; i < n_chans; i++) {
Bill Pemberton1f6325d2009-03-16 22:06:31 -04002567 const struct comedi_krange *krange;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07002568
David Schleef03aef4b2009-02-17 17:04:22 -08002569 chan = CR_CHAN(chanspec[i]);
2570 range = CR_RANGE(chanspec[i]);
2571 krange = s->range_table->range + range;
2572 invert = 0;
2573 conf = 0;
2574 switch (krange->max - krange->min) {
2575 case 20000000:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002576 conf |= NI_M_AO_CFG_BANK_REF_INT_10V;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002577 ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002578 break;
2579 case 10000000:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002580 conf |= NI_M_AO_CFG_BANK_REF_INT_5V;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002581 ni_writeb(dev, 0, NI_M_AO_REF_ATTENUATION_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002582 break;
2583 case 4000000:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002584 conf |= NI_M_AO_CFG_BANK_REF_INT_10V;
H Hartley Sweetenb06afa12015-05-01 14:58:41 -07002585 ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002586 NI_M_AO_REF_ATTENUATION_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002587 break;
2588 case 2000000:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002589 conf |= NI_M_AO_CFG_BANK_REF_INT_5V;
H Hartley Sweetenb06afa12015-05-01 14:58:41 -07002590 ni_writeb(dev, NI_M_AO_REF_ATTENUATION_X5,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002591 NI_M_AO_REF_ATTENUATION_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002592 break;
2593 default:
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07002594 dev_err(dev->class_dev,
Haneen Mohammedcd255032015-03-05 13:01:49 +03002595 "bug! unhandled ao reference voltage\n");
David Schleef03aef4b2009-02-17 17:04:22 -08002596 break;
2597 }
2598 switch (krange->max + krange->min) {
2599 case 0:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002600 conf |= NI_M_AO_CFG_BANK_OFFSET_0V;
David Schleef03aef4b2009-02-17 17:04:22 -08002601 break;
2602 case 10000000:
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002603 conf |= NI_M_AO_CFG_BANK_OFFSET_5V;
David Schleef03aef4b2009-02-17 17:04:22 -08002604 break;
2605 default:
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07002606 dev_err(dev->class_dev,
Haneen Mohammedcd255032015-03-05 13:01:49 +03002607 "bug! unhandled ao offset voltage\n");
David Schleef03aef4b2009-02-17 17:04:22 -08002608 break;
2609 }
2610 if (timed)
H Hartley Sweetenbae45302015-05-01 14:58:40 -07002611 conf |= NI_M_AO_CFG_BANK_UPDATE_TIMED;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002612 ni_writeb(dev, conf, NI_M_AO_CFG_BANK_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002613 devpriv->ao_conf[chan] = conf;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002614 ni_writeb(dev, i, NI_M_AO_WAVEFORM_ORDER_REG(chan));
David Schleef03aef4b2009-02-17 17:04:22 -08002615 }
2616 return invert;
2617}
2618
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302619static int ni_old_ao_config_chanlist(struct comedi_device *dev,
2620 struct comedi_subdevice *s,
2621 unsigned int chanspec[],
2622 unsigned int n_chans)
David Schleef03aef4b2009-02-17 17:04:22 -08002623{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002624 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08002625 unsigned int range;
2626 unsigned int chan;
2627 unsigned int conf;
2628 int i;
2629 int invert = 0;
2630
2631 for (i = 0; i < n_chans; i++) {
2632 chan = CR_CHAN(chanspec[i]);
2633 range = CR_RANGE(chanspec[i]);
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002634 conf = NI_E_AO_DACSEL(chan);
David Schleef03aef4b2009-02-17 17:04:22 -08002635
H Hartley Sweetenfed3c232014-07-14 12:23:40 -07002636 if (comedi_range_is_bipolar(s, range)) {
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002637 conf |= NI_E_AO_CFG_BIP;
H Hartley Sweeten47277362014-07-14 12:23:47 -07002638 invert = (s->maxdata + 1) >> 1;
H Hartley Sweetenfed3c232014-07-14 12:23:40 -07002639 } else {
2640 invert = 0;
David Schleef03aef4b2009-02-17 17:04:22 -08002641 }
H Hartley Sweetenfed3c232014-07-14 12:23:40 -07002642 if (comedi_range_is_external(s, range))
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002643 conf |= NI_E_AO_EXT_REF;
David Schleef03aef4b2009-02-17 17:04:22 -08002644
2645 /* not all boards can deglitch, but this shouldn't hurt */
2646 if (chanspec[i] & CR_DEGLITCH)
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002647 conf |= NI_E_AO_DEGLITCH;
David Schleef03aef4b2009-02-17 17:04:22 -08002648
2649 /* analog reference */
2650 /* AREF_OTHER connects AO ground to AI ground, i think */
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002651 if (CR_AREF(chanspec[i]) == AREF_OTHER)
2652 conf |= NI_E_AO_GROUND_REF;
David Schleef03aef4b2009-02-17 17:04:22 -08002653
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07002654 ni_writew(dev, conf, NI_E_AO_CFG_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002655 devpriv->ao_conf[chan] = conf;
2656 }
2657 return invert;
2658}
2659
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302660static int ni_ao_config_chanlist(struct comedi_device *dev,
2661 struct comedi_subdevice *s,
2662 unsigned int chanspec[], unsigned int n_chans,
2663 int timed)
David Schleef03aef4b2009-02-17 17:04:22 -08002664{
H Hartley Sweeten17733212014-06-19 10:20:32 -07002665 struct ni_private *devpriv = dev->private;
H Hartley Sweeten6293e352013-03-05 10:20:41 -07002666
H Hartley Sweeten17733212014-06-19 10:20:32 -07002667 if (devpriv->is_m_series)
David Schleef03aef4b2009-02-17 17:04:22 -08002668 return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302669 timed);
David Schleef03aef4b2009-02-17 17:04:22 -08002670 else
2671 return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
2672}
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302673
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302674static int ni_ao_insn_write(struct comedi_device *dev,
2675 struct comedi_subdevice *s,
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002676 struct comedi_insn *insn,
2677 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08002678{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002679 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08002680 unsigned int chan = CR_CHAN(insn->chanspec);
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002681 unsigned int range = CR_RANGE(insn->chanspec);
2682 int reg;
2683 int i;
David Schleef03aef4b2009-02-17 17:04:22 -08002684
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002685 if (devpriv->is_6xxx) {
H Hartley Sweetenef391542015-05-01 15:00:11 -07002686 ni_ao_win_outw(dev, 1 << chan, NI671X_AO_IMMEDIATE_REG);
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002687
H Hartley Sweetenef391542015-05-01 15:00:11 -07002688 reg = NI671X_DAC_DIRECT_DATA_REG(chan);
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002689 } else if (devpriv->is_m_series) {
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07002690 reg = NI_M_DAC_DIRECT_DATA_REG(chan);
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002691 } else {
H Hartley Sweeten25e941a2015-05-01 15:00:01 -07002692 reg = NI_E_DAC_DIRECT_DATA_REG(chan);
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002693 }
David Schleef03aef4b2009-02-17 17:04:22 -08002694
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002695 ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08002696
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002697 for (i = 0; i < insn->n; i++) {
2698 unsigned int val = data[i];
David Schleef03aef4b2009-02-17 17:04:22 -08002699
H Hartley Sweetenb6d977e2014-08-25 16:04:15 -07002700 s->readback[chan] = val;
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002701
H Hartley Sweeten79816da12014-07-14 12:23:48 -07002702 if (devpriv->is_6xxx) {
2703 /*
2704 * 6xxx boards have bipolar outputs, munge the
2705 * unsigned comedi values to 2's complement
2706 */
2707 val = comedi_offset_munge(s, val);
2708
2709 ni_ao_win_outw(dev, val, reg);
2710 } else if (devpriv->is_m_series) {
2711 /*
2712 * M-series boards use offset binary values for
2713 * bipolar and uinpolar outputs
2714 */
H Hartley Sweetenbfb0c282014-07-14 12:23:43 -07002715 ni_writew(dev, val, reg);
2716 } else {
2717 /*
2718 * Non-M series boards need two's complement values
2719 * for bipolar ranges.
2720 */
2721 if (comedi_range_is_bipolar(s, range))
2722 val = comedi_offset_munge(s, val);
2723
2724 ni_writew(dev, val, reg);
2725 }
2726 }
2727
2728 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08002729}
2730
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302731static int ni_ao_insn_config(struct comedi_device *dev,
2732 struct comedi_subdevice *s,
2733 struct comedi_insn *insn, unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08002734{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01002735 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002736 struct ni_private *devpriv = dev->private;
H Hartley Sweeten836b5712014-10-31 12:04:29 -07002737 unsigned int nbytes;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002738
David Schleef03aef4b2009-02-17 17:04:22 -08002739 switch (data[0]) {
2740 case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302741 switch (data[1]) {
David Schleef03aef4b2009-02-17 17:04:22 -08002742 case COMEDI_OUTPUT:
H Hartley Sweeten836b5712014-10-31 12:04:29 -07002743 nbytes = comedi_samples_to_bytes(s,
2744 board->ao_fifo_depth);
2745 data[2] = 1 + nbytes;
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05302746 if (devpriv->mite)
2747 data[2] += devpriv->mite->fifo_size;
David Schleef03aef4b2009-02-17 17:04:22 -08002748 break;
2749 case COMEDI_INPUT:
2750 data[2] = 0;
2751 break;
2752 default:
2753 return -EINVAL;
David Schleef03aef4b2009-02-17 17:04:22 -08002754 }
2755 return 0;
2756 default:
2757 break;
2758 }
2759
2760 return -EINVAL;
2761}
2762
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002763static int ni_ao_inttrig(struct comedi_device *dev,
2764 struct comedi_subdevice *s,
2765 unsigned int trig_num)
David Schleef03aef4b2009-02-17 17:04:22 -08002766{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07002767 struct ni_private *devpriv = dev->private;
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07002768 struct comedi_cmd *cmd = &s->async->cmd;
David Schleef03aef4b2009-02-17 17:04:22 -08002769 int ret;
2770 int interrupt_b_bits;
2771 int i;
2772 static const int timeout = 1000;
2773
Ian Abbottf0f4b0cc3a2016-07-19 12:17:39 +01002774 /*
2775 * Require trig_num == cmd->start_arg when cmd->start_src == TRIG_INT.
2776 * For backwards compatibility, also allow trig_num == 0 when
2777 * cmd->start_src != TRIG_INT (i.e. when cmd->start_src == TRIG_EXT);
2778 * in that case, the internal trigger is being used as a pre-trigger
2779 * before the external trigger.
2780 */
2781 if (!(trig_num == cmd->start_arg ||
2782 (trig_num == 0 && cmd->start_src != TRIG_INT)))
David Schleef03aef4b2009-02-17 17:04:22 -08002783 return -EINVAL;
2784
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07002785 /*
2786 * Null trig at beginning prevent ao start trigger from executing more
2787 * than once per command (and doing things like trying to allocate the
2788 * ao dma channel multiple times).
2789 */
David Schleef03aef4b2009-02-17 17:04:22 -08002790 s->async->inttrig = NULL;
2791
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07002792 ni_set_bits(dev, NISTC_INTB_ENA_REG,
2793 NISTC_INTB_ENA_AO_FIFO | NISTC_INTB_ENA_AO_ERR, 0);
2794 interrupt_b_bits = NISTC_INTB_ENA_AO_ERR;
David Schleef03aef4b2009-02-17 17:04:22 -08002795#ifdef PCIDMA
H Hartley Sweeten8102f3d2015-05-01 14:59:34 -07002796 ni_stc_writew(dev, 1, NISTC_DAC_FIFO_CLR_REG);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07002797 if (devpriv->is_6xxx)
H Hartley Sweetenef391542015-05-01 15:00:11 -07002798 ni_ao_win_outl(dev, 0x6, NI611X_AO_FIFO_OFFSET_LOAD_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002799 ret = ni_ao_setup_MITE_dma(dev);
2800 if (ret)
2801 return ret;
2802 ret = ni_ao_wait_for_dma_load(dev);
2803 if (ret < 0)
2804 return ret;
2805#else
2806 ret = ni_ao_prep_fifo(dev, s);
2807 if (ret == 0)
2808 return -EPIPE;
2809
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07002810 interrupt_b_bits |= NISTC_INTB_ENA_AO_FIFO;
David Schleef03aef4b2009-02-17 17:04:22 -08002811#endif
2812
H Hartley Sweeten72bca4f2015-05-01 14:59:24 -07002813 ni_stc_writew(dev, devpriv->ao_mode3 | NISTC_AO_MODE3_NOT_AN_UPDATE,
2814 NISTC_AO_MODE3_REG);
2815 ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002816 /* wait for DACs to be loaded */
2817 for (i = 0; i < timeout; i++) {
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07002818 udelay(1);
H Hartley Sweetenbab382e2015-05-01 14:59:48 -07002819 if ((ni_stc_readw(dev, NISTC_STATUS2_REG) &
2820 NISTC_STATUS2_AO_TMRDACWRS_IN_PROGRESS) == 0)
David Schleef03aef4b2009-02-17 17:04:22 -08002821 break;
2822 }
2823 if (i == timeout) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07002824 dev_err(dev->class_dev,
2825 "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear\n");
David Schleef03aef4b2009-02-17 17:04:22 -08002826 return -EIO;
2827 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07002828 /*
2829 * stc manual says we are need to clear error interrupt after
2830 * AO_TMRDACWRs_In_Progress_St clears
2831 */
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07002832 ni_stc_writew(dev, NISTC_INTB_ACK_AO_ERR, NISTC_INTB_ACK_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002833
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07002834 ni_set_bits(dev, NISTC_INTB_ENA_REG, interrupt_b_bits, 1);
David Schleef03aef4b2009-02-17 17:04:22 -08002835
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07002836 ni_stc_writew(dev, NISTC_AO_CMD1_UI_ARM |
2837 NISTC_AO_CMD1_UC_ARM |
2838 NISTC_AO_CMD1_BC_ARM |
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07002839 devpriv->ao_cmd1,
2840 NISTC_AO_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002841
H Hartley Sweeten382b3c42015-05-01 14:58:57 -07002842 ni_stc_writew(dev, NISTC_AO_CMD2_START1_PULSE | devpriv->ao_cmd2,
2843 NISTC_AO_CMD2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002844
2845 return 0;
2846}
2847
Spencer E. Olson080e6792016-01-27 14:28:27 -07002848/*
2849 * begin ni_ao_cmd.
2850 * Organized similar to NI-STC and MHDDK examples.
2851 * ni_ao_cmd is broken out into configuration sub-routines for clarity.
2852 */
2853
2854static void ni_ao_cmd_personalize(struct comedi_device *dev,
2855 const struct comedi_cmd *cmd)
David Schleef03aef4b2009-02-17 17:04:22 -08002856{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01002857 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07002858 unsigned int bits;
David Schleef03aef4b2009-02-17 17:04:22 -08002859
H Hartley Sweeten707502f2015-05-01 14:59:25 -07002860 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002861
Spencer E. Olson080e6792016-01-27 14:28:27 -07002862 bits =
2863 /* fast CPU interface--only eseries */
2864 /* ((slow CPU interface) ? 0 : AO_Fast_CPU) | */
2865 NISTC_AO_PERSONAL_BC_SRC_SEL |
2866 0 /* (use_original_pulse ? 0 : NISTC_AO_PERSONAL_UPDATE_TIMEBASE) */ |
2867 /*
2868 * FIXME: start setting following bit when appropriate. Need to
2869 * determine whether board is E4 or E1.
2870 * FROM MHHDK:
2871 * if board is E4 or E1
2872 * Set bit "NISTC_AO_PERSONAL_UPDATE_PW" to 0
2873 * else
2874 * set it to 1
2875 */
2876 NISTC_AO_PERSONAL_UPDATE_PW |
2877 /* FIXME: when should we set following bit to zero? */
2878 NISTC_AO_PERSONAL_TMRDACWR_PW |
2879 (board->ao_fifo_depth ?
2880 NISTC_AO_PERSONAL_FIFO_ENA : NISTC_AO_PERSONAL_DMA_PIO_CTRL)
2881 ;
2882#if 0
2883 /*
2884 * FIXME:
2885 * add something like ".has_individual_dacs = 0" to ni_board_struct
2886 * since, as F Hess pointed out, not all in m series have singles. not
2887 * sure if e-series all have duals...
2888 */
David Schleef03aef4b2009-02-17 17:04:22 -08002889
Spencer E. Olson080e6792016-01-27 14:28:27 -07002890 /*
2891 * F Hess: windows driver does not set NISTC_AO_PERSONAL_NUM_DAC bit for
2892 * 6281, verified with bus analyzer.
2893 */
2894 if (devpriv->is_m_series)
2895 bits |= NISTC_AO_PERSONAL_NUM_DAC;
2896#endif
2897 ni_stc_writew(dev, bits, NISTC_AO_PERSONAL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002898
Spencer E. Olson080e6792016-01-27 14:28:27 -07002899 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
2900}
David Schleef03aef4b2009-02-17 17:04:22 -08002901
Spencer E. Olson080e6792016-01-27 14:28:27 -07002902static void ni_ao_cmd_set_trigger(struct comedi_device *dev,
2903 const struct comedi_cmd *cmd)
2904{
2905 struct ni_private *devpriv = dev->private;
H Hartley Sweeten55f9e7d2016-04-14 09:58:00 -07002906 unsigned int trigsel;
David Schleef03aef4b2009-02-17 17:04:22 -08002907
Spencer E. Olson080e6792016-01-27 14:28:27 -07002908 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002909
Spencer E. Olson080e6792016-01-27 14:28:27 -07002910 /* sync */
David Schleef03aef4b2009-02-17 17:04:22 -08002911 if (cmd->stop_src == TRIG_NONE) {
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07002912 devpriv->ao_mode1 |= NISTC_AO_MODE1_CONTINUOUS;
2913 devpriv->ao_mode1 &= ~NISTC_AO_MODE1_TRIGGER_ONCE;
David Schleef03aef4b2009-02-17 17:04:22 -08002914 } else {
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07002915 devpriv->ao_mode1 &= ~NISTC_AO_MODE1_CONTINUOUS;
2916 devpriv->ao_mode1 |= NISTC_AO_MODE1_TRIGGER_ONCE;
David Schleef03aef4b2009-02-17 17:04:22 -08002917 }
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07002918 ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
H Hartley Sweetenf21844d2015-05-01 14:59:22 -07002919
H Hartley Sweeten55f9e7d2016-04-14 09:58:00 -07002920 if (cmd->start_src == TRIG_INT) {
2921 trigsel = NISTC_AO_TRIG_START1_EDGE |
2922 NISTC_AO_TRIG_START1_SYNC;
2923 } else { /* TRIG_EXT */
2924 trigsel = NISTC_AO_TRIG_START1_SEL(CR_CHAN(cmd->start_arg) + 1);
2925 /* 0=active high, 1=active low. see daq-stc 3-24 (p186) */
2926 if (cmd->start_arg & CR_INVERT)
2927 trigsel |= NISTC_AO_TRIG_START1_POLARITY;
2928 /* 0=edge detection disabled, 1=enabled */
2929 if (cmd->start_arg & CR_EDGE)
2930 trigsel |= NISTC_AO_TRIG_START1_EDGE;
David Schleef03aef4b2009-02-17 17:04:22 -08002931 }
H Hartley Sweeten55f9e7d2016-04-14 09:58:00 -07002932 ni_stc_writew(dev, trigsel, NISTC_AO_TRIG_SEL_REG);
2933
Spencer E. Olson080e6792016-01-27 14:28:27 -07002934 /* AO_Delayed_START1 = 0, we do not support delayed start...yet */
H Hartley Sweetenf21844d2015-05-01 14:59:22 -07002935
Spencer E. Olson080e6792016-01-27 14:28:27 -07002936 /* sync */
2937 /* select DA_START1 as PFI6/AO_START1 when configured as an output */
H Hartley Sweeten72bca4f2015-05-01 14:59:24 -07002938 devpriv->ao_mode3 &= ~NISTC_AO_MODE3_TRIG_LEN;
2939 ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08002940
Spencer E. Olson080e6792016-01-27 14:28:27 -07002941 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
2942}
2943
2944static void ni_ao_cmd_set_counters(struct comedi_device *dev,
2945 const struct comedi_cmd *cmd)
2946{
2947 struct ni_private *devpriv = dev->private;
2948 /* Not supporting 'waveform staging' or 'local buffer with pauses' */
2949
2950 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
2951 /*
2952 * This relies on ao_mode1/(Trigger_Once | Continuous) being set in
2953 * set_trigger above. It is unclear whether we really need to re-write
2954 * this register with these values. The mhddk examples for e-series
2955 * show writing this in both places, but the examples for m-series show
2956 * a single write in the set_counters function (here).
2957 */
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07002958 ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
Spencer E. Olson080e6792016-01-27 14:28:27 -07002959
2960 /* sync (upload number of buffer iterations -1) */
2961 /* indicate that we want to use BC_Load_A_Register as the source */
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07002962 devpriv->ao_mode2 &= ~NISTC_AO_MODE2_BC_INIT_LOAD_SRC;
2963 ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
Spencer E. Olson080e6792016-01-27 14:28:27 -07002964
2965 /*
2966 * if the BC_TC interrupt is still issued in spite of UC, BC, UI
2967 * ignoring BC_TC, then we will need to find a way to ignore that
2968 * interrupt in continuous mode.
2969 */
2970 ni_stc_writel(dev, 0, NISTC_AO_BC_LOADA_REG); /* iter once */
2971
2972 /* sync (issue command to load number of buffer iterations -1) */
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07002973 ni_stc_writew(dev, NISTC_AO_CMD1_BC_LOAD, NISTC_AO_CMD1_REG);
Spencer E. Olson080e6792016-01-27 14:28:27 -07002974
2975 /* sync (upload number of updates in buffer) */
2976 /* indicate that we want to use UC_Load_A_Register as the source */
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07002977 devpriv->ao_mode2 &= ~NISTC_AO_MODE2_UC_INIT_LOAD_SRC;
2978 ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
Spencer E. Olson080e6792016-01-27 14:28:27 -07002979
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07002980 /*
2981 * if a user specifies '0', this automatically assumes the entire 24bit
2982 * address space is available for the (multiple iterations of single
2983 * buffer) MISB. Otherwise, stop_arg specifies the MISB length that
2984 * will be used, regardless of whether we are in continuous mode or not.
2985 * In continuous mode, the output will just iterate indefinitely over
2986 * the MISB.
2987 */
Spencer E. Olson080e6792016-01-27 14:28:27 -07002988 {
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07002989 unsigned int stop_arg = cmd->stop_arg > 0 ?
Spencer E. Olson080e6792016-01-27 14:28:27 -07002990 (cmd->stop_arg & 0xffffff) : 0xffffff;
2991
H Hartley Sweeten17733212014-06-19 10:20:32 -07002992 if (devpriv->is_m_series) {
Spencer E. Olson080e6792016-01-27 14:28:27 -07002993 /*
2994 * this is how the NI example code does it for m-series
2995 * boards, verified correct with 6259
2996 */
2997 ni_stc_writel(dev, stop_arg - 1, NISTC_AO_UC_LOADA_REG);
2998
2999 /* sync (issue cmd to load number of updates in MISB) */
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07003000 ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD,
3001 NISTC_AO_CMD1_REG);
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303002 } else {
Spencer E. Olson080e6792016-01-27 14:28:27 -07003003 ni_stc_writel(dev, stop_arg, NISTC_AO_UC_LOADA_REG);
3004
3005 /* sync (issue cmd to load number of updates in MISB) */
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07003006 ni_stc_writew(dev, NISTC_AO_CMD1_UC_LOAD,
3007 NISTC_AO_CMD1_REG);
Spencer E. Olson080e6792016-01-27 14:28:27 -07003008
3009 /*
3010 * sync (upload number of updates-1 in MISB)
3011 * --eseries only?
3012 */
3013 ni_stc_writel(dev, stop_arg - 1, NISTC_AO_UC_LOADA_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003014 }
David Schleef03aef4b2009-02-17 17:04:22 -08003015 }
3016
Spencer E. Olson080e6792016-01-27 14:28:27 -07003017 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
3018}
3019
3020static void ni_ao_cmd_set_update(struct comedi_device *dev,
3021 const struct comedi_cmd *cmd)
3022{
3023 struct ni_private *devpriv = dev->private;
3024
3025 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
3026
3027 /*
3028 * zero out these bit fields to be set below. Does an ao-reset do this
3029 * automatically?
3030 */
3031 devpriv->ao_mode1 &= ~(
3032 NISTC_AO_MODE1_UI_SRC_MASK |
3033 NISTC_AO_MODE1_UI_SRC_POLARITY |
3034 NISTC_AO_MODE1_UPDATE_SRC_MASK |
3035 NISTC_AO_MODE1_UPDATE_SRC_POLARITY
3036 );
3037
H Hartley Sweeten1392dcc2016-04-14 09:58:01 -07003038 if (cmd->scan_begin_src == TRIG_TIMER) {
3039 unsigned int trigvar;
3040
Spencer E. Olson080e6792016-01-27 14:28:27 -07003041 devpriv->ao_cmd2 &= ~NISTC_AO_CMD2_BC_GATE_ENA;
3042
3043 /*
3044 * NOTE: there are several other ways of configuring internal
3045 * updates, but we'll only support one for now: using
3046 * AO_IN_TIMEBASE, w/o waveform staging, w/o a delay between
3047 * START1 and first update, and also w/o local buffer mode w/
3048 * pauses.
3049 */
3050
3051 /*
3052 * This is already done above:
3053 * devpriv->ao_mode1 &= ~(
3054 * // set UPDATE_Source to UI_TC:
3055 * NISTC_AO_MODE1_UPDATE_SRC_MASK |
3056 * // set UPDATE_Source_Polarity to rising (required?)
3057 * NISTC_AO_MODE1_UPDATE_SRC_POLARITY |
3058 * // set UI_Source to AO_IN_TIMEBASE1:
3059 * NISTC_AO_MODE1_UI_SRC_MASK |
3060 * // set UI_Source_Polarity to rising (required?)
3061 * NISTC_AO_MODE1_UI_SRC_POLARITY
3062 * );
3063 */
3064
3065 /*
3066 * TODO: use ao_ui_clock_source to allow all possible signals
3067 * to be routed to UI_Source_Select. See tSTC.h for
3068 * eseries/ni67xx and tMSeries.h for mseries.
3069 */
3070
H Hartley Sweeten1392dcc2016-04-14 09:58:01 -07003071 trigvar = ni_ns_to_timer(dev, cmd->scan_begin_arg,
3072 CMDF_ROUND_NEAREST);
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003073
H Hartley Sweeten1392dcc2016-04-14 09:58:01 -07003074 /*
3075 * Wait N TB3 ticks after the start trigger before
3076 * clocking (N must be >=2).
3077 */
3078 /* following line: 2-1 per STC */
3079 ni_stc_writel(dev, 1, NISTC_AO_UI_LOADA_REG);
3080 ni_stc_writew(dev, NISTC_AO_CMD1_UI_LOAD, NISTC_AO_CMD1_REG);
Ian Abbott2bc52402017-06-30 12:02:18 +01003081 ni_stc_writel(dev, trigvar, NISTC_AO_UI_LOADA_REG);
H Hartley Sweeten1392dcc2016-04-14 09:58:01 -07003082 } else { /* TRIG_EXT */
Spencer E. Olson080e6792016-01-27 14:28:27 -07003083 /* FIXME: assert scan_begin_arg != 0, ret failure otherwise */
3084 devpriv->ao_cmd2 |= NISTC_AO_CMD2_BC_GATE_ENA;
3085 devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC(
3086 CR_CHAN(cmd->scan_begin_arg));
David Schleef03aef4b2009-02-17 17:04:22 -08003087 if (cmd->scan_begin_arg & CR_INVERT)
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07003088 devpriv->ao_mode1 |= NISTC_AO_MODE1_UPDATE_SRC_POLARITY;
David Schleef03aef4b2009-02-17 17:04:22 -08003089 }
Spencer E. Olson080e6792016-01-27 14:28:27 -07003090
H Hartley Sweeten382b3c42015-05-01 14:58:57 -07003091 ni_stc_writew(dev, devpriv->ao_cmd2, NISTC_AO_CMD2_REG);
H Hartley Sweeten4e5ce0a2015-05-01 14:59:07 -07003092 ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07003093 devpriv->ao_mode2 &= ~(NISTC_AO_MODE2_UI_RELOAD_MODE(3) |
3094 NISTC_AO_MODE2_UI_INIT_LOAD_SRC);
3095 ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003096
Spencer E. Olsond2a6c322016-01-27 14:28:26 -07003097 /* Configure DAQ-STC for Timed update mode */
3098 devpriv->ao_cmd1 |= NISTC_AO_CMD1_DAC1_UPDATE_MODE |
3099 NISTC_AO_CMD1_DAC0_UPDATE_MODE;
3100 /* We are not using UPDATE2-->don't have to set DACx_Source_Select */
3101 ni_stc_writew(dev, devpriv->ao_cmd1, NISTC_AO_CMD1_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003102
Spencer E. Olson080e6792016-01-27 14:28:27 -07003103 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
3104}
3105
3106static void ni_ao_cmd_set_channels(struct comedi_device *dev,
3107 struct comedi_subdevice *s)
3108{
3109 struct ni_private *devpriv = dev->private;
3110 const struct comedi_cmd *cmd = &s->async->cmd;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003111 unsigned int bits = 0;
Spencer E. Olson080e6792016-01-27 14:28:27 -07003112
3113 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
3114
3115 if (devpriv->is_6xxx) {
3116 unsigned int i;
3117
3118 bits = 0;
3119 for (i = 0; i < cmd->chanlist_len; ++i) {
3120 int chan = CR_CHAN(cmd->chanlist[i]);
3121
3122 bits |= 1 << chan;
3123 ni_ao_win_outw(dev, chan, NI611X_AO_WAVEFORM_GEN_REG);
3124 }
3125 ni_ao_win_outw(dev, bits, NI611X_AO_TIMED_REG);
3126 }
3127
3128 ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
3129
3130 if (cmd->scan_end_arg > 1) {
3131 devpriv->ao_mode1 |= NISTC_AO_MODE1_MULTI_CHAN;
3132 bits = NISTC_AO_OUT_CTRL_CHANS(cmd->scan_end_arg - 1)
3133 | NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ;
3134
3135 } else {
3136 devpriv->ao_mode1 &= ~NISTC_AO_MODE1_MULTI_CHAN;
3137 bits = NISTC_AO_OUT_CTRL_UPDATE_SEL_HIGHZ;
3138 if (devpriv->is_m_series | devpriv->is_6xxx)
3139 bits |= NISTC_AO_OUT_CTRL_CHANS(0);
3140 else
3141 bits |= NISTC_AO_OUT_CTRL_CHANS(
3142 CR_CHAN(cmd->chanlist[0]));
3143 }
3144
3145 ni_stc_writew(dev, devpriv->ao_mode1, NISTC_AO_MODE1_REG);
3146 ni_stc_writew(dev, bits, NISTC_AO_OUT_CTRL_REG);
3147
3148 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
3149}
3150
3151static void ni_ao_cmd_set_stop_conditions(struct comedi_device *dev,
3152 const struct comedi_cmd *cmd)
3153{
3154 struct ni_private *devpriv = dev->private;
3155
3156 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
3157
H Hartley Sweeten72bca4f2015-05-01 14:59:24 -07003158 devpriv->ao_mode3 |= NISTC_AO_MODE3_STOP_ON_OVERRUN_ERR;
3159 ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003160
Spencer E. Olson080e6792016-01-27 14:28:27 -07003161 /*
3162 * Since we are not supporting waveform staging, we ignore these errors:
3163 * NISTC_AO_MODE3_STOP_ON_BC_TC_ERR,
3164 * NISTC_AO_MODE3_STOP_ON_BC_TC_TRIG_ERR
3165 */
3166
3167 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
3168}
3169
3170static void ni_ao_cmd_set_fifo_mode(struct comedi_device *dev)
3171{
3172 struct ni_private *devpriv = dev->private;
3173
3174 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
3175
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07003176 devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_MODE_MASK;
David Schleef03aef4b2009-02-17 17:04:22 -08003177#ifdef PCIDMA
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07003178 devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF_F;
David Schleef03aef4b2009-02-17 17:04:22 -08003179#else
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07003180 devpriv->ao_mode2 |= NISTC_AO_MODE2_FIFO_MODE_HF;
David Schleef03aef4b2009-02-17 17:04:22 -08003181#endif
Spencer E. Olson080e6792016-01-27 14:28:27 -07003182 /* NOTE: this is where use_onboard_memory=True would be implemented */
H Hartley Sweetenec8bf722015-05-01 14:59:08 -07003183 devpriv->ao_mode2 &= ~NISTC_AO_MODE2_FIFO_REXMIT_ENA;
3184 ni_stc_writew(dev, devpriv->ao_mode2, NISTC_AO_MODE2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003185
Spencer E. Olson080e6792016-01-27 14:28:27 -07003186 /* enable sending of ao fifo requests (dma request) */
H Hartley Sweeten2b6285da2015-05-01 14:59:21 -07003187 ni_stc_writew(dev, NISTC_AO_START_AOFREQ_ENA, NISTC_AO_START_SEL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003188
H Hartley Sweeten707502f2015-05-01 14:59:25 -07003189 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003190
Spencer E. Olson080e6792016-01-27 14:28:27 -07003191 /* we are not supporting boards with virtual fifos */
3192}
3193
3194static void ni_ao_cmd_set_interrupts(struct comedi_device *dev,
3195 struct comedi_subdevice *s)
3196{
3197 if (s->async->cmd.stop_src == TRIG_COUNT)
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07003198 ni_set_bits(dev, NISTC_INTB_ENA_REG,
3199 NISTC_INTB_ENA_AO_BC_TC, 1);
David Schleef03aef4b2009-02-17 17:04:22 -08003200
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003201 s->async->inttrig = ni_ao_inttrig;
Spencer E. Olson080e6792016-01-27 14:28:27 -07003202}
David Schleef03aef4b2009-02-17 17:04:22 -08003203
Spencer E. Olson080e6792016-01-27 14:28:27 -07003204static int ni_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
3205{
3206 struct ni_private *devpriv = dev->private;
3207 const struct comedi_cmd *cmd = &s->async->cmd;
3208
3209 if (dev->irq == 0) {
3210 dev_err(dev->class_dev, "cannot run command without an irq");
3211 return -EIO;
3212 }
3213
3214 /* ni_ao_reset should have already been done */
3215 ni_ao_cmd_personalize(dev, cmd);
3216 /* clearing fifo and preload happens elsewhere */
3217
3218 ni_ao_cmd_set_trigger(dev, cmd);
3219 ni_ao_cmd_set_counters(dev, cmd);
3220 ni_ao_cmd_set_update(dev, cmd);
3221 ni_ao_cmd_set_channels(dev, s);
3222 ni_ao_cmd_set_stop_conditions(dev, cmd);
3223 ni_ao_cmd_set_fifo_mode(dev);
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07003224 ni_cmd_set_mite_transfer(devpriv->ao_mite_ring, s, cmd, 0x00ffffff);
Spencer E. Olson080e6792016-01-27 14:28:27 -07003225 ni_ao_cmd_set_interrupts(dev, s);
3226
3227 /*
3228 * arm(ing) and star(ting) happen in ni_ao_inttrig, which _must_ be
3229 * called for ao commands since 1) TRIG_NOW is not supported and 2) DMA
3230 * must be setup and initially written to before arm/start happen.
3231 */
David Schleef03aef4b2009-02-17 17:04:22 -08003232 return 0;
3233}
3234
Spencer E. Olson080e6792016-01-27 14:28:27 -07003235/* end ni_ao_cmd */
3236
Bill Pembertonda91b262009-04-09 16:07:03 -04003237static int ni_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303238 struct comedi_cmd *cmd)
David Schleef03aef4b2009-02-17 17:04:22 -08003239{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01003240 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003241 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08003242 int err = 0;
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003243 unsigned int tmp;
David Schleef03aef4b2009-02-17 17:04:22 -08003244
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003245 /* Step 1 : check if triggers are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08003246
Ian Abbott311fd9b2015-03-27 19:14:24 +00003247 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT);
3248 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003249 TRIG_TIMER | TRIG_EXT);
Ian Abbott311fd9b2015-03-27 19:14:24 +00003250 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
3251 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
3252 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
David Schleef03aef4b2009-02-17 17:04:22 -08003253
3254 if (err)
3255 return 1;
3256
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003257 /* Step 2a : make sure trigger sources are unique */
David Schleef03aef4b2009-02-17 17:04:22 -08003258
Ian Abbott311fd9b2015-03-27 19:14:24 +00003259 err |= comedi_check_trigger_is_unique(cmd->start_src);
3260 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
3261 err |= comedi_check_trigger_is_unique(cmd->stop_src);
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003262
3263 /* Step 2b : and mutually compatible */
David Schleef03aef4b2009-02-17 17:04:22 -08003264
3265 if (err)
3266 return 2;
3267
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003268 /* Step 3: check if arguments are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08003269
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003270 switch (cmd->start_src) {
3271 case TRIG_INT:
Ian Abbott311fd9b2015-03-27 19:14:24 +00003272 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003273 break;
3274 case TRIG_EXT:
3275 tmp = CR_CHAN(cmd->start_arg);
David Schleef03aef4b2009-02-17 17:04:22 -08003276
3277 if (tmp > 18)
3278 tmp = 18;
3279 tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
Ian Abbott311fd9b2015-03-27 19:14:24 +00003280 err |= comedi_check_trigger_arg_is(&cmd->start_arg, tmp);
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003281 break;
David Schleef03aef4b2009-02-17 17:04:22 -08003282 }
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003283
David Schleef03aef4b2009-02-17 17:04:22 -08003284 if (cmd->scan_begin_src == TRIG_TIMER) {
Ian Abbott311fd9b2015-03-27 19:14:24 +00003285 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
3286 board->ao_speed);
3287 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
3288 devpriv->clock_ns *
3289 0xffffff);
David Schleef03aef4b2009-02-17 17:04:22 -08003290 }
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003291
Ian Abbott311fd9b2015-03-27 19:14:24 +00003292 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
3293 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
3294 cmd->chanlist_len);
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07003295 err |= comedi_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff);
David Schleef03aef4b2009-02-17 17:04:22 -08003296
3297 if (err)
3298 return 3;
3299
3300 /* step 4: fix up any arguments */
3301 if (cmd->scan_begin_src == TRIG_TIMER) {
3302 tmp = cmd->scan_begin_arg;
3303 cmd->scan_begin_arg =
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303304 ni_timer_to_ns(dev, ni_ns_to_timer(dev,
3305 cmd->scan_begin_arg,
H Hartley Sweetena207c122014-07-18 17:01:16 -07003306 cmd->flags));
David Schleef03aef4b2009-02-17 17:04:22 -08003307 if (tmp != cmd->scan_begin_arg)
3308 err++;
3309 }
3310 if (err)
3311 return 4;
3312
David Schleef03aef4b2009-02-17 17:04:22 -08003313 return 0;
3314}
3315
Bill Pembertonda91b262009-04-09 16:07:03 -04003316static int ni_ao_reset(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08003317{
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003318 /* See 3.6.1.2 "Resetting", of DAQ-STC Technical Reference Manual */
3319
3320 /*
3321 * In the following, the "--sync" comments are meant to denote
3322 * asynchronous boundaries for setting the registers as described in the
3323 * DAQ-STC mostly in the order also described in the DAQ-STC.
3324 */
3325
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003326 struct ni_private *devpriv = dev->private;
3327
David Schleef03aef4b2009-02-17 17:04:22 -08003328 ni_release_ao_mite_channel(dev);
3329
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003330 /* --sync (reset AO) */
3331 if (devpriv->is_m_series)
3332 /* following example in mhddk for m-series */
3333 ni_stc_writew(dev, NISTC_RESET_AO, NISTC_RESET_REG);
3334
3335 /*--sync (start config) */
H Hartley Sweeten707502f2015-05-01 14:59:25 -07003336 ni_stc_writew(dev, NISTC_RESET_AO_CFG_START, NISTC_RESET_REG);
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003337
3338 /*--sync (Disarm) */
H Hartley Sweeten7bfcc2d2015-05-01 14:59:00 -07003339 ni_stc_writew(dev, NISTC_AO_CMD1_DISARM, NISTC_AO_CMD1_REG);
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003340
3341 /*
3342 * --sync
3343 * (clear bunch of registers--mseries mhddk examples do not include
3344 * this)
3345 */
3346 devpriv->ao_cmd1 = 0;
3347 devpriv->ao_cmd2 = 0;
David Schleef03aef4b2009-02-17 17:04:22 -08003348 devpriv->ao_mode1 = 0;
David Schleef03aef4b2009-02-17 17:04:22 -08003349 devpriv->ao_mode2 = 0;
H Hartley Sweeten17733212014-06-19 10:20:32 -07003350 if (devpriv->is_m_series)
H Hartley Sweeten72bca4f2015-05-01 14:59:24 -07003351 devpriv->ao_mode3 = NISTC_AO_MODE3_LAST_GATE_DISABLE;
David Schleef03aef4b2009-02-17 17:04:22 -08003352 else
3353 devpriv->ao_mode3 = 0;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07003354
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003355 ni_stc_writew(dev, 0, NISTC_AO_PERSONAL_REG);
3356 ni_stc_writew(dev, 0, NISTC_AO_CMD1_REG);
3357 ni_stc_writew(dev, 0, NISTC_AO_CMD2_REG);
3358 ni_stc_writew(dev, 0, NISTC_AO_MODE1_REG);
3359 ni_stc_writew(dev, 0, NISTC_AO_MODE2_REG);
3360 ni_stc_writew(dev, 0, NISTC_AO_OUT_CTRL_REG);
3361 ni_stc_writew(dev, devpriv->ao_mode3, NISTC_AO_MODE3_REG);
3362 ni_stc_writew(dev, 0, NISTC_AO_START_SEL_REG);
3363 ni_stc_writew(dev, 0, NISTC_AO_TRIG_SEL_REG);
3364
3365 /*--sync (disable interrupts) */
3366 ni_set_bits(dev, NISTC_INTB_ENA_REG, ~0, 0);
3367
3368 /*--sync (ack) */
3369 ni_stc_writew(dev, NISTC_AO_PERSONAL_BC_SRC_SEL, NISTC_AO_PERSONAL_REG);
3370 ni_stc_writew(dev, NISTC_INTB_ACK_AO_ALL, NISTC_INTB_ACK_REG);
3371
3372 /*--not in DAQ-STC. which doc? */
3373 if (devpriv->is_6xxx) {
3374 ni_ao_win_outw(dev, (1u << s->n_chan) - 1u,
3375 NI671X_AO_IMMEDIATE_REG);
H Hartley Sweetenef391542015-05-01 15:00:11 -07003376 ni_ao_win_outw(dev, NI611X_AO_MISC_CLEAR_WG,
3377 NI611X_AO_MISC_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003378 }
H Hartley Sweeten707502f2015-05-01 14:59:25 -07003379 ni_stc_writew(dev, NISTC_RESET_AO_CFG_END, NISTC_RESET_REG);
Spencer E. Olson5c93736c2016-01-27 14:28:25 -07003380 /*--end */
David Schleef03aef4b2009-02-17 17:04:22 -08003381
3382 return 0;
3383}
3384
Bill Pemberton2696fb52009-03-27 11:29:34 -04003385/* digital io */
David Schleef03aef4b2009-02-17 17:04:22 -08003386
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303387static int ni_dio_insn_config(struct comedi_device *dev,
3388 struct comedi_subdevice *s,
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003389 struct comedi_insn *insn,
3390 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08003391{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003392 struct ni_private *devpriv = dev->private;
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003393 int ret;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003394
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003395 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
3396 if (ret)
3397 return ret;
David Schleef03aef4b2009-02-17 17:04:22 -08003398
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003399 devpriv->dio_control &= ~NISTC_DIO_CTRL_DIR_MASK;
3400 devpriv->dio_control |= NISTC_DIO_CTRL_DIR(s->io_bits);
3401 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003402
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003403 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08003404}
3405
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303406static int ni_dio_insn_bits(struct comedi_device *dev,
3407 struct comedi_subdevice *s,
H Hartley Sweeten61716672013-08-30 11:06:38 -07003408 struct comedi_insn *insn,
3409 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08003410{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003411 struct ni_private *devpriv = dev->private;
3412
H Hartley Sweeten61716672013-08-30 11:06:38 -07003413 /* Make sure we're not using the serial part of the dio */
H Hartley Sweeten05aafee2015-05-01 14:59:01 -07003414 if ((data[0] & (NISTC_DIO_SDIN | NISTC_DIO_SDOUT)) &&
3415 devpriv->serial_interval_ns)
H Hartley Sweeten61716672013-08-30 11:06:38 -07003416 return -EBUSY;
H Hartley Sweeten52070662012-06-18 11:18:25 -07003417
H Hartley Sweeten61716672013-08-30 11:06:38 -07003418 if (comedi_dio_update_state(s, data)) {
H Hartley Sweeten05aafee2015-05-01 14:59:01 -07003419 devpriv->dio_output &= ~NISTC_DIO_OUT_PARALLEL_MASK;
3420 devpriv->dio_output |= NISTC_DIO_OUT_PARALLEL(s->state);
3421 ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003422 }
H Hartley Sweeten61716672013-08-30 11:06:38 -07003423
H Hartley Sweeten6f764a42015-05-01 14:59:42 -07003424 data[1] = ni_stc_readw(dev, NISTC_DIO_IN_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003425
H Hartley Sweetena2714e32012-06-18 13:16:35 -07003426 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08003427}
3428
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07003429#ifdef PCIDMA
Bill Pembertonda91b262009-04-09 16:07:03 -04003430static int ni_m_series_dio_insn_config(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303431 struct comedi_subdevice *s,
3432 struct comedi_insn *insn,
3433 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08003434{
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003435 int ret;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003436
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003437 ret = comedi_dio_insn_config(dev, s, insn, data, 0);
3438 if (ret)
3439 return ret;
David Schleef03aef4b2009-02-17 17:04:22 -08003440
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003441 ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003442
H Hartley Sweetenddf62f22013-08-06 09:32:33 -07003443 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08003444}
3445
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303446static int ni_m_series_dio_insn_bits(struct comedi_device *dev,
3447 struct comedi_subdevice *s,
3448 struct comedi_insn *insn,
3449 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08003450{
H Hartley Sweeten61716672013-08-30 11:06:38 -07003451 if (comedi_dio_update_state(s, data))
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003452 ni_writel(dev, s->state, NI_M_DIO_REG);
H Hartley Sweeten61716672013-08-30 11:06:38 -07003453
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003454 data[1] = ni_readl(dev, NI_M_DIO_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003455
H Hartley Sweetena2714e32012-06-18 13:16:35 -07003456 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08003457}
3458
H Hartley Sweeten368c2dc2014-04-16 14:19:19 -07003459static int ni_cdio_check_chanlist(struct comedi_device *dev,
3460 struct comedi_subdevice *s,
3461 struct comedi_cmd *cmd)
3462{
3463 int i;
3464
3465 for (i = 0; i < cmd->chanlist_len; ++i) {
3466 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
3467
3468 if (chan != i)
3469 return -EINVAL;
3470 }
3471
3472 return 0;
3473}
3474
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303475static int ni_cdio_cmdtest(struct comedi_device *dev,
3476 struct comedi_subdevice *s, struct comedi_cmd *cmd)
David Schleef03aef4b2009-02-17 17:04:22 -08003477{
3478 int err = 0;
3479 int tmp;
David Schleef03aef4b2009-02-17 17:04:22 -08003480
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003481 /* Step 1 : check if triggers are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08003482
Ian Abbott311fd9b2015-03-27 19:14:24 +00003483 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT);
3484 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
3485 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
3486 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
3487 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE);
David Schleef03aef4b2009-02-17 17:04:22 -08003488
3489 if (err)
3490 return 1;
3491
H Hartley Sweeten27020ff2012-09-26 14:11:10 -07003492 /* Step 2a : make sure trigger sources are unique */
3493 /* Step 2b : and mutually compatible */
David Schleef03aef4b2009-02-17 17:04:22 -08003494
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003495 /* Step 3: check if arguments are trivially valid */
David Schleef03aef4b2009-02-17 17:04:22 -08003496
Ian Abbott311fd9b2015-03-27 19:14:24 +00003497 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08003498
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003499 tmp = cmd->scan_begin_arg;
H Hartley Sweeten258f0042015-05-01 14:58:50 -07003500 tmp &= CR_PACK_FLAGS(NI_M_CDO_MODE_SAMPLE_SRC_MASK, 0, 0, CR_INVERT);
H Hartley Sweetenc3be5c72012-11-13 18:00:36 -07003501 if (tmp != cmd->scan_begin_arg)
3502 err |= -EINVAL;
3503
Ian Abbott311fd9b2015-03-27 19:14:24 +00003504 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
3505 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
3506 cmd->chanlist_len);
Spencer E. Olsonf164cbf2016-01-27 14:28:29 -07003507 err |= comedi_check_trigger_arg_max(&cmd->stop_arg,
3508 s->async->prealloc_bufsz /
3509 comedi_bytes_per_scan(s));
David Schleef03aef4b2009-02-17 17:04:22 -08003510
3511 if (err)
3512 return 3;
3513
H Hartley Sweetenb32381c2014-08-25 15:23:52 -07003514 /* Step 4: fix up any arguments */
David Schleef03aef4b2009-02-17 17:04:22 -08003515
H Hartley Sweeten368c2dc2014-04-16 14:19:19 -07003516 /* Step 5: check channel list if it exists */
H Hartley Sweetenb32381c2014-08-25 15:23:52 -07003517
H Hartley Sweeten368c2dc2014-04-16 14:19:19 -07003518 if (cmd->chanlist && cmd->chanlist_len > 0)
3519 err |= ni_cdio_check_chanlist(dev, s, cmd);
David Schleef03aef4b2009-02-17 17:04:22 -08003520
3521 if (err)
3522 return 5;
3523
3524 return 0;
3525}
3526
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003527static int ni_cdo_inttrig(struct comedi_device *dev,
3528 struct comedi_subdevice *s,
3529 unsigned int trig_num)
David Schleef03aef4b2009-02-17 17:04:22 -08003530{
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003531 struct comedi_cmd *cmd = &s->async->cmd;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003532 const unsigned int timeout = 1000;
David Schleef03aef4b2009-02-17 17:04:22 -08003533 int retval = 0;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003534 unsigned int i;
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07003535 struct ni_private *devpriv = dev->private;
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07003536 unsigned long flags;
David Schleef03aef4b2009-02-17 17:04:22 -08003537
H Hartley Sweetenebb657b2014-04-17 10:08:11 -07003538 if (trig_num != cmd->start_arg)
3539 return -EINVAL;
3540
David Schleef03aef4b2009-02-17 17:04:22 -08003541 s->async->inttrig = NULL;
3542
3543 /* read alloc the entire buffer */
Ian Abbottd13be552014-05-06 13:12:07 +01003544 comedi_buf_read_alloc(s, s->async->prealloc_bufsz);
David Schleef03aef4b2009-02-17 17:04:22 -08003545
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003546 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08003547 if (devpriv->cdo_mite_chan) {
3548 mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
3549 mite_dma_arm(devpriv->cdo_mite_chan);
3550 } else {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07003551 dev_err(dev->class_dev, "BUG: no cdo mite channel?\n");
David Schleef03aef4b2009-02-17 17:04:22 -08003552 retval = -EIO;
3553 }
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003554 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08003555 if (retval < 0)
3556 return retval;
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07003557
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003558 /*
3559 * XXX not sure what interrupt C group does
3560 * wait for dma to fill output fifo
H Hartley Sweeten60f078f2015-05-01 14:58:51 -07003561 * ni_writeb(dev, NI_M_INTC_ENA, NI_M_INTC_ENA_REG);
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003562 */
David Schleef03aef4b2009-02-17 17:04:22 -08003563 for (i = 0; i < timeout; ++i) {
H Hartley Sweetend53be922015-05-01 14:58:46 -07003564 if (ni_readl(dev, NI_M_CDIO_STATUS_REG) &
3565 NI_M_CDIO_STATUS_CDO_FIFO_FULL)
David Schleef03aef4b2009-02-17 17:04:22 -08003566 break;
H Hartley Sweeten8a5b8172016-04-14 09:58:03 -07003567 usleep_range(10, 100);
David Schleef03aef4b2009-02-17 17:04:22 -08003568 }
3569 if (i == timeout) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07003570 dev_err(dev->class_dev, "dma failed to fill cdo fifo!\n");
H Hartley Sweetenfed37a12014-05-28 16:26:35 -07003571 s->cancel(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08003572 return -EIO;
3573 }
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003574 ni_writel(dev, NI_M_CDO_CMD_ARM |
3575 NI_M_CDO_CMD_ERR_INT_ENA_SET |
3576 NI_M_CDO_CMD_F_E_INT_ENA_SET,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003577 NI_M_CDIO_CMD_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003578 return retval;
3579}
3580
H Hartley Sweeten07929282014-05-28 16:26:34 -07003581static int ni_cdio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
3582{
Spencer E. Olsonf164cbf2016-01-27 14:28:29 -07003583 struct ni_private *devpriv = dev->private;
H Hartley Sweeten07929282014-05-28 16:26:34 -07003584 const struct comedi_cmd *cmd = &s->async->cmd;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003585 unsigned int cdo_mode_bits;
H Hartley Sweeten07929282014-05-28 16:26:34 -07003586 int retval;
3587
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003588 ni_writel(dev, NI_M_CDO_CMD_RESET, NI_M_CDIO_CMD_REG);
H Hartley Sweeten258f0042015-05-01 14:58:50 -07003589 cdo_mode_bits = NI_M_CDO_MODE_FIFO_MODE |
3590 NI_M_CDO_MODE_HALT_ON_ERROR |
3591 NI_M_CDO_MODE_SAMPLE_SRC(CR_CHAN(cmd->scan_begin_arg));
H Hartley Sweeten07929282014-05-28 16:26:34 -07003592 if (cmd->scan_begin_arg & CR_INVERT)
H Hartley Sweeten258f0042015-05-01 14:58:50 -07003593 cdo_mode_bits |= NI_M_CDO_MODE_POLARITY;
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003594 ni_writel(dev, cdo_mode_bits, NI_M_CDO_MODE_REG);
H Hartley Sweeten07929282014-05-28 16:26:34 -07003595 if (s->io_bits) {
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003596 ni_writel(dev, s->state, NI_M_CDO_FIFO_DATA_REG);
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003597 ni_writel(dev, NI_M_CDO_CMD_SW_UPDATE, NI_M_CDIO_CMD_REG);
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003598 ni_writel(dev, s->io_bits, NI_M_CDO_MASK_ENA_REG);
H Hartley Sweeten07929282014-05-28 16:26:34 -07003599 } else {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07003600 dev_err(dev->class_dev,
3601 "attempted to run digital output command with no lines configured as outputs\n");
H Hartley Sweeten07929282014-05-28 16:26:34 -07003602 return -EIO;
3603 }
3604 retval = ni_request_cdo_mite_channel(dev);
3605 if (retval < 0)
3606 return retval;
3607
Spencer E. Olsonf164cbf2016-01-27 14:28:29 -07003608 ni_cmd_set_mite_transfer(devpriv->cdo_mite_ring, s, cmd,
3609 s->async->prealloc_bufsz /
3610 comedi_bytes_per_scan(s));
3611
H Hartley Sweeten07929282014-05-28 16:26:34 -07003612 s->async->inttrig = ni_cdo_inttrig;
3613
3614 return 0;
3615}
3616
Bill Pembertonda91b262009-04-09 16:07:03 -04003617static int ni_cdio_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08003618{
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003619 ni_writel(dev, NI_M_CDO_CMD_DISARM |
3620 NI_M_CDO_CMD_ERR_INT_ENA_CLR |
3621 NI_M_CDO_CMD_F_E_INT_ENA_CLR |
3622 NI_M_CDO_CMD_F_REQ_INT_ENA_CLR,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003623 NI_M_CDIO_CMD_REG);
3624 /*
3625 * XXX not sure what interrupt C group does
3626 * ni_writeb(dev, 0, NI_M_INTC_ENA_REG);
3627 */
3628 ni_writel(dev, 0, NI_M_CDO_MASK_ENA_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003629 ni_release_cdo_mite_channel(dev);
3630 return 0;
3631}
3632
Bill Pembertonda91b262009-04-09 16:07:03 -04003633static void handle_cdio_interrupt(struct comedi_device *dev)
David Schleef03aef4b2009-02-17 17:04:22 -08003634{
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07003635 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003636 unsigned int cdio_status;
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07003637 struct comedi_subdevice *s = &dev->subdevices[NI_DIO_SUBDEV];
David Schleef03aef4b2009-02-17 17:04:22 -08003638 unsigned long flags;
David Schleef03aef4b2009-02-17 17:04:22 -08003639
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003640 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
H Hartley Sweetenf7d005c2016-04-21 12:04:44 -07003641 if (devpriv->cdo_mite_chan)
3642 mite_ack_linkc(devpriv->cdo_mite_chan, s, true);
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003643 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
David Schleef03aef4b2009-02-17 17:04:22 -08003644
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003645 cdio_status = ni_readl(dev, NI_M_CDIO_STATUS_REG);
H Hartley Sweetend53be922015-05-01 14:58:46 -07003646 if (cdio_status & NI_M_CDIO_STATUS_CDO_ERROR) {
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07003647 /* XXX just guessing this is needed and does something useful */
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003648 ni_writel(dev, NI_M_CDO_CMD_ERR_INT_CONFIRM,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003649 NI_M_CDIO_CMD_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003650 s->async->events |= COMEDI_CB_OVERFLOW;
3651 }
H Hartley Sweetend53be922015-05-01 14:58:46 -07003652 if (cdio_status & NI_M_CDIO_STATUS_CDO_FIFO_EMPTY) {
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07003653 ni_writel(dev, NI_M_CDO_CMD_F_E_INT_ENA_CLR,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07003654 NI_M_CDIO_CMD_REG);
Chase Southwoodb9ede312014-01-10 22:02:57 -06003655 /* s->async->events |= COMEDI_CB_EOA; */
David Schleef03aef4b2009-02-17 17:04:22 -08003656 }
H Hartley Sweetenb9a69a12014-09-18 11:11:30 -07003657 comedi_handle_events(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08003658}
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07003659#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -08003660
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303661static int ni_serial_hw_readwrite8(struct comedi_device *dev,
3662 struct comedi_subdevice *s,
3663 unsigned char data_out,
3664 unsigned char *data_in)
David Schleef03aef4b2009-02-17 17:04:22 -08003665{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003666 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08003667 unsigned int status1;
3668 int err = 0, count = 20;
3669
H Hartley Sweeten05aafee2015-05-01 14:59:01 -07003670 devpriv->dio_output &= ~NISTC_DIO_OUT_SERIAL_MASK;
3671 devpriv->dio_output |= NISTC_DIO_OUT_SERIAL(data_out);
3672 ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003673
H Hartley Sweetend3fed082015-05-01 14:59:46 -07003674 status1 = ni_stc_readw(dev, NISTC_STATUS1_REG);
3675 if (status1 & NISTC_STATUS1_SERIO_IN_PROG) {
David Schleef03aef4b2009-02-17 17:04:22 -08003676 err = -EBUSY;
H Hartley Sweetenb24a3ec2016-04-14 09:58:05 -07003677 goto error;
David Schleef03aef4b2009-02-17 17:04:22 -08003678 }
3679
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003680 devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_START;
3681 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
3682 devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_START;
David Schleef03aef4b2009-02-17 17:04:22 -08003683
3684 /* Wait until STC says we're done, but don't loop infinitely. */
H Hartley Sweetend3fed082015-05-01 14:59:46 -07003685 while ((status1 = ni_stc_readw(dev, NISTC_STATUS1_REG)) &
3686 NISTC_STATUS1_SERIO_IN_PROG) {
David Schleef03aef4b2009-02-17 17:04:22 -08003687 /* Delay one bit per loop */
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003688 udelay((devpriv->serial_interval_ns + 999) / 1000);
David Schleef03aef4b2009-02-17 17:04:22 -08003689 if (--count < 0) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07003690 dev_err(dev->class_dev,
Haneen Mohammedcd255032015-03-05 13:01:49 +03003691 "SPI serial I/O didn't finish in time!\n");
David Schleef03aef4b2009-02-17 17:04:22 -08003692 err = -ETIME;
H Hartley Sweetenb24a3ec2016-04-14 09:58:05 -07003693 goto error;
David Schleef03aef4b2009-02-17 17:04:22 -08003694 }
3695 }
3696
H Hartley Sweetend3fed082015-05-01 14:59:46 -07003697 /*
3698 * Delay for last bit. This delay is absolutely necessary, because
3699 * NISTC_STATUS1_SERIO_IN_PROG goes high one bit too early.
3700 */
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003701 udelay((devpriv->serial_interval_ns + 999) / 1000);
David Schleef03aef4b2009-02-17 17:04:22 -08003702
H Hartley Sweetenc6be1542015-03-04 12:15:40 -07003703 if (data_in)
H Hartley Sweeten8fbb0152015-05-01 14:59:47 -07003704 *data_in = ni_stc_readw(dev, NISTC_DIO_SERIAL_IN_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003705
H Hartley Sweetenb24a3ec2016-04-14 09:58:05 -07003706error:
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003707 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003708
3709 return err;
3710}
3711
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303712static int ni_serial_sw_readwrite8(struct comedi_device *dev,
3713 struct comedi_subdevice *s,
3714 unsigned char data_out,
3715 unsigned char *data_in)
David Schleef03aef4b2009-02-17 17:04:22 -08003716{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003717 struct ni_private *devpriv = dev->private;
David Schleef03aef4b2009-02-17 17:04:22 -08003718 unsigned char mask, input = 0;
3719
David Schleef03aef4b2009-02-17 17:04:22 -08003720 /* Wait for one bit before transfer */
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003721 udelay((devpriv->serial_interval_ns + 999) / 1000);
David Schleef03aef4b2009-02-17 17:04:22 -08003722
3723 for (mask = 0x80; mask; mask >>= 1) {
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07003724 /*
3725 * Output current bit; note that we cannot touch s->state
3726 * because it is a per-subdevice field, and serial is
3727 * a separate subdevice from DIO.
3728 */
H Hartley Sweeten05aafee2015-05-01 14:59:01 -07003729 devpriv->dio_output &= ~NISTC_DIO_SDOUT;
Chase Southwoodbc461552014-01-10 22:02:33 -06003730 if (data_out & mask)
H Hartley Sweeten05aafee2015-05-01 14:59:01 -07003731 devpriv->dio_output |= NISTC_DIO_SDOUT;
3732 ni_stc_writew(dev, devpriv->dio_output, NISTC_DIO_OUT_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003733
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07003734 /*
3735 * Assert SDCLK (active low, inverted), wait for half of
3736 * the delay, deassert SDCLK, and wait for the other half.
3737 */
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003738 devpriv->dio_control |= NISTC_DIO_SDCLK;
3739 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003740
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003741 udelay((devpriv->serial_interval_ns + 999) / 2000);
David Schleef03aef4b2009-02-17 17:04:22 -08003742
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003743 devpriv->dio_control &= ~NISTC_DIO_SDCLK;
3744 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003745
Greg Kroah-Hartman5f74ea12009-04-27 14:44:31 -07003746 udelay((devpriv->serial_interval_ns + 999) / 2000);
David Schleef03aef4b2009-02-17 17:04:22 -08003747
3748 /* Input current bit */
H Hartley Sweeten6f764a42015-05-01 14:59:42 -07003749 if (ni_stc_readw(dev, NISTC_DIO_IN_REG) & NISTC_DIO_SDIN)
David Schleef03aef4b2009-02-17 17:04:22 -08003750 input |= mask;
David Schleef03aef4b2009-02-17 17:04:22 -08003751 }
H Hartley Sweeten9d6a0f62013-11-26 10:21:32 -07003752
David Schleef03aef4b2009-02-17 17:04:22 -08003753 if (data_in)
3754 *data_in = input;
3755
3756 return 0;
3757}
3758
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003759static int ni_serial_insn_config(struct comedi_device *dev,
3760 struct comedi_subdevice *s,
3761 struct comedi_insn *insn,
3762 unsigned int *data)
3763{
3764 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003765 unsigned int clk_fout = devpriv->clock_and_fout;
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003766 int err = insn->n;
3767 unsigned char byte_out, byte_in = 0;
3768
3769 if (insn->n != 2)
3770 return -EINVAL;
3771
3772 switch (data[0]) {
3773 case INSN_CONFIG_SERIAL_CLOCK:
3774 devpriv->serial_hw_mode = 1;
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003775 devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_ENA;
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003776
3777 if (data[1] == SERIAL_DISABLED) {
3778 devpriv->serial_hw_mode = 0;
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003779 devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA |
3780 NISTC_DIO_SDCLK);
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003781 data[1] = SERIAL_DISABLED;
3782 devpriv->serial_interval_ns = data[1];
3783 } else if (data[1] <= SERIAL_600NS) {
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07003784 /*
3785 * Warning: this clock speed is too fast to reliably
3786 * control SCXI.
3787 */
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003788 devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE;
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003789 clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE;
3790 clk_fout &= ~NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003791 data[1] = SERIAL_600NS;
3792 devpriv->serial_interval_ns = data[1];
3793 } else if (data[1] <= SERIAL_1_2US) {
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003794 devpriv->dio_control &= ~NISTC_DIO_CTRL_HW_SER_TIMEBASE;
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003795 clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE |
3796 NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003797 data[1] = SERIAL_1_2US;
3798 devpriv->serial_interval_ns = data[1];
3799 } else if (data[1] <= SERIAL_10US) {
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003800 devpriv->dio_control |= NISTC_DIO_CTRL_HW_SER_TIMEBASE;
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003801 clk_fout |= NISTC_CLK_FOUT_SLOW_TIMEBASE |
3802 NISTC_CLK_FOUT_DIO_SER_OUT_DIV2;
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07003803 /*
3804 * Note: NISTC_CLK_FOUT_DIO_SER_OUT_DIV2 only affects
3805 * 600ns/1.2us. If you turn divide_by_2 off with the
3806 * slow clock, you will still get 10us, except then
3807 * all your delays are wrong.
3808 */
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003809 data[1] = SERIAL_10US;
3810 devpriv->serial_interval_ns = data[1];
3811 } else {
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003812 devpriv->dio_control &= ~(NISTC_DIO_CTRL_HW_SER_ENA |
3813 NISTC_DIO_SDCLK);
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003814 devpriv->serial_hw_mode = 0;
3815 data[1] = (data[1] / 1000) * 1000;
3816 devpriv->serial_interval_ns = data[1];
3817 }
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003818 devpriv->clock_and_fout = clk_fout;
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003819
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07003820 ni_stc_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003821 ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003822 return 1;
3823
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003824 case INSN_CONFIG_BIDIRECTIONAL_DATA:
3825
3826 if (devpriv->serial_interval_ns == 0)
3827 return -EINVAL;
3828
3829 byte_out = data[1] & 0xFF;
3830
3831 if (devpriv->serial_hw_mode) {
3832 err = ni_serial_hw_readwrite8(dev, s, byte_out,
3833 &byte_in);
3834 } else if (devpriv->serial_interval_ns > 0) {
3835 err = ni_serial_sw_readwrite8(dev, s, byte_out,
3836 &byte_in);
3837 } else {
Haneen Mohammedcd255032015-03-05 13:01:49 +03003838 dev_err(dev->class_dev, "serial disabled!\n");
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003839 return -EINVAL;
3840 }
3841 if (err < 0)
3842 return err;
3843 data[1] = byte_in & 0xFF;
3844 return insn->n;
3845
3846 break;
3847 default:
3848 return -EINVAL;
3849 }
H Hartley Sweeten189e1732014-05-28 16:26:36 -07003850}
3851
Bill Pembertonda91b262009-04-09 16:07:03 -04003852static void init_ao_67xx(struct comedi_device *dev, struct comedi_subdevice *s)
David Schleef03aef4b2009-02-17 17:04:22 -08003853{
3854 int i;
3855
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303856 for (i = 0; i < s->n_chan; i++) {
H Hartley Sweetenb497b8d2015-05-01 14:59:59 -07003857 ni_ao_win_outw(dev, NI_E_AO_DACSEL(i) | 0x0,
H Hartley Sweetenef391542015-05-01 15:00:11 -07003858 NI67XX_AO_CFG2_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003859 }
H Hartley Sweetenef391542015-05-01 15:00:11 -07003860 ni_ao_win_outw(dev, 0x0, NI67XX_AO_SP_UPDATES_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08003861}
3862
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003863static const struct mio_regmap ni_gpct_to_stc_regmap[] = {
H Hartley Sweeten38aba4c2015-05-01 14:59:23 -07003864 [NITIO_G0_AUTO_INC] = { NISTC_G0_AUTOINC_REG, 2 },
3865 [NITIO_G1_AUTO_INC] = { NISTC_G1_AUTOINC_REG, 2 },
H Hartley Sweeten5fa2fa42015-05-01 14:58:58 -07003866 [NITIO_G0_CMD] = { NISTC_G0_CMD_REG, 2 },
3867 [NITIO_G1_CMD] = { NISTC_G1_CMD_REG, 2 },
H Hartley Sweeten27650d92015-05-01 14:59:43 -07003868 [NITIO_G0_HW_SAVE] = { NISTC_G0_HW_SAVE_REG, 4 },
3869 [NITIO_G1_HW_SAVE] = { NISTC_G1_HW_SAVE_REG, 4 },
H Hartley Sweetend9c41152015-05-01 14:59:44 -07003870 [NITIO_G0_SW_SAVE] = { NISTC_G0_SAVE_REG, 4 },
3871 [NITIO_G1_SW_SAVE] = { NISTC_G1_SAVE_REG, 4 },
H Hartley Sweetenaff27002015-05-01 14:59:06 -07003872 [NITIO_G0_MODE] = { NISTC_G0_MODE_REG, 2 },
3873 [NITIO_G1_MODE] = { NISTC_G1_MODE_REG, 2 },
3874 [NITIO_G0_LOADA] = { NISTC_G0_LOADA_REG, 4 },
3875 [NITIO_G1_LOADA] = { NISTC_G1_LOADA_REG, 4 },
3876 [NITIO_G0_LOADB] = { NISTC_G0_LOADB_REG, 4 },
3877 [NITIO_G1_LOADB] = { NISTC_G1_LOADB_REG, 4 },
3878 [NITIO_G0_INPUT_SEL] = { NISTC_G0_INPUT_SEL_REG, 2 },
3879 [NITIO_G1_INPUT_SEL] = { NISTC_G1_INPUT_SEL_REG, 2 },
H Hartley Sweeten0a9752d2015-05-01 14:58:29 -07003880 [NITIO_G0_CNT_MODE] = { 0x1b0, 2 }, /* M-Series only */
3881 [NITIO_G1_CNT_MODE] = { 0x1b2, 2 }, /* M-Series only */
3882 [NITIO_G0_GATE2] = { 0x1b4, 2 }, /* M-Series only */
3883 [NITIO_G1_GATE2] = { 0x1b6, 2 }, /* M-Series only */
H Hartley Sweeten7f0e1ba2015-05-01 14:59:39 -07003884 [NITIO_G01_STATUS] = { NISTC_G01_STATUS_REG, 2 },
H Hartley Sweeten707502f2015-05-01 14:59:25 -07003885 [NITIO_G01_RESET] = { NISTC_RESET_REG, 2 },
H Hartley Sweetend3fed082015-05-01 14:59:46 -07003886 [NITIO_G01_STATUS1] = { NISTC_STATUS1_REG, 2 },
H Hartley Sweetenbab382e2015-05-01 14:59:48 -07003887 [NITIO_G01_STATUS2] = { NISTC_STATUS2_REG, 2 },
H Hartley Sweeten0a9752d2015-05-01 14:58:29 -07003888 [NITIO_G0_DMA_CFG] = { 0x1b8, 2 }, /* M-Series only */
3889 [NITIO_G1_DMA_CFG] = { 0x1ba, 2 }, /* M-Series only */
3890 [NITIO_G0_DMA_STATUS] = { 0x1b8, 2 }, /* M-Series only */
3891 [NITIO_G1_DMA_STATUS] = { 0x1ba, 2 }, /* M-Series only */
3892 [NITIO_G0_ABZ] = { 0x1c0, 2 }, /* M-Series only */
3893 [NITIO_G1_ABZ] = { 0x1c2, 2 }, /* M-Series only */
H Hartley Sweeten480456d2015-05-01 14:58:54 -07003894 [NITIO_G0_INT_ACK] = { NISTC_INTA_ACK_REG, 2 },
H Hartley Sweeten4a6de8322015-05-01 14:58:55 -07003895 [NITIO_G1_INT_ACK] = { NISTC_INTB_ACK_REG, 2 },
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07003896 [NITIO_G0_STATUS] = { NISTC_AI_STATUS1_REG, 2 },
H Hartley Sweetend123ee32015-05-01 14:59:38 -07003897 [NITIO_G1_STATUS] = { NISTC_AO_STATUS1_REG, 2 },
H Hartley Sweeten5cca26a2015-05-01 14:59:26 -07003898 [NITIO_G0_INT_ENA] = { NISTC_INTA_ENA_REG, 2 },
H Hartley Sweeten4c9c1d22015-05-01 14:59:28 -07003899 [NITIO_G1_INT_ENA] = { NISTC_INTB_ENA_REG, 2 },
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003900};
H Hartley Sweetenf7401972014-07-16 11:02:08 -07003901
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003902static unsigned int ni_gpct_to_stc_register(struct comedi_device *dev,
3903 enum ni_gpct_register reg)
3904{
3905 const struct mio_regmap *regmap;
3906
3907 if (reg < ARRAY_SIZE(ni_gpct_to_stc_regmap)) {
3908 regmap = &ni_gpct_to_stc_regmap[reg];
3909 } else {
Geliang Tang71f50e22015-05-25 14:20:44 +00003910 dev_warn(dev->class_dev, "%s: unhandled register=0x%x\n",
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003911 __func__, reg);
David Schleef03aef4b2009-02-17 17:04:22 -08003912 return 0;
David Schleef03aef4b2009-02-17 17:04:22 -08003913 }
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003914
3915 return regmap->mio_reg;
David Schleef03aef4b2009-02-17 17:04:22 -08003916}
3917
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003918static void ni_gpct_write_register(struct ni_gpct *counter, unsigned int bits,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303919 enum ni_gpct_register reg)
David Schleef03aef4b2009-02-17 17:04:22 -08003920{
Bill Pemberton71b5f4f2009-03-16 22:05:08 -04003921 struct comedi_device *dev = counter->counter_dev->dev;
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003922 unsigned int stc_register = ni_gpct_to_stc_register(dev, reg);
David Schleef03aef4b2009-02-17 17:04:22 -08003923
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003924 if (stc_register == 0)
3925 return;
3926
David Schleef03aef4b2009-02-17 17:04:22 -08003927 switch (reg) {
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003928 /* m-series only registers */
H Hartley Sweeten12375292013-12-19 16:31:33 -07003929 case NITIO_G0_CNT_MODE:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003930 case NITIO_G1_CNT_MODE:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003931 case NITIO_G0_GATE2:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003932 case NITIO_G1_GATE2:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003933 case NITIO_G0_DMA_CFG:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003934 case NITIO_G1_DMA_CFG:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003935 case NITIO_G0_ABZ:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003936 case NITIO_G1_ABZ:
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003937 ni_writew(dev, bits, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003938 break;
3939
3940 /* 32 bit registers */
H Hartley Sweeten12375292013-12-19 16:31:33 -07003941 case NITIO_G0_LOADA:
3942 case NITIO_G1_LOADA:
3943 case NITIO_G0_LOADB:
3944 case NITIO_G1_LOADB:
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07003945 ni_stc_writel(dev, bits, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003946 break;
3947
3948 /* 16 bit registers */
H Hartley Sweeten12375292013-12-19 16:31:33 -07003949 case NITIO_G0_INT_ENA:
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003950 ni_set_bitfield(dev, stc_register,
H Hartley Sweeten2e2f7b72016-04-14 09:58:02 -07003951 NISTC_INTA_ENA_G0_GATE | NISTC_INTA_ENA_G0_TC,
3952 bits);
David Schleef03aef4b2009-02-17 17:04:22 -08003953 break;
H Hartley Sweeten12375292013-12-19 16:31:33 -07003954 case NITIO_G1_INT_ENA:
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003955 ni_set_bitfield(dev, stc_register,
H Hartley Sweeten2e2f7b72016-04-14 09:58:02 -07003956 NISTC_INTB_ENA_G1_GATE | NISTC_INTB_ENA_G1_TC,
3957 bits);
David Schleef03aef4b2009-02-17 17:04:22 -08003958 break;
David Schleef03aef4b2009-02-17 17:04:22 -08003959 default:
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07003960 ni_stc_writew(dev, bits, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003961 }
3962}
3963
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07003964static unsigned int ni_gpct_read_register(struct ni_gpct *counter,
3965 enum ni_gpct_register reg)
David Schleef03aef4b2009-02-17 17:04:22 -08003966{
Bill Pemberton71b5f4f2009-03-16 22:05:08 -04003967 struct comedi_device *dev = counter->counter_dev->dev;
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003968 unsigned int stc_register = ni_gpct_to_stc_register(dev, reg);
3969
3970 if (stc_register == 0)
3971 return 0;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003972
David Schleef03aef4b2009-02-17 17:04:22 -08003973 switch (reg) {
3974 /* m-series only registers */
H Hartley Sweeten12375292013-12-19 16:31:33 -07003975 case NITIO_G0_DMA_STATUS:
H Hartley Sweeten12375292013-12-19 16:31:33 -07003976 case NITIO_G1_DMA_STATUS:
H Hartley Sweetencfdb34292015-05-01 14:58:28 -07003977 return ni_readw(dev, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003978
3979 /* 32 bit registers */
H Hartley Sweeten12375292013-12-19 16:31:33 -07003980 case NITIO_G0_HW_SAVE:
3981 case NITIO_G1_HW_SAVE:
3982 case NITIO_G0_SW_SAVE:
3983 case NITIO_G1_SW_SAVE:
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07003984 return ni_stc_readl(dev, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003985
3986 /* 16 bit registers */
3987 default:
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07003988 return ni_stc_readw(dev, stc_register);
David Schleef03aef4b2009-02-17 17:04:22 -08003989 }
David Schleef03aef4b2009-02-17 17:04:22 -08003990}
3991
Bill Pembertonda91b262009-04-09 16:07:03 -04003992static int ni_freq_out_insn_read(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05303993 struct comedi_subdevice *s,
H Hartley Sweetend9c42612014-05-28 16:26:54 -07003994 struct comedi_insn *insn,
3995 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08003996{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07003997 struct ni_private *devpriv = dev->private;
H Hartley Sweetena47fc022015-05-01 14:59:10 -07003998 unsigned int val = NISTC_CLK_FOUT_TO_DIVIDER(devpriv->clock_and_fout);
H Hartley Sweetend9c42612014-05-28 16:26:54 -07003999 int i;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07004000
H Hartley Sweetend9c42612014-05-28 16:26:54 -07004001 for (i = 0; i < insn->n; i++)
4002 data[i] = val;
4003
4004 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08004005}
4006
Bill Pembertonda91b262009-04-09 16:07:03 -04004007static int ni_freq_out_insn_write(struct comedi_device *dev,
Mithlesh Thukral0a85b6f2009-06-08 21:04:41 +05304008 struct comedi_subdevice *s,
H Hartley Sweeten00a92c02014-05-28 16:26:53 -07004009 struct comedi_insn *insn,
4010 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08004011{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07004012 struct ni_private *devpriv = dev->private;
4013
H Hartley Sweeten00a92c02014-05-28 16:26:53 -07004014 if (insn->n) {
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004015 unsigned int val = data[insn->n - 1];
4016
4017 devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_ENA;
4018 ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
4019 devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_DIVIDER_MASK;
H Hartley Sweeten00a92c02014-05-28 16:26:53 -07004020
4021 /* use the last data value to set the fout divider */
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004022 devpriv->clock_and_fout |= NISTC_CLK_FOUT_DIVIDER(val);
H Hartley Sweeten00a92c02014-05-28 16:26:53 -07004023
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004024 devpriv->clock_and_fout |= NISTC_CLK_FOUT_ENA;
4025 ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
H Hartley Sweeten00a92c02014-05-28 16:26:53 -07004026 }
David Schleef03aef4b2009-02-17 17:04:22 -08004027 return insn->n;
4028}
4029
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004030static int ni_freq_out_insn_config(struct comedi_device *dev,
4031 struct comedi_subdevice *s,
4032 struct comedi_insn *insn,
4033 unsigned int *data)
David Schleef03aef4b2009-02-17 17:04:22 -08004034{
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07004035 struct ni_private *devpriv = dev->private;
4036
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004037 switch (data[0]) {
4038 case INSN_CONFIG_SET_CLOCK_SRC:
4039 switch (data[1]) {
4040 case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004041 devpriv->clock_and_fout &= ~NISTC_CLK_FOUT_TIMEBASE_SEL;
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004042 break;
4043 case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004044 devpriv->clock_and_fout |= NISTC_CLK_FOUT_TIMEBASE_SEL;
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004045 break;
4046 default:
4047 return -EINVAL;
4048 }
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004049 ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08004050 break;
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004051 case INSN_CONFIG_GET_CLOCK_SRC:
H Hartley Sweetena47fc022015-05-01 14:59:10 -07004052 if (devpriv->clock_and_fout & NISTC_CLK_FOUT_TIMEBASE_SEL) {
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004053 data[1] = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
4054 data[2] = TIMEBASE_2_NS;
4055 } else {
4056 data[1] = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
4057 data[2] = TIMEBASE_1_NS * 2;
4058 }
David Schleef03aef4b2009-02-17 17:04:22 -08004059 break;
4060 default:
4061 return -EINVAL;
4062 }
H Hartley Sweetene63dabd2014-05-28 16:26:52 -07004063 return insn->n;
David Schleef03aef4b2009-02-17 17:04:22 -08004064}
4065
H Hartley Sweeten67393c42014-08-12 11:41:20 -07004066static int ni_8255_callback(struct comedi_device *dev,
4067 int dir, int port, int data, unsigned long iobase)
H Hartley Sweetenf5985862014-05-28 16:26:24 -07004068{
H Hartley Sweetenf5985862014-05-28 16:26:24 -07004069 if (dir) {
H Hartley Sweeten67393c42014-08-12 11:41:20 -07004070 ni_writeb(dev, data, iobase + 2 * port);
H Hartley Sweetenf5985862014-05-28 16:26:24 -07004071 return 0;
H Hartley Sweetenf5985862014-05-28 16:26:24 -07004072 }
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004073
H Hartley Sweeten67393c42014-08-12 11:41:20 -07004074 return ni_readb(dev, iobase + 2 * port);
H Hartley Sweetenf5985862014-05-28 16:26:24 -07004075}
4076
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004077static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data)
4078{
4079 struct ni_private *devpriv = dev->private;
4080
4081 data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
4082 data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
4083 return 3;
4084}
4085
4086static int ni_m_series_pwm_config(struct comedi_device *dev,
4087 struct comedi_subdevice *s,
4088 struct comedi_insn *insn,
4089 unsigned int *data)
4090{
4091 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004092 unsigned int up_count, down_count;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004093
4094 switch (data[0]) {
4095 case INSN_CONFIG_PWM_OUTPUT:
4096 switch (data[1]) {
Ian Abbott3280c2d2014-09-03 13:45:57 +01004097 case CMDF_ROUND_NEAREST:
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05304098 up_count = DIV_ROUND_CLOSEST(data[2],
4099 devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004100 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004101 case CMDF_ROUND_DOWN:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004102 up_count = data[2] / devpriv->clock_ns;
4103 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004104 case CMDF_ROUND_UP:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004105 up_count =
Bhaktipriya Shridhar7f9d2b12016-03-10 00:05:16 +05304106 DIV_ROUND_UP(data[2], devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004107 break;
4108 default:
4109 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004110 }
4111 switch (data[3]) {
Ian Abbott3280c2d2014-09-03 13:45:57 +01004112 case CMDF_ROUND_NEAREST:
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05304113 down_count = DIV_ROUND_CLOSEST(data[4],
4114 devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004115 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004116 case CMDF_ROUND_DOWN:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004117 down_count = data[4] / devpriv->clock_ns;
4118 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004119 case CMDF_ROUND_UP:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004120 down_count =
Bhaktipriya Shridhar7f9d2b12016-03-10 00:05:16 +05304121 DIV_ROUND_UP(data[4], devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004122 break;
4123 default:
4124 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004125 }
4126 if (up_count * devpriv->clock_ns != data[2] ||
4127 down_count * devpriv->clock_ns != data[4]) {
4128 data[2] = up_count * devpriv->clock_ns;
4129 data[4] = down_count * devpriv->clock_ns;
4130 return -EAGAIN;
4131 }
H Hartley Sweetencc679f92015-05-01 14:58:42 -07004132 ni_writel(dev, NI_M_CAL_PWM_HIGH_TIME(up_count) |
4133 NI_M_CAL_PWM_LOW_TIME(down_count),
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004134 NI_M_CAL_PWM_REG);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004135 devpriv->pwm_up_count = up_count;
4136 devpriv->pwm_down_count = down_count;
4137 return 5;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004138 case INSN_CONFIG_GET_PWM_OUTPUT:
4139 return ni_get_pwm_config(dev, data);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004140 default:
4141 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004142 }
4143 return 0;
4144}
4145
4146static int ni_6143_pwm_config(struct comedi_device *dev,
4147 struct comedi_subdevice *s,
4148 struct comedi_insn *insn,
4149 unsigned int *data)
4150{
4151 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004152 unsigned int up_count, down_count;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004153
4154 switch (data[0]) {
4155 case INSN_CONFIG_PWM_OUTPUT:
4156 switch (data[1]) {
Ian Abbott3280c2d2014-09-03 13:45:57 +01004157 case CMDF_ROUND_NEAREST:
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05304158 up_count = DIV_ROUND_CLOSEST(data[2],
4159 devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004160 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004161 case CMDF_ROUND_DOWN:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004162 up_count = data[2] / devpriv->clock_ns;
4163 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004164 case CMDF_ROUND_UP:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004165 up_count =
Bhaktipriya Shridhar7f9d2b12016-03-10 00:05:16 +05304166 DIV_ROUND_UP(data[2], devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004167 break;
4168 default:
4169 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004170 }
4171 switch (data[3]) {
Ian Abbott3280c2d2014-09-03 13:45:57 +01004172 case CMDF_ROUND_NEAREST:
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05304173 down_count = DIV_ROUND_CLOSEST(data[4],
4174 devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004175 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004176 case CMDF_ROUND_DOWN:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004177 down_count = data[4] / devpriv->clock_ns;
4178 break;
Ian Abbott3280c2d2014-09-03 13:45:57 +01004179 case CMDF_ROUND_UP:
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004180 down_count =
Bhaktipriya Shridhar7f9d2b12016-03-10 00:05:16 +05304181 DIV_ROUND_UP(data[4], devpriv->clock_ns);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004182 break;
4183 default:
4184 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004185 }
4186 if (up_count * devpriv->clock_ns != data[2] ||
4187 down_count * devpriv->clock_ns != data[4]) {
4188 data[2] = up_count * devpriv->clock_ns;
4189 data[4] = down_count * devpriv->clock_ns;
4190 return -EAGAIN;
4191 }
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07004192 ni_writel(dev, up_count, NI6143_CALIB_HI_TIME_REG);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004193 devpriv->pwm_up_count = up_count;
H Hartley Sweetenee3e21a2015-05-01 15:00:08 -07004194 ni_writel(dev, down_count, NI6143_CALIB_LO_TIME_REG);
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004195 devpriv->pwm_down_count = down_count;
4196 return 5;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004197 case INSN_CONFIG_GET_PWM_OUTPUT:
4198 return ni_get_pwm_config(dev, data);
4199 default:
4200 return -EINVAL;
H Hartley Sweeten1e49c5d2014-05-28 16:26:26 -07004201 }
4202 return 0;
4203}
4204
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004205static int pack_mb88341(int addr, int val, int *bitstring)
4206{
4207 /*
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07004208 * Fujitsu MB 88341
4209 * Note that address bits are reversed. Thanks to
4210 * Ingo Keen for noticing this.
4211 *
4212 * Note also that the 88341 expects address values from
4213 * 1-12, whereas we use channel numbers 0-11. The NI
4214 * docs use 1-12, also, so be careful here.
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004215 */
4216 addr++;
4217 *bitstring = ((addr & 0x1) << 11) |
4218 ((addr & 0x2) << 9) |
4219 ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
4220 return 12;
4221}
4222
4223static int pack_dac8800(int addr, int val, int *bitstring)
4224{
4225 *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
4226 return 11;
4227}
4228
4229static int pack_dac8043(int addr, int val, int *bitstring)
4230{
4231 *bitstring = val & 0xfff;
4232 return 12;
4233}
4234
4235static int pack_ad8522(int addr, int val, int *bitstring)
4236{
4237 *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
4238 return 16;
4239}
4240
4241static int pack_ad8804(int addr, int val, int *bitstring)
4242{
4243 *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
4244 return 12;
4245}
4246
4247static int pack_ad8842(int addr, int val, int *bitstring)
4248{
4249 *bitstring = ((addr + 1) << 8) | (val & 0xff);
4250 return 12;
4251}
4252
4253struct caldac_struct {
4254 int n_chans;
4255 int n_bits;
4256 int (*packbits)(int, int, int *);
4257};
4258
4259static struct caldac_struct caldacs[] = {
4260 [mb88341] = {12, 8, pack_mb88341},
4261 [dac8800] = {8, 8, pack_dac8800},
4262 [dac8043] = {1, 12, pack_dac8043},
4263 [ad8522] = {2, 12, pack_ad8522},
4264 [ad8804] = {12, 8, pack_ad8804},
4265 [ad8842] = {8, 8, pack_ad8842},
4266 [ad8804_debug] = {16, 8, pack_ad8804},
4267};
4268
4269static void ni_write_caldac(struct comedi_device *dev, int addr, int val)
4270{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01004271 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004272 struct ni_private *devpriv = dev->private;
4273 unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004274 unsigned int cmd;
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004275 int i;
4276 int type;
4277
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004278 if (devpriv->caldacs[addr] == val)
4279 return;
4280 devpriv->caldacs[addr] = val;
4281
4282 for (i = 0; i < 3; i++) {
4283 type = board->caldac[i];
4284 if (type == caldac_none)
4285 break;
4286 if (addr < caldacs[type].n_chans) {
4287 bits = caldacs[type].packbits(addr, val, &bitstring);
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004288 loadbit = NI_E_SERIAL_CMD_DAC_LD(i);
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004289 break;
4290 }
4291 addr -= caldacs[type].n_chans;
4292 }
4293
H Hartley Sweetenaccb2982015-04-20 11:49:05 -07004294 /* bits will be 0 if there is no caldac for the given addr */
4295 if (bits == 0)
4296 return;
4297
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004298 for (bit = 1 << (bits - 1); bit; bit >>= 1) {
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004299 cmd = (bit & bitstring) ? NI_E_SERIAL_CMD_SDATA : 0;
4300 ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004301 udelay(1);
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004302 ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004303 udelay(1);
4304 }
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004305 ni_writeb(dev, loadbit, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004306 udelay(1);
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004307 ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004308}
4309
4310static int ni_calib_insn_write(struct comedi_device *dev,
4311 struct comedi_subdevice *s,
4312 struct comedi_insn *insn,
4313 unsigned int *data)
4314{
4315 ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
4316
4317 return 1;
4318}
4319
4320static int ni_calib_insn_read(struct comedi_device *dev,
4321 struct comedi_subdevice *s,
4322 struct comedi_insn *insn,
4323 unsigned int *data)
4324{
4325 struct ni_private *devpriv = dev->private;
4326
4327 data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
4328
4329 return 1;
4330}
4331
4332static void caldac_setup(struct comedi_device *dev, struct comedi_subdevice *s)
4333{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01004334 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004335 struct ni_private *devpriv = dev->private;
4336 int i, j;
4337 int n_dacs;
4338 int n_chans = 0;
4339 int n_bits;
4340 int diffbits = 0;
4341 int type;
4342 int chan;
4343
4344 type = board->caldac[0];
4345 if (type == caldac_none)
4346 return;
4347 n_bits = caldacs[type].n_bits;
4348 for (i = 0; i < 3; i++) {
4349 type = board->caldac[i];
4350 if (type == caldac_none)
4351 break;
4352 if (caldacs[type].n_bits != n_bits)
4353 diffbits = 1;
4354 n_chans += caldacs[type].n_chans;
4355 }
4356 n_dacs = i;
4357 s->n_chan = n_chans;
4358
4359 if (diffbits) {
H Hartley Sweetenbeb1cc12016-04-14 09:57:57 -07004360 unsigned int *maxdata_list = devpriv->caldac_maxdata_list;
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004361
4362 if (n_chans > MAX_N_CALDACS)
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004363 dev_err(dev->class_dev,
4364 "BUG! MAX_N_CALDACS too small\n");
H Hartley Sweetenbeb1cc12016-04-14 09:57:57 -07004365 s->maxdata_list = maxdata_list;
H Hartley Sweeten62c2bce2014-05-28 16:26:28 -07004366 chan = 0;
4367 for (i = 0; i < n_dacs; i++) {
4368 type = board->caldac[i];
4369 for (j = 0; j < caldacs[type].n_chans; j++) {
4370 maxdata_list[chan] =
4371 (1 << caldacs[type].n_bits) - 1;
4372 chan++;
4373 }
4374 }
4375
4376 for (chan = 0; chan < s->n_chan; chan++)
4377 ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
4378 } else {
4379 type = board->caldac[0];
4380 s->maxdata = (1 << caldacs[type].n_bits) - 1;
4381
4382 for (chan = 0; chan < s->n_chan; chan++)
4383 ni_write_caldac(dev, i, s->maxdata / 2);
4384 }
4385}
4386
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004387static int ni_read_eeprom(struct comedi_device *dev, int addr)
4388{
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004389 unsigned int cmd = NI_E_SERIAL_CMD_EEPROM_CS;
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004390 int bit;
4391 int bitstring;
4392
4393 bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004394 ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004395 for (bit = 0x8000; bit; bit >>= 1) {
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004396 if (bit & bitstring)
4397 cmd |= NI_E_SERIAL_CMD_SDATA;
4398 else
4399 cmd &= ~NI_E_SERIAL_CMD_SDATA;
4400
4401 ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
4402 ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004403 }
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004404 cmd = NI_E_SERIAL_CMD_EEPROM_CS;
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004405 bitstring = 0;
4406 for (bit = 0x80; bit; bit >>= 1) {
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004407 ni_writeb(dev, cmd, NI_E_SERIAL_CMD_REG);
4408 ni_writeb(dev, NI_E_SERIAL_CMD_SCLK | cmd, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten906170b2015-05-01 14:59:52 -07004409 if (ni_readb(dev, NI_E_STATUS_REG) & NI_E_STATUS_PROMOUT)
4410 bitstring |= bit;
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004411 }
H Hartley Sweeten2ed183f2015-05-01 14:59:53 -07004412 ni_writeb(dev, 0, NI_E_SERIAL_CMD_REG);
H Hartley Sweeten36adeee2014-05-28 16:26:25 -07004413
4414 return bitstring;
4415}
4416
4417static int ni_eeprom_insn_read(struct comedi_device *dev,
4418 struct comedi_subdevice *s,
4419 struct comedi_insn *insn,
4420 unsigned int *data)
4421{
4422 data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
4423
4424 return 1;
4425}
4426
4427static int ni_m_series_eeprom_insn_read(struct comedi_device *dev,
4428 struct comedi_subdevice *s,
4429 struct comedi_insn *insn,
4430 unsigned int *data)
4431{
4432 struct ni_private *devpriv = dev->private;
4433
4434 data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
4435
4436 return 1;
4437}
4438
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004439static unsigned int ni_old_get_pfi_routing(struct comedi_device *dev,
4440 unsigned int chan)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004441{
4442 /* pre-m-series boards have fixed signals on pfi pins */
4443 switch (chan) {
4444 case 0:
4445 return NI_PFI_OUTPUT_AI_START1;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004446 case 1:
4447 return NI_PFI_OUTPUT_AI_START2;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004448 case 2:
4449 return NI_PFI_OUTPUT_AI_CONVERT;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004450 case 3:
4451 return NI_PFI_OUTPUT_G_SRC1;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004452 case 4:
4453 return NI_PFI_OUTPUT_G_GATE1;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004454 case 5:
4455 return NI_PFI_OUTPUT_AO_UPDATE_N;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004456 case 6:
4457 return NI_PFI_OUTPUT_AO_START1;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004458 case 7:
4459 return NI_PFI_OUTPUT_AI_START_PULSE;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004460 case 8:
4461 return NI_PFI_OUTPUT_G_SRC0;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004462 case 9:
4463 return NI_PFI_OUTPUT_G_GATE0;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004464 default:
Haneen Mohammedcd255032015-03-05 13:01:49 +03004465 dev_err(dev->class_dev, "bug, unhandled case in switch.\n");
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004466 break;
4467 }
4468 return 0;
4469}
4470
4471static int ni_old_set_pfi_routing(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004472 unsigned int chan, unsigned int source)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004473{
4474 /* pre-m-series boards have fixed signals on pfi pins */
4475 if (source != ni_old_get_pfi_routing(dev, chan))
4476 return -EINVAL;
4477 return 2;
4478}
4479
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004480static unsigned int ni_m_series_get_pfi_routing(struct comedi_device *dev,
4481 unsigned int chan)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004482{
4483 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004484 const unsigned int array_offset = chan / 3;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004485
H Hartley Sweeten43e9d882015-05-01 14:58:43 -07004486 return NI_M_PFI_OUT_SEL_TO_SRC(chan,
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004487 devpriv->pfi_output_select_reg[array_offset]);
4488}
4489
4490static int ni_m_series_set_pfi_routing(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004491 unsigned int chan, unsigned int source)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004492{
4493 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004494 unsigned int index = chan / 3;
H Hartley Sweetene0852f62015-05-01 14:58:30 -07004495 unsigned short val = devpriv->pfi_output_select_reg[index];
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004496
4497 if ((source & 0x1f) != source)
4498 return -EINVAL;
H Hartley Sweetene0852f62015-05-01 14:58:30 -07004499
H Hartley Sweeten43e9d882015-05-01 14:58:43 -07004500 val &= ~NI_M_PFI_OUT_SEL_MASK(chan);
4501 val |= NI_M_PFI_OUT_SEL(chan, source);
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004502 ni_writew(dev, val, NI_M_PFI_OUT_SEL_REG(index));
H Hartley Sweetene0852f62015-05-01 14:58:30 -07004503 devpriv->pfi_output_select_reg[index] = val;
4504
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004505 return 2;
4506}
4507
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004508static unsigned int ni_get_pfi_routing(struct comedi_device *dev,
4509 unsigned int chan)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004510{
H Hartley Sweeten17733212014-06-19 10:20:32 -07004511 struct ni_private *devpriv = dev->private;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004512
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004513 return (devpriv->is_m_series)
4514 ? ni_m_series_get_pfi_routing(dev, chan)
4515 : ni_old_get_pfi_routing(dev, chan);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004516}
4517
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004518static int ni_set_pfi_routing(struct comedi_device *dev,
4519 unsigned int chan, unsigned int source)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004520{
H Hartley Sweeten17733212014-06-19 10:20:32 -07004521 struct ni_private *devpriv = dev->private;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004522
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004523 return (devpriv->is_m_series)
4524 ? ni_m_series_set_pfi_routing(dev, chan, source)
4525 : ni_old_set_pfi_routing(dev, chan, source);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004526}
4527
4528static int ni_config_filter(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004529 unsigned int pfi_channel,
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004530 enum ni_pfi_filter_select filter)
4531{
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07004532 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004533 unsigned int bits;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004534
H Hartley Sweeten17733212014-06-19 10:20:32 -07004535 if (!devpriv->is_m_series)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004536 return -ENOTSUPP;
H Hartley Sweeten17733212014-06-19 10:20:32 -07004537
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004538 bits = ni_readl(dev, NI_M_PFI_FILTER_REG);
H Hartley Sweeten0dee7ec2015-05-01 14:58:44 -07004539 bits &= ~NI_M_PFI_FILTER_SEL_MASK(pfi_channel);
4540 bits |= NI_M_PFI_FILTER_SEL(pfi_channel, filter);
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004541 ni_writel(dev, bits, NI_M_PFI_FILTER_REG);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004542 return 0;
4543}
4544
4545static int ni_pfi_insn_config(struct comedi_device *dev,
4546 struct comedi_subdevice *s,
4547 struct comedi_insn *insn,
4548 unsigned int *data)
4549{
4550 struct ni_private *devpriv = dev->private;
4551 unsigned int chan;
4552
4553 if (insn->n < 1)
4554 return -EINVAL;
4555
4556 chan = CR_CHAN(insn->chanspec);
4557
4558 switch (data[0]) {
4559 case COMEDI_OUTPUT:
H Hartley Sweeten5ecadf82015-05-01 14:59:12 -07004560 ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 1);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004561 break;
4562 case COMEDI_INPUT:
H Hartley Sweeten5ecadf82015-05-01 14:59:12 -07004563 ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, 1 << chan, 0);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004564 break;
4565 case INSN_CONFIG_DIO_QUERY:
4566 data[1] =
4567 (devpriv->io_bidirection_pin_reg & (1 << chan)) ?
4568 COMEDI_OUTPUT : COMEDI_INPUT;
4569 return 0;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004570 case INSN_CONFIG_SET_ROUTING:
4571 return ni_set_pfi_routing(dev, chan, data[1]);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004572 case INSN_CONFIG_GET_ROUTING:
4573 data[1] = ni_get_pfi_routing(dev, chan);
4574 break;
4575 case INSN_CONFIG_FILTER:
4576 return ni_config_filter(dev, chan, data[1]);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004577 default:
4578 return -EINVAL;
4579 }
4580 return 0;
4581}
4582
4583static int ni_pfi_insn_bits(struct comedi_device *dev,
4584 struct comedi_subdevice *s,
4585 struct comedi_insn *insn,
4586 unsigned int *data)
4587{
H Hartley Sweeten9c340ac2014-05-29 10:56:32 -07004588 struct ni_private *devpriv = dev->private;
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004589
H Hartley Sweeten17733212014-06-19 10:20:32 -07004590 if (!devpriv->is_m_series)
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004591 return -ENOTSUPP;
4592
4593 if (comedi_dio_update_state(s, data))
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004594 ni_writew(dev, s->state, NI_M_PFI_DO_REG);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004595
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004596 data[1] = ni_readw(dev, NI_M_PFI_DI_REG);
H Hartley Sweeten4187a792014-05-28 16:26:30 -07004597
4598 return insn->n;
4599}
4600
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004601static int cs5529_wait_for_idle(struct comedi_device *dev)
4602{
4603 unsigned short status;
4604 const int timeout = HZ;
4605 int i;
4606
4607 for (i = 0; i < timeout; i++) {
H Hartley Sweetenef391542015-05-01 15:00:11 -07004608 status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG);
4609 if ((status & NI67XX_CAL_STATUS_BUSY) == 0)
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004610 break;
4611 set_current_state(TASK_INTERRUPTIBLE);
4612 if (schedule_timeout(1))
4613 return -EIO;
4614 }
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004615 if (i == timeout) {
Haneen Mohammedcd255032015-03-05 13:01:49 +03004616 dev_err(dev->class_dev, "timeout\n");
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004617 return -ETIME;
4618 }
4619 return 0;
4620}
4621
4622static void cs5529_command(struct comedi_device *dev, unsigned short value)
4623{
4624 static const int timeout = 100;
4625 int i;
4626
H Hartley Sweetenef391542015-05-01 15:00:11 -07004627 ni_ao_win_outw(dev, value, NI67XX_CAL_CMD_REG);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004628 /* give time for command to start being serially clocked into cs5529.
H Hartley Sweetenef391542015-05-01 15:00:11 -07004629 * this insures that the NI67XX_CAL_STATUS_BUSY bit will get properly
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004630 * set before we exit this function.
4631 */
4632 for (i = 0; i < timeout; i++) {
H Hartley Sweetenef391542015-05-01 15:00:11 -07004633 if (ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG) &
4634 NI67XX_CAL_STATUS_BUSY)
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004635 break;
4636 udelay(1);
4637 }
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004638 if (i == timeout)
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07004639 dev_err(dev->class_dev,
4640 "possible problem - never saw adc go busy?\n");
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004641}
4642
4643static int cs5529_do_conversion(struct comedi_device *dev,
4644 unsigned short *data)
4645{
4646 int retval;
4647 unsigned short status;
4648
H Hartley Sweeten94f0cbb2015-05-01 15:00:10 -07004649 cs5529_command(dev, CS5529_CMD_CB | CS5529_CMD_SINGLE_CONV);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004650 retval = cs5529_wait_for_idle(dev);
4651 if (retval) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07004652 dev_err(dev->class_dev,
4653 "timeout or signal in cs5529_do_conversion()\n");
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004654 return -ETIME;
4655 }
H Hartley Sweetenef391542015-05-01 15:00:11 -07004656 status = ni_ao_win_inw(dev, NI67XX_CAL_STATUS_REG);
4657 if (status & NI67XX_CAL_STATUS_OSC_DETECT) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004658 dev_err(dev->class_dev,
4659 "cs5529 conversion error, status CSS_OSC_DETECT\n");
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004660 return -EIO;
4661 }
H Hartley Sweetenef391542015-05-01 15:00:11 -07004662 if (status & NI67XX_CAL_STATUS_OVERRANGE) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004663 dev_err(dev->class_dev,
4664 "cs5529 conversion error, overrange (ignoring)\n");
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004665 }
4666 if (data) {
H Hartley Sweetenef391542015-05-01 15:00:11 -07004667 *data = ni_ao_win_inw(dev, NI67XX_CAL_DATA_REG);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004668 /* cs5529 returns 16 bit signed data in bipolar mode */
4669 *data ^= (1 << 15);
4670 }
4671 return 0;
4672}
4673
4674static int cs5529_ai_insn_read(struct comedi_device *dev,
4675 struct comedi_subdevice *s,
4676 struct comedi_insn *insn,
4677 unsigned int *data)
4678{
4679 int n, retval;
4680 unsigned short sample;
4681 unsigned int channel_select;
4682 const unsigned int INTERNAL_REF = 0x1000;
4683
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07004684 /*
4685 * Set calibration adc source. Docs lie, reference select bits 8 to 11
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004686 * do nothing. bit 12 seems to chooses internal reference voltage, bit
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07004687 * 13 causes the adc input to go overrange (maybe reads external
4688 * reference?)
4689 */
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004690 if (insn->chanspec & CR_ALT_SOURCE)
4691 channel_select = INTERNAL_REF;
4692 else
4693 channel_select = CR_CHAN(insn->chanspec);
H Hartley Sweetenef391542015-05-01 15:00:11 -07004694 ni_ao_win_outw(dev, channel_select, NI67XX_AO_CAL_CHAN_SEL_REG);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004695
4696 for (n = 0; n < insn->n; n++) {
4697 retval = cs5529_do_conversion(dev, &sample);
4698 if (retval < 0)
4699 return retval;
4700 data[n] = sample;
4701 }
4702 return insn->n;
4703}
4704
4705static void cs5529_config_write(struct comedi_device *dev, unsigned int value,
4706 unsigned int reg_select_bits)
4707{
H Hartley Sweetenef391542015-05-01 15:00:11 -07004708 ni_ao_win_outw(dev, (value >> 16) & 0xff, NI67XX_CAL_CFG_HI_REG);
4709 ni_ao_win_outw(dev, value & 0xffff, NI67XX_CAL_CFG_LO_REG);
H Hartley Sweeten94f0cbb2015-05-01 15:00:10 -07004710 reg_select_bits &= CS5529_CMD_REG_MASK;
4711 cs5529_command(dev, CS5529_CMD_CB | reg_select_bits);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004712 if (cs5529_wait_for_idle(dev))
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07004713 dev_err(dev->class_dev,
4714 "timeout or signal in %s\n", __func__);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004715}
4716
4717static int init_cs5529(struct comedi_device *dev)
4718{
H Hartley Sweetenb738aa32015-05-01 15:00:09 -07004719 unsigned int config_bits = CS5529_CFG_PORT_FLAG |
4720 CS5529_CFG_WORD_RATE_2180;
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004721
4722#if 1
4723 /* do self-calibration */
H Hartley Sweetenb738aa32015-05-01 15:00:09 -07004724 cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_BOTH_SELF,
H Hartley Sweeten94f0cbb2015-05-01 15:00:10 -07004725 CS5529_CFG_REG);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004726 /* need to force a conversion for calibration to run */
4727 cs5529_do_conversion(dev, NULL);
4728#else
4729 /* force gain calibration to 1 */
H Hartley Sweeten94f0cbb2015-05-01 15:00:10 -07004730 cs5529_config_write(dev, 0x400000, CS5529_GAIN_REG);
H Hartley Sweetenb738aa32015-05-01 15:00:09 -07004731 cs5529_config_write(dev, config_bits | CS5529_CFG_CALIB_OFFSET_SELF,
H Hartley Sweeten94f0cbb2015-05-01 15:00:10 -07004732 CS5529_CFG_REG);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004733 if (cs5529_wait_for_idle(dev))
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07004734 dev_err(dev->class_dev,
4735 "timeout or signal in %s\n", __func__);
H Hartley Sweeten24e7c352014-05-28 16:26:31 -07004736#endif
4737 return 0;
4738}
4739
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004740/*
4741 * Find best multiplier/divider to try and get the PLL running at 80 MHz
4742 * given an arbitrary frequency input clock.
4743 */
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004744static int ni_mseries_get_pll_parameters(unsigned int reference_period_ns,
4745 unsigned int *freq_divider,
4746 unsigned int *freq_multiplier,
4747 unsigned int *actual_period_ns)
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004748{
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004749 unsigned int div;
4750 unsigned int best_div = 1;
4751 unsigned int mult;
4752 unsigned int best_mult = 1;
4753 static const unsigned int pico_per_nano = 1000;
4754 const unsigned int reference_picosec = reference_period_ns *
4755 pico_per_nano;
H Hartley Sweetenbd474a02016-04-14 09:57:55 -07004756 /*
4757 * m-series wants the phased-locked loop to output 80MHz, which is
4758 * divided by 4 to 20 MHz for most timing clocks
4759 */
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004760 static const unsigned int target_picosec = 12500;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004761 int best_period_picosec = 0;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07004762
H Hartley Sweetenb965e6a2015-05-01 14:58:37 -07004763 for (div = 1; div <= NI_M_PLL_MAX_DIVISOR; ++div) {
4764 for (mult = 1; mult <= NI_M_PLL_MAX_MULTIPLIER; ++mult) {
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004765 unsigned int new_period_ps =
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004766 (reference_picosec * div) / mult;
4767 if (abs(new_period_ps - target_picosec) <
4768 abs(best_period_picosec - target_picosec)) {
4769 best_period_picosec = new_period_ps;
4770 best_div = div;
4771 best_mult = mult;
4772 }
4773 }
4774 }
H Hartley Sweeten07e6b2e2014-07-18 13:29:53 -07004775 if (best_period_picosec == 0)
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004776 return -EIO;
H Hartley Sweeten07e6b2e2014-07-18 13:29:53 -07004777
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004778 *freq_divider = best_div;
4779 *freq_multiplier = best_mult;
H Hartley Sweeten68556ff2016-04-14 09:58:04 -07004780 /* return the actual period (* fudge factor for 80 to 20 MHz) */
4781 *actual_period_ns = DIV_ROUND_CLOSEST(best_period_picosec * 4,
Bhaktipriya Shridhar1e5a05d2016-02-21 16:13:01 +05304782 pico_per_nano);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004783 return 0;
4784}
4785
4786static int ni_mseries_set_pll_master_clock(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004787 unsigned int source,
4788 unsigned int period_ns)
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004789{
4790 struct ni_private *devpriv = dev->private;
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004791 static const unsigned int min_period_ns = 50;
4792 static const unsigned int max_period_ns = 1000;
4793 static const unsigned int timeout = 1000;
4794 unsigned int pll_control_bits;
4795 unsigned int freq_divider;
4796 unsigned int freq_multiplier;
4797 unsigned int rtsi;
4798 unsigned int i;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004799 int retval;
4800
4801 if (source == NI_MIO_PLL_PXI10_CLOCK)
4802 period_ns = 100;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07004803 /*
4804 * These limits are somewhat arbitrary, but NI advertises 1 to 20MHz
4805 * range so we'll use that.
4806 */
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004807 if (period_ns < min_period_ns || period_ns > max_period_ns) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004808 dev_err(dev->class_dev,
4809 "%s: you must specify an input clock frequency between %i and %i nanosec for the phased-lock loop\n",
4810 __func__, min_period_ns, max_period_ns);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004811 return -EINVAL;
4812 }
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004813 devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07004814 ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004815 NISTC_RTSI_TRIG_DIR_REG);
H Hartley Sweetenb965e6a2015-05-01 14:58:37 -07004816 pll_control_bits = NI_M_PLL_CTRL_ENA | NI_M_PLL_CTRL_VCO_MODE_75_150MHZ;
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004817 devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_TIMEBASE1_PLL |
4818 NI_M_CLK_FOUT2_TIMEBASE3_PLL;
4819 devpriv->clock_and_fout2 &= ~NI_M_CLK_FOUT2_PLL_SRC_MASK;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004820 switch (source) {
4821 case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004822 devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_STAR;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004823 break;
4824 case NI_MIO_PLL_PXI10_CLOCK:
4825 /* pxi clock is 10MHz */
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004826 devpriv->clock_and_fout2 |= NI_M_CLK_FOUT2_PLL_SRC_PXI10;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004827 break;
4828 default:
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004829 for (rtsi = 0; rtsi <= NI_M_MAX_RTSI_CHAN; ++rtsi) {
4830 if (source == NI_MIO_PLL_RTSI_CLOCK(rtsi)) {
4831 devpriv->clock_and_fout2 |=
4832 NI_M_CLK_FOUT2_PLL_SRC_RTSI(rtsi);
4833 break;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004834 }
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004835 }
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004836 if (rtsi > NI_M_MAX_RTSI_CHAN)
4837 return -EINVAL;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004838 break;
4839 }
H Hartley Sweeten07e6b2e2014-07-18 13:29:53 -07004840 retval = ni_mseries_get_pll_parameters(period_ns,
4841 &freq_divider,
4842 &freq_multiplier,
4843 &devpriv->clock_ns);
4844 if (retval < 0) {
4845 dev_err(dev->class_dev,
Haneen Mohammedcd255032015-03-05 13:01:49 +03004846 "bug, failed to find pll parameters\n");
H Hartley Sweeten07e6b2e2014-07-18 13:29:53 -07004847 return retval;
4848 }
4849
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004850 ni_writew(dev, devpriv->clock_and_fout2, NI_M_CLK_FOUT2_REG);
H Hartley Sweetenb965e6a2015-05-01 14:58:37 -07004851 pll_control_bits |= NI_M_PLL_CTRL_DIVISOR(freq_divider) |
4852 NI_M_PLL_CTRL_MULTIPLIER(freq_multiplier);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004853
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004854 ni_writew(dev, pll_control_bits, NI_M_PLL_CTRL_REG);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004855 devpriv->clock_source = source;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07004856 /* it takes a few hundred microseconds for PLL to lock */
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004857 for (i = 0; i < timeout; ++i) {
H Hartley Sweetenb1c70642015-05-01 14:58:38 -07004858 if (ni_readw(dev, NI_M_PLL_STATUS_REG) & NI_M_PLL_STATUS_LOCKED)
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004859 break;
4860 udelay(1);
4861 }
4862 if (i == timeout) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004863 dev_err(dev->class_dev,
4864 "%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns\n",
4865 __func__, source, period_ns);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004866 return -ETIMEDOUT;
4867 }
4868 return 3;
4869}
4870
4871static int ni_set_master_clock(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004872 unsigned int source, unsigned int period_ns)
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004873{
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004874 struct ni_private *devpriv = dev->private;
4875
4876 if (source == NI_MIO_INTERNAL_CLOCK) {
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004877 devpriv->rtsi_trig_direction_reg &= ~NISTC_RTSI_TRIG_USE_CLK;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07004878 ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004879 NISTC_RTSI_TRIG_DIR_REG);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004880 devpriv->clock_ns = TIMEBASE_1_NS;
H Hartley Sweeten17733212014-06-19 10:20:32 -07004881 if (devpriv->is_m_series) {
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004882 devpriv->clock_and_fout2 &=
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07004883 ~(NI_M_CLK_FOUT2_TIMEBASE1_PLL |
4884 NI_M_CLK_FOUT2_TIMEBASE3_PLL);
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07004885 ni_writew(dev, devpriv->clock_and_fout2,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07004886 NI_M_CLK_FOUT2_REG);
4887 ni_writew(dev, 0, NI_M_PLL_CTRL_REG);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004888 }
4889 devpriv->clock_source = source;
4890 } else {
H Hartley Sweeten17733212014-06-19 10:20:32 -07004891 if (devpriv->is_m_series) {
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004892 return ni_mseries_set_pll_master_clock(dev, source,
4893 period_ns);
4894 } else {
4895 if (source == NI_MIO_RTSI_CLOCK) {
4896 devpriv->rtsi_trig_direction_reg |=
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004897 NISTC_RTSI_TRIG_USE_CLK;
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07004898 ni_stc_writew(dev,
4899 devpriv->rtsi_trig_direction_reg,
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004900 NISTC_RTSI_TRIG_DIR_REG);
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004901 if (period_ns == 0) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004902 dev_err(dev->class_dev,
Haneen Mohammedcd255032015-03-05 13:01:49 +03004903 "we don't handle an unspecified clock period correctly yet, returning error\n");
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004904 return -EINVAL;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004905 }
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004906 devpriv->clock_ns = period_ns;
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004907 devpriv->clock_source = source;
H Hartley Sweeten6ac986d02015-03-05 13:21:18 -07004908 } else {
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004909 return -EINVAL;
H Hartley Sweeten6ac986d02015-03-05 13:21:18 -07004910 }
H Hartley Sweeten624b1612014-05-28 16:26:46 -07004911 }
4912 }
4913 return 3;
4914}
4915
H Hartley Sweetenae437632014-05-28 16:26:45 -07004916static int ni_valid_rtsi_output_source(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004917 unsigned int chan, unsigned int source)
H Hartley Sweetenae437632014-05-28 16:26:45 -07004918{
H Hartley Sweeten17733212014-06-19 10:20:32 -07004919 struct ni_private *devpriv = dev->private;
H Hartley Sweetenae437632014-05-28 16:26:45 -07004920
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004921 if (chan >= NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
4922 if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07004923 if (source == NI_RTSI_OUTPUT_RTSI_OSC)
4924 return 1;
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004925
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07004926 dev_err(dev->class_dev,
4927 "%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards\n",
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004928 __func__, chan, NISTC_RTSI_TRIG_OLD_CLK_CHAN);
H Hartley Sweeten0953ee42014-07-16 10:43:34 -07004929 return 0;
H Hartley Sweetenae437632014-05-28 16:26:45 -07004930 }
4931 return 0;
4932 }
4933 switch (source) {
4934 case NI_RTSI_OUTPUT_ADR_START1:
4935 case NI_RTSI_OUTPUT_ADR_START2:
4936 case NI_RTSI_OUTPUT_SCLKG:
4937 case NI_RTSI_OUTPUT_DACUPDN:
4938 case NI_RTSI_OUTPUT_DA_START1:
4939 case NI_RTSI_OUTPUT_G_SRC0:
4940 case NI_RTSI_OUTPUT_G_GATE0:
4941 case NI_RTSI_OUTPUT_RGOUT0:
4942 case NI_RTSI_OUTPUT_RTSI_BRD_0:
4943 return 1;
H Hartley Sweetenae437632014-05-28 16:26:45 -07004944 case NI_RTSI_OUTPUT_RTSI_OSC:
H Hartley Sweeten95940962014-07-16 10:43:33 -07004945 return (devpriv->is_m_series) ? 1 : 0;
H Hartley Sweetenae437632014-05-28 16:26:45 -07004946 default:
4947 return 0;
H Hartley Sweetenae437632014-05-28 16:26:45 -07004948 }
4949}
4950
4951static int ni_set_rtsi_routing(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004952 unsigned int chan, unsigned int src)
H Hartley Sweetenae437632014-05-28 16:26:45 -07004953{
4954 struct ni_private *devpriv = dev->private;
4955
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004956 if (ni_valid_rtsi_output_source(dev, chan, src) == 0)
H Hartley Sweetenae437632014-05-28 16:26:45 -07004957 return -EINVAL;
4958 if (chan < 4) {
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004959 devpriv->rtsi_trig_a_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan);
4960 devpriv->rtsi_trig_a_output_reg |= NISTC_RTSI_TRIG(chan, src);
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07004961 ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004962 NISTC_RTSI_TRIGA_OUT_REG);
H Hartley Sweetenae437632014-05-28 16:26:45 -07004963 } else if (chan < 8) {
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004964 devpriv->rtsi_trig_b_output_reg &= ~NISTC_RTSI_TRIG_MASK(chan);
4965 devpriv->rtsi_trig_b_output_reg |= NISTC_RTSI_TRIG(chan, src);
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07004966 ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004967 NISTC_RTSI_TRIGB_OUT_REG);
H Hartley Sweetenae437632014-05-28 16:26:45 -07004968 }
4969 return 2;
4970}
4971
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07004972static unsigned int ni_get_rtsi_routing(struct comedi_device *dev,
4973 unsigned int chan)
H Hartley Sweetenae437632014-05-28 16:26:45 -07004974{
4975 struct ni_private *devpriv = dev->private;
4976
4977 if (chan < 4) {
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004978 return NISTC_RTSI_TRIG_TO_SRC(chan,
4979 devpriv->rtsi_trig_a_output_reg);
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004980 } else if (chan < NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series)) {
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07004981 return NISTC_RTSI_TRIG_TO_SRC(chan,
4982 devpriv->rtsi_trig_b_output_reg);
H Hartley Sweetenae437632014-05-28 16:26:45 -07004983 } else {
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004984 if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN)
H Hartley Sweetenae437632014-05-28 16:26:45 -07004985 return NI_RTSI_OUTPUT_RTSI_OSC;
Haneen Mohammedcd255032015-03-05 13:01:49 +03004986 dev_err(dev->class_dev, "bug! should never get here?\n");
H Hartley Sweetenae437632014-05-28 16:26:45 -07004987 return 0;
4988 }
4989}
4990
4991static int ni_rtsi_insn_config(struct comedi_device *dev,
4992 struct comedi_subdevice *s,
4993 struct comedi_insn *insn,
4994 unsigned int *data)
4995{
H Hartley Sweetenae437632014-05-28 16:26:45 -07004996 struct ni_private *devpriv = dev->private;
4997 unsigned int chan = CR_CHAN(insn->chanspec);
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07004998 unsigned int max_chan = NISTC_RTSI_TRIG_NUM_CHAN(devpriv->is_m_series);
H Hartley Sweetenae437632014-05-28 16:26:45 -07004999
5000 switch (data[0]) {
5001 case INSN_CONFIG_DIO_OUTPUT:
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005002 if (chan < max_chan) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07005003 devpriv->rtsi_trig_direction_reg |=
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005004 NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
5005 } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07005006 devpriv->rtsi_trig_direction_reg |=
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005007 NISTC_RTSI_TRIG_DRV_CLK;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005008 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005009 ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005010 NISTC_RTSI_TRIG_DIR_REG);
H Hartley Sweetenae437632014-05-28 16:26:45 -07005011 break;
5012 case INSN_CONFIG_DIO_INPUT:
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005013 if (chan < max_chan) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07005014 devpriv->rtsi_trig_direction_reg &=
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005015 ~NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series);
5016 } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07005017 devpriv->rtsi_trig_direction_reg &=
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005018 ~NISTC_RTSI_TRIG_DRV_CLK;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005019 }
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005020 ni_stc_writew(dev, devpriv->rtsi_trig_direction_reg,
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005021 NISTC_RTSI_TRIG_DIR_REG);
H Hartley Sweetenae437632014-05-28 16:26:45 -07005022 break;
5023 case INSN_CONFIG_DIO_QUERY:
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005024 if (chan < max_chan) {
H Hartley Sweetenae437632014-05-28 16:26:45 -07005025 data[1] =
5026 (devpriv->rtsi_trig_direction_reg &
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005027 NISTC_RTSI_TRIG_DIR(chan, devpriv->is_m_series))
H Hartley Sweetenae437632014-05-28 16:26:45 -07005028 ? INSN_CONFIG_DIO_OUTPUT
5029 : INSN_CONFIG_DIO_INPUT;
H Hartley Sweetena4f18b12015-05-01 14:59:14 -07005030 } else if (chan == NISTC_RTSI_TRIG_OLD_CLK_CHAN) {
5031 data[1] = (devpriv->rtsi_trig_direction_reg &
5032 NISTC_RTSI_TRIG_DRV_CLK)
5033 ? INSN_CONFIG_DIO_OUTPUT
5034 : INSN_CONFIG_DIO_INPUT;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005035 }
5036 return 2;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005037 case INSN_CONFIG_SET_CLOCK_SRC:
5038 return ni_set_master_clock(dev, data[1], data[2]);
H Hartley Sweetenae437632014-05-28 16:26:45 -07005039 case INSN_CONFIG_GET_CLOCK_SRC:
5040 data[1] = devpriv->clock_source;
5041 data[2] = devpriv->clock_ns;
5042 return 3;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005043 case INSN_CONFIG_SET_ROUTING:
5044 return ni_set_rtsi_routing(dev, chan, data[1]);
H Hartley Sweetenae437632014-05-28 16:26:45 -07005045 case INSN_CONFIG_GET_ROUTING:
5046 data[1] = ni_get_rtsi_routing(dev, chan);
5047 return 2;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005048 default:
5049 return -EINVAL;
H Hartley Sweetenae437632014-05-28 16:26:45 -07005050 }
5051 return 1;
5052}
5053
H Hartley Sweeten12db1412014-05-28 16:26:32 -07005054static int ni_rtsi_insn_bits(struct comedi_device *dev,
5055 struct comedi_subdevice *s,
5056 struct comedi_insn *insn,
5057 unsigned int *data)
5058{
5059 data[1] = 0;
5060
5061 return insn->n;
5062}
5063
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005064static void ni_rtsi_init(struct comedi_device *dev)
5065{
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005066 struct ni_private *devpriv = dev->private;
5067
5068 /* Initialises the RTSI bus signal switch to a default state */
5069
H Hartley Sweeten40aafd72015-05-01 14:58:36 -07005070 /*
5071 * Use 10MHz instead of 20MHz for RTSI clock frequency. Appears
5072 * to have no effect, at least on pxi-6281, which always uses
5073 * 20MHz rtsi clock frequency
5074 */
5075 devpriv->clock_and_fout2 = NI_M_CLK_FOUT2_RTSI_10MHZ;
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005076 /* Set clock mode to internal */
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005077 if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0)
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07005078 dev_err(dev->class_dev, "ni_set_master_clock failed, bug?\n");
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005079 /* default internal lines routing to RTSI bus lines */
5080 devpriv->rtsi_trig_a_output_reg =
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07005081 NISTC_RTSI_TRIG(0, NI_RTSI_OUTPUT_ADR_START1) |
5082 NISTC_RTSI_TRIG(1, NI_RTSI_OUTPUT_ADR_START2) |
5083 NISTC_RTSI_TRIG(2, NI_RTSI_OUTPUT_SCLKG) |
5084 NISTC_RTSI_TRIG(3, NI_RTSI_OUTPUT_DACUPDN);
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005085 ni_stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07005086 NISTC_RTSI_TRIGA_OUT_REG);
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005087 devpriv->rtsi_trig_b_output_reg =
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07005088 NISTC_RTSI_TRIG(4, NI_RTSI_OUTPUT_DA_START1) |
5089 NISTC_RTSI_TRIG(5, NI_RTSI_OUTPUT_G_SRC0) |
5090 NISTC_RTSI_TRIG(6, NI_RTSI_OUTPUT_G_GATE0);
H Hartley Sweeten17733212014-06-19 10:20:32 -07005091 if (devpriv->is_m_series)
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005092 devpriv->rtsi_trig_b_output_reg |=
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07005093 NISTC_RTSI_TRIG(7, NI_RTSI_OUTPUT_RTSI_OSC);
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005094 ni_stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
H Hartley Sweeten390bc6f2015-05-01 14:59:32 -07005095 NISTC_RTSI_TRIGB_OUT_REG);
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005096
H Hartley Sweeten24a11ba2015-05-01 14:59:33 -07005097 /*
5098 * Sets the source and direction of the 4 on board lines
5099 * ni_stc_writew(dev, 0, NISTC_RTSI_BOARD_REG);
5100 */
H Hartley Sweeten892885e2014-05-28 16:26:44 -07005101}
5102
H Hartley Sweetenc8508a12014-05-28 16:26:29 -07005103#ifdef PCIDMA
5104static int ni_gpct_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
5105{
5106 struct ni_gpct *counter = s->private;
5107 int retval;
5108
5109 retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
5110 COMEDI_INPUT);
5111 if (retval) {
H Hartley Sweeten5ac1d822014-07-17 11:57:33 -07005112 dev_err(dev->class_dev,
5113 "no dma channel available for use by counter\n");
H Hartley Sweetenc8508a12014-05-28 16:26:29 -07005114 return retval;
5115 }
H Hartley Sweetenf8cfd0e2014-07-28 10:27:04 -07005116 ni_tio_acknowledge(counter);
H Hartley Sweetenc8508a12014-05-28 16:26:29 -07005117 ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
5118
5119 return ni_tio_cmd(dev, s);
5120}
5121
5122static int ni_gpct_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
5123{
5124 struct ni_gpct *counter = s->private;
5125 int retval;
5126
5127 retval = ni_tio_cancel(counter);
5128 ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
5129 ni_release_gpct_mite_channel(dev, counter->counter_index);
5130 return retval;
5131}
5132#endif
5133
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005134static irqreturn_t ni_E_interrupt(int irq, void *d)
5135{
5136 struct comedi_device *dev = d;
H Hartley Sweetenba5c0da2016-04-21 12:04:41 -07005137 struct comedi_subdevice *s_ai = dev->read_subdev;
H Hartley Sweeten7ef17452016-04-21 12:04:39 -07005138 struct comedi_subdevice *s_ao = dev->write_subdev;
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005139 unsigned short a_status;
5140 unsigned short b_status;
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005141 unsigned long flags;
5142#ifdef PCIDMA
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005143 struct ni_private *devpriv = dev->private;
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005144#endif
5145
5146 if (!dev->attached)
5147 return IRQ_NONE;
H Hartley Sweetenb6a0e5b2016-04-14 09:57:56 -07005148 smp_mb(); /* make sure dev->attached is checked */
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005149
5150 /* lock to avoid race with comedi_poll */
5151 spin_lock_irqsave(&dev->spinlock, flags);
H Hartley Sweeten7b14fff2015-05-01 14:59:37 -07005152 a_status = ni_stc_readw(dev, NISTC_AI_STATUS1_REG);
H Hartley Sweetend123ee32015-05-01 14:59:38 -07005153 b_status = ni_stc_readw(dev, NISTC_AO_STATUS1_REG);
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005154#ifdef PCIDMA
Spencer E. Olson6aab7fe2016-01-27 14:28:28 -07005155 if (devpriv->mite) {
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005156 unsigned long flags_too;
5157
5158 spin_lock_irqsave(&devpriv->mite_channel_lock, flags_too);
H Hartley Sweetenf7d005c2016-04-21 12:04:44 -07005159 if (s_ai && devpriv->ai_mite_chan)
5160 mite_ack_linkc(devpriv->ai_mite_chan, s_ai, false);
5161 if (s_ao && devpriv->ao_mite_chan)
5162 mite_ack_linkc(devpriv->ao_mite_chan, s_ao, false);
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005163 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags_too);
5164 }
5165#endif
5166 ack_a_interrupt(dev, a_status);
5167 ack_b_interrupt(dev, b_status);
H Hartley Sweeten3da088c2016-04-21 12:04:43 -07005168 if (s_ai) {
5169 if (a_status & NISTC_AI_STATUS1_INTA)
5170 handle_a_interrupt(dev, s_ai, a_status);
5171 /* handle any interrupt or dma events */
5172 comedi_handle_events(dev, s_ai);
5173 }
H Hartley Sweeten4b2d7382016-04-21 12:04:40 -07005174 if (s_ao) {
5175 if (b_status & NISTC_AO_STATUS1_INTB)
5176 handle_b_interrupt(dev, s_ao, b_status);
5177 /* handle any interrupt or dma events */
5178 comedi_handle_events(dev, s_ao);
5179 }
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005180 handle_gpct_interrupt(dev, 0);
5181 handle_gpct_interrupt(dev, 1);
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07005182#ifdef PCIDMA
5183 if (devpriv->is_m_series)
5184 handle_cdio_interrupt(dev);
5185#endif
H Hartley Sweetenc75527f2014-05-28 16:26:42 -07005186
5187 spin_unlock_irqrestore(&dev->spinlock, flags);
5188 return IRQ_HANDLED;
5189}
5190
H Hartley Sweeten2832b182014-05-28 16:26:49 -07005191static int ni_alloc_private(struct comedi_device *dev)
5192{
5193 struct ni_private *devpriv;
5194
5195 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
5196 if (!devpriv)
5197 return -ENOMEM;
5198
5199 spin_lock_init(&devpriv->window_lock);
5200 spin_lock_init(&devpriv->soft_reg_copy_lock);
5201 spin_lock_init(&devpriv->mite_channel_lock);
5202
5203 return 0;
5204}
5205
H Hartley Sweeten1fa955b2014-06-20 11:10:23 -07005206static int ni_E_init(struct comedi_device *dev,
H Hartley Sweetenfe20a342016-04-14 09:57:53 -07005207 unsigned int interrupt_pin, unsigned int irq_polarity)
David Schleef03aef4b2009-02-17 17:04:22 -08005208{
Ian Abbott7cf94ad2014-09-09 11:26:44 +01005209 const struct ni_board_struct *board = dev->board_ptr;
H Hartley Sweeten0e05c552012-10-15 10:19:06 -07005210 struct ni_private *devpriv = dev->private;
Bill Pemberton34c43922009-03-16 22:05:14 -04005211 struct comedi_subdevice *s;
H Hartley Sweeten8b6c5692012-06-12 11:59:33 -07005212 int ret;
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005213 int i;
David Schleef03aef4b2009-02-17 17:04:22 -08005214
H Hartley Sweeten6293e352013-03-05 10:20:41 -07005215 if (board->n_aochan > MAX_N_AO_CHAN) {
H Hartley Sweeten89c4695e2014-07-18 13:29:52 -07005216 dev_err(dev->class_dev, "bug! n_aochan > MAX_N_AO_CHAN\n");
David Schleef03aef4b2009-02-17 17:04:22 -08005217 return -EINVAL;
5218 }
5219
H Hartley Sweetencaedecf2014-07-14 12:23:59 -07005220 /* initialize clock dividers */
H Hartley Sweetena47fc022015-05-01 14:59:10 -07005221 devpriv->clock_and_fout = NISTC_CLK_FOUT_SLOW_DIV2 |
5222 NISTC_CLK_FOUT_SLOW_TIMEBASE |
5223 NISTC_CLK_FOUT_TO_BOARD_DIV2 |
5224 NISTC_CLK_FOUT_TO_BOARD;
H Hartley Sweetencaedecf2014-07-14 12:23:59 -07005225 if (!devpriv->is_6xxx) {
5226 /* BEAM is this needed for PCI-6143 ?? */
H Hartley Sweetena47fc022015-05-01 14:59:10 -07005227 devpriv->clock_and_fout |= (NISTC_CLK_FOUT_AI_OUT_DIV2 |
5228 NISTC_CLK_FOUT_AO_OUT_DIV2);
H Hartley Sweetencaedecf2014-07-14 12:23:59 -07005229 }
H Hartley Sweetena47fc022015-05-01 14:59:10 -07005230 ni_stc_writew(dev, devpriv->clock_and_fout, NISTC_CLK_FOUT_REG);
H Hartley Sweetencaedecf2014-07-14 12:23:59 -07005231
H Hartley Sweeten8b6c5692012-06-12 11:59:33 -07005232 ret = comedi_alloc_subdevices(dev, NI_NUM_SUBDEVICES);
5233 if (ret)
5234 return ret;
David Schleef03aef4b2009-02-17 17:04:22 -08005235
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005236 /* Analog Input subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005237 s = &dev->subdevices[NI_AI_SUBDEV];
H Hartley Sweeten6293e352013-03-05 10:20:41 -07005238 if (board->n_adchan) {
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005239 s->type = COMEDI_SUBD_AI;
5240 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_DITHER;
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07005241 if (!devpriv->is_611x)
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005242 s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
H Hartley Sweetendb2255f2014-07-14 12:23:52 -07005243 if (board->ai_maxdata > 0xffff)
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005244 s->subdev_flags |= SDF_LSAMPL;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005245 if (devpriv->is_m_series)
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005246 s->subdev_flags |= SDF_SOFT_CALIBRATED;
5247 s->n_chan = board->n_adchan;
5248 s->maxdata = board->ai_maxdata;
5249 s->range_table = ni_range_lkup[board->gainlkup];
5250 s->insn_read = ni_ai_insn_read;
5251 s->insn_config = ni_ai_insn_config;
5252 if (dev->irq) {
5253 dev->read_subdev = s;
5254 s->subdev_flags |= SDF_CMD_READ;
5255 s->len_chanlist = 512;
5256 s->do_cmdtest = ni_ai_cmdtest;
5257 s->do_cmd = ni_ai_cmd;
5258 s->cancel = ni_ai_reset;
5259 s->poll = ni_ai_poll;
5260 s->munge = ni_ai_munge;
5261
5262 if (devpriv->mite)
5263 s->async_dma_dir = DMA_FROM_DEVICE;
5264 }
H Hartley Sweeteneeca0ca2014-07-14 12:24:00 -07005265
5266 /* reset the analog input configuration */
5267 ni_ai_reset(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08005268 } else {
H Hartley Sweetena06500b2014-07-14 12:23:55 -07005269 s->type = COMEDI_SUBD_UNUSED;
David Schleef03aef4b2009-02-17 17:04:22 -08005270 }
5271
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005272 /* Analog Output subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005273 s = &dev->subdevices[NI_AO_SUBDEV];
H Hartley Sweeten6293e352013-03-05 10:20:41 -07005274 if (board->n_aochan) {
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005275 s->type = COMEDI_SUBD_AO;
5276 s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005277 if (devpriv->is_m_series)
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005278 s->subdev_flags |= SDF_SOFT_CALIBRATED;
5279 s->n_chan = board->n_aochan;
5280 s->maxdata = board->ao_maxdata;
5281 s->range_table = board->ao_range_table;
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005282 s->insn_config = ni_ao_insn_config;
H Hartley Sweetenb6d977e2014-08-25 16:04:15 -07005283 s->insn_write = ni_ao_insn_write;
H Hartley Sweetenb6d977e2014-08-25 16:04:15 -07005284
5285 ret = comedi_alloc_subdev_readback(s);
5286 if (ret)
5287 return ret;
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005288
5289 /*
5290 * Along with the IRQ we need either a FIFO or DMA for
5291 * async command support.
5292 */
5293 if (dev->irq && (board->ao_fifo_depth || devpriv->mite)) {
David Schleef03aef4b2009-02-17 17:04:22 -08005294 dev->write_subdev = s;
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005295 s->subdev_flags |= SDF_CMD_WRITE;
5296 s->len_chanlist = s->n_chan;
5297 s->do_cmdtest = ni_ao_cmdtest;
5298 s->do_cmd = ni_ao_cmd;
5299 s->cancel = ni_ao_reset;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005300 if (!devpriv->is_m_series)
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005301 s->munge = ni_ao_munge;
5302
5303 if (devpriv->mite)
5304 s->async_dma_dir = DMA_TO_DEVICE;
David Schleef03aef4b2009-02-17 17:04:22 -08005305 }
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005306
5307 if (devpriv->is_67xx)
5308 init_ao_67xx(dev, s);
H Hartley Sweeteneeca0ca2014-07-14 12:24:00 -07005309
5310 /* reset the analog output configuration */
5311 ni_ao_reset(dev, s);
David Schleef03aef4b2009-02-17 17:04:22 -08005312 } else {
H Hartley Sweeten80a94e42014-07-14 12:23:56 -07005313 s->type = COMEDI_SUBD_UNUSED;
David Schleef03aef4b2009-02-17 17:04:22 -08005314 }
David Schleef03aef4b2009-02-17 17:04:22 -08005315
H Hartley Sweeten2d4ecc32014-07-14 12:23:58 -07005316 /* Digital I/O subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005317 s = &dev->subdevices[NI_DIO_SUBDEV];
H Hartley Sweeten2d4ecc32014-07-14 12:23:58 -07005318 s->type = COMEDI_SUBD_DIO;
5319 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
5320 s->n_chan = board->has_32dio_chan ? 32 : 8;
5321 s->maxdata = 1;
5322 s->range_table = &range_digital;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005323 if (devpriv->is_m_series) {
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07005324#ifdef PCIDMA
H Hartley Sweeten2d4ecc32014-07-14 12:23:58 -07005325 s->subdev_flags |= SDF_LSAMPL;
5326 s->insn_bits = ni_m_series_dio_insn_bits;
5327 s->insn_config = ni_m_series_dio_insn_config;
5328 if (dev->irq) {
5329 s->subdev_flags |= SDF_CMD_WRITE /* | SDF_CMD_READ */;
5330 s->len_chanlist = s->n_chan;
5331 s->do_cmdtest = ni_cdio_cmdtest;
5332 s->do_cmd = ni_cdio_cmd;
5333 s->cancel = ni_cdio_cancel;
David Schleef03aef4b2009-02-17 17:04:22 -08005334
H Hartley Sweeten2d4ecc32014-07-14 12:23:58 -07005335 /* M-series boards use DMA */
5336 s->async_dma_dir = DMA_BIDIRECTIONAL;
5337 }
5338
5339 /* reset DIO and set all channels to inputs */
H Hartley Sweeten3c3eb8e2015-05-01 14:58:47 -07005340 ni_writel(dev, NI_M_CDO_CMD_RESET |
5341 NI_M_CDI_CMD_RESET,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005342 NI_M_CDIO_CMD_REG);
5343 ni_writel(dev, s->io_bits, NI_M_DIO_DIR_REG);
H Hartley Sweetencf122bb2016-04-14 09:57:52 -07005344#endif /* PCIDMA */
David Schleef03aef4b2009-02-17 17:04:22 -08005345 } else {
H Hartley Sweeten2d4ecc32014-07-14 12:23:58 -07005346 s->insn_bits = ni_dio_insn_bits;
5347 s->insn_config = ni_dio_insn_config;
5348
5349 /* set all channels to inputs */
H Hartley Sweeten59a97c32015-05-01 14:59:02 -07005350 devpriv->dio_control = NISTC_DIO_CTRL_DIR(s->io_bits);
5351 ni_writew(dev, devpriv->dio_control, NISTC_DIO_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08005352 }
5353
5354 /* 8255 device */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005355 s = &dev->subdevices[NI_8255_DIO_SUBDEV];
H Hartley Sweetene6439a42014-02-03 10:43:25 -07005356 if (board->has_8255) {
H Hartley Sweeten61260f52015-05-01 14:59:55 -07005357 ret = subdev_8255_init(dev, s, ni_8255_callback,
5358 NI_E_8255_BASE);
H Hartley Sweetene6439a42014-02-03 10:43:25 -07005359 if (ret)
5360 return ret;
5361 } else {
David Schleef03aef4b2009-02-17 17:04:22 -08005362 s->type = COMEDI_SUBD_UNUSED;
H Hartley Sweetene6439a42014-02-03 10:43:25 -07005363 }
David Schleef03aef4b2009-02-17 17:04:22 -08005364
5365 /* formerly general purpose counter/timer device, but no longer used */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005366 s = &dev->subdevices[NI_UNUSED_SUBDEV];
David Schleef03aef4b2009-02-17 17:04:22 -08005367 s->type = COMEDI_SUBD_UNUSED;
5368
H Hartley Sweetencb429502014-07-14 12:24:01 -07005369 /* Calibration subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005370 s = &dev->subdevices[NI_CALIBRATION_SUBDEV];
H Hartley Sweetencb429502014-07-14 12:24:01 -07005371 s->type = COMEDI_SUBD_CALIB;
5372 s->subdev_flags = SDF_INTERNAL;
5373 s->n_chan = 1;
5374 s->maxdata = 0;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005375 if (devpriv->is_m_series) {
H Hartley Sweetencb429502014-07-14 12:24:01 -07005376 /* internal PWM output used for AI nonlinearity calibration */
5377 s->insn_config = ni_m_series_pwm_config;
5378
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005379 ni_writel(dev, 0x0, NI_M_CAL_PWM_REG);
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07005380 } else if (devpriv->is_6143) {
H Hartley Sweetencb429502014-07-14 12:24:01 -07005381 /* internal PWM output used for AI nonlinearity calibration */
5382 s->insn_config = ni_6143_pwm_config;
David Schleef03aef4b2009-02-17 17:04:22 -08005383 } else {
H Hartley Sweetencb429502014-07-14 12:24:01 -07005384 s->subdev_flags |= SDF_WRITABLE;
5385 s->insn_read = ni_calib_insn_read;
5386 s->insn_write = ni_calib_insn_write;
5387
5388 /* setup the caldacs and find the real n_chan and maxdata */
David Schleef03aef4b2009-02-17 17:04:22 -08005389 caldac_setup(dev, s);
5390 }
5391
H Hartley Sweeten433c79f2014-07-14 12:24:02 -07005392 /* EEPROM subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005393 s = &dev->subdevices[NI_EEPROM_SUBDEV];
H Hartley Sweeten433c79f2014-07-14 12:24:02 -07005394 s->type = COMEDI_SUBD_MEMORY;
5395 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
5396 s->maxdata = 0xff;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005397 if (devpriv->is_m_series) {
H Hartley Sweeten433c79f2014-07-14 12:24:02 -07005398 s->n_chan = M_SERIES_EEPROM_SIZE;
5399 s->insn_read = ni_m_series_eeprom_insn_read;
David Schleef03aef4b2009-02-17 17:04:22 -08005400 } else {
H Hartley Sweeten433c79f2014-07-14 12:24:02 -07005401 s->n_chan = 512;
5402 s->insn_read = ni_eeprom_insn_read;
David Schleef03aef4b2009-02-17 17:04:22 -08005403 }
5404
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005405 /* Digital I/O (PFI) subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005406 s = &dev->subdevices[NI_PFI_DIO_SUBDEV];
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005407 s->type = COMEDI_SUBD_DIO;
5408 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
5409 s->maxdata = 1;
H Hartley Sweeten17733212014-06-19 10:20:32 -07005410 if (devpriv->is_m_series) {
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005411 s->n_chan = 16;
5412 s->insn_bits = ni_pfi_insn_bits;
5413
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005414 ni_writew(dev, s->state, NI_M_PFI_DO_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08005415 for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07005416 ni_writew(dev, devpriv->pfi_output_select_reg[i],
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005417 NI_M_PFI_OUT_SEL_REG(i));
David Schleef03aef4b2009-02-17 17:04:22 -08005418 }
5419 } else {
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005420 s->n_chan = 10;
David Schleef03aef4b2009-02-17 17:04:22 -08005421 }
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005422 s->insn_config = ni_pfi_insn_config;
5423
H Hartley Sweeten5ecadf82015-05-01 14:59:12 -07005424 ni_set_bits(dev, NISTC_IO_BIDIR_PIN_REG, ~0, 0);
David Schleef03aef4b2009-02-17 17:04:22 -08005425
5426 /* cs5529 calibration adc */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005427 s = &dev->subdevices[NI_CS5529_CALIBRATION_SUBDEV];
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07005428 if (devpriv->is_67xx) {
David Schleef03aef4b2009-02-17 17:04:22 -08005429 s->type = COMEDI_SUBD_AI;
5430 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
Bill Pemberton2696fb52009-03-27 11:29:34 -04005431 /* one channel for each analog output channel */
H Hartley Sweeten6293e352013-03-05 10:20:41 -07005432 s->n_chan = board->n_aochan;
David Schleef03aef4b2009-02-17 17:04:22 -08005433 s->maxdata = (1 << 16) - 1;
5434 s->range_table = &range_unknown; /* XXX */
5435 s->insn_read = cs5529_ai_insn_read;
5436 s->insn_config = NULL;
5437 init_cs5529(dev);
5438 } else {
5439 s->type = COMEDI_SUBD_UNUSED;
5440 }
5441
5442 /* Serial */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005443 s = &dev->subdevices[NI_SERIAL_SUBDEV];
David Schleef03aef4b2009-02-17 17:04:22 -08005444 s->type = COMEDI_SUBD_SERIAL;
5445 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
5446 s->n_chan = 1;
5447 s->maxdata = 0xff;
5448 s->insn_config = ni_serial_insn_config;
5449 devpriv->serial_interval_ns = 0;
5450 devpriv->serial_hw_mode = 0;
5451
5452 /* RTSI */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005453 s = &dev->subdevices[NI_RTSI_SUBDEV];
David Schleef03aef4b2009-02-17 17:04:22 -08005454 s->type = COMEDI_SUBD_DIO;
5455 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
5456 s->n_chan = 8;
5457 s->maxdata = 1;
5458 s->insn_bits = ni_rtsi_insn_bits;
5459 s->insn_config = ni_rtsi_insn_config;
5460 ni_rtsi_init(dev);
5461
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005462 /* allocate and initialize the gpct counter device */
David Schleef03aef4b2009-02-17 17:04:22 -08005463 devpriv->counter_dev = ni_gpct_device_construct(dev,
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005464 ni_gpct_write_register,
5465 ni_gpct_read_register,
5466 (devpriv->is_m_series)
5467 ? ni_gpct_variant_m_series
5468 : ni_gpct_variant_e_series,
5469 NUM_GPCT);
Kumar Amit Mehtac095fad2014-02-26 01:04:45 +02005470 if (!devpriv->counter_dev)
5471 return -ENOMEM;
5472
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005473 /* Counter (gpct) subdevices */
H Hartley Sweeten43f2c8b72014-07-14 12:24:03 -07005474 for (i = 0; i < NUM_GPCT; ++i) {
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005475 struct ni_gpct *gpct = &devpriv->counter_dev->counters[i];
David Schleef03aef4b2009-02-17 17:04:22 -08005476
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005477 /* setup and initialize the counter */
5478 gpct->chip_index = 0;
5479 gpct->counter_index = i;
5480 ni_tio_init_counter(gpct);
5481
5482 s = &dev->subdevices[NI_GPCT_SUBDEV(i)];
5483 s->type = COMEDI_SUBD_COUNTER;
5484 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
5485 s->n_chan = 3;
5486 s->maxdata = (devpriv->is_m_series) ? 0xffffffff
5487 : 0x00ffffff;
5488 s->insn_read = ni_tio_insn_read;
Ian Abbott5ca05342016-07-20 17:07:34 +01005489 s->insn_write = ni_tio_insn_write;
H Hartley Sweetenc607b332014-07-14 12:24:04 -07005490 s->insn_config = ni_tio_insn_config;
5491#ifdef PCIDMA
5492 if (dev->irq && devpriv->mite) {
5493 s->subdev_flags |= SDF_CMD_READ /* | SDF_CMD_WRITE */;
5494 s->len_chanlist = 1;
5495 s->do_cmdtest = ni_tio_cmdtest;
5496 s->do_cmd = ni_gpct_cmd;
5497 s->cancel = ni_gpct_cancel;
5498
5499 s->async_dma_dir = DMA_BIDIRECTIONAL;
5500 }
5501#endif
5502 s->private = gpct;
David Schleef03aef4b2009-02-17 17:04:22 -08005503 }
5504
H Hartley Sweeten4168ac92014-07-14 12:24:05 -07005505 /* Frequency output subdevice */
H Hartley Sweetenf9cd92e2012-09-05 18:50:19 -07005506 s = &dev->subdevices[NI_FREQ_OUT_SUBDEV];
H Hartley Sweeten4168ac92014-07-14 12:24:05 -07005507 s->type = COMEDI_SUBD_COUNTER;
5508 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
5509 s->n_chan = 1;
5510 s->maxdata = 0xf;
5511 s->insn_read = ni_freq_out_insn_read;
5512 s->insn_write = ni_freq_out_insn_write;
5513 s->insn_config = ni_freq_out_insn_config;
David Schleef03aef4b2009-02-17 17:04:22 -08005514
David Schleef03aef4b2009-02-17 17:04:22 -08005515 if (dev->irq) {
H Hartley Sweeten00b14b12014-06-19 10:20:34 -07005516 ni_stc_writew(dev,
H Hartley Sweetend8f62c42015-05-01 14:59:15 -07005517 (irq_polarity ? NISTC_INT_CTRL_INT_POL : 0) |
5518 (NISTC_INT_CTRL_3PIN_INT & 0) |
5519 NISTC_INT_CTRL_INTA_ENA |
5520 NISTC_INT_CTRL_INTB_ENA |
5521 NISTC_INT_CTRL_INTA_SEL(interrupt_pin) |
5522 NISTC_INT_CTRL_INTB_SEL(interrupt_pin),
5523 NISTC_INT_CTRL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08005524 }
5525
5526 /* DMA setup */
H Hartley Sweetena4b7ef92015-05-01 15:00:03 -07005527 ni_writeb(dev, devpriv->ai_ao_select_reg, NI_E_DMA_AI_AO_SEL_REG);
H Hartley Sweeten7d6f3aa2015-05-01 15:00:04 -07005528 ni_writeb(dev, devpriv->g0_g1_select_reg, NI_E_DMA_G0_G1_SEL_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08005529
H Hartley Sweetena52b53e2014-07-14 12:23:44 -07005530 if (devpriv->is_6xxx) {
H Hartley Sweeten0418da52015-05-01 15:00:07 -07005531 ni_writeb(dev, 0, NI611X_MAGIC_REG);
H Hartley Sweeten17733212014-06-19 10:20:32 -07005532 } else if (devpriv->is_m_series) {
David Schleef03aef4b2009-02-17 17:04:22 -08005533 int channel;
H Hartley Sweetenf7401972014-07-16 11:02:08 -07005534
H Hartley Sweeten6293e352013-03-05 10:20:41 -07005535 for (channel = 0; channel < board->n_aochan; ++channel) {
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07005536 ni_writeb(dev, 0xf,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005537 NI_M_AO_WAVEFORM_ORDER_REG(channel));
H Hartley Sweeten5a92cac2014-06-19 10:20:35 -07005538 ni_writeb(dev, 0x0,
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005539 NI_M_AO_REF_ATTENUATION_REG(channel));
David Schleef03aef4b2009-02-17 17:04:22 -08005540 }
H Hartley Sweeten975b6d22015-05-01 14:58:34 -07005541 ni_writeb(dev, 0x0, NI_M_AO_CALIB_REG);
David Schleef03aef4b2009-02-17 17:04:22 -08005542 }
5543
David Schleef03aef4b2009-02-17 17:04:22 -08005544 return 0;
5545}
H Hartley Sweeten2832b182014-05-28 16:26:49 -07005546
5547static void mio_common_detach(struct comedi_device *dev)
5548{
5549 struct ni_private *devpriv = dev->private;
5550
H Hartley Sweeten99307a62016-03-22 11:10:42 -07005551 if (devpriv)
5552 ni_gpct_device_destroy(devpriv->counter_dev);
H Hartley Sweeten2832b182014-05-28 16:26:49 -07005553}