staging: comedi: daqboard2000: use designated initializers
[sfrench/cifs-2.6.git] / drivers / staging / comedi / drivers / daqboard2000.c
1 /*
2  * comedi/drivers/daqboard2000.c
3  * hardware driver for IOtech DAQboard/2000
4  *
5  * COMEDI - Linux Control and Measurement Device Interface
6  * Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
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  * Driver: daqboard2000
20  * Description: IOTech DAQBoard/2000
21  * Author: Anders Blomdell <anders.blomdell@control.lth.se>
22  * Status: works
23  * Updated: Mon, 14 Apr 2008 15:28:52 +0100
24  * Devices: [IOTech] DAQBoard/2000 (daqboard2000)
25  *
26  * Much of the functionality of this driver was determined from reading
27  * the source code for the Windows driver.
28  *
29  * The FPGA on the board requires firmware, which is available from
30  * http://www.comedi.org in the comedi_nonfree_firmware tarball.
31  *
32  * Configuration options: not applicable, uses PCI auto config
33  */
34 /*
35  * This card was obviously never intended to leave the Windows world,
36  * since it lacked all kind of hardware documentation (except for cable
37  * pinouts, plug and pray has something to catch up with yet).
38  *
39  * With some help from our swedish distributor, we got the Windows sourcecode
40  * for the card, and here are the findings so far.
41  *
42  * 1. A good document that describes the PCI interface chip is 9080db-106.pdf
43  *    available from http://www.plxtech.com/products/io/pci9080
44  *
45  * 2. The initialization done so far is:
46  *      a. program the FPGA (windows code sans a lot of error messages)
47  *      b.
48  *
49  * 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled,
50  *    you have to output values to all enabled DAC's until result appears, I
51  *    guess that it has something to do with pacer clocks, but the source
52  *    gives me no clues. I'll keep it simple so far.
53  *
54  * 4. Analog in.
55  *    Each channel in the scanlist seems to be controlled by four
56  *    control words:
57  *
58  *      Word0:
59  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60  *        ! | | | ! | | | ! | | | ! | | | !
61  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62  *
63  *      Word1:
64  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65  *        ! | | | ! | | | ! | | | ! | | | !
66  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67  *         |             |       | | | | |
68  *         +------+------+       | | | | +-- Digital input (??)
69  *                |              | | | +---- 10 us settling time
70  *                |              | | +------ Suspend acquisition (last to scan)
71  *                |              | +-------- Simultaneous sample and hold
72  *                |              +---------- Signed data format
73  *                +------------------------- Correction offset low
74  *
75  *      Word2:
76  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77  *        ! | | | ! | | | ! | | | ! | | | !
78  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79  *         |     | |     | | | | | |     |
80  *         +-----+ +--+--+ +++ +++ +--+--+
81  *            |       |     |   |     +----- Expansion channel
82  *            |       |     |   +----------- Expansion gain
83  *            |       |     +--------------- Channel (low)
84  *            |       +--------------------- Correction offset high
85  *            +----------------------------- Correction gain low
86  *      Word3:
87  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
88  *        ! | | | ! | | | ! | | | ! | | | !
89  *        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90  *         |             | | | |   | | | |
91  *         +------+------+ | | +-+-+ | | +-- Low bank enable
92  *                |        | |   |   | +---- High bank enable
93  *                |        | |   |   +------ Hi/low select
94  *                |        | |   +---------- Gain (1,?,2,4,8,16,32,64)
95  *                |        | +-------------- differential/single ended
96  *                |        +---------------- Unipolar
97  *                +------------------------- Correction gain high
98  *
99  * 999. The card seems to have an incredible amount of capabilities, but
100  *      trying to reverse engineer them from the Windows source is beyond my
101  *      patience.
102  *
103  */
104
105 #include <linux/module.h>
106 #include <linux/delay.h>
107 #include <linux/interrupt.h>
108
109 #include "../comedi_pci.h"
110
111 #include "8255.h"
112 #include "plx9080.h"
113
114 #define DB2K_FIRMWARE           "daqboard2000_firmware.bin"
115
116 #define DB2K_SUBSYSTEM_IDS2     0x0002  /* Daqboard/2000 - 2 Dacs */
117 #define DB2K_SUBSYSTEM_IDS4     0x0004  /* Daqboard/2000 - 4 Dacs */
118
119 static const struct comedi_lrange db2k_ai_range = {
120         13, {
121                 BIP_RANGE(10),
122                 BIP_RANGE(5),
123                 BIP_RANGE(2.5),
124                 BIP_RANGE(1.25),
125                 BIP_RANGE(0.625),
126                 BIP_RANGE(0.3125),
127                 BIP_RANGE(0.156),
128                 UNI_RANGE(10),
129                 UNI_RANGE(5),
130                 UNI_RANGE(2.5),
131                 UNI_RANGE(1.25),
132                 UNI_RANGE(0.625),
133                 UNI_RANGE(0.3125)
134         }
135 };
136
137 /*
138  * Register Memory Map
139  */
140 #define DB2K_REG_ACQ_CONTROL                    0x00            /* u16 (w) */
141 #define DB2K_REG_ACQ_STATUS                     0x00            /* u16 (r) */
142 #define DB2K_REG_ACQ_SCAN_LIST_FIFO             0x02            /* u16 */
143 #define DB2K_REG_ACQ_PACER_CLOCK_DIV_LOW        0x04            /* u32 */
144 #define DB2K_REG_ACQ_SCAN_COUNTER               0x08            /* u16 */
145 #define DB2K_REG_ACQ_PACER_CLOCK_DIV_HIGH       0x0a            /* u16 */
146 #define DB2K_REG_ACQ_TRIGGER_COUNT              0x0c            /* u16 */
147 #define DB2K_REG_ACQ_RESULTS_FIFO               0x10            /* u16 */
148 #define DB2K_REG_ACQ_RESULTS_SHADOW             0x14            /* u16 */
149 #define DB2K_REG_ACQ_ADC_RESULT                 0x18            /* u16 */
150 #define DB2K_REG_DAC_SCAN_COUNTER               0x1c            /* u16 */
151 #define DB2K_REG_DAC_CONTROL                    0x20            /* u16 (w) */
152 #define DB2K_REG_DAC_STATUS                     0x20            /* u16 (r) */
153 #define DB2K_REG_DAC_FIFO                       0x24            /* s16 */
154 #define DB2K_REG_DAC_PACER_CLOCK_DIV            0x2a            /* u16 */
155 #define DB2K_REG_REF_DACS                       0x2c            /* u16 */
156 #define DB2K_REG_DIO_CONTROL                    0x30            /* u16 */
157 #define DB2K_REG_P3_HSIO_DATA                   0x32            /* s16 */
158 #define DB2K_REG_P3_CONTROL                     0x34            /* u16 */
159 #define DB2K_REG_CAL_EEPROM_CONTROL             0x36            /* u16 */
160 #define DB2K_REG_DAC_SETTING(x)                 (0x38 + (x) * 2) /* s16 */
161 #define DB2K_REG_DIO_P2_EXP_IO_8_BIT            0x40            /* s16 */
162 #define DB2K_REG_COUNTER_TIMER_CONTROL          0x80            /* u16 */
163 #define DB2K_REG_COUNTER_INPUT(x)               (0x88 + (x) * 2) /* s16 */
164 #define DB2K_REG_TIMER_DIV(x)                   (0xa0 + (x) * 2) /* u16 */
165 #define DB2K_REG_DMA_CONTROL                    0xb0            /* u16 */
166 #define DB2K_REG_TRIG_CONTROL                   0xb2            /* u16 */
167 #define DB2K_REG_CAL_EEPROM                     0xb8            /* u16 */
168 #define DB2K_REG_ACQ_DIGITAL_MARK               0xba            /* u16 */
169 #define DB2K_REG_TRIG_DACS                      0xbc            /* u16 */
170 #define DB2K_REG_DIO_P2_EXP_IO_16_BIT(x)        (0xc0 + (x) * 2) /* s16 */
171
172 /* CPLD registers */
173 #define DB2K_REG_CPLD_STATUS                    0x1000          /* u16 (r) */
174 #define DB2K_REG_CPLD_WDATA                     0x1000          /* u16 (w) */
175
176 /* Scan Sequencer programming */
177 #define DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST            0x0011
178 #define DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST             0x0010
179
180 /* Prepare for acquisition */
181 #define DB2K_ACQ_CONTROL_RESET_SCAN_LIST_FIFO           0x0004
182 #define DB2K_ACQ_CONTROL_RESET_RESULTS_FIFO             0x0002
183 #define DB2K_ACQ_CONTROL_RESET_CONFIG_PIPE              0x0001
184
185 /* Pacer Clock Control */
186 #define DB2K_ACQ_CONTROL_ADC_PACER_INTERNAL             0x0030
187 #define DB2K_ACQ_CONTROL_ADC_PACER_EXTERNAL             0x0032
188 #define DB2K_ACQ_CONTROL_ADC_PACER_ENABLE               0x0031
189 #define DB2K_ACQ_CONTROL_ADC_PACER_ENABLE_DAC_PACER     0x0034
190 #define DB2K_ACQ_CONTROL_ADC_PACER_DISABLE              0x0030
191 #define DB2K_ACQ_CONTROL_ADC_PACER_NORMAL_MODE          0x0060
192 #define DB2K_ACQ_CONTROL_ADC_PACER_COMPATIBILITY_MODE   0x0061
193 #define DB2K_ACQ_CONTROL_ADC_PACER_INTERNAL_OUT_ENABLE  0x0008
194 #define DB2K_ACQ_CONTROL_ADC_PACER_EXTERNAL_RISING      0x0100
195
196 /* Acquisition status bits */
197 #define DB2K_ACQ_STATUS_RESULTS_FIFO_MORE_1_SAMPLE      0x0001
198 #define DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA           0x0002
199 #define DB2K_ACQ_STATUS_RESULTS_FIFO_OVERRUN            0x0004
200 #define DB2K_ACQ_STATUS_LOGIC_SCANNING                  0x0008
201 #define DB2K_ACQ_STATUS_CONFIG_PIPE_FULL                0x0010
202 #define DB2K_ACQ_STATUS_SCAN_LIST_FIFO_EMPTY            0x0020
203 #define DB2K_ACQ_STATUS_ADC_NOT_READY                   0x0040
204 #define DB2K_ACQ_STATUS_ARBITRATION_FAILURE             0x0080
205 #define DB2K_ACQ_STATUS_ADC_PACER_OVERRUN               0x0100
206 #define DB2K_ACQ_STATUS_DAC_PACER_OVERRUN               0x0200
207
208 /* DAC status */
209 #define DB2K_DAC_STATUS_DAC_FULL                        0x0001
210 #define DB2K_DAC_STATUS_REF_BUSY                        0x0002
211 #define DB2K_DAC_STATUS_TRIG_BUSY                       0x0004
212 #define DB2K_DAC_STATUS_CAL_BUSY                        0x0008
213 #define DB2K_DAC_STATUS_DAC_BUSY(x)                     (0x0010 << (x))
214
215 /* DAC control */
216 #define DB2K_DAC_CONTROL_ENABLE_BIT                     0x0001
217 #define DB2K_DAC_CONTROL_DATA_IS_SIGNED                 0x0002
218 #define DB2K_DAC_CONTROL_RESET_FIFO                     0x0004
219 #define DB2K_DAC_CONTROL_DAC_DISABLE(x)                 (0x0020 + ((x) << 4))
220 #define DB2K_DAC_CONTROL_DAC_ENABLE(x)                  (0x0021 + ((x) << 4))
221 #define DB2K_DAC_CONTROL_PATTERN_DISABLE                0x0060
222 #define DB2K_DAC_CONTROL_PATTERN_ENABLE                 0x0061
223
224 /* Trigger Control */
225 #define DB2K_TRIG_CONTROL_TYPE_ANALOG                   0x0000
226 #define DB2K_TRIG_CONTROL_TYPE_TTL                      0x0010
227 #define DB2K_TRIG_CONTROL_EDGE_HI_LO                    0x0004
228 #define DB2K_TRIG_CONTROL_EDGE_LO_HI                    0x0000
229 #define DB2K_TRIG_CONTROL_LEVEL_ABOVE                   0x0000
230 #define DB2K_TRIG_CONTROL_LEVEL_BELOW                   0x0004
231 #define DB2K_TRIG_CONTROL_SENSE_LEVEL                   0x0002
232 #define DB2K_TRIG_CONTROL_SENSE_EDGE                    0x0000
233 #define DB2K_TRIG_CONTROL_ENABLE                        0x0001
234 #define DB2K_TRIG_CONTROL_DISABLE                       0x0000
235
236 /* Reference Dac Selection */
237 #define DB2K_REF_DACS_SET                               0x0080
238 #define DB2K_REF_DACS_SELECT_POS_REF                    0x0100
239 #define DB2K_REF_DACS_SELECT_NEG_REF                    0x0000
240
241 /* CPLD status bits */
242 #define DB2K_CPLD_STATUS_INIT                           0x0002
243 #define DB2K_CPLD_STATUS_TXREADY                        0x0004
244 #define DB2K_CPLD_VERSION_MASK                          0xf000
245 /* "New CPLD" signature. */
246 #define DB2K_CPLD_VERSION_NEW                           0x5000
247
248 struct db2k_boardtype {
249         const char *name;
250         int id;
251 };
252
253 static const struct db2k_boardtype db2k_boardtypes[] = {
254         {
255                 .name           = "ids2",
256                 .id             = DB2K_SUBSYSTEM_IDS2,
257         },
258         {
259                 .name           = "ids4",
260                 .id             = DB2K_SUBSYSTEM_IDS4,
261         },
262 };
263
264 struct db2k_private {
265         void __iomem *plx;
266 };
267
268 static void db2k_write_acq_scan_list_entry(struct comedi_device *dev, u16 entry)
269 {
270         writew(entry & 0x00ff, dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
271         writew((entry >> 8) & 0x00ff,
272                dev->mmio + DB2K_REG_ACQ_SCAN_LIST_FIFO);
273 }
274
275 static void db2k_setup_sampling(struct comedi_device *dev, int chan, int gain)
276 {
277         u16 word0, word1, word2, word3;
278
279         /* Channel 0-7 diff, channel 8-23 single ended */
280         word0 = 0;
281         word1 = 0x0004;         /* Last scan */
282         word2 = (chan << 6) & 0x00c0;
283         switch (chan / 4) {
284         case 0:
285                 word3 = 0x0001;
286                 break;
287         case 1:
288                 word3 = 0x0002;
289                 break;
290         case 2:
291                 word3 = 0x0005;
292                 break;
293         case 3:
294                 word3 = 0x0006;
295                 break;
296         case 4:
297                 word3 = 0x0041;
298                 break;
299         case 5:
300                 word3 = 0x0042;
301                 break;
302         default:
303                 word3 = 0;
304                 break;
305         }
306         /* These should be read from EEPROM */
307         word2 |= 0x0800;        /* offset */
308         word3 |= 0xc000;        /* gain */
309         db2k_write_acq_scan_list_entry(dev, word0);
310         db2k_write_acq_scan_list_entry(dev, word1);
311         db2k_write_acq_scan_list_entry(dev, word2);
312         db2k_write_acq_scan_list_entry(dev, word3);
313 }
314
315 static int db2k_ai_status(struct comedi_device *dev, struct comedi_subdevice *s,
316                           struct comedi_insn *insn, unsigned long context)
317 {
318         unsigned int status;
319
320         status = readw(dev->mmio + DB2K_REG_ACQ_STATUS);
321         if (status & context)
322                 return 0;
323         return -EBUSY;
324 }
325
326 static int db2k_ai_insn_read(struct comedi_device *dev,
327                              struct comedi_subdevice *s,
328                              struct comedi_insn *insn, unsigned int *data)
329 {
330         int gain, chan;
331         int ret;
332         int i;
333
334         writew(DB2K_ACQ_CONTROL_RESET_SCAN_LIST_FIFO |
335                DB2K_ACQ_CONTROL_RESET_RESULTS_FIFO |
336                DB2K_ACQ_CONTROL_RESET_CONFIG_PIPE,
337                dev->mmio + DB2K_REG_ACQ_CONTROL);
338
339         /*
340          * If pacer clock is not set to some high value (> 10 us), we
341          * risk multiple samples to be put into the result FIFO.
342          */
343         /* 1 second, should be long enough */
344         writel(1000000, dev->mmio + DB2K_REG_ACQ_PACER_CLOCK_DIV_LOW);
345         writew(0, dev->mmio + DB2K_REG_ACQ_PACER_CLOCK_DIV_HIGH);
346
347         gain = CR_RANGE(insn->chanspec);
348         chan = CR_CHAN(insn->chanspec);
349
350         /*
351          * This doesn't look efficient.  I decided to take the conservative
352          * approach when I did the insn conversion.  Perhaps it would be
353          * better to have broken it completely, then someone would have been
354          * forced to fix it.  --ds
355          */
356         for (i = 0; i < insn->n; i++) {
357                 db2k_setup_sampling(dev, chan, gain);
358                 /* Enable reading from the scanlist FIFO */
359                 writew(DB2K_ACQ_CONTROL_SEQ_START_SCAN_LIST,
360                        dev->mmio + DB2K_REG_ACQ_CONTROL);
361
362                 ret = comedi_timeout(dev, s, insn, db2k_ai_status,
363                                      DB2K_ACQ_STATUS_CONFIG_PIPE_FULL);
364                 if (ret)
365                         return ret;
366
367                 writew(DB2K_ACQ_CONTROL_ADC_PACER_ENABLE,
368                        dev->mmio + DB2K_REG_ACQ_CONTROL);
369
370                 ret = comedi_timeout(dev, s, insn, db2k_ai_status,
371                                      DB2K_ACQ_STATUS_LOGIC_SCANNING);
372                 if (ret)
373                         return ret;
374
375                 ret =
376                 comedi_timeout(dev, s, insn, db2k_ai_status,
377                                DB2K_ACQ_STATUS_RESULTS_FIFO_HAS_DATA);
378                 if (ret)
379                         return ret;
380
381                 data[i] = readw(dev->mmio + DB2K_REG_ACQ_RESULTS_FIFO);
382                 writew(DB2K_ACQ_CONTROL_ADC_PACER_DISABLE,
383                        dev->mmio + DB2K_REG_ACQ_CONTROL);
384                 writew(DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST,
385                        dev->mmio + DB2K_REG_ACQ_CONTROL);
386         }
387
388         return i;
389 }
390
391 static int db2k_ao_eoc(struct comedi_device *dev, struct comedi_subdevice *s,
392                        struct comedi_insn *insn, unsigned long context)
393 {
394         unsigned int chan = CR_CHAN(insn->chanspec);
395         unsigned int status;
396
397         status = readw(dev->mmio + DB2K_REG_DAC_STATUS);
398         if ((status & DB2K_DAC_STATUS_DAC_BUSY(chan)) == 0)
399                 return 0;
400         return -EBUSY;
401 }
402
403 static int db2k_ao_insn_write(struct comedi_device *dev,
404                               struct comedi_subdevice *s,
405                               struct comedi_insn *insn, unsigned int *data)
406 {
407         unsigned int chan = CR_CHAN(insn->chanspec);
408         int i;
409
410         for (i = 0; i < insn->n; i++) {
411                 unsigned int val = data[i];
412                 int ret;
413
414                 writew(val, dev->mmio + DB2K_REG_DAC_SETTING(chan));
415
416                 ret = comedi_timeout(dev, s, insn, db2k_ao_eoc, 0);
417                 if (ret)
418                         return ret;
419
420                 s->readback[chan] = val;
421         }
422
423         return insn->n;
424 }
425
426 static void db2k_reset_local_bus(struct comedi_device *dev)
427 {
428         struct db2k_private *devpriv = dev->private;
429         u32 cntrl;
430
431         cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
432         cntrl |= PLX_CNTRL_RESET;
433         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
434         mdelay(10);
435         cntrl &= ~PLX_CNTRL_RESET;
436         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
437         mdelay(10);
438 }
439
440 static void db2k_reload_plx(struct comedi_device *dev)
441 {
442         struct db2k_private *devpriv = dev->private;
443         u32 cntrl;
444
445         cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
446         cntrl &= ~PLX_CNTRL_EERELOAD;
447         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
448         mdelay(10);
449         cntrl |= PLX_CNTRL_EERELOAD;
450         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
451         mdelay(10);
452         cntrl &= ~PLX_CNTRL_EERELOAD;
453         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
454         mdelay(10);
455 }
456
457 static void db2k_pulse_prog_pin(struct comedi_device *dev)
458 {
459         struct db2k_private *devpriv = dev->private;
460         u32 cntrl;
461
462         cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
463         cntrl |= PLX_CNTRL_USERO;
464         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
465         mdelay(10);
466         cntrl &= ~PLX_CNTRL_USERO;
467         writel(cntrl, devpriv->plx + PLX_REG_CNTRL);
468         mdelay(10);     /* Not in the original code, but I like symmetry... */
469 }
470
471 static int db2k_wait_cpld_init(struct comedi_device *dev)
472 {
473         int result = -ETIMEDOUT;
474         int i;
475         u16 cpld;
476
477         /* timeout after 50 tries -> 5ms */
478         for (i = 0; i < 50; i++) {
479                 cpld = readw(dev->mmio + DB2K_REG_CPLD_STATUS);
480                 if (cpld & DB2K_CPLD_STATUS_INIT) {
481                         result = 0;
482                         break;
483                 }
484                 usleep_range(100, 1000);
485         }
486         udelay(5);
487         return result;
488 }
489
490 static int db2k_wait_cpld_txready(struct comedi_device *dev)
491 {
492         int i;
493
494         for (i = 0; i < 100; i++) {
495                 if (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
496                     DB2K_CPLD_STATUS_TXREADY) {
497                         return 0;
498                 }
499                 udelay(1);
500         }
501         return -ETIMEDOUT;
502 }
503
504 static int db2k_write_cpld(struct comedi_device *dev, u16 data, bool new_cpld)
505 {
506         int result = 0;
507
508         if (new_cpld) {
509                 result = db2k_wait_cpld_txready(dev);
510                 if (result)
511                         return result;
512         } else {
513                 usleep_range(10, 20);
514         }
515         writew(data, dev->mmio + DB2K_REG_CPLD_WDATA);
516         if (!(readw(dev->mmio + DB2K_REG_CPLD_STATUS) & DB2K_CPLD_STATUS_INIT))
517                 result = -EIO;
518
519         return result;
520 }
521
522 static int db2k_wait_fpga_programmed(struct comedi_device *dev)
523 {
524         struct db2k_private *devpriv = dev->private;
525         int i;
526
527         /* Time out after 200 tries -> 20ms */
528         for (i = 0; i < 200; i++) {
529                 u32 cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
530                 /* General Purpose Input (USERI) set on FPGA "DONE". */
531                 if (cntrl & PLX_CNTRL_USERI)
532                         return 0;
533
534                 usleep_range(100, 1000);
535         }
536         return -ETIMEDOUT;
537 }
538
539 static int db2k_load_firmware(struct comedi_device *dev, const u8 *cpld_array,
540                               size_t len, unsigned long context)
541 {
542         struct db2k_private *devpriv = dev->private;
543         int result = -EIO;
544         u32 cntrl;
545         int retry;
546         size_t i;
547         bool new_cpld;
548
549         /* Look for FPGA start sequence in firmware. */
550         for (i = 0; i + 1 < len; i++) {
551                 if (cpld_array[i] == 0xff && cpld_array[i + 1] == 0x20)
552                         break;
553         }
554         if (i + 1 >= len) {
555                 dev_err(dev->class_dev, "bad firmware - no start sequence\n");
556                 return -EINVAL;
557         }
558         /* Check length is even. */
559         if ((len - i) & 1) {
560                 dev_err(dev->class_dev,
561                         "bad firmware - odd length (%zu = %zu - %zu)\n",
562                         len - i, len, i);
563                 return -EINVAL;
564         }
565         /* Strip firmware header. */
566         cpld_array += i;
567         len -= i;
568
569         /* Check to make sure the serial eeprom is present on the board */
570         cntrl = readl(devpriv->plx + PLX_REG_CNTRL);
571         if (!(cntrl & PLX_CNTRL_EEPRESENT))
572                 return -EIO;
573
574         for (retry = 0; retry < 3; retry++) {
575                 db2k_reset_local_bus(dev);
576                 db2k_reload_plx(dev);
577                 db2k_pulse_prog_pin(dev);
578                 result = db2k_wait_cpld_init(dev);
579                 if (result)
580                         continue;
581
582                 new_cpld = (readw(dev->mmio + DB2K_REG_CPLD_STATUS) &
583                             DB2K_CPLD_VERSION_MASK) == DB2K_CPLD_VERSION_NEW;
584                 for (; i < len; i += 2) {
585                         u16 data = (cpld_array[i] << 8) + cpld_array[i + 1];
586
587                         result = db2k_write_cpld(dev, data, new_cpld);
588                         if (result)
589                                 break;
590                 }
591                 if (result == 0)
592                         result = db2k_wait_fpga_programmed(dev);
593                 if (result == 0) {
594                         db2k_reset_local_bus(dev);
595                         db2k_reload_plx(dev);
596                         break;
597                 }
598         }
599         return result;
600 }
601
602 static void db2k_adc_stop_dma_transfer(struct comedi_device *dev)
603 {
604 }
605
606 static void db2k_adc_disarm(struct comedi_device *dev)
607 {
608         /* Disable hardware triggers */
609         udelay(2);
610         writew(DB2K_TRIG_CONTROL_TYPE_ANALOG | DB2K_TRIG_CONTROL_DISABLE,
611                dev->mmio + DB2K_REG_TRIG_CONTROL);
612         udelay(2);
613         writew(DB2K_TRIG_CONTROL_TYPE_TTL | DB2K_TRIG_CONTROL_DISABLE,
614                dev->mmio + DB2K_REG_TRIG_CONTROL);
615
616         /* Stop the scan list FIFO from loading the configuration pipe */
617         udelay(2);
618         writew(DB2K_ACQ_CONTROL_SEQ_STOP_SCAN_LIST,
619                dev->mmio + DB2K_REG_ACQ_CONTROL);
620
621         /* Stop the pacer clock */
622         udelay(2);
623         writew(DB2K_ACQ_CONTROL_ADC_PACER_DISABLE,
624                dev->mmio + DB2K_REG_ACQ_CONTROL);
625
626         /* Stop the input dma (abort channel 1) */
627         db2k_adc_stop_dma_transfer(dev);
628 }
629
630 static void db2k_activate_reference_dacs(struct comedi_device *dev)
631 {
632         unsigned int val;
633         int timeout;
634
635         /*  Set the + reference dac value in the FPGA */
636         writew(DB2K_REF_DACS_SET | DB2K_REF_DACS_SELECT_POS_REF,
637                dev->mmio + DB2K_REG_REF_DACS);
638         for (timeout = 0; timeout < 20; timeout++) {
639                 val = readw(dev->mmio + DB2K_REG_DAC_STATUS);
640                 if ((val & DB2K_DAC_STATUS_REF_BUSY) == 0)
641                         break;
642                 udelay(2);
643         }
644
645         /*  Set the - reference dac value in the FPGA */
646         writew(DB2K_REF_DACS_SET | DB2K_REF_DACS_SELECT_NEG_REF,
647                dev->mmio + DB2K_REG_REF_DACS);
648         for (timeout = 0; timeout < 20; timeout++) {
649                 val = readw(dev->mmio + DB2K_REG_DAC_STATUS);
650                 if ((val & DB2K_DAC_STATUS_REF_BUSY) == 0)
651                         break;
652                 udelay(2);
653         }
654 }
655
656 static void db2k_initialize_ctrs(struct comedi_device *dev)
657 {
658 }
659
660 static void db2k_initialize_tmrs(struct comedi_device *dev)
661 {
662 }
663
664 static void db2k_dac_disarm(struct comedi_device *dev)
665 {
666 }
667
668 static void db2k_initialize_adc(struct comedi_device *dev)
669 {
670         db2k_adc_disarm(dev);
671         db2k_activate_reference_dacs(dev);
672         db2k_initialize_ctrs(dev);
673         db2k_initialize_tmrs(dev);
674 }
675
676 static void db2k_initialize_dac(struct comedi_device *dev)
677 {
678         db2k_dac_disarm(dev);
679 }
680
681 static int db2k_8255_cb(struct comedi_device *dev, int dir, int port, int data,
682                         unsigned long iobase)
683 {
684         if (dir) {
685                 writew(data, dev->mmio + iobase + port * 2);
686                 return 0;
687         }
688         return readw(dev->mmio + iobase + port * 2);
689 }
690
691 static const void *db2k_find_boardinfo(struct comedi_device *dev,
692                                        struct pci_dev *pcidev)
693 {
694         const struct db2k_boardtype *board;
695         int i;
696
697         if (pcidev->subsystem_vendor != PCI_VENDOR_ID_IOTECH)
698                 return NULL;
699
700         for (i = 0; i < ARRAY_SIZE(db2k_boardtypes); i++) {
701                 board = &db2k_boardtypes[i];
702                 if (pcidev->subsystem_device == board->id)
703                         return board;
704         }
705         return NULL;
706 }
707
708 static int db2k_auto_attach(struct comedi_device *dev,
709                             unsigned long context_unused)
710 {
711         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
712         const struct db2k_boardtype *board;
713         struct db2k_private *devpriv;
714         struct comedi_subdevice *s;
715         int result;
716
717         board = db2k_find_boardinfo(dev, pcidev);
718         if (!board)
719                 return -ENODEV;
720         dev->board_ptr = board;
721         dev->board_name = board->name;
722
723         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
724         if (!devpriv)
725                 return -ENOMEM;
726
727         result = comedi_pci_enable(dev);
728         if (result)
729                 return result;
730
731         devpriv->plx = pci_ioremap_bar(pcidev, 0);
732         dev->mmio = pci_ioremap_bar(pcidev, 2);
733         if (!devpriv->plx || !dev->mmio)
734                 return -ENOMEM;
735
736         result = comedi_alloc_subdevices(dev, 3);
737         if (result)
738                 return result;
739
740         result = comedi_load_firmware(dev, &comedi_to_pci_dev(dev)->dev,
741                                       DB2K_FIRMWARE, db2k_load_firmware, 0);
742         if (result < 0)
743                 return result;
744
745         db2k_initialize_adc(dev);
746         db2k_initialize_dac(dev);
747
748         s = &dev->subdevices[0];
749         /* ai subdevice */
750         s->type = COMEDI_SUBD_AI;
751         s->subdev_flags = SDF_READABLE | SDF_GROUND;
752         s->n_chan = 24;
753         s->maxdata = 0xffff;
754         s->insn_read = db2k_ai_insn_read;
755         s->range_table = &db2k_ai_range;
756
757         s = &dev->subdevices[1];
758         /* ao subdevice */
759         s->type = COMEDI_SUBD_AO;
760         s->subdev_flags = SDF_WRITABLE;
761         s->n_chan = 2;
762         s->maxdata = 0xffff;
763         s->insn_write = db2k_ao_insn_write;
764         s->range_table = &range_bipolar10;
765
766         result = comedi_alloc_subdev_readback(s);
767         if (result)
768                 return result;
769
770         s = &dev->subdevices[2];
771         return subdev_8255_init(dev, s, db2k_8255_cb,
772                                 DB2K_REG_DIO_P2_EXP_IO_8_BIT);
773 }
774
775 static void db2k_detach(struct comedi_device *dev)
776 {
777         struct db2k_private *devpriv = dev->private;
778
779         if (devpriv && devpriv->plx)
780                 iounmap(devpriv->plx);
781         comedi_pci_detach(dev);
782 }
783
784 static struct comedi_driver db2k_driver = {
785         .driver_name    = "daqboard2000",
786         .module         = THIS_MODULE,
787         .auto_attach    = db2k_auto_attach,
788         .detach         = db2k_detach,
789 };
790
791 static int db2k_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
792 {
793         return comedi_pci_auto_config(dev, &db2k_driver, id->driver_data);
794 }
795
796 static const struct pci_device_id db2k_pci_table[] = {
797         { PCI_DEVICE(PCI_VENDOR_ID_IOTECH, 0x0409) },
798         { 0 }
799 };
800 MODULE_DEVICE_TABLE(pci, db2k_pci_table);
801
802 static struct pci_driver db2k_pci_driver = {
803         .name           = "daqboard2000",
804         .id_table       = db2k_pci_table,
805         .probe          = db2k_pci_probe,
806         .remove         = comedi_pci_auto_unconfig,
807 };
808 module_comedi_pci_driver(db2k_driver, db2k_pci_driver);
809
810 MODULE_AUTHOR("Comedi http://www.comedi.org");
811 MODULE_DESCRIPTION("Comedi low-level driver");
812 MODULE_LICENSE("GPL");
813 MODULE_FIRMWARE(DB2K_FIRMWARE);