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 /*
29 Driver: ni_labpc_cs
30 Description: National Instruments Lab-PC (& compatibles)
31 Author: Frank Mori Hess <fmhess@users.sourceforge.net>
32 Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
33 Status: works
34 
35 Thanks go to Fredrik Lingvall for much testing and perseverance in
36 helping to debug daqcard-1200 support.
37 
38 The 1200 series boards have onboard calibration dacs for correcting
39 analog input/output offsets and gains.  The proper settings for these
40 caldacs are stored on the board's eeprom.  To read the caldac values
41 from the eeprom and store them into a file that can be then be used by
42 comedilib, use the comedi_calibrate program.
43 
44 Configuration options:
45   none
46 
47 The daqcard-1200 has quirky chanlist requirements
48 when scanning multiple channels.  Multiple channel scan
49 sequence must start at highest channel, then decrement down to
50 channel 0.  Chanlists consisting of all one channel
51 are also legal, and allow you to pace conversions in bursts.
52 
53 */
54 
55 /*
56 
57 NI manuals:
58 340988a (daqcard-1200)
59 
60 */
61 
62 #undef LABPC_DEBUG  /* debugging messages */
63 
64 #include "../comedidev.h"
65 
66 #include <linux/delay.h>
67 #include <linux/slab.h>
68 
69 #include "8253.h"
70 #include "8255.h"
71 #include "comedi_fc.h"
72 #include "ni_labpc.h"
73 
74 #include <pcmcia/cistpl.h>
75 #include <pcmcia/cisreg.h>
76 #include <pcmcia/ds.h>
77 
78 static struct pcmcia_device *pcmcia_cur_dev;
79 
80 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it);
81 
82 static const struct labpc_board_struct labpc_cs_boards[] = {
83 	{
84 	 .name = "daqcard-1200",
85 	 .device_id = 0x103,	/* 0x10b is manufacturer id,
86 				   0x103 is device id */
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 	 },
97 	/* duplicate entry, to support using alternate name */
98 	{
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 	 },
111 };
112 
113 /*
114  * Useful for shorthand access to the particular board structure
115  */
116 #define thisboard ((const struct labpc_board_struct *)dev->board_ptr)
117 
118 static struct comedi_driver driver_labpc_cs = {
119 	.driver_name = "ni_labpc_cs",
120 	.module = THIS_MODULE,
121 	.attach = &labpc_attach,
122 	.detach = &labpc_common_detach,
123 	.num_names = ARRAY_SIZE(labpc_cs_boards),
124 	.board_name = &labpc_cs_boards[0].name,
125 	.offset = sizeof(struct labpc_board_struct),
126 };
127 
labpc_attach(struct comedi_device * dev,struct comedi_devconfig * it)128 static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
129 {
130 	unsigned long iobase = 0;
131 	unsigned int irq = 0;
132 	struct pcmcia_device *link;
133 
134 	/* allocate and initialize dev->private */
135 	if (alloc_private(dev, sizeof(struct labpc_private)) < 0)
136 		return -ENOMEM;
137 
138 	/*  get base address, irq etc. based on bustype */
139 	switch (thisboard->bustype) {
140 	case pcmcia_bustype:
141 		link = pcmcia_cur_dev;	/* XXX hack */
142 		if (!link)
143 			return -EIO;
144 		iobase = link->resource[0]->start;
145 		irq = link->irq;
146 		break;
147 	default:
148 		pr_err("bug! couldn't determine board type\n");
149 		return -EINVAL;
150 		break;
151 	}
152 	return labpc_common_attach(dev, iobase, irq, 0);
153 }
154 
155 static void labpc_config(struct pcmcia_device *link);
156 static void labpc_release(struct pcmcia_device *link);
157 static int labpc_cs_suspend(struct pcmcia_device *p_dev);
158 static int labpc_cs_resume(struct pcmcia_device *p_dev);
159 
160 static int labpc_cs_attach(struct pcmcia_device *);
161 static void labpc_cs_detach(struct pcmcia_device *);
162 
163 struct local_info_t {
164 	struct pcmcia_device *link;
165 	int stop;
166 	struct bus_operations *bus;
167 };
168 
labpc_cs_attach(struct pcmcia_device * link)169 static int labpc_cs_attach(struct pcmcia_device *link)
170 {
171 	struct local_info_t *local;
172 
173 	dev_dbg(&link->dev, "labpc_cs_attach()\n");
174 
175 	/* Allocate space for private device-specific data */
176 	local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
177 	if (!local)
178 		return -ENOMEM;
179 	local->link = link;
180 	link->priv = local;
181 
182 	pcmcia_cur_dev = link;
183 
184 	labpc_config(link);
185 
186 	return 0;
187 }				/* labpc_cs_attach */
188 
labpc_cs_detach(struct pcmcia_device * link)189 static void labpc_cs_detach(struct pcmcia_device *link)
190 {
191 	dev_dbg(&link->dev, "labpc_cs_detach\n");
192 
193 	/*
194 	   If the device is currently configured and active, we won't
195 	   actually delete it yet.  Instead, it is marked so that when
196 	   the release() function is called, that will trigger a proper
197 	   detach().
198 	 */
199 	((struct local_info_t *)link->priv)->stop = 1;
200 	labpc_release(link);
201 
202 	/* This points to the parent local_info_t struct (may be null) */
203 	kfree(link->priv);
204 
205 }				/* labpc_cs_detach */
206 
labpc_pcmcia_config_loop(struct pcmcia_device * p_dev,void * priv_data)207 static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
208 				void *priv_data)
209 {
210 	if (p_dev->config_index == 0)
211 		return -EINVAL;
212 
213 	return pcmcia_request_io(p_dev);
214 }
215 
216 
labpc_config(struct pcmcia_device * link)217 static void labpc_config(struct pcmcia_device *link)
218 {
219 	int ret;
220 
221 	dev_dbg(&link->dev, "labpc_config\n");
222 
223 	link->config_flags |= CONF_ENABLE_IRQ | CONF_ENABLE_PULSE_IRQ |
224 		CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
225 
226 	ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, NULL);
227 	if (ret) {
228 		dev_warn(&link->dev, "no configuration found\n");
229 		goto failed;
230 	}
231 
232 	if (!link->irq)
233 		goto failed;
234 
235 	ret = pcmcia_enable_device(link);
236 	if (ret)
237 		goto failed;
238 
239 	return;
240 
241 failed:
242 	labpc_release(link);
243 
244 }				/* labpc_config */
245 
labpc_release(struct pcmcia_device * link)246 static void labpc_release(struct pcmcia_device *link)
247 {
248 	dev_dbg(&link->dev, "labpc_release\n");
249 
250 	pcmcia_disable_device(link);
251 }				/* labpc_release */
252 
labpc_cs_suspend(struct pcmcia_device * link)253 static int labpc_cs_suspend(struct pcmcia_device *link)
254 {
255 	struct local_info_t *local = link->priv;
256 
257 	/* Mark the device as stopped, to block IO until later */
258 	local->stop = 1;
259 	return 0;
260 }				/* labpc_cs_suspend */
261 
labpc_cs_resume(struct pcmcia_device * link)262 static int labpc_cs_resume(struct pcmcia_device *link)
263 {
264 	struct local_info_t *local = link->priv;
265 
266 	local->stop = 0;
267 	return 0;
268 }				/* labpc_cs_resume */
269 
270 static const struct pcmcia_device_id labpc_cs_ids[] = {
271 	/* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
272 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103),	/* daqcard-1200 */
273 	PCMCIA_DEVICE_NULL
274 };
275 
276 MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
277 MODULE_AUTHOR("Frank Mori Hess <fmhess@users.sourceforge.net>");
278 MODULE_DESCRIPTION("Comedi driver for National Instruments Lab-PC");
279 MODULE_LICENSE("GPL");
280 
281 struct pcmcia_driver labpc_cs_driver = {
282 	.probe = labpc_cs_attach,
283 	.remove = labpc_cs_detach,
284 	.suspend = labpc_cs_suspend,
285 	.resume = labpc_cs_resume,
286 	.id_table = labpc_cs_ids,
287 	.owner = THIS_MODULE,
288 	.name = "daqcard-1200",
289 };
290 
init_labpc_cs(void)291 static int __init init_labpc_cs(void)
292 {
293 	pcmcia_register_driver(&labpc_cs_driver);
294 	return 0;
295 }
296 
exit_labpc_cs(void)297 static void __exit exit_labpc_cs(void)
298 {
299 	pcmcia_unregister_driver(&labpc_cs_driver);
300 }
301 
labpc_init_module(void)302 int __init labpc_init_module(void)
303 {
304 	int ret;
305 
306 	ret = init_labpc_cs();
307 	if (ret < 0)
308 		return ret;
309 
310 	return comedi_driver_register(&driver_labpc_cs);
311 }
312 
labpc_exit_module(void)313 void __exit labpc_exit_module(void)
314 {
315 	exit_labpc_cs();
316 	comedi_driver_unregister(&driver_labpc_cs);
317 }
318 
319 module_init(labpc_init_module);
320 module_exit(labpc_exit_module);
321