Merge tag 'cleanup-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[cascardo/linux.git] / drivers / staging / comedi / drivers / ni_mio_cs.c
1 /*
2     comedi/drivers/ni_mio_cs.c
3     Hardware driver for NI PCMCIA MIO E series cards
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 1997-2000 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_mio_cs
20 Description: National Instruments DAQCard E series
21 Author: ds
22 Status: works
23 Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
24   DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
25 Updated: Thu Oct 23 19:43:17 CDT 2003
26
27 See the notes in the ni_atmio.o driver.
28 */
29 /*
30         The real guts of the driver is in ni_mio_common.c, which is
31         included by all the E series drivers.
32
33         References for specifications:
34
35            341080a.pdf  DAQCard E Series Register Level Programmer Manual
36
37 */
38
39 #include <linux/module.h>
40 #include "../comedidev.h"
41
42 #include <linux/delay.h>
43
44 #include "ni_stc.h"
45 #include "8255.h"
46
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/ds.h>
49
50 /*
51  *  AT specific setup
52  */
53
54 static const struct ni_board_struct ni_boards[] = {
55         {
56                 .name           = "DAQCard-ai-16xe-50",
57                 .device_id      = 0x010d,
58                 .n_adchan       = 16,
59                 .ai_maxdata     = 0xffff,
60                 .ai_fifo_depth  = 1024,
61                 .gainlkup       = ai_gain_8,
62                 .ai_speed       = 5000,
63                 .caldac         = { dac8800, dac8043 },
64         }, {
65                 .name           = "DAQCard-ai-16e-4",
66                 .device_id      = 0x010c,
67                 .n_adchan       = 16,
68                 .ai_maxdata     = 0x0fff,
69                 .ai_fifo_depth  = 1024,
70                 .gainlkup       = ai_gain_16,
71                 .ai_speed       = 4000,
72                 .caldac         = { mb88341 },          /* verified */
73         }, {
74                 .name           = "DAQCard-6062E",
75                 .device_id      = 0x02c4,
76                 .n_adchan       = 16,
77                 .ai_maxdata     = 0x0fff,
78                 .ai_fifo_depth  = 8192,
79                 .gainlkup       = ai_gain_16,
80                 .ai_speed       = 2000,
81                 .n_aochan       = 2,
82                 .ao_maxdata     = 0x0fff,
83                 .ao_fifo_depth  = 2048,
84                 .ao_range_table = &range_bipolar10,
85                 .ao_speed       = 1176,
86                 .caldac         = { ad8804_debug },     /* verified */
87          }, {
88                 /* specs incorrect! */
89                 .name           = "DAQCard-6024E",
90                 .device_id      = 0x075e,
91                 .n_adchan       = 16,
92                 .ai_maxdata     = 0x0fff,
93                 .ai_fifo_depth  = 1024,
94                 .gainlkup       = ai_gain_4,
95                 .ai_speed       = 5000,
96                 .n_aochan       = 2,
97                 .ao_maxdata     = 0x0fff,
98                 .ao_range_table = &range_bipolar10,
99                 .ao_speed       = 1000000,
100                 .caldac         = { ad8804_debug },
101         }, {
102                 /* specs incorrect! */
103                 .name           = "DAQCard-6036E",
104                 .device_id      = 0x0245,
105                 .n_adchan       = 16,
106                 .ai_maxdata     = 0xffff,
107                 .ai_fifo_depth  = 1024,
108                 .alwaysdither   = 1,
109                 .gainlkup       = ai_gain_4,
110                 .ai_speed       = 5000,
111                 .n_aochan       = 2,
112                 .ao_maxdata     = 0xffff,
113                 .ao_range_table = &range_bipolar10,
114                 .ao_speed       = 1000000,
115                 .caldac         = { ad8804_debug },
116          },
117 #if 0
118         {
119                 .name           = "DAQCard-6715",
120                 .device_id      = 0x0000,       /* unknown */
121                 .n_aochan       = 8,
122                 .ao_maxdata     = 0x0fff,
123                 .ao_671x        = 8192,
124                 .caldac         = { mb88341, mb88341 },
125         },
126 #endif
127 };
128
129 #include "ni_mio_common.c"
130
131 static const void *ni_getboardtype(struct comedi_device *dev,
132                                    struct pcmcia_device *link)
133 {
134         static const struct ni_board_struct *board;
135         int i;
136
137         for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
138                 board = &ni_boards[i];
139                 if (board->device_id == link->card_id)
140                         return board;
141         }
142         return NULL;
143 }
144
145 static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
146 {
147         int base, ret;
148
149         p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
150         p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
151
152         for (base = 0x000; base < 0x400; base += 0x20) {
153                 p_dev->resource[0]->start = base;
154                 ret = pcmcia_request_io(p_dev);
155                 if (!ret)
156                         return 0;
157         }
158         return -ENODEV;
159 }
160
161 static int mio_cs_auto_attach(struct comedi_device *dev,
162                               unsigned long context)
163 {
164         struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
165         static const struct ni_board_struct *board;
166         struct ni_private *devpriv;
167         int ret;
168
169         board = ni_getboardtype(dev, link);
170         if (!board)
171                 return -ENODEV;
172         dev->board_ptr = board;
173         dev->board_name = board->name;
174
175         link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
176         ret = comedi_pcmcia_enable(dev, mio_pcmcia_config_loop);
177         if (ret)
178                 return ret;
179         dev->iobase = link->resource[0]->start;
180
181         link->priv = dev;
182         ret = pcmcia_request_irq(link, ni_E_interrupt);
183         if (ret)
184                 return ret;
185         dev->irq = link->irq;
186
187         ret = ni_alloc_private(dev);
188         if (ret)
189                 return ret;
190
191         devpriv = dev->private;
192
193         return ni_E_init(dev, 0, 1);
194 }
195
196 static void mio_cs_detach(struct comedi_device *dev)
197 {
198         mio_common_detach(dev);
199         comedi_pcmcia_disable(dev);
200 }
201
202 static struct comedi_driver driver_ni_mio_cs = {
203         .driver_name    = "ni_mio_cs",
204         .module         = THIS_MODULE,
205         .auto_attach    = mio_cs_auto_attach,
206         .detach         = mio_cs_detach,
207 };
208
209 static int cs_attach(struct pcmcia_device *link)
210 {
211         return comedi_pcmcia_auto_config(link, &driver_ni_mio_cs);
212 }
213
214 static const struct pcmcia_device_id ni_mio_cs_ids[] = {
215         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d),        /* DAQCard-ai-16xe-50 */
216         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c),        /* DAQCard-ai-16e-4 */
217         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4),        /* DAQCard-6062E */
218         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e),        /* DAQCard-6024E */
219         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245),        /* DAQCard-6036E */
220         PCMCIA_DEVICE_NULL
221 };
222 MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
223
224 static struct pcmcia_driver ni_mio_cs_driver = {
225         .name           = "ni_mio_cs",
226         .owner          = THIS_MODULE,
227         .id_table       = ni_mio_cs_ids,
228         .probe          = cs_attach,
229         .remove         = comedi_pcmcia_auto_unconfig,
230 };
231 module_comedi_pcmcia_driver(driver_ni_mio_cs, ni_mio_cs_driver);
232
233 MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series");
234 MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
235 MODULE_LICENSE("GPL");