]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/staging/comedi/drivers/ni_660x.c
Merge branch 'i2c/for-5.9' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
[mirror_ubuntu-hirsute-kernel.git] / drivers / staging / comedi / drivers / ni_660x.c
CommitLineData
e184e2be 1// SPDX-License-Identifier: GPL-2.0+
58dd7c0a 2/*
aa36af20 3 * Hardware driver for NI 660x devices
aa36af20 4 */
58dd7c0a
M
5
6/*
71d92fac
IA
7 * Driver: ni_660x
8 * Description: National Instruments 660x counter/timer boards
9 * Devices: [National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
51c4ba64 10 * PCI-6608, PXI-6608, PCI-6624, PXI-6624
71d92fac
IA
11 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
12 * Herman.Bruyninckx@mech.kuleuven.ac.be,
13 * Wim.Meeussen@mech.kuleuven.ac.be,
14 * Klaas.Gadeyne@mech.kuleuven.ac.be,
15 * Frank Mori Hess <fmhess@users.sourceforge.net>
0d0ad829 16 * Updated: Mon, 16 Jan 2017 14:00:43 +0000
71d92fac
IA
17 * Status: experimental
18 *
19 * Encoders work. PulseGeneration (both single pulse and pulse train)
20 * works. Buffered commands work for input but not output.
c8c8ff88 21 *
71d92fac
IA
22 * References:
23 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
24 * DAQ 6601/6602 User Manual (NI 322137B-01)
25 */
58dd7c0a 26
ce157f80 27#include <linux/module.h>
25436dc9 28#include <linux/interrupt.h>
33782dd5 29
a6c760b1 30#include "../comedi_pci.h"
33782dd5 31
58dd7c0a
M
32#include "mite.h"
33#include "ni_tio.h"
347e2448 34#include "ni_routes.h"
58dd7c0a 35
58dd7c0a 36/* See Register-Level Programmer Manual page 3.1 */
1246f05b 37enum ni_660x_register {
4f2c3b20 38 /* see enum ni_gpct_register */
242311d1
HS
39 NI660X_STC_DIO_PARALLEL_INPUT = NITIO_NUM_REGS,
40 NI660X_STC_DIO_OUTPUT,
41 NI660X_STC_DIO_CONTROL,
42 NI660X_STC_DIO_SERIAL_INPUT,
1246f05b
HS
43 NI660X_DIO32_INPUT,
44 NI660X_DIO32_OUTPUT,
45 NI660X_CLK_CFG,
46 NI660X_GLOBAL_INT_STATUS,
47 NI660X_DMA_CFG,
48 NI660X_GLOBAL_INT_CFG,
49 NI660X_IO_CFG_0_1,
50 NI660X_IO_CFG_2_3,
51 NI660X_IO_CFG_4_5,
52 NI660X_IO_CFG_6_7,
53 NI660X_IO_CFG_8_9,
54 NI660X_IO_CFG_10_11,
55 NI660X_IO_CFG_12_13,
56 NI660X_IO_CFG_14_15,
57 NI660X_IO_CFG_16_17,
58 NI660X_IO_CFG_18_19,
59 NI660X_IO_CFG_20_21,
60 NI660X_IO_CFG_22_23,
61 NI660X_IO_CFG_24_25,
62 NI660X_IO_CFG_26_27,
63 NI660X_IO_CFG_28_29,
64 NI660X_IO_CFG_30_31,
65 NI660X_IO_CFG_32_33,
66 NI660X_IO_CFG_34_35,
67 NI660X_IO_CFG_36_37,
68 NI660X_IO_CFG_38_39,
69 NI660X_NUM_REGS,
251411cf 70};
58dd7c0a 71
502552e1
HS
72#define NI660X_CLK_CFG_COUNTER_SWAP BIT(21)
73
41014593
HS
74#define NI660X_GLOBAL_INT_COUNTER0 BIT(8)
75#define NI660X_GLOBAL_INT_COUNTER1 BIT(9)
76#define NI660X_GLOBAL_INT_COUNTER2 BIT(10)
77#define NI660X_GLOBAL_INT_COUNTER3 BIT(11)
78#define NI660X_GLOBAL_INT_CASCADE BIT(29)
79#define NI660X_GLOBAL_INT_GLOBAL_POL BIT(30)
80#define NI660X_GLOBAL_INT_GLOBAL BIT(31)
81
fecf4cce
HS
82#define NI660X_DMA_CFG_SEL(_c, _s) (((_s) & 0x1f) << (8 * (_c)))
83#define NI660X_DMA_CFG_SEL_MASK(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
84#define NI660X_DMA_CFG_SEL_NONE(_c) NI660X_DMA_CFG_SEL((_c), 0x1f)
85#define NI660X_DMA_CFG_RESET(_c) NI660X_DMA_CFG_SEL((_c), 0x80)
86
01ead0de
HS
87#define NI660X_IO_CFG(x) (NI660X_IO_CFG_0_1 + ((x) / 2))
88#define NI660X_IO_CFG_OUT_SEL(_c, _s) (((_s) & 0x3) << (((_c) % 2) ? 0 : 8))
89#define NI660X_IO_CFG_OUT_SEL_MASK(_c) NI660X_IO_CFG_OUT_SEL((_c), 0x3)
01ead0de
HS
90#define NI660X_IO_CFG_IN_SEL(_c, _s) (((_s) & 0x7) << (((_c) % 2) ? 4 : 12))
91#define NI660X_IO_CFG_IN_SEL_MASK(_c) NI660X_IO_CFG_IN_SEL((_c), 0x7)
58dd7c0a 92
b38700a2 93struct ni_660x_register_data {
2696fb57 94 int offset; /* Offset from base address from GPCT chip */
87090141 95 char size; /* 2 or 4 bytes */
0cb5e8ff
BP
96};
97
b38700a2 98static const struct ni_660x_register_data ni_660x_reg_data[NI660X_NUM_REGS] = {
4f2c3b20
HS
99 [NITIO_G0_INT_ACK] = { 0x004, 2 }, /* write */
100 [NITIO_G0_STATUS] = { 0x004, 2 }, /* read */
101 [NITIO_G1_INT_ACK] = { 0x006, 2 }, /* write */
102 [NITIO_G1_STATUS] = { 0x006, 2 }, /* read */
103 [NITIO_G01_STATUS] = { 0x008, 2 }, /* read */
104 [NITIO_G0_CMD] = { 0x00c, 2 }, /* write */
9392e5dd 105 [NI660X_STC_DIO_PARALLEL_INPUT] = { 0x00e, 2 }, /* read */
4f2c3b20
HS
106 [NITIO_G1_CMD] = { 0x00e, 2 }, /* write */
107 [NITIO_G0_HW_SAVE] = { 0x010, 4 }, /* read */
108 [NITIO_G1_HW_SAVE] = { 0x014, 4 }, /* read */
9392e5dd
HS
109 [NI660X_STC_DIO_OUTPUT] = { 0x014, 2 }, /* write */
110 [NI660X_STC_DIO_CONTROL] = { 0x016, 2 }, /* write */
4f2c3b20
HS
111 [NITIO_G0_SW_SAVE] = { 0x018, 4 }, /* read */
112 [NITIO_G1_SW_SAVE] = { 0x01c, 4 }, /* read */
113 [NITIO_G0_MODE] = { 0x034, 2 }, /* write */
114 [NITIO_G01_STATUS1] = { 0x036, 2 }, /* read */
115 [NITIO_G1_MODE] = { 0x036, 2 }, /* write */
9392e5dd 116 [NI660X_STC_DIO_SERIAL_INPUT] = { 0x038, 2 }, /* read */
4f2c3b20
HS
117 [NITIO_G0_LOADA] = { 0x038, 4 }, /* write */
118 [NITIO_G01_STATUS2] = { 0x03a, 2 }, /* read */
119 [NITIO_G0_LOADB] = { 0x03c, 4 }, /* write */
120 [NITIO_G1_LOADA] = { 0x040, 4 }, /* write */
121 [NITIO_G1_LOADB] = { 0x044, 4 }, /* write */
122 [NITIO_G0_INPUT_SEL] = { 0x048, 2 }, /* write */
123 [NITIO_G1_INPUT_SEL] = { 0x04a, 2 }, /* write */
124 [NITIO_G0_AUTO_INC] = { 0x088, 2 }, /* write */
125 [NITIO_G1_AUTO_INC] = { 0x08a, 2 }, /* write */
126 [NITIO_G01_RESET] = { 0x090, 2 }, /* write */
127 [NITIO_G0_INT_ENA] = { 0x092, 2 }, /* write */
128 [NITIO_G1_INT_ENA] = { 0x096, 2 }, /* write */
129 [NITIO_G0_CNT_MODE] = { 0x0b0, 2 }, /* write */
130 [NITIO_G1_CNT_MODE] = { 0x0b2, 2 }, /* write */
131 [NITIO_G0_GATE2] = { 0x0b4, 2 }, /* write */
132 [NITIO_G1_GATE2] = { 0x0b6, 2 }, /* write */
133 [NITIO_G0_DMA_CFG] = { 0x0b8, 2 }, /* write */
134 [NITIO_G0_DMA_STATUS] = { 0x0b8, 2 }, /* read */
135 [NITIO_G1_DMA_CFG] = { 0x0ba, 2 }, /* write */
136 [NITIO_G1_DMA_STATUS] = { 0x0ba, 2 }, /* read */
137 [NITIO_G2_INT_ACK] = { 0x104, 2 }, /* write */
138 [NITIO_G2_STATUS] = { 0x104, 2 }, /* read */
139 [NITIO_G3_INT_ACK] = { 0x106, 2 }, /* write */
140 [NITIO_G3_STATUS] = { 0x106, 2 }, /* read */
141 [NITIO_G23_STATUS] = { 0x108, 2 }, /* read */
142 [NITIO_G2_CMD] = { 0x10c, 2 }, /* write */
143 [NITIO_G3_CMD] = { 0x10e, 2 }, /* write */
144 [NITIO_G2_HW_SAVE] = { 0x110, 4 }, /* read */
145 [NITIO_G3_HW_SAVE] = { 0x114, 4 }, /* read */
146 [NITIO_G2_SW_SAVE] = { 0x118, 4 }, /* read */
147 [NITIO_G3_SW_SAVE] = { 0x11c, 4 }, /* read */
148 [NITIO_G2_MODE] = { 0x134, 2 }, /* write */
149 [NITIO_G23_STATUS1] = { 0x136, 2 }, /* read */
150 [NITIO_G3_MODE] = { 0x136, 2 }, /* write */
151 [NITIO_G2_LOADA] = { 0x138, 4 }, /* write */
152 [NITIO_G23_STATUS2] = { 0x13a, 2 }, /* read */
153 [NITIO_G2_LOADB] = { 0x13c, 4 }, /* write */
154 [NITIO_G3_LOADA] = { 0x140, 4 }, /* write */
155 [NITIO_G3_LOADB] = { 0x144, 4 }, /* write */
156 [NITIO_G2_INPUT_SEL] = { 0x148, 2 }, /* write */
157 [NITIO_G3_INPUT_SEL] = { 0x14a, 2 }, /* write */
158 [NITIO_G2_AUTO_INC] = { 0x188, 2 }, /* write */
159 [NITIO_G3_AUTO_INC] = { 0x18a, 2 }, /* write */
160 [NITIO_G23_RESET] = { 0x190, 2 }, /* write */
161 [NITIO_G2_INT_ENA] = { 0x192, 2 }, /* write */
162 [NITIO_G3_INT_ENA] = { 0x196, 2 }, /* write */
163 [NITIO_G2_CNT_MODE] = { 0x1b0, 2 }, /* write */
164 [NITIO_G3_CNT_MODE] = { 0x1b2, 2 }, /* write */
165 [NITIO_G2_GATE2] = { 0x1b4, 2 }, /* write */
166 [NITIO_G3_GATE2] = { 0x1b6, 2 }, /* write */
167 [NITIO_G2_DMA_CFG] = { 0x1b8, 2 }, /* write */
168 [NITIO_G2_DMA_STATUS] = { 0x1b8, 2 }, /* read */
169 [NITIO_G3_DMA_CFG] = { 0x1ba, 2 }, /* write */
170 [NITIO_G3_DMA_STATUS] = { 0x1ba, 2 }, /* read */
9392e5dd
HS
171 [NI660X_DIO32_INPUT] = { 0x414, 4 }, /* read */
172 [NI660X_DIO32_OUTPUT] = { 0x510, 4 }, /* write */
173 [NI660X_CLK_CFG] = { 0x73c, 4 }, /* write */
174 [NI660X_GLOBAL_INT_STATUS] = { 0x754, 4 }, /* read */
175 [NI660X_DMA_CFG] = { 0x76c, 4 }, /* write */
176 [NI660X_GLOBAL_INT_CFG] = { 0x770, 4 }, /* write */
177 [NI660X_IO_CFG_0_1] = { 0x77c, 2 }, /* read/write */
178 [NI660X_IO_CFG_2_3] = { 0x77e, 2 }, /* read/write */
179 [NI660X_IO_CFG_4_5] = { 0x780, 2 }, /* read/write */
180 [NI660X_IO_CFG_6_7] = { 0x782, 2 }, /* read/write */
181 [NI660X_IO_CFG_8_9] = { 0x784, 2 }, /* read/write */
182 [NI660X_IO_CFG_10_11] = { 0x786, 2 }, /* read/write */
183 [NI660X_IO_CFG_12_13] = { 0x788, 2 }, /* read/write */
184 [NI660X_IO_CFG_14_15] = { 0x78a, 2 }, /* read/write */
185 [NI660X_IO_CFG_16_17] = { 0x78c, 2 }, /* read/write */
186 [NI660X_IO_CFG_18_19] = { 0x78e, 2 }, /* read/write */
187 [NI660X_IO_CFG_20_21] = { 0x790, 2 }, /* read/write */
188 [NI660X_IO_CFG_22_23] = { 0x792, 2 }, /* read/write */
189 [NI660X_IO_CFG_24_25] = { 0x794, 2 }, /* read/write */
190 [NI660X_IO_CFG_26_27] = { 0x796, 2 }, /* read/write */
191 [NI660X_IO_CFG_28_29] = { 0x798, 2 }, /* read/write */
192 [NI660X_IO_CFG_30_31] = { 0x79a, 2 }, /* read/write */
193 [NI660X_IO_CFG_32_33] = { 0x79c, 2 }, /* read/write */
194 [NI660X_IO_CFG_34_35] = { 0x79e, 2 }, /* read/write */
195 [NI660X_IO_CFG_36_37] = { 0x7a0, 2 }, /* read/write */
196 [NI660X_IO_CFG_38_39] = { 0x7a2, 2 } /* read/write */
58dd7c0a
M
197};
198
8f266d50 199#define NI660X_CHIP_OFFSET 0x800
58dd7c0a 200
97bcce5a
HS
201enum ni_660x_boardid {
202 BOARD_PCI6601,
203 BOARD_PCI6602,
204 BOARD_PXI6602,
51c4ba64 205 BOARD_PCI6608,
97bcce5a 206 BOARD_PXI6608,
0d0ad829 207 BOARD_PCI6624,
8bdfefb7 208 BOARD_PXI6624
97bcce5a
HS
209};
210
50792813 211struct ni_660x_board {
58dd7c0a 212 const char *name;
2225320e 213 unsigned int n_chips; /* total number of TIO chips */
50792813 214};
58dd7c0a 215
50792813 216static const struct ni_660x_board ni_660x_boards[] = {
97bcce5a 217 [BOARD_PCI6601] = {
e2b8360f
HS
218 .name = "PCI-6601",
219 .n_chips = 1,
220 },
97bcce5a 221 [BOARD_PCI6602] = {
e2b8360f
HS
222 .name = "PCI-6602",
223 .n_chips = 2,
224 },
97bcce5a 225 [BOARD_PXI6602] = {
e2b8360f
HS
226 .name = "PXI-6602",
227 .n_chips = 2,
228 },
51c4ba64
SO
229 [BOARD_PCI6608] = {
230 .name = "PCI-6608",
231 .n_chips = 2,
232 },
97bcce5a 233 [BOARD_PXI6608] = {
e2b8360f
HS
234 .name = "PXI-6608",
235 .n_chips = 2,
236 },
0d0ad829
IA
237 [BOARD_PCI6624] = {
238 .name = "PCI-6624",
239 .n_chips = 2,
240 },
8bdfefb7
IA
241 [BOARD_PXI6624] = {
242 .name = "PXI-6624",
243 .n_chips = 2,
244 },
58dd7c0a
M
245};
246
ccef0da8
HS
247#define NI660X_NUM_PFI_CHANNELS 40
248
249/* there are only up to 3 dma channels, but the register layout allows for 4 */
250#define NI660X_MAX_DMA_CHANNEL 4
251
252#define NI660X_COUNTERS_PER_CHIP 4
253#define NI660X_MAX_CHIPS 2
254#define NI660X_MAX_COUNTERS (NI660X_MAX_CHIPS * \
255 NI660X_COUNTERS_PER_CHIP)
58dd7c0a 256
b3be94ea 257struct ni_660x_private {
1a8da31b 258 struct mite *mite;
58dd7c0a 259 struct ni_gpct_device *counter_dev;
19d9212e 260 struct mite_ring *ring[NI660X_MAX_CHIPS][NI660X_COUNTERS_PER_CHIP];
e8f6e2b9 261 /* protects mite channel request/release */
58dd7c0a 262 spinlock_t mite_channel_lock;
e8f6e2b9 263 /* prevents races between interrupt and comedi_poll */
894db119 264 spinlock_t interrupt_lock;
ccef0da8
HS
265 unsigned int dma_cfg[NI660X_MAX_CHIPS];
266 unsigned int io_cfg[NI660X_NUM_PFI_CHANNELS];
aa94f288 267 u64 io_dir;
347e2448 268 struct ni_route_tables routing_tables;
b3be94ea 269};
58dd7c0a 270
4f2c3b20
HS
271static void ni_660x_write(struct comedi_device *dev, unsigned int chip,
272 unsigned int bits, unsigned int reg)
58dd7c0a 273{
8f266d50
HS
274 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
275 ni_660x_reg_data[reg].offset;
58dd7c0a 276
b38700a2 277 if (ni_660x_reg_data[reg].size == 2)
5f8a5f4f 278 writew(bits, dev->mmio + addr);
87090141 279 else
5f8a5f4f 280 writel(bits, dev->mmio + addr);
58dd7c0a
M
281}
282
ad98c18c 283static unsigned int ni_660x_read(struct comedi_device *dev,
4f2c3b20 284 unsigned int chip, unsigned int reg)
58dd7c0a 285{
8f266d50
HS
286 unsigned int addr = (chip * NI660X_CHIP_OFFSET) +
287 ni_660x_reg_data[reg].offset;
58dd7c0a 288
b38700a2 289 if (ni_660x_reg_data[reg].size == 2)
5f8a5f4f 290 return readw(dev->mmio + addr);
87090141 291 return readl(dev->mmio + addr);
58dd7c0a
M
292}
293
dc285820
HS
294static void ni_660x_gpct_write(struct ni_gpct *counter, unsigned int bits,
295 enum ni_gpct_register reg)
58dd7c0a 296{
71b5f4f1 297 struct comedi_device *dev = counter->counter_dev->dev;
0c9434e3 298
4f2c3b20 299 ni_660x_write(dev, counter->chip_index, bits, reg);
58dd7c0a
M
300}
301
dc285820 302static unsigned int ni_660x_gpct_read(struct ni_gpct *counter,
0a85b6f0 303 enum ni_gpct_register reg)
58dd7c0a 304{
71b5f4f1 305 struct comedi_device *dev = counter->counter_dev->dev;
0c26c7ed 306
4f2c3b20 307 return ni_660x_read(dev, counter->chip_index, reg);
58dd7c0a
M
308}
309
da91b269 310static inline void ni_660x_set_dma_channel(struct comedi_device *dev,
2225320e 311 unsigned int mite_channel,
0a85b6f0 312 struct ni_gpct *counter)
58dd7c0a 313{
8c12ec26 314 struct ni_660x_private *devpriv = dev->private;
2225320e 315 unsigned int chip = counter->chip_index;
8c12ec26 316
fecf4cce
HS
317 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
318 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL(mite_channel,
319 counter->counter_index);
9678b73e
HS
320 ni_660x_write(dev, chip, devpriv->dma_cfg[chip] |
321 NI660X_DMA_CFG_RESET(mite_channel),
322 NI660X_DMA_CFG);
58dd7c0a
M
323}
324
da91b269 325static inline void ni_660x_unset_dma_channel(struct comedi_device *dev,
2225320e 326 unsigned int mite_channel,
0a85b6f0 327 struct ni_gpct *counter)
58dd7c0a 328{
8c12ec26 329 struct ni_660x_private *devpriv = dev->private;
2225320e 330 unsigned int chip = counter->chip_index;
8c12ec26 331
fecf4cce
HS
332 devpriv->dma_cfg[chip] &= ~NI660X_DMA_CFG_SEL_MASK(mite_channel);
333 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(mite_channel);
9678b73e 334 ni_660x_write(dev, chip, devpriv->dma_cfg[chip], NI660X_DMA_CFG);
58dd7c0a
M
335}
336
da91b269 337static int ni_660x_request_mite_channel(struct comedi_device *dev,
0a85b6f0
MT
338 struct ni_gpct *counter,
339 enum comedi_io_direction direction)
58dd7c0a 340{
8c12ec26 341 struct ni_660x_private *devpriv = dev->private;
19d9212e 342 struct mite_ring *ring;
58dd7c0a 343 struct mite_channel *mite_chan;
515b5e6b 344 unsigned long flags;
58dd7c0a 345
8c12ec26 346 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
19d9212e 347 ring = devpriv->ring[counter->chip_index][counter->counter_index];
515b5e6b 348 mite_chan = mite_request_channel(devpriv->mite, ring);
307da4b2 349 if (!mite_chan) {
8c12ec26 350 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
22bc059e
HS
351 dev_err(dev->class_dev,
352 "failed to reserve mite dma channel for counter\n");
58dd7c0a
M
353 return -EBUSY;
354 }
355 mite_chan->dir = direction;
356 ni_tio_set_mite_channel(counter, mite_chan);
357 ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
8c12ec26 358 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
359 return 0;
360}
361
ce48a911
HS
362static void ni_660x_release_mite_channel(struct comedi_device *dev,
363 struct ni_gpct *counter)
58dd7c0a 364{
8c12ec26 365 struct ni_660x_private *devpriv = dev->private;
58dd7c0a
M
366 unsigned long flags;
367
8c12ec26 368 spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
369 if (counter->mite_chan) {
370 struct mite_channel *mite_chan = counter->mite_chan;
371
372 ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
373 ni_tio_set_mite_channel(counter, NULL);
374 mite_release_channel(mite_chan);
375 }
8c12ec26 376 spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
58dd7c0a
M
377}
378
da91b269 379static int ni_660x_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
58dd7c0a 380{
00edbc31 381 struct ni_gpct *counter = s->private;
58dd7c0a
M
382 int retval;
383
58dd7c0a
M
384 retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
385 if (retval) {
22bc059e
HS
386 dev_err(dev->class_dev,
387 "no dma channel available for use by counter\n");
58dd7c0a
M
388 return retval;
389 }
f8cfd0eb 390 ni_tio_acknowledge(counter);
58dd7c0a 391
16cc181d 392 return ni_tio_cmd(dev, s);
58dd7c0a
M
393}
394
da91b269 395static int ni_660x_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
58dd7c0a 396{
00edbc31 397 struct ni_gpct *counter = s->private;
58dd7c0a
M
398 int retval;
399
400 retval = ni_tio_cancel(counter);
401 ni_660x_release_mite_channel(dev, counter);
402 return retval;
403}
404
01b6442b 405static void set_tio_counterswap(struct comedi_device *dev, int chip)
58dd7c0a 406{
2225320e 407 unsigned int bits = 0;
01b6442b
HS
408
409 /*
410 * See P. 3.5 of the Register-Level Programming manual.
411 * The CounterSwap bit has to be set on the second chip,
412 * otherwise it will try to use the same pins as the
413 * first chip.
58dd7c0a 414 */
01b6442b 415 if (chip)
502552e1 416 bits = NI660X_CLK_CFG_COUNTER_SWAP;
01b6442b 417
9678b73e 418 ni_660x_write(dev, chip, bits, NI660X_CLK_CFG);
58dd7c0a
M
419}
420
da91b269 421static void ni_660x_handle_gpct_interrupt(struct comedi_device *dev,
0a85b6f0 422 struct comedi_subdevice *s)
58dd7c0a 423{
00edbc31
HS
424 struct ni_gpct *counter = s->private;
425
426 ni_tio_handle_interrupt(counter, s);
9e1a0824 427 comedi_handle_events(dev, s);
58dd7c0a
M
428}
429
70265d24 430static irqreturn_t ni_660x_interrupt(int irq, void *d)
58dd7c0a 431{
71b5f4f1 432 struct comedi_device *dev = d;
8c12ec26 433 struct ni_660x_private *devpriv = dev->private;
34c43922 434 struct comedi_subdevice *s;
2225320e 435 unsigned int i;
894db119 436 unsigned long flags;
58dd7c0a 437
a7401cdd 438 if (!dev->attached)
58dd7c0a 439 return IRQ_NONE;
5262d035
HS
440 /* make sure dev->attached is checked before doing anything else */
441 smp_mb();
442
894db119 443 /* lock to avoid race with comedi_poll */
8c12ec26 444 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
520e6191
HS
445 for (i = 0; i < dev->n_subdevices; ++i) {
446 s = &dev->subdevices[i];
447 if (s->type == COMEDI_SUBD_COUNTER)
448 ni_660x_handle_gpct_interrupt(dev, s);
58dd7c0a 449 }
8c12ec26 450 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
58dd7c0a
M
451 return IRQ_HANDLED;
452}
453
894db119
FMH
454static int ni_660x_input_poll(struct comedi_device *dev,
455 struct comedi_subdevice *s)
456{
8c12ec26 457 struct ni_660x_private *devpriv = dev->private;
00edbc31 458 struct ni_gpct *counter = s->private;
894db119 459 unsigned long flags;
8c12ec26 460
894db119 461 /* lock to avoid race with comedi_poll */
8c12ec26 462 spin_lock_irqsave(&devpriv->interrupt_lock, flags);
51d43005 463 mite_sync_dma(counter->mite_chan, s);
8c12ec26 464 spin_unlock_irqrestore(&devpriv->interrupt_lock, flags);
e9edef3a 465 return comedi_buf_read_n_available(s);
894db119
FMH
466}
467
0a85b6f0 468static int ni_660x_buf_change(struct comedi_device *dev,
d546b896 469 struct comedi_subdevice *s)
58dd7c0a 470{
8c12ec26 471 struct ni_660x_private *devpriv = dev->private;
00edbc31 472 struct ni_gpct *counter = s->private;
19d9212e 473 struct mite_ring *ring;
58dd7c0a
M
474 int ret;
475
19d9212e 476 ring = devpriv->ring[counter->chip_index][counter->counter_index];
515b5e6b 477 ret = mite_buf_change(ring, s);
58dd7c0a
M
478 if (ret < 0)
479 return ret;
480
481 return 0;
482}
483
da91b269 484static int ni_660x_allocate_private(struct comedi_device *dev)
58dd7c0a 485{
8c12ec26 486 struct ni_660x_private *devpriv;
2225320e 487 unsigned int i;
58dd7c0a 488
0bdab509 489 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
c34fa261
HS
490 if (!devpriv)
491 return -ENOMEM;
c3744138 492
8c12ec26
HS
493 spin_lock_init(&devpriv->mite_channel_lock);
494 spin_lock_init(&devpriv->interrupt_lock);
ccef0da8 495 for (i = 0; i < NI660X_NUM_PFI_CHANNELS; ++i)
aa94f288 496 devpriv->io_cfg[i] = NI_660X_PFI_OUTPUT_COUNTER;
900b7808 497
58dd7c0a
M
498 return 0;
499}
500
da91b269 501static int ni_660x_alloc_mite_rings(struct comedi_device *dev)
58dd7c0a 502{
da8e2a52 503 const struct ni_660x_board *board = dev->board_ptr;
8c12ec26 504 struct ni_660x_private *devpriv = dev->private;
2225320e
HS
505 unsigned int i;
506 unsigned int j;
58dd7c0a 507
9186ccde 508 for (i = 0; i < board->n_chips; ++i) {
ccef0da8 509 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j) {
19d9212e
HS
510 devpriv->ring[i][j] = mite_alloc_ring(devpriv->mite);
511 if (!devpriv->ring[i][j])
58dd7c0a 512 return -ENOMEM;
58dd7c0a
M
513 }
514 }
515 return 0;
516}
517
da91b269 518static void ni_660x_free_mite_rings(struct comedi_device *dev)
58dd7c0a 519{
da8e2a52 520 const struct ni_660x_board *board = dev->board_ptr;
8c12ec26 521 struct ni_660x_private *devpriv = dev->private;
2225320e
HS
522 unsigned int i;
523 unsigned int j;
58dd7c0a 524
9186ccde 525 for (i = 0; i < board->n_chips; ++i) {
ccef0da8 526 for (j = 0; j < NI660X_COUNTERS_PER_CHIP; ++j)
19d9212e 527 mite_free_ring(devpriv->ring[i][j]);
58dd7c0a
M
528 }
529}
530
da91b269 531static int ni_660x_dio_insn_bits(struct comedi_device *dev,
0a85b6f0 532 struct comedi_subdevice *s,
826f783a
HS
533 struct comedi_insn *insn,
534 unsigned int *data)
58dd7c0a 535{
826f783a
HS
536 unsigned int shift = CR_CHAN(insn->chanspec);
537 unsigned int mask = data[0] << shift;
538 unsigned int bits = data[1] << shift;
58dd7c0a 539
826f783a
HS
540 /*
541 * There are 40 channels in this subdevice but only 32 are usable
542 * as DIO. The shift adjusts the mask/bits to account for the base
543 * channel in insn->chanspec. The state update can then be handled
544 * normally for the 32 usable channels.
545 */
546 if (mask) {
547 s->state &= ~mask;
548 s->state |= (bits & mask);
9678b73e 549 ni_660x_write(dev, 0, s->state, NI660X_DIO32_OUTPUT);
58dd7c0a 550 }
826f783a
HS
551
552 /*
553 * Return the input channels, shifted back to account for the base
554 * channel.
555 */
556 data[1] = ni_660x_read(dev, 0, NI660X_DIO32_INPUT) >> shift;
1246f05b 557
a2714e3e 558 return insn->n;
58dd7c0a
M
559}
560
0a85b6f0 561static void ni_660x_select_pfi_output(struct comedi_device *dev,
518d3842 562 unsigned int chan, unsigned int out_sel)
58dd7c0a 563{
da8e2a52 564 const struct ni_660x_board *board = dev->board_ptr;
518d3842
HS
565 unsigned int active_chip = 0;
566 unsigned int idle_chip = 0;
567 unsigned int bits;
58dd7c0a 568
fa86c007
SO
569 if (chan >= NI_PFI(0))
570 /* allow new and old names of pfi channels to work. */
571 chan -= NI_PFI(0);
572
9186ccde 573 if (board->n_chips > 1) {
aa94f288 574 if (out_sel == NI_660X_PFI_OUTPUT_COUNTER &&
518d3842
HS
575 chan >= 8 && chan <= 23) {
576 /* counters 4-7 pfi channels */
577 active_chip = 1;
578 idle_chip = 0;
0a85b6f0 579 } else {
518d3842
HS
580 /* counters 0-3 pfi channels */
581 active_chip = 0;
582 idle_chip = 1;
58dd7c0a
M
583 }
584 }
585
518d3842
HS
586 if (idle_chip != active_chip) {
587 /* set the pfi channel to high-z on the inactive chip */
588 bits = ni_660x_read(dev, idle_chip, NI660X_IO_CFG(chan));
589 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
aa94f288 590 bits |= NI660X_IO_CFG_OUT_SEL(chan, 0); /* high-z */
518d3842 591 ni_660x_write(dev, idle_chip, bits, NI660X_IO_CFG(chan));
58dd7c0a
M
592 }
593
518d3842
HS
594 /* set the pfi channel output on the active chip */
595 bits = ni_660x_read(dev, active_chip, NI660X_IO_CFG(chan));
596 bits &= ~NI660X_IO_CFG_OUT_SEL_MASK(chan);
597 bits |= NI660X_IO_CFG_OUT_SEL(chan, out_sel);
598 ni_660x_write(dev, active_chip, bits, NI660X_IO_CFG(chan));
58dd7c0a
M
599}
600
a0c5e846
SO
601static void ni_660x_set_pfi_direction(struct comedi_device *dev,
602 unsigned int chan,
603 unsigned int direction)
604{
605 struct ni_660x_private *devpriv = dev->private;
606 u64 bit;
607
fa86c007
SO
608 if (chan >= NI_PFI(0))
609 /* allow new and old names of pfi channels to work. */
610 chan -= NI_PFI(0);
611
a0c5e846
SO
612 bit = 1ULL << chan;
613
614 if (direction == COMEDI_OUTPUT) {
615 devpriv->io_dir |= bit;
616 /* reset the output to currently assigned output value */
617 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
618 } else {
619 devpriv->io_dir &= ~bit;
620 /* set pin to high-z; do not change currently assigned route */
621 ni_660x_select_pfi_output(dev, chan, 0);
622 }
623}
624
625static unsigned int ni_660x_get_pfi_direction(struct comedi_device *dev,
626 unsigned int chan)
627{
628 struct ni_660x_private *devpriv = dev->private;
629 u64 bit;
630
fa86c007
SO
631 if (chan >= NI_PFI(0))
632 /* allow new and old names of pfi channels to work. */
633 chan -= NI_PFI(0);
634
a0c5e846
SO
635 bit = 1ULL << chan;
636
637 return (devpriv->io_dir & bit) ? COMEDI_OUTPUT : COMEDI_INPUT;
638}
639
2225320e
HS
640static int ni_660x_set_pfi_routing(struct comedi_device *dev,
641 unsigned int chan, unsigned int source)
58dd7c0a 642{
8c12ec26
HS
643 struct ni_660x_private *devpriv = dev->private;
644
fa86c007
SO
645 if (chan >= NI_PFI(0))
646 /* allow new and old names of pfi channels to work. */
647 chan -= NI_PFI(0);
648
aa94f288
HS
649 switch (source) {
650 case NI_660X_PFI_OUTPUT_COUNTER:
651 if (chan < 8)
58dd7c0a 652 return -EINVAL;
aa94f288
HS
653 break;
654 case NI_660X_PFI_OUTPUT_DIO:
655 if (chan > 31)
58dd7c0a 656 return -EINVAL;
479826cc 657 break;
aa94f288
HS
658 default:
659 return -EINVAL;
58dd7c0a 660 }
58dd7c0a 661
aa94f288 662 devpriv->io_cfg[chan] = source;
a0c5e846 663 if (ni_660x_get_pfi_direction(dev, chan) == COMEDI_OUTPUT)
aa94f288 664 ni_660x_select_pfi_output(dev, chan, devpriv->io_cfg[chan]);
58dd7c0a
M
665 return 0;
666}
667
a0c5e846
SO
668static int ni_660x_get_pfi_routing(struct comedi_device *dev, unsigned int chan)
669{
670 struct ni_660x_private *devpriv = dev->private;
671
fa86c007
SO
672 if (chan >= NI_PFI(0))
673 /* allow new and old names of pfi channels to work. */
674 chan -= NI_PFI(0);
675
a0c5e846
SO
676 return devpriv->io_cfg[chan];
677}
678
679static void ni_660x_set_pfi_filter(struct comedi_device *dev,
680 unsigned int chan, unsigned int value)
681{
682 unsigned int val;
683
fa86c007
SO
684 if (chan >= NI_PFI(0))
685 /* allow new and old names of pfi channels to work. */
686 chan -= NI_PFI(0);
687
a0c5e846
SO
688 val = ni_660x_read(dev, 0, NI660X_IO_CFG(chan));
689 val &= ~NI660X_IO_CFG_IN_SEL_MASK(chan);
690 val |= NI660X_IO_CFG_IN_SEL(chan, value);
691 ni_660x_write(dev, 0, val, NI660X_IO_CFG(chan));
692}
693
da91b269 694static int ni_660x_dio_insn_config(struct comedi_device *dev,
0a85b6f0 695 struct comedi_subdevice *s,
56c645ff
HS
696 struct comedi_insn *insn,
697 unsigned int *data)
58dd7c0a 698{
56c645ff 699 unsigned int chan = CR_CHAN(insn->chanspec);
56c645ff 700 int ret;
58dd7c0a
M
701
702 switch (data[0]) {
703 case INSN_CONFIG_DIO_OUTPUT:
a0c5e846 704 ni_660x_set_pfi_direction(dev, chan, COMEDI_OUTPUT);
58dd7c0a 705 break;
56c645ff 706
58dd7c0a 707 case INSN_CONFIG_DIO_INPUT:
a0c5e846 708 ni_660x_set_pfi_direction(dev, chan, COMEDI_INPUT);
58dd7c0a 709 break;
56c645ff 710
58dd7c0a 711 case INSN_CONFIG_DIO_QUERY:
a0c5e846 712 data[1] = ni_660x_get_pfi_direction(dev, chan);
56c645ff
HS
713 break;
714
58dd7c0a 715 case INSN_CONFIG_SET_ROUTING:
56c645ff
HS
716 ret = ni_660x_set_pfi_routing(dev, chan, data[1]);
717 if (ret)
718 return ret;
58dd7c0a 719 break;
56c645ff 720
58dd7c0a 721 case INSN_CONFIG_GET_ROUTING:
a0c5e846 722 data[1] = ni_660x_get_pfi_routing(dev, chan);
58dd7c0a 723 break;
56c645ff 724
58dd7c0a 725 case INSN_CONFIG_FILTER:
a0c5e846 726 ni_660x_set_pfi_filter(dev, chan, data[1]);
58dd7c0a 727 break;
56c645ff 728
58dd7c0a
M
729 default:
730 return -EINVAL;
95cd17c9 731 }
56c645ff
HS
732
733 return insn->n;
58dd7c0a 734}
3c323c01 735
fa86c007
SO
736static unsigned int _ni_get_valid_routes(struct comedi_device *dev,
737 unsigned int n_pairs,
738 unsigned int *pair_data)
739{
740 struct ni_660x_private *devpriv = dev->private;
741
742 return ni_get_valid_routes(&devpriv->routing_tables, n_pairs,
743 pair_data);
744}
745
746/*
747 * Retrieves the current source of the output selector for the given
748 * destination. If the terminal for the destination is not already configured
749 * as an output, this function returns -EINVAL as error.
750 *
751 * Return: The register value of the destination output selector;
752 * -EINVAL if terminal is not configured for output.
753 */
754static inline int get_output_select_source(int dest, struct comedi_device *dev)
755{
756 struct ni_660x_private *devpriv = dev->private;
757 int reg = -1;
758
759 if (channel_is_pfi(dest)) {
760 if (ni_660x_get_pfi_direction(dev, dest) == COMEDI_OUTPUT)
761 reg = ni_660x_get_pfi_routing(dev, dest);
762 } else if (channel_is_rtsi(dest)) {
763 dev_dbg(dev->class_dev,
764 "%s: unhandled rtsi destination (%d) queried\n",
765 __func__, dest);
766 /*
767 * The following can be enabled when RTSI routing info is
768 * determined (not currently documented):
769 * if (ni_get_rtsi_direction(dev, dest) == COMEDI_OUTPUT) {
770 * reg = ni_get_rtsi_routing(dev, dest);
771
772 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
773 * dest = NI_RGOUT0; ** prepare for lookup below **
774 * reg = get_rgout0_reg(dev);
775 * } else if (reg >= NI_RTSI_OUTPUT_RTSI_BRD(0) &&
776 * reg <= NI_RTSI_OUTPUT_RTSI_BRD(3)) {
777 * const int i = reg - NI_RTSI_OUTPUT_RTSI_BRD(0);
778
779 * dest = NI_RTSI_BRD(i); ** prepare for lookup **
780 * reg = get_ith_rtsi_brd_reg(i, dev);
781 * }
782 * }
783 */
784 } else if (channel_is_ctr(dest)) {
785 reg = ni_tio_get_routing(devpriv->counter_dev, dest);
786 } else {
787 dev_dbg(dev->class_dev,
788 "%s: unhandled destination (%d) queried\n",
789 __func__, dest);
790 }
791
792 if (reg >= 0)
793 return ni_find_route_source(CR_CHAN(reg), dest,
794 &devpriv->routing_tables);
795 return -EINVAL;
796}
797
798/*
799 * Test a route:
800 *
801 * Return: -1 if not connectible;
802 * 0 if connectible and not connected;
803 * 1 if connectible and connected.
804 */
805static inline int test_route(unsigned int src, unsigned int dest,
806 struct comedi_device *dev)
807{
808 struct ni_660x_private *devpriv = dev->private;
809 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
810 &devpriv->routing_tables);
811
812 if (reg < 0)
813 return -1;
814 if (get_output_select_source(dest, dev) != CR_CHAN(src))
815 return 0;
816 return 1;
817}
818
819/* Connect the actual route. */
820static inline int connect_route(unsigned int src, unsigned int dest,
821 struct comedi_device *dev)
822{
823 struct ni_660x_private *devpriv = dev->private;
824 s8 reg = ni_route_to_register(CR_CHAN(src), dest,
825 &devpriv->routing_tables);
826 s8 current_src;
827
828 if (reg < 0)
829 /* route is not valid */
830 return -EINVAL;
831
832 current_src = get_output_select_source(dest, dev);
833 if (current_src == CR_CHAN(src))
834 return -EALREADY;
835 if (current_src >= 0)
836 /* destination mux is already busy. complain, don't overwrite */
837 return -EBUSY;
838
839 /* The route is valid and available. Now connect... */
840 if (channel_is_pfi(CR_CHAN(dest))) {
841 /*
842 * set routing and then direction so that the output does not
843 * first get generated with the wrong pin
844 */
845 ni_660x_set_pfi_routing(dev, dest, reg);
846 ni_660x_set_pfi_direction(dev, dest, COMEDI_OUTPUT);
847 } else if (channel_is_rtsi(CR_CHAN(dest))) {
848 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
849 __func__, dest);
850 return -EINVAL;
851 /*
852 * The following can be enabled when RTSI routing info is
853 * determined (not currently documented):
854 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
855 * int ret = incr_rgout0_src_use(src, dev);
856
857 * if (ret < 0)
858 * return ret;
859 * } else if (ni_rtsi_route_requires_mux(reg)) {
860 * ** Attempt to allocate and route (src->brd) **
861 * int brd = incr_rtsi_brd_src_use(src, dev);
862
863 * if (brd < 0)
864 * return brd;
865
866 * ** Now lookup the register value for (brd->dest) **
867 * reg = ni_lookup_route_register(brd, CR_CHAN(dest),
868 * &devpriv->routing_tables);
869 * }
870
871 * ni_set_rtsi_direction(dev, dest, COMEDI_OUTPUT);
872 * ni_set_rtsi_routing(dev, dest, reg);
873 */
874 } else if (channel_is_ctr(CR_CHAN(dest))) {
875 /*
876 * we are adding back the channel modifier info to set
877 * invert/edge info passed by the user
878 */
879 ni_tio_set_routing(devpriv->counter_dev, dest,
880 reg | (src & ~CR_CHAN(-1)));
881 } else {
882 return -EINVAL;
883 }
884 return 0;
885}
886
887static inline int disconnect_route(unsigned int src, unsigned int dest,
888 struct comedi_device *dev)
889{
890 struct ni_660x_private *devpriv = dev->private;
891 s8 reg = ni_route_to_register(CR_CHAN(src), CR_CHAN(dest),
892 &devpriv->routing_tables);
893
894 if (reg < 0)
895 /* route is not valid */
896 return -EINVAL;
897 if (get_output_select_source(dest, dev) != CR_CHAN(src))
898 /* cannot disconnect something not connected */
899 return -EINVAL;
900
901 /* The route is valid and is connected. Now disconnect... */
902 if (channel_is_pfi(CR_CHAN(dest))) {
903 unsigned int source = ((CR_CHAN(dest) - NI_PFI(0)) < 8)
904 ? NI_660X_PFI_OUTPUT_DIO
905 : NI_660X_PFI_OUTPUT_COUNTER;
906
907 /* set the pfi to high impedance, and disconnect */
908 ni_660x_set_pfi_direction(dev, dest, COMEDI_INPUT);
909 ni_660x_set_pfi_routing(dev, dest, source);
910 } else if (channel_is_rtsi(CR_CHAN(dest))) {
911 dev_dbg(dev->class_dev, "%s: unhandled rtsi destination (%d)\n",
912 __func__, dest);
913 return -EINVAL;
914 /*
915 * The following can be enabled when RTSI routing info is
916 * determined (not currently documented):
917 * if (reg == NI_RTSI_OUTPUT_RGOUT0) {
918 * int ret = decr_rgout0_src_use(src, dev);
919
920 * if (ret < 0)
921 * return ret;
922 * } else if (ni_rtsi_route_requires_mux(reg)) {
923 * ** find which RTSI_BRD line is source for rtsi pin **
924 * int brd = ni_find_route_source(
925 * ni_get_rtsi_routing(dev, dest), CR_CHAN(dest),
926 * &devpriv->routing_tables);
927
928 * if (brd < 0)
929 * return brd;
930
931 * ** decrement/disconnect RTSI_BRD line from source **
932 * decr_rtsi_brd_src_use(src, brd, dev);
933 * }
934
935 * ** set rtsi output selector to default state **
936 * reg = default_rtsi_routing[CR_CHAN(dest) - TRIGGER_LINE(0)];
937 * ni_set_rtsi_direction(dev, dest, COMEDI_INPUT);
938 * ni_set_rtsi_routing(dev, dest, reg);
939 */
940 } else if (channel_is_ctr(CR_CHAN(dest))) {
941 ni_tio_unset_routing(devpriv->counter_dev, dest);
942 } else {
943 return -EINVAL;
944 }
945 return 0;
946}
947
948static int ni_global_insn_config(struct comedi_device *dev,
949 struct comedi_insn *insn,
950 unsigned int *data)
951{
952 switch (data[0]) {
953 case INSN_DEVICE_CONFIG_TEST_ROUTE:
954 data[0] = test_route(data[1], data[2], dev);
955 return 2;
956 case INSN_DEVICE_CONFIG_CONNECT_ROUTE:
957 return connect_route(data[1], data[2], dev);
958 case INSN_DEVICE_CONFIG_DISCONNECT_ROUTE:
959 return disconnect_route(data[1], data[2], dev);
960 /*
961 * This case is already handled one level up.
962 * case INSN_DEVICE_CONFIG_GET_ROUTES:
963 */
964 default:
965 return -EINVAL;
966 }
967 return 1;
968}
969
2363cbf0
HS
970static void ni_660x_init_tio_chips(struct comedi_device *dev,
971 unsigned int n_chips)
972{
973 struct ni_660x_private *devpriv = dev->private;
974 unsigned int chip;
975 unsigned int chan;
976
977 /*
978 * We use the ioconfig registers to control dio direction, so zero
979 * output enables in stc dio control reg.
980 */
981 ni_660x_write(dev, 0, 0, NI660X_STC_DIO_CONTROL);
982
983 for (chip = 0; chip < n_chips; ++chip) {
984 /* init dma configuration register */
985 devpriv->dma_cfg[chip] = 0;
986 for (chan = 0; chan < NI660X_MAX_DMA_CHANNEL; ++chan)
987 devpriv->dma_cfg[chip] |= NI660X_DMA_CFG_SEL_NONE(chan);
988 ni_660x_write(dev, chip, devpriv->dma_cfg[chip],
989 NI660X_DMA_CFG);
990
991 /* init ioconfig registers */
992 for (chan = 0; chan < NI660X_NUM_PFI_CHANNELS; ++chan)
993 ni_660x_write(dev, chip, 0, NI660X_IO_CFG(chan));
994 }
995}
996
a690b7e5 997static int ni_660x_auto_attach(struct comedi_device *dev,
97bcce5a 998 unsigned long context)
990b9eed 999{
750af5e5 1000 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
97bcce5a 1001 const struct ni_660x_board *board = NULL;
990b9eed
HS
1002 struct ni_660x_private *devpriv;
1003 struct comedi_subdevice *s;
32f89d8e 1004 struct ni_gpct_device *gpct_dev;
b15f5069 1005 unsigned int n_counters;
520e6191 1006 int subdev;
990b9eed 1007 int ret;
2225320e
HS
1008 unsigned int i;
1009 unsigned int global_interrupt_config_bits;
990b9eed 1010
97bcce5a
HS
1011 if (context < ARRAY_SIZE(ni_660x_boards))
1012 board = &ni_660x_boards[context];
1013 if (!board)
1014 return -ENODEV;
1015 dev->board_ptr = board;
1016 dev->board_name = board->name;
1017
818f569f
HS
1018 ret = comedi_pci_enable(dev);
1019 if (ret)
1020 return ret;
818f569f 1021
990b9eed
HS
1022 ret = ni_660x_allocate_private(dev);
1023 if (ret < 0)
1024 return ret;
1025 devpriv = dev->private;
1026
48f2c1ae 1027 devpriv->mite = mite_attach(dev, true); /* use win1 */
990b9eed
HS
1028 if (!devpriv->mite)
1029 return -ENOMEM;
1030
990b9eed
HS
1031 ret = ni_660x_alloc_mite_rings(dev);
1032 if (ret < 0)
1033 return ret;
1034
2363cbf0
HS
1035 ni_660x_init_tio_chips(dev, board->n_chips);
1036
347e2448 1037 /* prepare the device for globally-named routes. */
e3b7ce73 1038 if (ni_assign_device_routes("ni_660x", board->name, NULL,
347e2448
SO
1039 &devpriv->routing_tables) < 0) {
1040 dev_warn(dev->class_dev, "%s: %s device has no signal routing table.\n",
1041 __func__, board->name);
1042 dev_warn(dev->class_dev, "%s: High level NI signal names will not be available for this %s board.\n",
1043 __func__, board->name);
fa86c007
SO
1044 } else {
1045 /*
1046 * only(?) assign insn_device_config if we have global names for
1047 * this device.
1048 */
1049 dev->insn_device_config = ni_global_insn_config;
1050 dev->get_valid_routes = _ni_get_valid_routes;
347e2448
SO
1051 }
1052
f229594a
HS
1053 n_counters = board->n_chips * NI660X_COUNTERS_PER_CHIP;
1054 gpct_dev = ni_gpct_device_construct(dev,
1055 ni_660x_gpct_write,
1056 ni_660x_gpct_read,
1057 ni_gpct_variant_660x,
347e2448
SO
1058 n_counters,
1059 NI660X_COUNTERS_PER_CHIP,
1060 &devpriv->routing_tables);
f229594a
HS
1061 if (!gpct_dev)
1062 return -ENOMEM;
1063 devpriv->counter_dev = gpct_dev;
1064
ccef0da8 1065 ret = comedi_alloc_subdevices(dev, 2 + NI660X_MAX_COUNTERS);
990b9eed
HS
1066 if (ret)
1067 return ret;
1068
520e6191
HS
1069 subdev = 0;
1070
1071 s = &dev->subdevices[subdev++];
990b9eed
HS
1072 /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
1073 s->type = COMEDI_SUBD_UNUSED;
1074
7e906186
HS
1075 /*
1076 * Digital I/O subdevice
1077 *
1078 * There are 40 channels but only the first 32 can be digital I/Os.
1079 * The last 8 are dedicated to counters 0 and 1.
1080 *
1081 * Counter 0-3 signals are from the first TIO chip.
1082 * Counter 4-7 signals are from the second TIO chip.
1083 *
1084 * Comedi External
1085 * PFI Chan DIO Chan Counter Signal
1086 * ------- -------- --------------
1087 * 0 0
1088 * 1 1
1089 * 2 2
1090 * 3 3
1091 * 4 4
1092 * 5 5
1093 * 6 6
1094 * 7 7
1095 * 8 8 CTR 7 OUT
1096 * 9 9 CTR 7 AUX
1097 * 10 10 CTR 7 GATE
1098 * 11 11 CTR 7 SOURCE
1099 * 12 12 CTR 6 OUT
1100 * 13 13 CTR 6 AUX
1101 * 14 14 CTR 6 GATE
1102 * 15 15 CTR 6 SOURCE
1103 * 16 16 CTR 5 OUT
1104 * 17 17 CTR 5 AUX
1105 * 18 18 CTR 5 GATE
1106 * 19 19 CTR 5 SOURCE
1107 * 20 20 CTR 4 OUT
1108 * 21 21 CTR 4 AUX
1109 * 22 22 CTR 4 GATE
1110 * 23 23 CTR 4 SOURCE
1111 * 24 24 CTR 3 OUT
1112 * 25 25 CTR 3 AUX
1113 * 26 26 CTR 3 GATE
1114 * 27 27 CTR 3 SOURCE
1115 * 28 28 CTR 2 OUT
1116 * 29 29 CTR 2 AUX
1117 * 30 30 CTR 2 GATE
1118 * 31 31 CTR 2 SOURCE
1119 * 32 CTR 1 OUT
1120 * 33 CTR 1 AUX
1121 * 34 CTR 1 GATE
1122 * 35 CTR 1 SOURCE
1123 * 36 CTR 0 OUT
1124 * 37 CTR 0 AUX
1125 * 38 CTR 0 GATE
1126 * 39 CTR 0 SOURCE
1127 */
520e6191 1128 s = &dev->subdevices[subdev++];
7e906186
HS
1129 s->type = COMEDI_SUBD_DIO;
1130 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
ccef0da8 1131 s->n_chan = NI660X_NUM_PFI_CHANNELS;
7e906186
HS
1132 s->maxdata = 1;
1133 s->range_table = &range_digital;
1134 s->insn_bits = ni_660x_dio_insn_bits;
1135 s->insn_config = ni_660x_dio_insn_config;
6d40805b 1136
34b7f1f8
HS
1137 /*
1138 * Default the DIO channels as:
1139 * chan 0-7: DIO inputs
1140 * chan 8-39: counter signal inputs
1141 */
1142 for (i = 0; i < s->n_chan; ++i) {
1143 unsigned int source = (i < 8) ? NI_660X_PFI_OUTPUT_DIO
1144 : NI_660X_PFI_OUTPUT_COUNTER;
1145
1146 ni_660x_set_pfi_routing(dev, i, source);
a0c5e846 1147 ni_660x_set_pfi_direction(dev, i, COMEDI_INPUT);/* high-z */
34b7f1f8
HS
1148 }
1149
32f89d8e 1150 /* Counter subdevices (4 NI TIO General Purpose Counters per chip) */
ccef0da8 1151 for (i = 0; i < NI660X_MAX_COUNTERS; ++i) {
520e6191 1152 s = &dev->subdevices[subdev++];
b15f5069 1153 if (i < n_counters) {
32f89d8e
HS
1154 struct ni_gpct *counter = &gpct_dev->counters[i];
1155
32f89d8e
HS
1156 s->type = COMEDI_SUBD_COUNTER;
1157 s->subdev_flags = SDF_READABLE | SDF_WRITABLE |
56e9bef5 1158 SDF_LSAMPL | SDF_CMD_READ;
32f89d8e
HS
1159 s->n_chan = 3;
1160 s->maxdata = 0xffffffff;
1161 s->insn_read = ni_tio_insn_read;
1162 s->insn_write = ni_tio_insn_write;
1163 s->insn_config = ni_tio_insn_config;
1164 s->len_chanlist = 1;
1165 s->do_cmd = ni_660x_cmd;
1166 s->do_cmdtest = ni_tio_cmdtest;
1167 s->cancel = ni_660x_cancel;
1168 s->poll = ni_660x_input_poll;
1169 s->buf_change = ni_660x_buf_change;
990b9eed 1170 s->async_dma_dir = DMA_BIDIRECTIONAL;
32f89d8e 1171 s->private = counter;
90ad57be
HS
1172
1173 ni_tio_init_counter(counter);
990b9eed 1174 } else {
32f89d8e 1175 s->type = COMEDI_SUBD_UNUSED;
990b9eed
HS
1176 }
1177 }
32f89d8e 1178
6d40805b
HS
1179 /*
1180 * To be safe, set counterswap bits on tio chips after all the counter
1181 * outputs have been set to high impedance mode.
1182 */
9186ccde 1183 for (i = 0; i < board->n_chips; ++i)
990b9eed
HS
1184 set_tio_counterswap(dev, i);
1185
71e06874
HS
1186 ret = request_irq(pcidev->irq, ni_660x_interrupt, IRQF_SHARED,
1187 dev->board_name, dev);
990b9eed
HS
1188 if (ret < 0) {
1189 dev_warn(dev->class_dev, " irq not available\n");
1190 return ret;
1191 }
ba9d29fe 1192 dev->irq = pcidev->irq;
41014593 1193 global_interrupt_config_bits = NI660X_GLOBAL_INT_GLOBAL;
9186ccde 1194 if (board->n_chips > 1)
41014593 1195 global_interrupt_config_bits |= NI660X_GLOBAL_INT_CASCADE;
9678b73e
HS
1196 ni_660x_write(dev, 0, global_interrupt_config_bits,
1197 NI660X_GLOBAL_INT_CFG);
c93999c2 1198
990b9eed
HS
1199 return 0;
1200}
1201
1202static void ni_660x_detach(struct comedi_device *dev)
1203{
1204 struct ni_660x_private *devpriv = dev->private;
1205
78d514fa
HS
1206 if (dev->irq) {
1207 ni_660x_write(dev, 0, 0, NI660X_GLOBAL_INT_CFG);
990b9eed 1208 free_irq(dev->irq, dev);
78d514fa 1209 }
990b9eed 1210 if (devpriv) {
26a0fe3f 1211 ni_gpct_device_destroy(devpriv->counter_dev);
b876e985
HS
1212 ni_660x_free_mite_rings(dev);
1213 mite_detach(devpriv->mite);
990b9eed 1214 }
5f8a5f4f
HS
1215 if (dev->mmio)
1216 iounmap(dev->mmio);
7f072f54 1217 comedi_pci_disable(dev);
990b9eed
HS
1218}
1219
1220static struct comedi_driver ni_660x_driver = {
1221 .driver_name = "ni_660x",
1222 .module = THIS_MODULE,
750af5e5 1223 .auto_attach = ni_660x_auto_attach,
990b9eed
HS
1224 .detach = ni_660x_detach,
1225};
1226
a690b7e5 1227static int ni_660x_pci_probe(struct pci_dev *dev,
b8f4ac23 1228 const struct pci_device_id *id)
990b9eed 1229{
b8f4ac23 1230 return comedi_pci_auto_config(dev, &ni_660x_driver, id->driver_data);
990b9eed
HS
1231}
1232
41e043fc 1233static const struct pci_device_id ni_660x_pci_table[] = {
97bcce5a
HS
1234 { PCI_VDEVICE(NI, 0x1310), BOARD_PCI6602 },
1235 { PCI_VDEVICE(NI, 0x1360), BOARD_PXI6602 },
1236 { PCI_VDEVICE(NI, 0x2c60), BOARD_PCI6601 },
51c4ba64 1237 { PCI_VDEVICE(NI, 0x2db0), BOARD_PCI6608 },
97bcce5a 1238 { PCI_VDEVICE(NI, 0x2cc0), BOARD_PXI6608 },
0d0ad829 1239 { PCI_VDEVICE(NI, 0x1e30), BOARD_PCI6624 },
8bdfefb7 1240 { PCI_VDEVICE(NI, 0x1e40), BOARD_PXI6624 },
97bcce5a 1241 { 0 }
990b9eed
HS
1242};
1243MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
1244
1245static struct pci_driver ni_660x_pci_driver = {
1246 .name = "ni_660x",
1247 .id_table = ni_660x_pci_table,
1248 .probe = ni_660x_pci_probe,
9901a4d7 1249 .remove = comedi_pci_auto_unconfig,
990b9eed
HS
1250};
1251module_comedi_pci_driver(ni_660x_driver, ni_660x_pci_driver);
1252
3659743d 1253MODULE_AUTHOR("Comedi https://www.comedi.org");
47470216 1254MODULE_DESCRIPTION("Comedi driver for NI 660x counter/timer boards");
3c323c01 1255MODULE_LICENSE("GPL");