2 kcomedilib/kcomedilib.c
3 a comedlib interface for kernel modules
5 COMEDI - Linux Control and Measurement Device Interface
6 Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
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.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #define __NO_VERSION__
25 #include <linux/module.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/fcntl.h>
31 #include <linux/delay.h>
32 #include <linux/ioport.h>
36 #include "../comedi.h"
37 #include "../comedilib.h"
38 #include "../comedidev.h"
40 MODULE_AUTHOR("David Schleef <ds@schleef.org>");
41 MODULE_DESCRIPTION("Comedi kernel library");
42 MODULE_LICENSE("GPL");
44 void *comedi_open(const char *filename
)
46 struct comedi_device_file_info
*dev_file_info
;
47 struct comedi_device
*dev
;
50 if (strncmp(filename
, "/dev/comedi", 11) != 0)
53 minor
= simple_strtoul(filename
+ 11, NULL
, 0);
55 if (minor
>= COMEDI_NUM_BOARD_MINORS
)
58 dev_file_info
= comedi_get_device_file_info(minor
);
59 if (dev_file_info
== NULL
)
61 dev
= dev_file_info
->device
;
63 if (dev
== NULL
|| !dev
->attached
)
66 if (!try_module_get(dev
->driver
->module
))
71 EXPORT_SYMBOL(comedi_open
);
73 int comedi_close(void *d
)
75 struct comedi_device
*dev
= (struct comedi_device
*)d
;
77 module_put(dev
->driver
->module
);
81 EXPORT_SYMBOL(comedi_close
);
85 * perform an instruction
87 static int comedi_do_insn(void *d
, struct comedi_insn
*insn
)
89 struct comedi_device
*dev
= (struct comedi_device
*)d
;
90 struct comedi_subdevice
*s
;
93 if (insn
->insn
& INSN_MASK_SPECIAL
) {
100 insn
->data
[0] = tv
.tv_sec
;
101 insn
->data
[1] = tv
.tv_usec
;
107 /* XXX isn't the value supposed to be nanosecs? */
108 if (insn
->n
!= 1 || insn
->data
[0] >= 100) {
112 udelay(insn
->data
[0]);
120 if (insn
->subdev
>= dev
->n_subdevices
) {
121 printk("%d not usable subdevice\n",
126 s
= dev
->subdevices
+ insn
->subdev
;
128 printk("no async\n");
132 if (!s
->async
->inttrig
) {
133 printk("no inttrig\n");
137 ret
= s
->async
->inttrig(dev
, s
, insn
->data
[0]);
145 /* a subdevice instruction */
146 if (insn
->subdev
>= dev
->n_subdevices
) {
150 s
= dev
->subdevices
+ insn
->subdev
;
152 if (s
->type
== COMEDI_SUBD_UNUSED
) {
153 printk("%d not useable subdevice\n", insn
->subdev
);
160 ret
= comedi_check_chanlist(s
, 1, &insn
->chanspec
);
162 printk("bad chanspec\n");
173 switch (insn
->insn
) {
175 ret
= s
->insn_read(dev
, s
, insn
, insn
->data
);
178 ret
= s
->insn_write(dev
, s
, insn
, insn
->data
);
181 ret
= s
->insn_bits(dev
, s
, insn
, insn
->data
);
184 /* XXX should check instruction length */
185 ret
= s
->insn_config(dev
, s
, insn
, insn
->data
);
197 /* XXX do we want this? -- abbotti #if'ed it out for now. */
198 if (ret
!= insn
->n
) {
199 printk("BUG: result of insn != insn.n\n");
209 int comedi_dio_config(void *dev
, unsigned int subdev
, unsigned int chan
,
212 struct comedi_insn insn
;
214 memset(&insn
, 0, sizeof(insn
));
215 insn
.insn
= INSN_CONFIG
;
218 insn
.subdev
= subdev
;
219 insn
.chanspec
= CR_PACK(chan
, 0, 0);
221 return comedi_do_insn(dev
, &insn
);
223 EXPORT_SYMBOL(comedi_dio_config
);
225 int comedi_dio_bitfield(void *dev
, unsigned int subdev
, unsigned int mask
,
228 struct comedi_insn insn
;
229 unsigned int data
[2];
232 memset(&insn
, 0, sizeof(insn
));
233 insn
.insn
= INSN_BITS
;
236 insn
.subdev
= subdev
;
241 ret
= comedi_do_insn(dev
, &insn
);
247 EXPORT_SYMBOL(comedi_dio_bitfield
);
249 int comedi_find_subdevice_by_type(void *d
, int type
, unsigned int subd
)
251 struct comedi_device
*dev
= (struct comedi_device
*)d
;
253 if (subd
> dev
->n_subdevices
)
256 for (; subd
< dev
->n_subdevices
; subd
++) {
257 if (dev
->subdevices
[subd
].type
== type
)
262 EXPORT_SYMBOL(comedi_find_subdevice_by_type
);
264 int comedi_get_n_channels(void *d
, unsigned int subdevice
)
266 struct comedi_device
*dev
= (struct comedi_device
*)d
;
267 struct comedi_subdevice
*s
= dev
->subdevices
+ subdevice
;
271 EXPORT_SYMBOL(comedi_get_n_channels
);