staging: comedi: rtd520: use DIV_ROUND_CLOSEST and DIV_ROUND_UP macros
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / rtd520.c
1 /*
2  * comedi/drivers/rtd520.c
3  * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
4  *
5  * COMEDI - Linux Control and Measurement Device Interface
6  * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
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  */
18
19 /*
20  * Driver: rtd520
21  * Description: Real Time Devices PCI4520/DM7520
22  * Devices: [Real Time Devices] DM7520HR-1 (DM7520), DM7520HR-8,
23  *   PCI4520 (PCI4520), PCI4520-8
24  * Author: Dan Christian
25  * Status: Works. Only tested on DM7520-8. Not SMP safe.
26  *
27  * Configuration options: not applicable, uses PCI auto config
28  */
29
30 /*
31  * Created by Dan Christian, NASA Ames Research Center.
32  *
33  * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
34  * Both have:
35  *   8/16 12 bit ADC with FIFO and channel gain table
36  *   8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
37  *   8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
38  *   2 12 bit DACs with FIFOs
39  *   2 bits output
40  *   2 bits input
41  *   bus mastering DMA
42  *   timers: ADC sample, pacer, burst, about, delay, DA1, DA2
43  *   sample counter
44  *   3 user timer/counters (8254)
45  *   external interrupt
46  *
47  * The DM7520 has slightly fewer features (fewer gain steps).
48  *
49  * These boards can support external multiplexors and multi-board
50  * synchronization, but this driver doesn't support that.
51  *
52  * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
53  * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
54  * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
55  * Call them and ask for the register level manual.
56  * PCI chip: http://www.plxtech.com/products/io/pci9080
57  *
58  * Notes:
59  * This board is memory mapped. There is some IO stuff, but it isn't needed.
60  *
61  * I use a pretty loose naming style within the driver (rtd_blah).
62  * All externally visible names should be rtd520_blah.
63  * I use camelCase for structures (and inside them).
64  * I may also use upper CamelCase for function names (old habit).
65  *
66  * This board is somewhat related to the RTD PCI4400 board.
67  *
68  * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
69  * das1800, since they have the best documented code. Driver cb_pcidas64.c
70  * uses the same DMA controller.
71  *
72  * As far as I can tell, the About interrupt doesn't work if Sample is
73  * also enabled. It turns out that About really isn't needed, since
74  * we always count down samples read.
75  *
76  * There was some timer/counter code, but it didn't follow the right API.
77  */
78
79 /*
80  * driver status:
81  *
82  * Analog-In supports instruction and command mode.
83  *
84  * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
85  * (single channel, 64K read buffer). I get random system lockups when
86  * using DMA with ALI-15xx based systems. I haven't been able to test
87  * any other chipsets. The lockups happen soon after the start of an
88  * acquistion, not in the middle of a long run.
89  *
90  * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
91  * (with a 256K read buffer).
92  *
93  * Digital-IO and Analog-Out only support instruction mode.
94  */
95
96 #include <linux/module.h>
97 #include <linux/delay.h>
98 #include <linux/interrupt.h>
99
100 #include "../comedi_pci.h"
101
102 #include "plx9080.h"
103
104 /*
105  * Local Address Space 0 Offsets
106  */
107 #define LAS0_USER_IO            0x0008  /* User I/O */
108 #define LAS0_ADC                0x0010  /* FIFO Status/Software A/D Start */
109 #define FS_DAC1_NOT_EMPTY       BIT(0)  /* DAC1 FIFO not empty */
110 #define FS_DAC1_HEMPTY          BIT(1)  /* DAC1 FIFO half empty */
111 #define FS_DAC1_NOT_FULL        BIT(2)  /* DAC1 FIFO not full */
112 #define FS_DAC2_NOT_EMPTY       BIT(4)  /* DAC2 FIFO not empty */
113 #define FS_DAC2_HEMPTY          BIT(5)  /* DAC2 FIFO half empty */
114 #define FS_DAC2_NOT_FULL        BIT(6)  /* DAC2 FIFO not full */
115 #define FS_ADC_NOT_EMPTY        BIT(8)  /* ADC FIFO not empty */
116 #define FS_ADC_HEMPTY           BIT(9)  /* ADC FIFO half empty */
117 #define FS_ADC_NOT_FULL         BIT(10) /* ADC FIFO not full */
118 #define FS_DIN_NOT_EMPTY        BIT(12) /* DIN FIFO not empty */
119 #define FS_DIN_HEMPTY           BIT(13) /* DIN FIFO half empty */
120 #define FS_DIN_NOT_FULL         BIT(14) /* DIN FIFO not full */
121 #define LAS0_UPDATE_DAC(x)      (0x0014 + ((x) * 0x4))  /* D/Ax Update (w) */
122 #define LAS0_DAC                0x0024  /* Software Simultaneous Update (w) */
123 #define LAS0_PACER              0x0028  /* Software Pacer Start/Stop */
124 #define LAS0_TIMER              0x002c  /* Timer Status/HDIN Software Trig. */
125 #define LAS0_IT                 0x0030  /* Interrupt Status/Enable */
126 #define IRQM_ADC_FIFO_WRITE     BIT(0)  /* ADC FIFO Write */
127 #define IRQM_CGT_RESET          BIT(1)  /* Reset CGT */
128 #define IRQM_CGT_PAUSE          BIT(3)  /* Pause CGT */
129 #define IRQM_ADC_ABOUT_CNT      BIT(4)  /* About Counter out */
130 #define IRQM_ADC_DELAY_CNT      BIT(5)  /* Delay Counter out */
131 #define IRQM_ADC_SAMPLE_CNT     BIT(6)  /* ADC Sample Counter */
132 #define IRQM_DAC1_UCNT          BIT(7)  /* DAC1 Update Counter */
133 #define IRQM_DAC2_UCNT          BIT(8)  /* DAC2 Update Counter */
134 #define IRQM_UTC1               BIT(9)  /* User TC1 out */
135 #define IRQM_UTC1_INV           BIT(10) /* User TC1 out, inverted */
136 #define IRQM_UTC2               BIT(11) /* User TC2 out */
137 #define IRQM_DIGITAL_IT         BIT(12) /* Digital Interrupt */
138 #define IRQM_EXTERNAL_IT        BIT(13) /* External Interrupt */
139 #define IRQM_ETRIG_RISING       BIT(14) /* Ext Trigger rising-edge */
140 #define IRQM_ETRIG_FALLING      BIT(15) /* Ext Trigger falling-edge */
141 #define LAS0_CLEAR              0x0034  /* Clear/Set Interrupt Clear Mask */
142 #define LAS0_OVERRUN            0x0038  /* Pending interrupts/Clear Overrun */
143 #define LAS0_PCLK               0x0040  /* Pacer Clock (24bit) */
144 #define LAS0_BCLK               0x0044  /* Burst Clock (10bit) */
145 #define LAS0_ADC_SCNT           0x0048  /* A/D Sample counter (10bit) */
146 #define LAS0_DAC1_UCNT          0x004c  /* D/A1 Update counter (10 bit) */
147 #define LAS0_DAC2_UCNT          0x0050  /* D/A2 Update counter (10 bit) */
148 #define LAS0_DCNT               0x0054  /* Delay counter (16 bit) */
149 #define LAS0_ACNT               0x0058  /* About counter (16 bit) */
150 #define LAS0_DAC_CLK            0x005c  /* DAC clock (16bit) */
151 #define LAS0_UTC0               0x0060  /* 8254 TC Counter 0 */
152 #define LAS0_UTC1               0x0064  /* 8254 TC Counter 1 */
153 #define LAS0_UTC2               0x0068  /* 8254 TC Counter 2 */
154 #define LAS0_UTC_CTRL           0x006c  /* 8254 TC Control */
155 #define LAS0_DIO0               0x0070  /* Digital I/O Port 0 */
156 #define LAS0_DIO1               0x0074  /* Digital I/O Port 1 */
157 #define LAS0_DIO0_CTRL          0x0078  /* Digital I/O Control */
158 #define LAS0_DIO_STATUS         0x007c  /* Digital I/O Status */
159 #define LAS0_BOARD_RESET        0x0100  /* Board reset */
160 #define LAS0_DMA0_SRC           0x0104  /* DMA 0 Sources select */
161 #define LAS0_DMA1_SRC           0x0108  /* DMA 1 Sources select */
162 #define LAS0_ADC_CONVERSION     0x010c  /* A/D Conversion Signal select */
163 #define LAS0_BURST_START        0x0110  /* Burst Clock Start Trigger select */
164 #define LAS0_PACER_START        0x0114  /* Pacer Clock Start Trigger select */
165 #define LAS0_PACER_STOP         0x0118  /* Pacer Clock Stop Trigger select */
166 #define LAS0_ACNT_STOP_ENABLE   0x011c  /* About Counter Stop Enable */
167 #define LAS0_PACER_REPEAT       0x0120  /* Pacer Start Trigger Mode select */
168 #define LAS0_DIN_START          0x0124  /* HiSpd DI Sampling Signal select */
169 #define LAS0_DIN_FIFO_CLEAR     0x0128  /* Digital Input FIFO Clear */
170 #define LAS0_ADC_FIFO_CLEAR     0x012c  /* A/D FIFO Clear */
171 #define LAS0_CGT_WRITE          0x0130  /* Channel Gain Table Write */
172 #define LAS0_CGL_WRITE          0x0134  /* Channel Gain Latch Write */
173 #define LAS0_CG_DATA            0x0138  /* Digital Table Write */
174 #define LAS0_CGT_ENABLE         0x013c  /* Channel Gain Table Enable */
175 #define LAS0_CG_ENABLE          0x0140  /* Digital Table Enable */
176 #define LAS0_CGT_PAUSE          0x0144  /* Table Pause Enable */
177 #define LAS0_CGT_RESET          0x0148  /* Reset Channel Gain Table */
178 #define LAS0_CGT_CLEAR          0x014c  /* Clear Channel Gain Table */
179 #define LAS0_DAC_CTRL(x)        (0x0150 + ((x) * 0x14)) /* D/Ax type/range */
180 #define LAS0_DAC_SRC(x)         (0x0154 + ((x) * 0x14)) /* D/Ax update source */
181 #define LAS0_DAC_CYCLE(x)       (0x0158 + ((x) * 0x14)) /* D/Ax cycle mode */
182 #define LAS0_DAC_RESET(x)       (0x015c + ((x) * 0x14)) /* D/Ax FIFO reset */
183 #define LAS0_DAC_FIFO_CLEAR(x)  (0x0160 + ((x) * 0x14)) /* D/Ax FIFO clear */
184 #define LAS0_ADC_SCNT_SRC       0x0178  /* A/D Sample Counter Source select */
185 #define LAS0_PACER_SELECT       0x0180  /* Pacer Clock select */
186 #define LAS0_SBUS0_SRC          0x0184  /* SyncBus 0 Source select */
187 #define LAS0_SBUS0_ENABLE       0x0188  /* SyncBus 0 enable */
188 #define LAS0_SBUS1_SRC          0x018c  /* SyncBus 1 Source select */
189 #define LAS0_SBUS1_ENABLE       0x0190  /* SyncBus 1 enable */
190 #define LAS0_SBUS2_SRC          0x0198  /* SyncBus 2 Source select */
191 #define LAS0_SBUS2_ENABLE       0x019c  /* SyncBus 2 enable */
192 #define LAS0_ETRG_POLARITY      0x01a4  /* Ext. Trigger polarity select */
193 #define LAS0_EINT_POLARITY      0x01a8  /* Ext. Interrupt polarity select */
194 #define LAS0_UTC0_CLOCK         0x01ac  /* UTC0 Clock select */
195 #define LAS0_UTC0_GATE          0x01b0  /* UTC0 Gate select */
196 #define LAS0_UTC1_CLOCK         0x01b4  /* UTC1 Clock select */
197 #define LAS0_UTC1_GATE          0x01b8  /* UTC1 Gate select */
198 #define LAS0_UTC2_CLOCK         0x01bc  /* UTC2 Clock select */
199 #define LAS0_UTC2_GATE          0x01c0  /* UTC2 Gate select */
200 #define LAS0_UOUT0_SELECT       0x01c4  /* User Output 0 source select */
201 #define LAS0_UOUT1_SELECT       0x01c8  /* User Output 1 source select */
202 #define LAS0_DMA0_RESET         0x01cc  /* DMA0 Request state machine reset */
203 #define LAS0_DMA1_RESET         0x01d0  /* DMA1 Request state machine reset */
204
205 /*
206  * Local Address Space 1 Offsets
207  */
208 #define LAS1_ADC_FIFO           0x0000  /* A/D FIFO (16bit) */
209 #define LAS1_HDIO_FIFO          0x0004  /* HiSpd DI FIFO (16bit) */
210 #define LAS1_DAC_FIFO(x)        (0x0008 + ((x) * 0x4))  /* D/Ax FIFO (16bit) */
211
212 /*
213  * Driver specific stuff (tunable)
214  */
215
216 /*
217  * We really only need 2 buffers.  More than that means being much
218  * smarter about knowing which ones are full.
219  */
220 #define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
221
222 /* Target period for periodic transfers.  This sets the user read latency. */
223 /* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
224 /* If this is too low, efficiency is poor */
225 #define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
226
227 /* Set a practical limit on how long a list to support (affects memory use) */
228 /* The board support a channel list up to the FIFO length (1K or 8K) */
229 #define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
230
231 /*
232  * Board specific stuff
233  */
234
235 #define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
236 #define RTD_CLOCK_BASE  125     /* clock period in ns */
237
238 /* Note: these speed are slower than the spec, but fit the counter resolution*/
239 #define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
240 /* max speed if we don't have to wait for settling */
241 #define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
242
243 #define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
244 /* min speed when only 1 channel (no burst counter) */
245 #define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
246
247 /* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
248 #define DMA_MODE_BITS (\
249                        PLX_LOCAL_BUS_16_WIDE_BITS \
250                        | PLX_DMA_EN_READYIN_BIT \
251                        | PLX_DMA_LOCAL_BURST_EN_BIT \
252                        | PLX_EN_CHAIN_BIT \
253                        | PLX_DMA_INTR_PCI_BIT \
254                        | PLX_LOCAL_ADDR_CONST_BIT \
255                        | PLX_DEMAND_MODE_BIT)
256
257 #define DMA_TRANSFER_BITS (\
258 /* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
259 /* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
260 /* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
261
262 /*
263  * Comedi specific stuff
264  */
265
266 /*
267  * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
268  */
269 static const struct comedi_lrange rtd_ai_7520_range = {
270         18, {
271                 /* +-5V input range gain steps */
272                 BIP_RANGE(5.0),
273                 BIP_RANGE(5.0 / 2),
274                 BIP_RANGE(5.0 / 4),
275                 BIP_RANGE(5.0 / 8),
276                 BIP_RANGE(5.0 / 16),
277                 BIP_RANGE(5.0 / 32),
278                 /* +-10V input range gain steps */
279                 BIP_RANGE(10.0),
280                 BIP_RANGE(10.0 / 2),
281                 BIP_RANGE(10.0 / 4),
282                 BIP_RANGE(10.0 / 8),
283                 BIP_RANGE(10.0 / 16),
284                 BIP_RANGE(10.0 / 32),
285                 /* +10V input range gain steps */
286                 UNI_RANGE(10.0),
287                 UNI_RANGE(10.0 / 2),
288                 UNI_RANGE(10.0 / 4),
289                 UNI_RANGE(10.0 / 8),
290                 UNI_RANGE(10.0 / 16),
291                 UNI_RANGE(10.0 / 32),
292         }
293 };
294
295 /* PCI4520 has two more gains (6 more entries) */
296 static const struct comedi_lrange rtd_ai_4520_range = {
297         24, {
298                 /* +-5V input range gain steps */
299                 BIP_RANGE(5.0),
300                 BIP_RANGE(5.0 / 2),
301                 BIP_RANGE(5.0 / 4),
302                 BIP_RANGE(5.0 / 8),
303                 BIP_RANGE(5.0 / 16),
304                 BIP_RANGE(5.0 / 32),
305                 BIP_RANGE(5.0 / 64),
306                 BIP_RANGE(5.0 / 128),
307                 /* +-10V input range gain steps */
308                 BIP_RANGE(10.0),
309                 BIP_RANGE(10.0 / 2),
310                 BIP_RANGE(10.0 / 4),
311                 BIP_RANGE(10.0 / 8),
312                 BIP_RANGE(10.0 / 16),
313                 BIP_RANGE(10.0 / 32),
314                 BIP_RANGE(10.0 / 64),
315                 BIP_RANGE(10.0 / 128),
316                 /* +10V input range gain steps */
317                 UNI_RANGE(10.0),
318                 UNI_RANGE(10.0 / 2),
319                 UNI_RANGE(10.0 / 4),
320                 UNI_RANGE(10.0 / 8),
321                 UNI_RANGE(10.0 / 16),
322                 UNI_RANGE(10.0 / 32),
323                 UNI_RANGE(10.0 / 64),
324                 UNI_RANGE(10.0 / 128),
325         }
326 };
327
328 /* Table order matches range values */
329 static const struct comedi_lrange rtd_ao_range = {
330         4, {
331                 UNI_RANGE(5),
332                 UNI_RANGE(10),
333                 BIP_RANGE(5),
334                 BIP_RANGE(10),
335         }
336 };
337
338 enum rtd_boardid {
339         BOARD_DM7520,
340         BOARD_PCI4520,
341 };
342
343 struct rtd_boardinfo {
344         const char *name;
345         int range_bip10;        /* start of +-10V range */
346         int range_uni10;        /* start of +10V range */
347         const struct comedi_lrange *ai_range;
348 };
349
350 static const struct rtd_boardinfo rtd520_boards[] = {
351         [BOARD_DM7520] = {
352                 .name           = "DM7520",
353                 .range_bip10    = 6,
354                 .range_uni10    = 12,
355                 .ai_range       = &rtd_ai_7520_range,
356         },
357         [BOARD_PCI4520] = {
358                 .name           = "PCI4520",
359                 .range_bip10    = 8,
360                 .range_uni10    = 16,
361                 .ai_range       = &rtd_ai_4520_range,
362         },
363 };
364
365 struct rtd_private {
366         /* memory mapped board structures */
367         void __iomem *las1;
368         void __iomem *lcfg;
369
370         long ai_count;          /* total transfer size (samples) */
371         int xfer_count;         /* # to transfer data. 0->1/2FIFO */
372         int flags;              /* flag event modes */
373         unsigned fifosz;
374 };
375
376 /* bit defines for "flags" */
377 #define SEND_EOS        0x01    /* send End Of Scan events */
378 #define DMA0_ACTIVE     0x02    /* DMA0 is active */
379 #define DMA1_ACTIVE     0x04    /* DMA1 is active */
380
381 /*
382  * Given a desired period and the clock period (both in ns), return the
383  * proper counter value (divider-1). Sets the original period to be the
384  * true value.
385  * Note: you have to check if the value is larger than the counter range!
386  */
387 static int rtd_ns_to_timer_base(unsigned int *nanosec,
388                                 unsigned int flags, int base)
389 {
390         int divider;
391
392         switch (flags & CMDF_ROUND_MASK) {
393         case CMDF_ROUND_NEAREST:
394         default:
395                 divider = DIV_ROUND_CLOSEST(*nanosec, base);
396                 break;
397         case CMDF_ROUND_DOWN:
398                 divider = (*nanosec) / base;
399                 break;
400         case CMDF_ROUND_UP:
401                 divider = DIV_ROUND_UP(*nanosec, base);
402                 break;
403         }
404         if (divider < 2)
405                 divider = 2;    /* min is divide by 2 */
406
407         /*
408          * Note: we don't check for max, because different timers
409          * have different ranges
410          */
411
412         *nanosec = base * divider;
413         return divider - 1;     /* countdown is divisor+1 */
414 }
415
416 /*
417  * Given a desired period (in ns), return the proper counter value
418  * (divider-1) for the internal clock. Sets the original period to
419  * be the true value.
420  */
421 static int rtd_ns_to_timer(unsigned int *ns, unsigned int flags)
422 {
423         return rtd_ns_to_timer_base(ns, flags, RTD_CLOCK_BASE);
424 }
425
426 /* Convert a single comedi channel-gain entry to a RTD520 table entry */
427 static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
428                                             unsigned int chanspec, int index)
429 {
430         const struct rtd_boardinfo *board = dev->board_ptr;
431         unsigned int chan = CR_CHAN(chanspec);
432         unsigned int range = CR_RANGE(chanspec);
433         unsigned int aref = CR_AREF(chanspec);
434         unsigned short r = 0;
435
436         r |= chan & 0xf;
437
438         /* Note: we also setup the channel list bipolar flag array */
439         if (range < board->range_bip10) {
440                 /* +-5 range */
441                 r |= 0x000;
442                 r |= (range & 0x7) << 4;
443         } else if (range < board->range_uni10) {
444                 /* +-10 range */
445                 r |= 0x100;
446                 r |= ((range - board->range_bip10) & 0x7) << 4;
447         } else {
448                 /* +10 range */
449                 r |= 0x200;
450                 r |= ((range - board->range_uni10) & 0x7) << 4;
451         }
452
453         switch (aref) {
454         case AREF_GROUND:       /* on-board ground */
455                 break;
456
457         case AREF_COMMON:
458                 r |= 0x80;      /* ref external analog common */
459                 break;
460
461         case AREF_DIFF:
462                 r |= 0x400;     /* differential inputs */
463                 break;
464
465         case AREF_OTHER:        /* ??? */
466                 break;
467         }
468         return r;
469 }
470
471 /* Setup the channel-gain table from a comedi list */
472 static void rtd_load_channelgain_list(struct comedi_device *dev,
473                                       unsigned int n_chan, unsigned int *list)
474 {
475         if (n_chan > 1) {       /* setup channel gain table */
476                 int ii;
477
478                 writel(0, dev->mmio + LAS0_CGT_CLEAR);
479                 writel(1, dev->mmio + LAS0_CGT_ENABLE);
480                 for (ii = 0; ii < n_chan; ii++) {
481                         writel(rtd_convert_chan_gain(dev, list[ii], ii),
482                                dev->mmio + LAS0_CGT_WRITE);
483                 }
484         } else {                /* just use the channel gain latch */
485                 writel(0, dev->mmio + LAS0_CGT_ENABLE);
486                 writel(rtd_convert_chan_gain(dev, list[0], 0),
487                        dev->mmio + LAS0_CGL_WRITE);
488         }
489 }
490
491 /*
492  * Determine fifo size by doing adc conversions until the fifo half
493  * empty status flag clears.
494  */
495 static int rtd520_probe_fifo_depth(struct comedi_device *dev)
496 {
497         unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
498         unsigned i;
499         static const unsigned limit = 0x2000;
500         unsigned fifo_size = 0;
501
502         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
503         rtd_load_channelgain_list(dev, 1, &chanspec);
504         /* ADC conversion trigger source: SOFTWARE */
505         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
506         /* convert  samples */
507         for (i = 0; i < limit; ++i) {
508                 unsigned fifo_status;
509                 /* trigger conversion */
510                 writew(0, dev->mmio + LAS0_ADC);
511                 usleep_range(1, 1000);
512                 fifo_status = readl(dev->mmio + LAS0_ADC);
513                 if ((fifo_status & FS_ADC_HEMPTY) == 0) {
514                         fifo_size = 2 * i;
515                         break;
516                 }
517         }
518         if (i == limit) {
519                 dev_info(dev->class_dev, "failed to probe fifo size.\n");
520                 return -EIO;
521         }
522         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
523         if (fifo_size != 0x400 && fifo_size != 0x2000) {
524                 dev_info(dev->class_dev,
525                          "unexpected fifo size of %i, expected 1024 or 8192.\n",
526                          fifo_size);
527                 return -EIO;
528         }
529         return fifo_size;
530 }
531
532 static int rtd_ai_eoc(struct comedi_device *dev,
533                       struct comedi_subdevice *s,
534                       struct comedi_insn *insn,
535                       unsigned long context)
536 {
537         unsigned int status;
538
539         status = readl(dev->mmio + LAS0_ADC);
540         if (status & FS_ADC_NOT_EMPTY)
541                 return 0;
542         return -EBUSY;
543 }
544
545 static int rtd_ai_rinsn(struct comedi_device *dev,
546                         struct comedi_subdevice *s, struct comedi_insn *insn,
547                         unsigned int *data)
548 {
549         struct rtd_private *devpriv = dev->private;
550         unsigned int range = CR_RANGE(insn->chanspec);
551         int ret;
552         int n;
553
554         /* clear any old fifo data */
555         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
556
557         /* write channel to multiplexer and clear channel gain table */
558         rtd_load_channelgain_list(dev, 1, &insn->chanspec);
559
560         /* ADC conversion trigger source: SOFTWARE */
561         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
562
563         /* convert n samples */
564         for (n = 0; n < insn->n; n++) {
565                 unsigned short d;
566                 /* trigger conversion */
567                 writew(0, dev->mmio + LAS0_ADC);
568
569                 ret = comedi_timeout(dev, s, insn, rtd_ai_eoc, 0);
570                 if (ret)
571                         return ret;
572
573                 /* read data */
574                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
575                 d >>= 3;        /* low 3 bits are marker lines */
576
577                 /* convert bipolar data to comedi unsigned data */
578                 if (comedi_range_is_bipolar(s, range))
579                         d = comedi_offset_munge(s, d);
580
581                 data[n] = d & s->maxdata;
582         }
583
584         /* return the number of samples read/written */
585         return n;
586 }
587
588 static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
589                      int count)
590 {
591         struct rtd_private *devpriv = dev->private;
592         struct comedi_async *async = s->async;
593         struct comedi_cmd *cmd = &async->cmd;
594         int ii;
595
596         for (ii = 0; ii < count; ii++) {
597                 unsigned int range = CR_RANGE(cmd->chanlist[async->cur_chan]);
598                 unsigned short d;
599
600                 if (devpriv->ai_count == 0) {   /* done */
601                         d = readw(devpriv->las1 + LAS1_ADC_FIFO);
602                         continue;
603                 }
604
605                 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
606                 d >>= 3;        /* low 3 bits are marker lines */
607
608                 /* convert bipolar data to comedi unsigned data */
609                 if (comedi_range_is_bipolar(s, range))
610                         d = comedi_offset_munge(s, d);
611                 d &= s->maxdata;
612
613                 if (!comedi_buf_write_samples(s, &d, 1))
614                         return -1;
615
616                 if (devpriv->ai_count > 0)      /* < 0, means read forever */
617                         devpriv->ai_count--;
618         }
619         return 0;
620 }
621
622 static irqreturn_t rtd_interrupt(int irq, void *d)
623 {
624         struct comedi_device *dev = d;
625         struct comedi_subdevice *s = dev->read_subdev;
626         struct rtd_private *devpriv = dev->private;
627         u32 overrun;
628         u16 status;
629         u16 fifo_status;
630
631         if (!dev->attached)
632                 return IRQ_NONE;
633
634         fifo_status = readl(dev->mmio + LAS0_ADC);
635         /* check for FIFO full, this automatically halts the ADC! */
636         if (!(fifo_status & FS_ADC_NOT_FULL))   /* 0 -> full */
637                 goto xfer_abort;
638
639         status = readw(dev->mmio + LAS0_IT);
640         /* if interrupt was not caused by our board, or handled above */
641         if (status == 0)
642                 return IRQ_HANDLED;
643
644         if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
645                 /*
646                  * since the priority interrupt controller may have queued
647                  * a sample counter interrupt, even though we have already
648                  * finished, we must handle the possibility that there is
649                  * no data here
650                  */
651                 if (!(fifo_status & FS_ADC_HEMPTY)) {
652                         /* FIFO half full */
653                         if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
654                                 goto xfer_abort;
655
656                         if (devpriv->ai_count == 0)
657                                 goto xfer_done;
658                 } else if (devpriv->xfer_count > 0) {
659                         if (fifo_status & FS_ADC_NOT_EMPTY) {
660                                 /* FIFO not empty */
661                                 if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
662                                         goto xfer_abort;
663
664                                 if (devpriv->ai_count == 0)
665                                         goto xfer_done;
666                         }
667                 }
668         }
669
670         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
671         if (overrun)
672                 goto xfer_abort;
673
674         /* clear the interrupt */
675         writew(status, dev->mmio + LAS0_CLEAR);
676         readw(dev->mmio + LAS0_CLEAR);
677
678         comedi_handle_events(dev, s);
679
680         return IRQ_HANDLED;
681
682 xfer_abort:
683         s->async->events |= COMEDI_CB_ERROR;
684
685 xfer_done:
686         s->async->events |= COMEDI_CB_EOA;
687
688         /* clear the interrupt */
689         status = readw(dev->mmio + LAS0_IT);
690         writew(status, dev->mmio + LAS0_CLEAR);
691         readw(dev->mmio + LAS0_CLEAR);
692
693         fifo_status = readl(dev->mmio + LAS0_ADC);
694         overrun = readl(dev->mmio + LAS0_OVERRUN) & 0xffff;
695
696         comedi_handle_events(dev, s);
697
698         return IRQ_HANDLED;
699 }
700
701 static int rtd_ai_cmdtest(struct comedi_device *dev,
702                           struct comedi_subdevice *s, struct comedi_cmd *cmd)
703 {
704         int err = 0;
705         unsigned int arg;
706
707         /* Step 1 : check if triggers are trivially valid */
708
709         err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW);
710         err |= comedi_check_trigger_src(&cmd->scan_begin_src,
711                                         TRIG_TIMER | TRIG_EXT);
712         err |= comedi_check_trigger_src(&cmd->convert_src,
713                                         TRIG_TIMER | TRIG_EXT);
714         err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
715         err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
716
717         if (err)
718                 return 1;
719
720         /* Step 2a : make sure trigger sources are unique */
721
722         err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
723         err |= comedi_check_trigger_is_unique(cmd->convert_src);
724         err |= comedi_check_trigger_is_unique(cmd->stop_src);
725
726         /* Step 2b : and mutually compatible */
727
728         if (err)
729                 return 2;
730
731         /* Step 3: check if arguments are trivially valid */
732
733         err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
734
735         if (cmd->scan_begin_src == TRIG_TIMER) {
736                 /* Note: these are time periods, not actual rates */
737                 if (cmd->chanlist_len == 1) {   /* no scanning */
738                         if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
739                                                          RTD_MAX_SPEED_1)) {
740                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
741                                                 CMDF_ROUND_UP);
742                                 err |= -EINVAL;
743                         }
744                         if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
745                                                          RTD_MIN_SPEED_1)) {
746                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
747                                                 CMDF_ROUND_DOWN);
748                                 err |= -EINVAL;
749                         }
750                 } else {
751                         if (comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
752                                                          RTD_MAX_SPEED)) {
753                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
754                                                 CMDF_ROUND_UP);
755                                 err |= -EINVAL;
756                         }
757                         if (comedi_check_trigger_arg_max(&cmd->scan_begin_arg,
758                                                          RTD_MIN_SPEED)) {
759                                 rtd_ns_to_timer(&cmd->scan_begin_arg,
760                                                 CMDF_ROUND_DOWN);
761                                 err |= -EINVAL;
762                         }
763                 }
764         } else {
765                 /* external trigger */
766                 /* should be level/edge, hi/lo specification here */
767                 /* should specify multiple external triggers */
768                 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
769         }
770
771         if (cmd->convert_src == TRIG_TIMER) {
772                 if (cmd->chanlist_len == 1) {   /* no scanning */
773                         if (comedi_check_trigger_arg_min(&cmd->convert_arg,
774                                                          RTD_MAX_SPEED_1)) {
775                                 rtd_ns_to_timer(&cmd->convert_arg,
776                                                 CMDF_ROUND_UP);
777                                 err |= -EINVAL;
778                         }
779                         if (comedi_check_trigger_arg_max(&cmd->convert_arg,
780                                                          RTD_MIN_SPEED_1)) {
781                                 rtd_ns_to_timer(&cmd->convert_arg,
782                                                 CMDF_ROUND_DOWN);
783                                 err |= -EINVAL;
784                         }
785                 } else {
786                         if (comedi_check_trigger_arg_min(&cmd->convert_arg,
787                                                          RTD_MAX_SPEED)) {
788                                 rtd_ns_to_timer(&cmd->convert_arg,
789                                                 CMDF_ROUND_UP);
790                                 err |= -EINVAL;
791                         }
792                         if (comedi_check_trigger_arg_max(&cmd->convert_arg,
793                                                          RTD_MIN_SPEED)) {
794                                 rtd_ns_to_timer(&cmd->convert_arg,
795                                                 CMDF_ROUND_DOWN);
796                                 err |= -EINVAL;
797                         }
798                 }
799         } else {
800                 /* external trigger */
801                 /* see above */
802                 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 9);
803         }
804
805         err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
806                                            cmd->chanlist_len);
807
808         if (cmd->stop_src == TRIG_COUNT)
809                 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
810         else    /* TRIG_NONE */
811                 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
812
813         if (err)
814                 return 3;
815
816         /* step 4: fix up any arguments */
817
818         if (cmd->scan_begin_src == TRIG_TIMER) {
819                 arg = cmd->scan_begin_arg;
820                 rtd_ns_to_timer(&arg, cmd->flags);
821                 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
822         }
823
824         if (cmd->convert_src == TRIG_TIMER) {
825                 arg = cmd->convert_arg;
826                 rtd_ns_to_timer(&arg, cmd->flags);
827                 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
828
829                 if (cmd->scan_begin_src == TRIG_TIMER) {
830                         arg = cmd->convert_arg * cmd->scan_end_arg;
831                         err |= comedi_check_trigger_arg_min(&cmd->
832                                                             scan_begin_arg,
833                                                             arg);
834                 }
835         }
836
837         if (err)
838                 return 4;
839
840         return 0;
841 }
842
843 static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
844 {
845         struct rtd_private *devpriv = dev->private;
846         struct comedi_cmd *cmd = &s->async->cmd;
847         int timer;
848
849         /* stop anything currently running */
850         /* pacer stop source: SOFTWARE */
851         writel(0, dev->mmio + LAS0_PACER_STOP);
852         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
853         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
854         writew(0, dev->mmio + LAS0_IT);
855         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
856         writel(0, dev->mmio + LAS0_OVERRUN);
857
858         /* start configuration */
859         /* load channel list and reset CGT */
860         rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
861
862         /* setup the common case and override if needed */
863         if (cmd->chanlist_len > 1) {
864                 /* pacer start source: SOFTWARE */
865                 writel(0, dev->mmio + LAS0_PACER_START);
866                 /* burst trigger source: PACER */
867                 writel(1, dev->mmio + LAS0_BURST_START);
868                 /* ADC conversion trigger source: BURST */
869                 writel(2, dev->mmio + LAS0_ADC_CONVERSION);
870         } else {                /* single channel */
871                 /* pacer start source: SOFTWARE */
872                 writel(0, dev->mmio + LAS0_PACER_START);
873                 /* ADC conversion trigger source: PACER */
874                 writel(1, dev->mmio + LAS0_ADC_CONVERSION);
875         }
876         writel((devpriv->fifosz / 2 - 1) & 0xffff, dev->mmio + LAS0_ACNT);
877
878         if (cmd->scan_begin_src == TRIG_TIMER) {
879                 /* scan_begin_arg is in nanoseconds */
880                 /* find out how many samples to wait before transferring */
881                 if (cmd->flags & CMDF_WAKE_EOS) {
882                         /*
883                          * this may generate un-sustainable interrupt rates
884                          * the application is responsible for doing the
885                          * right thing
886                          */
887                         devpriv->xfer_count = cmd->chanlist_len;
888                         devpriv->flags |= SEND_EOS;
889                 } else {
890                         /* arrange to transfer data periodically */
891                         devpriv->xfer_count =
892                             (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
893                             cmd->scan_begin_arg;
894                         if (devpriv->xfer_count < cmd->chanlist_len) {
895                                 /* transfer after each scan (and avoid 0) */
896                                 devpriv->xfer_count = cmd->chanlist_len;
897                         } else {        /* make a multiple of scan length */
898                                 devpriv->xfer_count =
899                                     (devpriv->xfer_count +
900                                      cmd->chanlist_len - 1)
901                                     / cmd->chanlist_len;
902                                 devpriv->xfer_count *= cmd->chanlist_len;
903                         }
904                         devpriv->flags |= SEND_EOS;
905                 }
906                 if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
907                         /* out of counter range, use 1/2 fifo instead */
908                         devpriv->xfer_count = 0;
909                         devpriv->flags &= ~SEND_EOS;
910                 } else {
911                         /* interrupt for each transfer */
912                         writel((devpriv->xfer_count - 1) & 0xffff,
913                                dev->mmio + LAS0_ACNT);
914                 }
915         } else {                /* unknown timing, just use 1/2 FIFO */
916                 devpriv->xfer_count = 0;
917                 devpriv->flags &= ~SEND_EOS;
918         }
919         /* pacer clock source: INTERNAL 8MHz */
920         writel(1, dev->mmio + LAS0_PACER_SELECT);
921         /* just interrupt, don't stop */
922         writel(1, dev->mmio + LAS0_ACNT_STOP_ENABLE);
923
924         /* BUG??? these look like enumerated values, but they are bit fields */
925
926         /* First, setup when to stop */
927         switch (cmd->stop_src) {
928         case TRIG_COUNT:        /* stop after N scans */
929                 devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
930                 if ((devpriv->xfer_count > 0) &&
931                     (devpriv->xfer_count > devpriv->ai_count)) {
932                         devpriv->xfer_count = devpriv->ai_count;
933                 }
934                 break;
935
936         case TRIG_NONE: /* stop when cancel is called */
937                 devpriv->ai_count = -1; /* read forever */
938                 break;
939         }
940
941         /* Scan timing */
942         switch (cmd->scan_begin_src) {
943         case TRIG_TIMER:        /* periodic scanning */
944                 timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
945                                         CMDF_ROUND_NEAREST);
946                 /* set PACER clock */
947                 writel(timer & 0xffffff, dev->mmio + LAS0_PCLK);
948
949                 break;
950
951         case TRIG_EXT:
952                 /* pacer start source: EXTERNAL */
953                 writel(1, dev->mmio + LAS0_PACER_START);
954                 break;
955         }
956
957         /* Sample timing within a scan */
958         switch (cmd->convert_src) {
959         case TRIG_TIMER:        /* periodic */
960                 if (cmd->chanlist_len > 1) {
961                         /* only needed for multi-channel */
962                         timer = rtd_ns_to_timer(&cmd->convert_arg,
963                                                 CMDF_ROUND_NEAREST);
964                         /* setup BURST clock */
965                         writel(timer & 0x3ff, dev->mmio + LAS0_BCLK);
966                 }
967
968                 break;
969
970         case TRIG_EXT:          /* external */
971                 /* burst trigger source: EXTERNAL */
972                 writel(2, dev->mmio + LAS0_BURST_START);
973                 break;
974         }
975         /* end configuration */
976
977         /*
978          * This doesn't seem to work.  There is no way to clear an interrupt
979          * that the priority controller has queued!
980          */
981         writew(~0, dev->mmio + LAS0_CLEAR);
982         readw(dev->mmio + LAS0_CLEAR);
983
984         /* TODO: allow multiple interrupt sources */
985         /* transfer every N samples */
986         writew(IRQM_ADC_ABOUT_CNT, dev->mmio + LAS0_IT);
987
988         /* BUG: start_src is ASSUMED to be TRIG_NOW */
989         /* BUG? it seems like things are running before the "start" */
990         readl(dev->mmio + LAS0_PACER);  /* start pacer */
991         return 0;
992 }
993
994 static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
995 {
996         struct rtd_private *devpriv = dev->private;
997
998         /* pacer stop source: SOFTWARE */
999         writel(0, dev->mmio + LAS0_PACER_STOP);
1000         writel(0, dev->mmio + LAS0_PACER);      /* stop pacer */
1001         writel(0, dev->mmio + LAS0_ADC_CONVERSION);
1002         writew(0, dev->mmio + LAS0_IT);
1003         devpriv->ai_count = 0;  /* stop and don't transfer any more */
1004         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1005         return 0;
1006 }
1007
1008 static int rtd_ao_eoc(struct comedi_device *dev,
1009                       struct comedi_subdevice *s,
1010                       struct comedi_insn *insn,
1011                       unsigned long context)
1012 {
1013         unsigned int chan = CR_CHAN(insn->chanspec);
1014         unsigned int bit = (chan == 0) ? FS_DAC1_NOT_EMPTY : FS_DAC2_NOT_EMPTY;
1015         unsigned int status;
1016
1017         status = readl(dev->mmio + LAS0_ADC);
1018         if (status & bit)
1019                 return 0;
1020         return -EBUSY;
1021 }
1022
1023 static int rtd_ao_insn_write(struct comedi_device *dev,
1024                              struct comedi_subdevice *s,
1025                              struct comedi_insn *insn,
1026                              unsigned int *data)
1027 {
1028         struct rtd_private *devpriv = dev->private;
1029         unsigned int chan = CR_CHAN(insn->chanspec);
1030         unsigned int range = CR_RANGE(insn->chanspec);
1031         int ret;
1032         int i;
1033
1034         /* Configure the output range (table index matches the range values) */
1035         writew(range & 7, dev->mmio + LAS0_DAC_CTRL(chan));
1036
1037         for (i = 0; i < insn->n; ++i) {
1038                 unsigned int val = data[i];
1039
1040                 /* bipolar uses 2's complement values with an extended sign */
1041                 if (comedi_range_is_bipolar(s, range)) {
1042                         val = comedi_offset_munge(s, val);
1043                         val |= (val & ((s->maxdata + 1) >> 1)) << 1;
1044                 }
1045
1046                 /* shift the 12-bit data (+ sign) to match the register */
1047                 val <<= 3;
1048
1049                 writew(val, devpriv->las1 + LAS1_DAC_FIFO(chan));
1050                 writew(0, dev->mmio + LAS0_UPDATE_DAC(chan));
1051
1052                 ret = comedi_timeout(dev, s, insn, rtd_ao_eoc, 0);
1053                 if (ret)
1054                         return ret;
1055
1056                 s->readback[chan] = data[i];
1057         }
1058
1059         return insn->n;
1060 }
1061
1062 static int rtd_dio_insn_bits(struct comedi_device *dev,
1063                              struct comedi_subdevice *s,
1064                              struct comedi_insn *insn,
1065                              unsigned int *data)
1066 {
1067         if (comedi_dio_update_state(s, data))
1068                 writew(s->state & 0xff, dev->mmio + LAS0_DIO0);
1069
1070         data[1] = readw(dev->mmio + LAS0_DIO0) & 0xff;
1071
1072         return insn->n;
1073 }
1074
1075 static int rtd_dio_insn_config(struct comedi_device *dev,
1076                                struct comedi_subdevice *s,
1077                                struct comedi_insn *insn,
1078                                unsigned int *data)
1079 {
1080         int ret;
1081
1082         ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1083         if (ret)
1084                 return ret;
1085
1086         /* TODO support digital match interrupts and strobes */
1087
1088         /* set direction */
1089         writew(0x01, dev->mmio + LAS0_DIO_STATUS);
1090         writew(s->io_bits & 0xff, dev->mmio + LAS0_DIO0_CTRL);
1091
1092         /* clear interrupts */
1093         writew(0x00, dev->mmio + LAS0_DIO_STATUS);
1094
1095         /* port1 can only be all input or all output */
1096
1097         /* there are also 2 user input lines and 2 user output lines */
1098
1099         return insn->n;
1100 }
1101
1102 static void rtd_reset(struct comedi_device *dev)
1103 {
1104         struct rtd_private *devpriv = dev->private;
1105
1106         writel(0, dev->mmio + LAS0_BOARD_RESET);
1107         usleep_range(100, 1000);        /* needed? */
1108         writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1109         writew(0, dev->mmio + LAS0_IT);
1110         writew(~0, dev->mmio + LAS0_CLEAR);
1111         readw(dev->mmio + LAS0_CLEAR);
1112 }
1113
1114 /*
1115  * initialize board, per RTD spec
1116  * also, initialize shadow registers
1117  */
1118 static void rtd_init_board(struct comedi_device *dev)
1119 {
1120         rtd_reset(dev);
1121
1122         writel(0, dev->mmio + LAS0_OVERRUN);
1123         writel(0, dev->mmio + LAS0_CGT_CLEAR);
1124         writel(0, dev->mmio + LAS0_ADC_FIFO_CLEAR);
1125         writel(0, dev->mmio + LAS0_DAC_RESET(0));
1126         writel(0, dev->mmio + LAS0_DAC_RESET(1));
1127         /* clear digital IO fifo */
1128         writew(0, dev->mmio + LAS0_DIO_STATUS);
1129         writeb((0 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1130         writeb((1 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1131         writeb((2 << 6) | 0x30, dev->mmio + LAS0_UTC_CTRL);
1132         writeb((3 << 6) | 0x00, dev->mmio + LAS0_UTC_CTRL);
1133         /* TODO: set user out source ??? */
1134 }
1135
1136 /* The RTD driver does this */
1137 static void rtd_pci_latency_quirk(struct comedi_device *dev,
1138                                   struct pci_dev *pcidev)
1139 {
1140         unsigned char pci_latency;
1141
1142         pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1143         if (pci_latency < 32) {
1144                 dev_info(dev->class_dev,
1145                          "PCI latency changed from %d to %d\n",
1146                          pci_latency, 32);
1147                 pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1148         }
1149 }
1150
1151 static int rtd_auto_attach(struct comedi_device *dev,
1152                            unsigned long context)
1153 {
1154         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1155         const struct rtd_boardinfo *board = NULL;
1156         struct rtd_private *devpriv;
1157         struct comedi_subdevice *s;
1158         int ret;
1159
1160         if (context < ARRAY_SIZE(rtd520_boards))
1161                 board = &rtd520_boards[context];
1162         if (!board)
1163                 return -ENODEV;
1164         dev->board_ptr = board;
1165         dev->board_name = board->name;
1166
1167         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1168         if (!devpriv)
1169                 return -ENOMEM;
1170
1171         ret = comedi_pci_enable(dev);
1172         if (ret)
1173                 return ret;
1174
1175         dev->mmio = pci_ioremap_bar(pcidev, 2);
1176         devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1177         devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1178         if (!dev->mmio || !devpriv->las1 || !devpriv->lcfg)
1179                 return -ENOMEM;
1180
1181         rtd_pci_latency_quirk(dev, pcidev);
1182
1183         if (pcidev->irq) {
1184                 ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1185                                   dev->board_name, dev);
1186                 if (ret == 0)
1187                         dev->irq = pcidev->irq;
1188         }
1189
1190         ret = comedi_alloc_subdevices(dev, 4);
1191         if (ret)
1192                 return ret;
1193
1194         s = &dev->subdevices[0];
1195         /* analog input subdevice */
1196         s->type         = COMEDI_SUBD_AI;
1197         s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1198         s->n_chan       = 16;
1199         s->maxdata      = 0x0fff;
1200         s->range_table  = board->ai_range;
1201         s->len_chanlist = RTD_MAX_CHANLIST;
1202         s->insn_read    = rtd_ai_rinsn;
1203         if (dev->irq) {
1204                 dev->read_subdev = s;
1205                 s->subdev_flags |= SDF_CMD_READ;
1206                 s->do_cmd       = rtd_ai_cmd;
1207                 s->do_cmdtest   = rtd_ai_cmdtest;
1208                 s->cancel       = rtd_ai_cancel;
1209         }
1210
1211         s = &dev->subdevices[1];
1212         /* analog output subdevice */
1213         s->type         = COMEDI_SUBD_AO;
1214         s->subdev_flags = SDF_WRITABLE;
1215         s->n_chan       = 2;
1216         s->maxdata      = 0x0fff;
1217         s->range_table  = &rtd_ao_range;
1218         s->insn_write   = rtd_ao_insn_write;
1219
1220         ret = comedi_alloc_subdev_readback(s);
1221         if (ret)
1222                 return ret;
1223
1224         s = &dev->subdevices[2];
1225         /* digital i/o subdevice */
1226         s->type         = COMEDI_SUBD_DIO;
1227         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1228         /* we only support port 0 right now.  Ignoring port 1 and user IO */
1229         s->n_chan       = 8;
1230         s->maxdata      = 1;
1231         s->range_table  = &range_digital;
1232         s->insn_bits    = rtd_dio_insn_bits;
1233         s->insn_config  = rtd_dio_insn_config;
1234
1235         /* timer/counter subdevices (not currently supported) */
1236         s = &dev->subdevices[3];
1237         s->type         = COMEDI_SUBD_COUNTER;
1238         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1239         s->n_chan       = 3;
1240         s->maxdata      = 0xffff;
1241
1242         rtd_init_board(dev);
1243
1244         ret = rtd520_probe_fifo_depth(dev);
1245         if (ret < 0)
1246                 return ret;
1247         devpriv->fifosz = ret;
1248
1249         if (dev->irq)
1250                 writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1251
1252         return 0;
1253 }
1254
1255 static void rtd_detach(struct comedi_device *dev)
1256 {
1257         struct rtd_private *devpriv = dev->private;
1258
1259         if (devpriv) {
1260                 /* Shut down any board ops by resetting it */
1261                 if (dev->mmio && devpriv->lcfg)
1262                         rtd_reset(dev);
1263                 if (dev->irq)
1264                         free_irq(dev->irq, dev);
1265                 if (dev->mmio)
1266                         iounmap(dev->mmio);
1267                 if (devpriv->las1)
1268                         iounmap(devpriv->las1);
1269                 if (devpriv->lcfg)
1270                         iounmap(devpriv->lcfg);
1271         }
1272         comedi_pci_disable(dev);
1273 }
1274
1275 static struct comedi_driver rtd520_driver = {
1276         .driver_name    = "rtd520",
1277         .module         = THIS_MODULE,
1278         .auto_attach    = rtd_auto_attach,
1279         .detach         = rtd_detach,
1280 };
1281
1282 static int rtd520_pci_probe(struct pci_dev *dev,
1283                             const struct pci_device_id *id)
1284 {
1285         return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1286 }
1287
1288 static const struct pci_device_id rtd520_pci_table[] = {
1289         { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1290         { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1291         { 0 }
1292 };
1293 MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1294
1295 static struct pci_driver rtd520_pci_driver = {
1296         .name           = "rtd520",
1297         .id_table       = rtd520_pci_table,
1298         .probe          = rtd520_pci_probe,
1299         .remove         = comedi_pci_auto_unconfig,
1300 };
1301 module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1302
1303 MODULE_AUTHOR("Comedi http://www.comedi.org");
1304 MODULE_DESCRIPTION("Comedi low-level driver");
1305 MODULE_LICENSE("GPL");