staging: comedi: ni_at_ao: move the boardinfo declaration
[firefly-linux-kernel-4.4.55.git] / drivers / staging / comedi / drivers / ni_at_ao.c
1 /*
2     comedi/drivers/ni_at_ao.c
3     Driver for NI AT-AO-6/10 boards
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 2000,2002 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 Driver: ni_at_ao
20 Description: National Instruments AT-AO-6/10
21 Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
22 Status: should work
23 Author: ds
24 Updated: Sun Dec 26 12:26:28 EST 2004
25
26 Configuration options:
27   [0] - I/O port base address
28   [1] - IRQ (unused)
29   [2] - DMA (unused)
30   [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V
31         bipolar, 1 for 0V to 10V unipolar)
32
33 */
34 /*
35  * Register-level programming information can be found in NI
36  * document 320379.pdf.
37  */
38
39 #include <linux/module.h>
40
41 #include "../comedidev.h"
42
43 #include "8253.h"
44
45 /*
46  * Register map
47  */
48 #define ATAO_DIO_REG            0x00
49 #define ATAO_CFG2_REG           0x02
50 #define ATAO_CFG2_CALLD_NOP     (0 << 14)
51 #define ATAO_CFG2_CALLD(x)      ((((x) >> 3) + 1) << 14)
52 #define ATAO_CFG2_FFRTEN        (1 << 13)
53 #define ATAO_CFG2_DACS(x)       (1 << (((x) / 2) + 8))
54 #define ATAO_CFG2_LDAC(x)       (1 << (((x) / 2) + 3))
55 #define ATAO_CFG2_PROMEN        (1 << 2)
56 #define ATAO_CFG2_SCLK          (1 << 1)
57 #define ATAO_CFG2_SDATA         (1 << 0)
58 #define ATAO_CFG3_REG           0x04
59 #define ATAO_CFG3_DMAMODE       (1 << 6)
60 #define ATAO_CFG3_CLKOUT        (1 << 5)
61 #define ATAO_CFG3_RCLKEN        (1 << 4)
62 #define ATAO_CFG3_DOUTEN2       (1 << 3)
63 #define ATAO_CFG3_DOUTEN1       (1 << 2)
64 #define ATAO_CFG3_EN2_5V        (1 << 1)
65 #define ATAO_CFG3_SCANEN        (1 << 0)
66 #define ATAO_82C53_BASE         0x06
67 #define ATAO_CFG1_REG           0x0a
68 #define ATAO_CFG1_EXTINT2EN     (1 << 15)
69 #define ATAO_CFG1_EXTINT1EN     (1 << 14)
70 #define ATAO_CFG1_CNTINT2EN     (1 << 13)
71 #define ATAO_CFG1_CNTINT1EN     (1 << 12)
72 #define ATAO_CFG1_TCINTEN       (1 << 11)
73 #define ATAO_CFG1_CNT1SRC       (1 << 10)
74 #define ATAO_CFG1_CNT2SRC       (1 << 9)
75 #define ATAO_CFG1_FIFOEN        (1 << 8)
76 #define ATAO_CFG1_GRP2WR        (1 << 7)
77 #define ATAO_CFG1_EXTUPDEN      (1 << 6)
78 #define ATAO_CFG1_DMARQ         (1 << 5)
79 #define ATAO_CFG1_DMAEN         (1 << 4)
80 #define ATAO_CFG1_CH(x)         (((x) & 0xf) << 0)
81 #define ATAO_STATUS_REG         0x0a
82 #define ATAO_STATUS_FH          (1 << 6)
83 #define ATAO_STATUS_FE          (1 << 5)
84 #define ATAO_STATUS_FF          (1 << 4)
85 #define ATAO_STATUS_INT2        (1 << 3)
86 #define ATAO_STATUS_INT1        (1 << 2)
87 #define ATAO_STATUS_TCINT       (1 << 1)
88 #define ATAO_STATUS_PROMOUT     (1 << 0)
89 #define ATAO_FIFO_WRITE_REG     0x0c
90 #define ATAO_FIFO_CLEAR_REG     0x0c
91 #define ATAO_AO_REG(x)          (0x0c + ((x) * 2))
92
93 /* registers with _2_ are accessed when GRP2WR is set in CFG1 */
94 #define ATAO_2_DMATCCLR_REG     0x00
95 #define ATAO_2_INT1CLR_REG      0x02
96 #define ATAO_2_INT2CLR_REG      0x04
97 #define ATAO_2_RTSISHFT_REG     0x06
98 #define ATAO_2_RTSISHFT_RSI     (1 << 0)
99 #define ATAO_2_RTSISTRB_REG     0x07
100
101 struct atao_board {
102         const char *name;
103         int n_ao_chans;
104 };
105
106 static const struct atao_board atao_boards[] = {
107         {
108                 .name           = "ai-ao-6",
109                 .n_ao_chans     = 6,
110         }, {
111                 .name           = "ai-ao-10",
112                 .n_ao_chans     = 10,
113         },
114 };
115
116 struct atao_private {
117         unsigned short cfg1;
118         unsigned short cfg3;
119
120         /* Used for AO readback */
121         unsigned int ao_readback[10];
122
123         /* Used for caldac readback */
124         unsigned char caldac[21];
125 };
126
127 static void atao_reset(struct comedi_device *dev)
128 {
129         struct atao_private *devpriv = dev->private;
130
131         /* This is the reset sequence described in the manual */
132
133         devpriv->cfg1 = 0;
134         outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
135
136         /* Put outputs of counter 1 and counter 2 in a high state */
137         i8254_load(dev->iobase + ATAO_82C53_BASE, 0,
138                    0, 0x0003, I8254_MODE4 | I8254_BINARY);
139         i8254_set_mode(dev->iobase + ATAO_82C53_BASE, 0,
140                    1, I8254_MODE4 | I8254_BINARY);
141
142         outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
143
144         devpriv->cfg3 = 0;
145         outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
146
147         inw(dev->iobase + ATAO_FIFO_CLEAR_REG);
148
149         devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
150         outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
151
152         outw(0, dev->iobase + ATAO_2_INT1CLR_REG);
153         outw(0, dev->iobase + ATAO_2_INT2CLR_REG);
154         outw(0, dev->iobase + ATAO_2_DMATCCLR_REG);
155
156         devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
157         outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
158 }
159
160 static int atao_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
161                          struct comedi_insn *insn, unsigned int *data)
162 {
163         struct atao_private *devpriv = dev->private;
164         int i;
165         int chan = CR_CHAN(insn->chanspec);
166         short bits;
167
168         for (i = 0; i < insn->n; i++) {
169                 bits = data[i] - 0x800;
170                 if (chan == 0) {
171                         devpriv->cfg1 |= ATAO_CFG1_GRP2WR;
172                         outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
173                 }
174                 outw(bits, dev->iobase + ATAO_AO_REG(chan));
175                 if (chan == 0) {
176                         devpriv->cfg1 &= ~ATAO_CFG1_GRP2WR;
177                         outw(devpriv->cfg1, dev->iobase + ATAO_CFG1_REG);
178                 }
179                 devpriv->ao_readback[chan] = data[i];
180         }
181
182         return i;
183 }
184
185 static int atao_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
186                          struct comedi_insn *insn, unsigned int *data)
187 {
188         struct atao_private *devpriv = dev->private;
189         int i;
190         int chan = CR_CHAN(insn->chanspec);
191
192         for (i = 0; i < insn->n; i++)
193                 data[i] = devpriv->ao_readback[chan];
194
195         return i;
196 }
197
198 static int atao_dio_insn_bits(struct comedi_device *dev,
199                               struct comedi_subdevice *s,
200                               struct comedi_insn *insn,
201                               unsigned int *data)
202 {
203         if (comedi_dio_update_state(s, data))
204                 outw(s->state, dev->iobase + ATAO_DIO_REG);
205
206         data[1] = inw(dev->iobase + ATAO_DIO_REG);
207
208         return insn->n;
209 }
210
211 static int atao_dio_insn_config(struct comedi_device *dev,
212                                 struct comedi_subdevice *s,
213                                 struct comedi_insn *insn,
214                                 unsigned int *data)
215 {
216         struct atao_private *devpriv = dev->private;
217         unsigned int chan = CR_CHAN(insn->chanspec);
218         unsigned int mask;
219         int ret;
220
221         if (chan < 4)
222                 mask = 0x0f;
223         else
224                 mask = 0xf0;
225
226         ret = comedi_dio_insn_config(dev, s, insn, data, mask);
227         if (ret)
228                 return ret;
229
230         if (s->io_bits & 0x0f)
231                 devpriv->cfg3 |= ATAO_CFG3_DOUTEN1;
232         else
233                 devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN1;
234         if (s->io_bits & 0xf0)
235                 devpriv->cfg3 |= ATAO_CFG3_DOUTEN2;
236         else
237                 devpriv->cfg3 &= ~ATAO_CFG3_DOUTEN2;
238
239         outw(devpriv->cfg3, dev->iobase + ATAO_CFG3_REG);
240
241         return insn->n;
242 }
243
244 /*
245  * There are three DAC8800 TrimDACs on the board. These are 8-channel,
246  * 8-bit DACs that are used to calibrate the Analog Output channels.
247  * The factory default calibration values are stored in the EEPROM.
248  * The TrimDACs, and EEPROM addresses, are mapped as:
249  *
250  *        Channel       EEPROM  Description
251  *   -----------------  ------  -----------------------------------
252  *    0 - DAC0 Chan 0    0x30   AO Channel 0 Offset
253  *    1 - DAC0 Chan 1    0x31   AO Channel 0 Gain
254  *    2 - DAC0 Chan 2    0x32   AO Channel 1 Offset
255  *    3 - DAC0 Chan 3    0x33   AO Channel 1 Gain
256  *    4 - DAC0 Chan 4    0x34   AO Channel 2 Offset
257  *    5 - DAC0 Chan 5    0x35   AO Channel 2 Gain
258  *    6 - DAC0 Chan 6    0x36   AO Channel 3 Offset
259  *    7 - DAC0 Chan 7    0x37   AO Channel 3 Gain
260  *    8 - DAC1 Chan 0    0x38   AO Channel 4 Offset
261  *    9 - DAC1 Chan 1    0x39   AO Channel 4 Gain
262  *   10 - DAC1 Chan 2    0x3a   AO Channel 5 Offset
263  *   11 - DAC1 Chan 3    0x3b   AO Channel 5 Gain
264  *   12 - DAC1 Chan 4    0x3c   2.5V Offset
265  *   13 - DAC1 Chan 5    0x3d   AO Channel 6 Offset (at-ao-10 only)
266  *   14 - DAC1 Chan 6    0x3e   AO Channel 6 Gain   (at-ao-10 only)
267  *   15 - DAC1 Chan 7    0x3f   AO Channel 7 Offset (at-ao-10 only)
268  *   16 - DAC2 Chan 0    0x40   AO Channel 7 Gain   (at-ao-10 only)
269  *   17 - DAC2 Chan 1    0x41   AO Channel 8 Offset (at-ao-10 only)
270  *   18 - DAC2 Chan 2    0x42   AO Channel 8 Gain   (at-ao-10 only)
271  *   19 - DAC2 Chan 3    0x43   AO Channel 9 Offset (at-ao-10 only)
272  *   20 - DAC2 Chan 4    0x44   AO Channel 9 Gain   (at-ao-10 only)
273  *        DAC2 Chan 5    0x45   Reserved
274  *        DAC2 Chan 6    0x46   Reserved
275  *        DAC2 Chan 7    0x47   Reserved
276  */
277 static int atao_calib_insn_write(struct comedi_device *dev,
278                                  struct comedi_subdevice *s,
279                                  struct comedi_insn *insn,
280                                  unsigned int *data)
281 {
282         struct atao_private *devpriv = dev->private;
283         unsigned int chan = CR_CHAN(insn->chanspec);
284         unsigned int bitstring;
285         unsigned int val;
286         int bit;
287
288         if (insn->n == 0)
289                 return 0;
290
291         devpriv->caldac[chan] = data[insn->n - 1] & s->maxdata;
292
293         /* write the channel and last data value to the caldac */
294         bitstring = ((chan & 0x7) << 8) | devpriv->caldac[chan];
295
296         /* clock the bitstring to the caldac; MSB -> LSB */
297         for (bit = 1 << 10; bit; bit >>= 1) {
298                 val = (bit & bitstring) ? ATAO_CFG2_SDATA : 0;
299
300                 outw(val, dev->iobase + ATAO_CFG2_REG);
301                 outw(val | ATAO_CFG2_SCLK, dev->iobase + ATAO_CFG2_REG);
302         }
303
304         /* strobe the caldac to load the value */
305         outw(ATAO_CFG2_CALLD(chan), dev->iobase + ATAO_CFG2_REG);
306         outw(ATAO_CFG2_CALLD_NOP, dev->iobase + ATAO_CFG2_REG);
307
308         return insn->n;
309 }
310
311 static int atao_calib_insn_read(struct comedi_device *dev,
312                                 struct comedi_subdevice *s,
313                                 struct comedi_insn *insn,
314                                 unsigned int *data)
315 {
316         struct atao_private *devpriv = dev->private;
317         unsigned int chan = CR_CHAN(insn->chanspec);
318         int i;
319
320         for (i = 0; i < insn->n; i++)
321                 data[i] = devpriv->caldac[chan];
322
323         return insn->n;
324 }
325
326 static int atao_attach(struct comedi_device *dev, struct comedi_devconfig *it)
327 {
328         const struct atao_board *board = comedi_board(dev);
329         struct atao_private *devpriv;
330         struct comedi_subdevice *s;
331         int ao_unipolar;
332         int ret;
333
334         ao_unipolar = it->options[3];
335
336         ret = comedi_request_region(dev, it->options[0], 0x20);
337         if (ret)
338                 return ret;
339
340         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
341         if (!devpriv)
342                 return -ENOMEM;
343
344         ret = comedi_alloc_subdevices(dev, 4);
345         if (ret)
346                 return ret;
347
348         s = &dev->subdevices[0];
349         /* analog output subdevice */
350         s->type = COMEDI_SUBD_AO;
351         s->subdev_flags = SDF_WRITABLE;
352         s->n_chan = board->n_ao_chans;
353         s->maxdata = (1 << 12) - 1;
354         if (ao_unipolar)
355                 s->range_table = &range_unipolar10;
356         else
357                 s->range_table = &range_bipolar10;
358         s->insn_write = &atao_ao_winsn;
359         s->insn_read = &atao_ao_rinsn;
360
361         s = &dev->subdevices[1];
362         /* digital i/o subdevice */
363         s->type = COMEDI_SUBD_DIO;
364         s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
365         s->n_chan = 8;
366         s->maxdata = 1;
367         s->range_table = &range_digital;
368         s->insn_bits = atao_dio_insn_bits;
369         s->insn_config = atao_dio_insn_config;
370
371         /* caldac subdevice */
372         s = &dev->subdevices[2];
373         s->type         = COMEDI_SUBD_CALIB;
374         s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
375         s->n_chan       = (board->n_ao_chans * 2) + 1;
376         s->maxdata      = 0xff;
377         s->insn_read    = atao_calib_insn_read;
378         s->insn_write   = atao_calib_insn_write;
379
380         s = &dev->subdevices[3];
381         /* eeprom subdevice */
382         /* s->type=COMEDI_SUBD_EEPROM; */
383         s->type = COMEDI_SUBD_UNUSED;
384
385         atao_reset(dev);
386
387         printk(KERN_INFO "\n");
388
389         return 0;
390 }
391
392 static struct comedi_driver ni_at_ao_driver = {
393         .driver_name    = "ni_at_ao",
394         .module         = THIS_MODULE,
395         .attach         = atao_attach,
396         .detach         = comedi_legacy_detach,
397         .board_name     = &atao_boards[0].name,
398         .offset         = sizeof(struct atao_board),
399         .num_names      = ARRAY_SIZE(atao_boards),
400 };
401 module_comedi_driver(ni_at_ao_driver);
402
403 MODULE_AUTHOR("Comedi http://www.comedi.org");
404 MODULE_DESCRIPTION("Comedi low-level driver");
405 MODULE_LICENSE("GPL");