Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / comedi / drivers / rti802.c
1 /*
2  * rti802.c
3  * Comedi driver for Analog Devices RTI-802 board
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 /*
20  * Driver: rti802
21  * Description: Analog Devices RTI-802
22  * Author: Anders Blomdell <anders.blomdell@control.lth.se>
23  * Devices: [Analog Devices] RTI-802 (rti802)
24  * Status: works
25  *
26  * Configuration Options:
27  *   [0] - i/o base
28  *   [1] - unused
29  *   [2,4,6,8,10,12,14,16] - dac#[0-7]  0=two's comp, 1=straight
30  *   [3,5,7,9,11,13,15,17] - dac#[0-7]  0=bipolar, 1=unipolar
31  */
32
33 #include <linux/module.h>
34 #include "../comedidev.h"
35
36 /*
37  * Register I/O map
38  */
39 #define RTI802_SELECT           0x00
40 #define RTI802_DATALOW          0x01
41 #define RTI802_DATAHIGH         0x02
42
43 struct rti802_private {
44         enum {
45                 dac_2comp, dac_straight
46         } dac_coding[8];
47         const struct comedi_lrange *range_type_list[8];
48 };
49
50 static int rti802_ao_insn_write(struct comedi_device *dev,
51                                 struct comedi_subdevice *s,
52                                 struct comedi_insn *insn,
53                                 unsigned int *data)
54 {
55         struct rti802_private *devpriv = dev->private;
56         unsigned int chan = CR_CHAN(insn->chanspec);
57         int i;
58
59         outb(chan, dev->iobase + RTI802_SELECT);
60
61         for (i = 0; i < insn->n; i++) {
62                 unsigned int val = data[i];
63
64                 s->readback[chan] = val;
65
66                 /* munge offset binary to two's complement if needed */
67                 if (devpriv->dac_coding[chan] == dac_2comp)
68                         val = comedi_offset_munge(s, val);
69
70                 outb(val & 0xff, dev->iobase + RTI802_DATALOW);
71                 outb((val >> 8) & 0xff, dev->iobase + RTI802_DATAHIGH);
72         }
73
74         return insn->n;
75 }
76
77 static int rti802_attach(struct comedi_device *dev, struct comedi_devconfig *it)
78 {
79         struct rti802_private *devpriv;
80         struct comedi_subdevice *s;
81         int i;
82         int ret;
83
84         ret = comedi_request_region(dev, it->options[0], 0x04);
85         if (ret)
86                 return ret;
87
88         devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
89         if (!devpriv)
90                 return -ENOMEM;
91
92         ret = comedi_alloc_subdevices(dev, 1);
93         if (ret)
94                 return ret;
95
96         /* Analog Output subdevice */
97         s = &dev->subdevices[0];
98         s->type         = COMEDI_SUBD_AO;
99         s->subdev_flags = SDF_WRITABLE;
100         s->maxdata      = 0xfff;
101         s->n_chan       = 8;
102         s->insn_write   = rti802_ao_insn_write;
103
104         ret = comedi_alloc_subdev_readback(s);
105         if (ret)
106                 return ret;
107
108         s->range_table_list = devpriv->range_type_list;
109         for (i = 0; i < 8; i++) {
110                 devpriv->dac_coding[i] = (it->options[3 + 2 * i])
111                         ? (dac_straight) : (dac_2comp);
112                 devpriv->range_type_list[i] = (it->options[2 + 2 * i])
113                         ? &range_unipolar10 : &range_bipolar10;
114         }
115
116         return 0;
117 }
118
119 static struct comedi_driver rti802_driver = {
120         .driver_name    = "rti802",
121         .module         = THIS_MODULE,
122         .attach         = rti802_attach,
123         .detach         = comedi_legacy_detach,
124 };
125 module_comedi_driver(rti802_driver);
126
127 MODULE_AUTHOR("Comedi http://www.comedi.org");
128 MODULE_DESCRIPTION("Comedi driver for Analog Devices RTI-802 board");
129 MODULE_LICENSE("GPL");