staging: comedi: ni_mio_common: remove devpriv macro
[deliverable/linux.git] / drivers / staging / comedi / drivers / ni_labpc_cs.c
CommitLineData
124b13b2
FMH
1/*
2 comedi/drivers/ni_labpc_cs.c
3 Driver for National Instruments daqcard-1200 boards
4 Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
5
6 PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
7 from the pcmcia package.
8 The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
9 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 are Copyright (C) 1999 David A. Hinds.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26************************************************************************
27*/
28/*
29Driver: ni_labpc_cs
30Description: National Instruments Lab-PC (& compatibles)
31Author: Frank Mori Hess <fmhess@users.sourceforge.net>
32Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
33Status: works
34
35Thanks go to Fredrik Lingvall for much testing and perseverance in
36helping to debug daqcard-1200 support.
37
38The 1200 series boards have onboard calibration dacs for correcting
39analog input/output offsets and gains. The proper settings for these
40caldacs are stored on the board's eeprom. To read the caldac values
41from the eeprom and store them into a file that can be then be used by
42comedilib, use the comedi_calibrate program.
43
44Configuration options:
45 none
46
47The daqcard-1200 has quirky chanlist requirements
48when scanning multiple channels. Multiple channel scan
49sequence must start at highest channel, then decrement down to
50channel 0. Chanlists consisting of all one channel
51are also legal, and allow you to pace conversions in bursts.
52
53*/
54
55/*
56
57NI manuals:
58340988a (daqcard-1200)
59
60*/
61
b79eb4c1 62#undef LABPC_DEBUG /* debugging messages */
124b13b2
FMH
63
64#include "../comedidev.h"
65
66#include <linux/delay.h>
5a0e3ad6 67#include <linux/slab.h>
124b13b2
FMH
68
69#include "8253.h"
70#include "8255.h"
71#include "comedi_fc.h"
72#include "ni_labpc.h"
73
124b13b2
FMH
74#include <pcmcia/cistpl.h>
75#include <pcmcia/cisreg.h>
76#include <pcmcia/ds.h>
77
96233181 78static struct pcmcia_device *pcmcia_cur_dev;
124b13b2 79
da91b269 80static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
124b13b2 81
9ad00740 82static const struct labpc_board_struct labpc_cs_boards[] = {
124b13b2 83 {
0a85b6f0 84 .name = "daqcard-1200",
63a4eca5
BM
85 .device_id = 0x103, /* 0x10b is manufacturer id,
86 0x103 is device id */
0a85b6f0
MT
87 .ai_speed = 10000,
88 .bustype = pcmcia_bustype,
89 .register_layout = labpc_1200_layout,
90 .has_ao = 1,
91 .ai_range_table = &range_labpc_1200_ai,
92 .ai_range_code = labpc_1200_ai_gain_bits,
93 .ai_range_is_unipolar = labpc_1200_is_unipolar,
94 .ai_scan_up = 0,
95 .memory_mapped_io = 0,
96 },
124b13b2
FMH
97 /* duplicate entry, to support using alternate name */
98 {
0a85b6f0
MT
99 .name = "ni_labpc_cs",
100 .device_id = 0x103,
101 .ai_speed = 10000,
102 .bustype = pcmcia_bustype,
103 .register_layout = labpc_1200_layout,
104 .has_ao = 1,
105 .ai_range_table = &range_labpc_1200_ai,
106 .ai_range_code = labpc_1200_ai_gain_bits,
107 .ai_range_is_unipolar = labpc_1200_is_unipolar,
108 .ai_scan_up = 0,
109 .memory_mapped_io = 0,
110 },
124b13b2
FMH
111};
112
113/*
114 * Useful for shorthand access to the particular board structure
115 */
9ad00740 116#define thisboard ((const struct labpc_board_struct *)dev->board_ptr)
124b13b2 117
139dfbdf 118static struct comedi_driver driver_labpc_cs = {
124b13b2
FMH
119 .driver_name = "ni_labpc_cs",
120 .module = THIS_MODULE,
121 .attach = &labpc_attach,
122 .detach = &labpc_common_detach,
8629efa4 123 .num_names = ARRAY_SIZE(labpc_cs_boards),
124b13b2 124 .board_name = &labpc_cs_boards[0].name,
9ad00740 125 .offset = sizeof(struct labpc_board_struct),
124b13b2
FMH
126};
127
da91b269 128static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
124b13b2
FMH
129{
130 unsigned long iobase = 0;
131 unsigned int irq = 0;
132 struct pcmcia_device *link;
133
134 /* allocate and initialize dev->private */
0a4eb4b6 135 if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
124b13b2
FMH
136 return -ENOMEM;
137
2696fb57 138 /* get base address, irq etc. based on bustype */
124b13b2
FMH
139 switch (thisboard->bustype) {
140 case pcmcia_bustype:
141 link = pcmcia_cur_dev; /* XXX hack */
142 if (!link)
143 return -EIO;
9a017a91 144 iobase = link->resource[0]->start;
eb14120f 145 irq = link->irq;
124b13b2
FMH
146 break;
147 default:
327ffc0c 148 pr_err("bug! couldn't determine board type\n");
124b13b2
FMH
149 return -EINVAL;
150 break;
151 }
152 return labpc_common_attach(dev, iobase, irq, 0);
153}
154
124b13b2
FMH
155static void labpc_config(struct pcmcia_device *link);
156static void labpc_release(struct pcmcia_device *link);
157static int labpc_cs_suspend(struct pcmcia_device *p_dev);
158static int labpc_cs_resume(struct pcmcia_device *p_dev);
159
124b13b2
FMH
160static int labpc_cs_attach(struct pcmcia_device *);
161static void labpc_cs_detach(struct pcmcia_device *);
162
e3f9f2c8 163struct local_info_t {
124b13b2 164 struct pcmcia_device *link;
124b13b2
FMH
165 int stop;
166 struct bus_operations *bus;
e3f9f2c8 167};
124b13b2 168
124b13b2
FMH
169static int labpc_cs_attach(struct pcmcia_device *link)
170{
e3f9f2c8 171 struct local_info_t *local;
124b13b2 172
55a19b39 173 dev_dbg(&link->dev, "labpc_cs_attach()\n");
124b13b2
FMH
174
175 /* Allocate space for private device-specific data */
e3f9f2c8 176 local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
124b13b2
FMH
177 if (!local)
178 return -ENOMEM;
179 local->link = link;
180 link->priv = local;
181
124b13b2
FMH
182 pcmcia_cur_dev = link;
183
184 labpc_config(link);
185
186 return 0;
187} /* labpc_cs_attach */
188
124b13b2
FMH
189static void labpc_cs_detach(struct pcmcia_device *link)
190{
99bd8f22
JMC
191 ((struct local_info_t *)link->priv)->stop = 1;
192 labpc_release(link);
124b13b2 193
92c4bad7
BM
194 /* This points to the parent local_info_t struct (may be null) */
195 kfree(link->priv);
124b13b2 196
484ecc95 197}
124b13b2 198
55a19b39 199static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
55a19b39 200 void *priv_data)
124b13b2 201{
00990e7c
DB
202 if (p_dev->config_index == 0)
203 return -EINVAL;
c3744138 204
00990e7c 205 return pcmcia_request_io(p_dev);
55a19b39 206}
124b13b2 207
124b13b2 208
55a19b39
DB
209static void labpc_config(struct pcmcia_device *link)
210{
55a19b39 211 int ret;
124b13b2 212
55a19b39 213 dev_dbg(&link->dev, "labpc_config\n");
124b13b2 214
440eed43 215 link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ |
00990e7c 216 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
440eed43 217
0f52e86d 218 ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
55a19b39
DB
219 if (ret) {
220 dev_warn(&link->dev, "no configuration found\n");
221 goto failed;
124b13b2
FMH
222 }
223
eb14120f
DB
224 if (!link->irq)
225 goto failed;
124b13b2 226
1ac71e5a 227 ret = pcmcia_enable_device(link);
55a19b39
DB
228 if (ret)
229 goto failed;
124b13b2 230
124b13b2
FMH
231 return;
232
55a19b39 233failed:
124b13b2
FMH
234 labpc_release(link);
235
236} /* labpc_config */
237
238static void labpc_release(struct pcmcia_device *link)
239{
55a19b39 240 dev_dbg(&link->dev, "labpc_release\n");
124b13b2
FMH
241
242 pcmcia_disable_device(link);
243} /* labpc_release */
244
124b13b2
FMH
245static int labpc_cs_suspend(struct pcmcia_device *link)
246{
e3f9f2c8 247 struct local_info_t *local = link->priv;
124b13b2
FMH
248
249 /* Mark the device as stopped, to block IO until later */
250 local->stop = 1;
251 return 0;
252} /* labpc_cs_suspend */
253
254static int labpc_cs_resume(struct pcmcia_device *link)
255{
e3f9f2c8 256 struct local_info_t *local = link->priv;
124b13b2
FMH
257
258 local->stop = 0;
259 return 0;
260} /* labpc_cs_resume */
261
2202a5a7 262static const struct pcmcia_device_id labpc_cs_ids[] = {
124b13b2
FMH
263 /* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
264 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
265 PCMCIA_DEVICE_NULL
266};
267
268MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
6c7f8196
AK
269MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
270MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC");
271MODULE_LICENSE("GPL");
124b13b2 272
0dcee6fe 273static struct pcmcia_driver labpc_cs_driver = {
124b13b2
FMH
274 .probe = labpc_cs_attach,
275 .remove = labpc_cs_detach,
276 .suspend = labpc_cs_suspend,
277 .resume = labpc_cs_resume,
278 .id_table = labpc_cs_ids,
279 .owner = THIS_MODULE,
2e9b981a 280 .name = "daqcard-1200",
124b13b2
FMH
281};
282
283static int __init init_labpc_cs(void)
284{
124b13b2
FMH
285 pcmcia_register_driver(&labpc_cs_driver);
286 return 0;
287}
288
289static void __exit exit_labpc_cs(void)
290{
124b13b2
FMH
291 pcmcia_unregister_driver(&labpc_cs_driver);
292}
293
0dcee6fe 294static int __init labpc_init_module(void)
124b13b2
FMH
295{
296 int ret;
297
298 ret = init_labpc_cs();
299 if (ret < 0)
300 return ret;
301
302 return comedi_driver_register(&driver_labpc_cs);
303}
304
0dcee6fe 305static void __exit labpc_exit_module(void)
124b13b2
FMH
306{
307 exit_labpc_cs();
308 comedi_driver_unregister(&driver_labpc_cs);
309}
310
124b13b2
FMH
311module_init(labpc_init_module);
312module_exit(labpc_exit_module);
This page took 0.368605 seconds and 5 git commands to generate.