staging: comedi: remove inline alloc_private()
[linux-2.6-block.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 129{
9a1a6cf8 130 struct labpc_private *devpriv;
124b13b2
FMH
131 unsigned long iobase = 0;
132 unsigned int irq = 0;
133 struct pcmcia_device *link;
134
c34fa261
HS
135 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
136 if (!devpriv)
137 return -ENOMEM;
138 dev->private = devpriv;
124b13b2 139
2696fb57 140 /* get base address, irq etc. based on bustype */
124b13b2
FMH
141 switch (thisboard->bustype) {
142 case pcmcia_bustype:
143 link = pcmcia_cur_dev; /* XXX hack */
144 if (!link)
145 return -EIO;
9a017a91 146 iobase = link->resource[0]->start;
eb14120f 147 irq = link->irq;
124b13b2
FMH
148 break;
149 default:
327ffc0c 150 pr_err("bug! couldn't determine board type\n");
124b13b2
FMH
151 return -EINVAL;
152 break;
153 }
154 return labpc_common_attach(dev, iobase, irq, 0);
155}
156
124b13b2
FMH
157static void labpc_config(struct pcmcia_device *link);
158static void labpc_release(struct pcmcia_device *link);
159static int labpc_cs_suspend(struct pcmcia_device *p_dev);
160static int labpc_cs_resume(struct pcmcia_device *p_dev);
161
124b13b2
FMH
162static int labpc_cs_attach(struct pcmcia_device *);
163static void labpc_cs_detach(struct pcmcia_device *);
164
e3f9f2c8 165struct local_info_t {
124b13b2 166 struct pcmcia_device *link;
124b13b2
FMH
167 int stop;
168 struct bus_operations *bus;
e3f9f2c8 169};
124b13b2 170
124b13b2
FMH
171static int labpc_cs_attach(struct pcmcia_device *link)
172{
e3f9f2c8 173 struct local_info_t *local;
124b13b2 174
55a19b39 175 dev_dbg(&link->dev, "labpc_cs_attach()\n");
124b13b2
FMH
176
177 /* Allocate space for private device-specific data */
e3f9f2c8 178 local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
124b13b2
FMH
179 if (!local)
180 return -ENOMEM;
181 local->link = link;
182 link->priv = local;
183
124b13b2
FMH
184 pcmcia_cur_dev = link;
185
186 labpc_config(link);
187
188 return 0;
189} /* labpc_cs_attach */
190
124b13b2
FMH
191static void labpc_cs_detach(struct pcmcia_device *link)
192{
99bd8f22
JMC
193 ((struct local_info_t *)link->priv)->stop = 1;
194 labpc_release(link);
124b13b2 195
92c4bad7
BM
196 /* This points to the parent local_info_t struct (may be null) */
197 kfree(link->priv);
124b13b2 198
484ecc95 199}
124b13b2 200
55a19b39 201static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
55a19b39 202 void *priv_data)
124b13b2 203{
00990e7c
DB
204 if (p_dev->config_index == 0)
205 return -EINVAL;
c3744138 206
00990e7c 207 return pcmcia_request_io(p_dev);
55a19b39 208}
124b13b2 209
124b13b2 210
55a19b39
DB
211static void labpc_config(struct pcmcia_device *link)
212{
55a19b39 213 int ret;
124b13b2 214
55a19b39 215 dev_dbg(&link->dev, "labpc_config\n");
124b13b2 216
440eed43 217 link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ |
00990e7c 218 CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
440eed43 219
0f52e86d 220 ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
55a19b39
DB
221 if (ret) {
222 dev_warn(&link->dev, "no configuration found\n");
223 goto failed;
124b13b2
FMH
224 }
225
eb14120f
DB
226 if (!link->irq)
227 goto failed;
124b13b2 228
1ac71e5a 229 ret = pcmcia_enable_device(link);
55a19b39
DB
230 if (ret)
231 goto failed;
124b13b2 232
124b13b2
FMH
233 return;
234
55a19b39 235failed:
124b13b2
FMH
236 labpc_release(link);
237
238} /* labpc_config */
239
240static void labpc_release(struct pcmcia_device *link)
241{
55a19b39 242 dev_dbg(&link->dev, "labpc_release\n");
124b13b2
FMH
243
244 pcmcia_disable_device(link);
245} /* labpc_release */
246
124b13b2
FMH
247static int labpc_cs_suspend(struct pcmcia_device *link)
248{
e3f9f2c8 249 struct local_info_t *local = link->priv;
124b13b2
FMH
250
251 /* Mark the device as stopped, to block IO until later */
252 local->stop = 1;
253 return 0;
254} /* labpc_cs_suspend */
255
256static int labpc_cs_resume(struct pcmcia_device *link)
257{
e3f9f2c8 258 struct local_info_t *local = link->priv;
124b13b2
FMH
259
260 local->stop = 0;
261 return 0;
262} /* labpc_cs_resume */
263
2202a5a7 264static const struct pcmcia_device_id labpc_cs_ids[] = {
124b13b2
FMH
265 /* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
266 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
267 PCMCIA_DEVICE_NULL
268};
269
270MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
6c7f8196
AK
271MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
272MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC");
273MODULE_LICENSE("GPL");
124b13b2 274
0dcee6fe 275static struct pcmcia_driver labpc_cs_driver = {
124b13b2
FMH
276 .probe = labpc_cs_attach,
277 .remove = labpc_cs_detach,
278 .suspend = labpc_cs_suspend,
279 .resume = labpc_cs_resume,
280 .id_table = labpc_cs_ids,
281 .owner = THIS_MODULE,
2e9b981a 282 .name = "daqcard-1200",
124b13b2
FMH
283};
284
285static int __init init_labpc_cs(void)
286{
124b13b2
FMH
287 pcmcia_register_driver(&labpc_cs_driver);
288 return 0;
289}
290
291static void __exit exit_labpc_cs(void)
292{
124b13b2
FMH
293 pcmcia_unregister_driver(&labpc_cs_driver);
294}
295
0dcee6fe 296static int __init labpc_init_module(void)
124b13b2
FMH
297{
298 int ret;
299
300 ret = init_labpc_cs();
301 if (ret < 0)
302 return ret;
303
304 return comedi_driver_register(&driver_labpc_cs);
305}
306
0dcee6fe 307static void __exit labpc_exit_module(void)
124b13b2
FMH
308{
309 exit_labpc_cs();
310 comedi_driver_unregister(&driver_labpc_cs);
311}
312
124b13b2
FMH
313module_init(labpc_init_module);
314module_exit(labpc_exit_module);