comedidev.h revision c28264dac4348b1514a9a0abcf0014c6b460637f
1/*
2    include/linux/comedidev.h
3    header file for kernel-only structures, variables, and constants
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    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.
21
22*/
23
24#ifndef _COMEDIDEV_H
25#define _COMEDIDEV_H
26
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/version.h>
30#include <linux/kdev_t.h>
31#include <linux/slab.h>
32#include <linux/errno.h>
33#include <linux/spinlock.h>
34#include <linux/mutex.h>
35#include <linux/wait.h>
36#include <linux/mm.h>
37#include <linux/init.h>
38#include <linux/vmalloc.h>
39#include "interrupt.h"
40#include <linux/dma-mapping.h>
41#include <linux/uaccess.h>
42#include <linux/io.h>
43
44#include "comedi.h"
45
46#define DPRINTK(format, args...)	do {		\
47	if (comedi_debug)				\
48		printk(KERN_DEBUG "comedi: " format , ## args);	\
49} while (0)
50
51#define COMEDI_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
52#define COMEDI_VERSION_CODE COMEDI_VERSION(COMEDI_MAJORVERSION, COMEDI_MINORVERSION, COMEDI_MICROVERSION)
53#define COMEDI_RELEASE VERSION
54
55#define COMEDI_INITCLEANUP_NOMODULE(x)					\
56	static int __init x ## _init_module(void)			\
57		{return comedi_driver_register(&(x));}			\
58	static void __exit x ## _cleanup_module(void)			\
59		{comedi_driver_unregister(&(x));} 			\
60	module_init(x ## _init_module);					\
61	module_exit(x ## _cleanup_module);					\
62
63#define COMEDI_MODULE_MACROS						\
64	MODULE_AUTHOR("Comedi http://www.comedi.org");		\
65	MODULE_DESCRIPTION("Comedi low-level driver");			\
66	MODULE_LICENSE("GPL");						\
67
68#define COMEDI_INITCLEANUP(x)						\
69	COMEDI_MODULE_MACROS		\
70	COMEDI_INITCLEANUP_NOMODULE(x)
71
72#define COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table) \
73	static int __devinit comedi_driver ## _pci_probe(struct pci_dev *dev, \
74		const struct pci_device_id *ent) \
75	{ \
76		return comedi_pci_auto_config(dev, comedi_driver.driver_name); \
77	} \
78	static void __devexit comedi_driver ## _pci_remove(struct pci_dev *dev) \
79	{ \
80		comedi_pci_auto_unconfig(dev); \
81	} \
82	static struct pci_driver comedi_driver ## _pci_driver = \
83	{ \
84		.id_table = pci_id_table, \
85		.probe = &comedi_driver ## _pci_probe, \
86		.remove = __devexit_p(&comedi_driver ## _pci_remove) \
87	}; \
88	static int __init comedi_driver ## _init_module(void) \
89	{ \
90		int retval; \
91		retval = comedi_driver_register(&comedi_driver); \
92		if (retval < 0) \
93			return retval; \
94		comedi_driver ## _pci_driver.name = (char *)comedi_driver.driver_name; \
95		return pci_register_driver(&comedi_driver ## _pci_driver); \
96	} \
97	static void __exit comedi_driver ## _cleanup_module(void) \
98	{ \
99		pci_unregister_driver(&comedi_driver ## _pci_driver); \
100		comedi_driver_unregister(&comedi_driver); \
101	} \
102	module_init(comedi_driver ## _init_module); \
103	module_exit(comedi_driver ## _cleanup_module);
104
105#define COMEDI_PCI_INITCLEANUP(comedi_driver, pci_id_table) \
106	COMEDI_MODULE_MACROS \
107	COMEDI_PCI_INITCLEANUP_NOMODULE(comedi_driver, pci_id_table)
108
109#define PCI_VENDOR_ID_INOVA		0x104c
110#define PCI_VENDOR_ID_NATINST		0x1093
111#define PCI_VENDOR_ID_DATX		0x1116
112#define PCI_VENDOR_ID_COMPUTERBOARDS	0x1307
113#define PCI_VENDOR_ID_ADVANTECH		0x13fe
114#define PCI_VENDOR_ID_RTD		0x1435
115#define PCI_VENDOR_ID_AMPLICON		0x14dc
116#define PCI_VENDOR_ID_ADLINK		0x144a
117#define PCI_VENDOR_ID_ICP		0x104c
118#define PCI_VENDOR_ID_CONTEC		0x1221
119#define PCI_VENDOR_ID_MEILHAUS		0x1402
120
121#define COMEDI_NUM_MINORS 0x100
122#define COMEDI_NUM_LEGACY_MINORS 0x10
123#define COMEDI_NUM_BOARD_MINORS 0x30
124#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
125
126typedef struct comedi_device_struct comedi_device;
127typedef struct comedi_subdevice_struct comedi_subdevice;
128typedef struct comedi_async_struct comedi_async;
129typedef struct comedi_driver_struct comedi_driver;
130typedef struct comedi_lrange_struct comedi_lrange;
131
132typedef struct device device_create_result_type;
133
134#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
135	device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
136
137struct comedi_subdevice_struct {
138	comedi_device *device;
139	int type;
140	int n_chan;
141	volatile int subdev_flags;
142	int len_chanlist;	/* maximum length of channel/gain list */
143
144	void *private;
145
146	comedi_async *async;
147
148	void *lock;
149	void *busy;
150	unsigned runflags;
151	spinlock_t spin_lock;
152
153	int io_bits;
154
155	lsampl_t maxdata;	/* if maxdata==0, use list */
156	const lsampl_t *maxdata_list;	/* list is channel specific */
157
158	unsigned int flags;
159	const unsigned int *flaglist;
160
161	unsigned int settling_time_0;
162
163	const comedi_lrange *range_table;
164	const comedi_lrange *const *range_table_list;
165
166	unsigned int *chanlist;	/* driver-owned chanlist (not used) */
167
168	int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *,
169		lsampl_t *);
170	int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *,
171		lsampl_t *);
172	int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *,
173		lsampl_t *);
174	int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *,
175		lsampl_t *);
176
177	int (*do_cmd) (comedi_device *, comedi_subdevice *);
178	int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *);
179	int (*poll) (comedi_device *, comedi_subdevice *);
180	int (*cancel) (comedi_device *, comedi_subdevice *);
181	/* int (*do_lock)(comedi_device *,comedi_subdevice *); */
182	/* int (*do_unlock)(comedi_device *,comedi_subdevice *); */
183
184	/* called when the buffer changes */
185	int (*buf_change) (comedi_device *dev, comedi_subdevice *s,
186		unsigned long new_size);
187
188	void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data,
189		unsigned int num_bytes, unsigned int start_chan_index);
190	enum dma_data_direction async_dma_dir;
191
192	unsigned int state;
193
194	device_create_result_type *class_dev;
195	int minor;
196};
197
198struct comedi_buf_page {
199	void *virt_addr;
200	dma_addr_t dma_addr;
201};
202
203struct comedi_async_struct {
204	comedi_subdevice *subdevice;
205
206	void *prealloc_buf;	/* pre-allocated buffer */
207	unsigned int prealloc_bufsz;	/* buffer size, in bytes */
208	struct comedi_buf_page *buf_page_list;	/* virtual and dma address of each page */
209	unsigned n_buf_pages;	/* num elements in buf_page_list */
210
211	unsigned int max_bufsize;	/* maximum buffer size, bytes */
212	unsigned int mmap_count;	/* current number of mmaps of prealloc_buf */
213
214	unsigned int buf_write_count;	/* byte count for writer (write completed) */
215	unsigned int buf_write_alloc_count;	/* byte count for writer (allocated for writing) */
216	unsigned int buf_read_count;	/* byte count for reader (read completed) */
217	unsigned int buf_read_alloc_count;	/* byte count for reader (allocated for reading) */
218
219	unsigned int buf_write_ptr;	/* buffer marker for writer */
220	unsigned int buf_read_ptr;	/* buffer marker for reader */
221
222	unsigned int cur_chan;	/* useless channel marker for interrupt */
223	/* number of bytes that have been received for current scan */
224	unsigned int scan_progress;
225	/* keeps track of where we are in chanlist as for munging */
226	unsigned int munge_chan;
227	/* number of bytes that have been munged */
228	unsigned int munge_count;
229	/* buffer marker for munging */
230	unsigned int munge_ptr;
231
232	unsigned int events;	/* events that have occurred */
233
234	comedi_cmd cmd;
235
236	wait_queue_head_t wait_head;
237
238	/* callback stuff */
239	unsigned int cb_mask;
240	int (*cb_func) (unsigned int flags, void *);
241	void *cb_arg;
242
243	int (*inttrig) (comedi_device *dev, comedi_subdevice *s,
244			unsigned int x);
245};
246
247struct comedi_driver_struct {
248	struct comedi_driver_struct *next;
249
250	const char *driver_name;
251	struct module *module;
252	int (*attach) (comedi_device *, comedi_devconfig *);
253	int (*detach) (comedi_device *);
254
255	/* number of elements in board_name and board_id arrays */
256	unsigned int num_names;
257	const char *const *board_name;
258	/* offset in bytes from one board name pointer to the next */
259	int offset;
260};
261
262struct comedi_device_struct {
263	int use_count;
264	comedi_driver *driver;
265	void *private;
266
267	device_create_result_type *class_dev;
268	int minor;
269	/* hw_dev is passed to dma_alloc_coherent when allocating async buffers
270	 * for subdevices that have async_dma_dir set to something other than
271	 * DMA_NONE */
272	struct device *hw_dev;
273
274	const char *board_name;
275	const void *board_ptr;
276	int attached;
277	int rt;
278	spinlock_t spinlock;
279	struct mutex mutex;
280	int in_request_module;
281
282	int n_subdevices;
283	comedi_subdevice *subdevices;
284
285	/* dumb */
286	unsigned long iobase;
287	unsigned int irq;
288
289	comedi_subdevice *read_subdev;
290	comedi_subdevice *write_subdev;
291
292	struct fasync_struct *async_queue;
293
294	void (*open) (comedi_device *dev);
295	void (*close) (comedi_device *dev);
296};
297
298struct comedi_device_file_info {
299	comedi_device *device;
300	comedi_subdevice *read_subdevice;
301	comedi_subdevice *write_subdevice;
302};
303
304#ifdef CONFIG_COMEDI_DEBUG
305extern int comedi_debug;
306#else
307static const int comedi_debug;
308#endif
309
310/*
311 * function prototypes
312 */
313
314void comedi_event(comedi_device *dev, comedi_subdevice *s);
315void comedi_error(const comedi_device *dev, const char *s);
316
317/* we can expand the number of bits used to encode devices/subdevices into
318 the minor number soon, after more distros support > 8 bit minor numbers
319 (like after Debian Etch gets released) */
320enum comedi_minor_bits {
321	COMEDI_DEVICE_MINOR_MASK = 0xf,
322	COMEDI_SUBDEVICE_MINOR_MASK = 0xf0
323};
324static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
325static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
326
327struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
328
329static inline comedi_subdevice *comedi_get_read_subdevice(
330				const struct comedi_device_file_info *info)
331{
332	if (info->read_subdevice)
333		return info->read_subdevice;
334	if (info->device == NULL)
335		return NULL;
336	return info->device->read_subdev;
337}
338
339static inline comedi_subdevice *comedi_get_write_subdevice(
340				const struct comedi_device_file_info *info)
341{
342	if (info->write_subdevice)
343		return info->write_subdevice;
344	if (info->device == NULL)
345		return NULL;
346	return info->device->write_subdev;
347}
348
349void comedi_device_detach(comedi_device *dev);
350int comedi_device_attach(comedi_device *dev, comedi_devconfig *it);
351int comedi_driver_register(comedi_driver *);
352int comedi_driver_unregister(comedi_driver *);
353
354void init_polling(void);
355void cleanup_polling(void);
356void start_polling(comedi_device *);
357void stop_polling(comedi_device *);
358
359int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long
360	new_size);
361
362#ifdef CONFIG_PROC_FS
363void comedi_proc_init(void);
364void comedi_proc_cleanup(void);
365#else
366static inline void comedi_proc_init(void)
367{
368}
369static inline void comedi_proc_cleanup(void)
370{
371}
372#endif
373
374/* subdevice runflags */
375enum subdevice_runflags {
376	SRF_USER = 0x00000001,
377	SRF_RT = 0x00000002,
378	/* indicates an COMEDI_CB_ERROR event has occurred since the last
379	 * command was started */
380	SRF_ERROR = 0x00000004,
381	SRF_RUNNING = 0x08000000
382};
383
384/*
385   various internal comedi functions
386 */
387
388int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg);
389int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist);
390void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
391	unsigned bits);
392unsigned comedi_get_subdevice_runflags(comedi_subdevice *s);
393int insn_inval(comedi_device *dev, comedi_subdevice *s,
394	comedi_insn *insn, lsampl_t *data);
395
396/* range stuff */
397
398#define RANGE(a, b)		{(a)*1e6, (b)*1e6, 0}
399#define RANGE_ext(a, b)		{(a)*1e6, (b)*1e6, RF_EXTERNAL}
400#define RANGE_mA(a, b)		{(a)*1e6, (b)*1e6, UNIT_mA}
401#define RANGE_unitless(a, b)	{(a)*1e6, (b)*1e6, 0}	/* XXX */
402#define BIP_RANGE(a)		{-(a)*1e6, (a)*1e6, 0}
403#define UNI_RANGE(a)		{0, (a)*1e6, 0}
404
405extern const comedi_lrange range_bipolar10;
406extern const comedi_lrange range_bipolar5;
407extern const comedi_lrange range_bipolar2_5;
408extern const comedi_lrange range_unipolar10;
409extern const comedi_lrange range_unipolar5;
410extern const comedi_lrange range_unknown;
411
412#define range_digital		range_unipolar5
413
414#if __GNUC__ >= 3
415#define GCC_ZERO_LENGTH_ARRAY
416#else
417#define GCC_ZERO_LENGTH_ARRAY 0
418#endif
419
420struct comedi_lrange_struct {
421	int length;
422	comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
423};
424
425/* some silly little inline functions */
426
427static inline int alloc_subdevices(comedi_device *dev,
428				   unsigned int num_subdevices)
429{
430	unsigned i;
431
432	dev->n_subdevices = num_subdevices;
433	dev->subdevices =
434		kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL);
435	if (!dev->subdevices)
436		return -ENOMEM;
437	for (i = 0; i < num_subdevices; ++i) {
438		dev->subdevices[i].device = dev;
439		dev->subdevices[i].async_dma_dir = DMA_NONE;
440		spin_lock_init(&dev->subdevices[i].spin_lock);
441		dev->subdevices[i].minor = -1;
442	}
443	return 0;
444}
445
446static inline int alloc_private(comedi_device *dev, int size)
447{
448	dev->private = kzalloc(size, GFP_KERNEL);
449	if (!dev->private)
450		return -ENOMEM;
451	return 0;
452}
453
454static inline unsigned int bytes_per_sample(const comedi_subdevice *subd)
455{
456	if (subd->subdev_flags & SDF_LSAMPL)
457		return sizeof(lsampl_t);
458	else
459		return sizeof(sampl_t);
460}
461
462/* must be used in attach to set dev->hw_dev if you wish to dma directly
463into comedi's buffer */
464static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
465{
466	if (dev->hw_dev)
467		put_device(dev->hw_dev);
468
469	dev->hw_dev = hw_dev;
470	if (dev->hw_dev) {
471		dev->hw_dev = get_device(dev->hw_dev);
472		BUG_ON(dev->hw_dev == NULL);
473	}
474}
475
476int comedi_buf_put(comedi_async *async, sampl_t x);
477int comedi_buf_get(comedi_async *async, sampl_t *x);
478
479unsigned int comedi_buf_write_n_available(comedi_async *async);
480unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
481unsigned int comedi_buf_write_alloc_strict(comedi_async *async,
482	unsigned int nbytes);
483unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
484unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes);
485unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
486unsigned int comedi_buf_read_n_available(comedi_async *async);
487void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset,
488	const void *source, unsigned int num_bytes);
489void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
490	void *destination, unsigned int num_bytes);
491static inline unsigned comedi_buf_write_n_allocated(comedi_async *async)
492{
493	return async->buf_write_alloc_count - async->buf_write_count;
494}
495static inline unsigned comedi_buf_read_n_allocated(comedi_async *async)
496{
497	return async->buf_read_alloc_count - async->buf_read_count;
498}
499
500void comedi_reset_async_buf(comedi_async *async);
501
502static inline void *comedi_aux_data(int options[], int n)
503{
504	unsigned long address;
505	unsigned long addressLow;
506	int bit_shift;
507	if (sizeof(int) >= sizeof(void *))
508		address = options[COMEDI_DEVCONF_AUX_DATA_LO];
509	else {
510		address = options[COMEDI_DEVCONF_AUX_DATA_HI];
511		bit_shift = sizeof(int) * 8;
512		address <<= bit_shift;
513		addressLow = options[COMEDI_DEVCONF_AUX_DATA_LO];
514		addressLow &= (1UL << bit_shift) - 1;
515		address |= addressLow;
516	}
517	if (n >= 1)
518		address += options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
519	if (n >= 2)
520		address += options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
521	if (n >= 3)
522		address += options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
523	BUG_ON(n > 3);
524	return (void *)address;
525}
526
527int comedi_alloc_board_minor(struct device *hardware_device);
528void comedi_free_board_minor(unsigned minor);
529int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s);
530void comedi_free_subdevice_minor(comedi_subdevice *s);
531int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
532void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
533struct usb_device;	/* forward declaration */
534int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
535void comedi_usb_auto_unconfig(struct usb_device *usbdev);
536
537#include "comedi_rt.h"
538
539#endif /* _COMEDIDEV_H */
540