linux/drivers/staging/comedi/comedidev.h
<<
>>
Prefs
   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/kdev_t.h>
  30#include <linux/slab.h>
  31#include <linux/delay.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 <linux/dma-mapping.h>
  40#include <linux/uaccess.h>
  41#include <linux/io.h>
  42#include <linux/timer.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_BOARD_MINORS 0x30
 123#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
 124
 125#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
 126        device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
 127
 128struct comedi_subdevice {
 129        struct comedi_device *device;
 130        int type;
 131        int n_chan;
 132        volatile int subdev_flags;
 133        int len_chanlist;       /* maximum length of channel/gain list */
 134
 135        void *private;
 136
 137        struct comedi_async *async;
 138
 139        void *lock;
 140        void *busy;
 141        unsigned runflags;
 142        spinlock_t spin_lock;
 143
 144        int io_bits;
 145
 146        unsigned int maxdata;   /* if maxdata==0, use list */
 147        const unsigned int *maxdata_list;       /* list is channel specific */
 148
 149        unsigned int flags;
 150        const unsigned int *flaglist;
 151
 152        unsigned int settling_time_0;
 153
 154        const struct comedi_lrange *range_table;
 155        const struct comedi_lrange *const *range_table_list;
 156
 157        unsigned int *chanlist; /* driver-owned chanlist (not used) */
 158
 159        int (*insn_read) (struct comedi_device *, struct comedi_subdevice *,
 160                          struct comedi_insn *, unsigned int *);
 161        int (*insn_write) (struct comedi_device *, struct comedi_subdevice *,
 162                           struct comedi_insn *, unsigned int *);
 163        int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *,
 164                          struct comedi_insn *, unsigned int *);
 165        int (*insn_config) (struct comedi_device *, struct comedi_subdevice *,
 166                            struct comedi_insn *, unsigned int *);
 167
 168        int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *);
 169        int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *,
 170                           struct comedi_cmd *);
 171        int (*poll) (struct comedi_device *, struct comedi_subdevice *);
 172        int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
 173        /* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
 174        /* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
 175
 176        /* called when the buffer changes */
 177        int (*buf_change) (struct comedi_device * dev,
 178                           struct comedi_subdevice * s, unsigned long new_size);
 179
 180        void (*munge) (struct comedi_device * dev, struct comedi_subdevice * s,
 181                       void *data, unsigned int num_bytes,
 182                       unsigned int start_chan_index);
 183        enum dma_data_direction async_dma_dir;
 184
 185        unsigned int state;
 186
 187        struct device *class_dev;
 188        int minor;
 189};
 190
 191struct comedi_buf_page {
 192        void *virt_addr;
 193        dma_addr_t dma_addr;
 194};
 195
 196struct comedi_async {
 197        struct comedi_subdevice *subdevice;
 198
 199        void *prealloc_buf;     /* pre-allocated buffer */
 200        unsigned int prealloc_bufsz;    /* buffer size, in bytes */
 201        struct comedi_buf_page *buf_page_list;  /* virtual and dma address of each page */
 202        unsigned n_buf_pages;   /* num elements in buf_page_list */
 203
 204        unsigned int max_bufsize;       /* maximum buffer size, bytes */
 205        unsigned int mmap_count;        /* current number of mmaps of prealloc_buf */
 206
 207        unsigned int buf_write_count;   /* byte count for writer (write completed) */
 208        unsigned int buf_write_alloc_count;     /* byte count for writer (allocated for writing) */
 209        unsigned int buf_read_count;    /* byte count for reader (read completed) */
 210        unsigned int buf_read_alloc_count;      /* byte count for reader (allocated for reading) */
 211
 212        unsigned int buf_write_ptr;     /* buffer marker for writer */
 213        unsigned int buf_read_ptr;      /* buffer marker for reader */
 214
 215        unsigned int cur_chan;  /* useless channel marker for interrupt */
 216        /* number of bytes that have been received for current scan */
 217        unsigned int scan_progress;
 218        /* keeps track of where we are in chanlist as for munging */
 219        unsigned int munge_chan;
 220        /* number of bytes that have been munged */
 221        unsigned int munge_count;
 222        /* buffer marker for munging */
 223        unsigned int munge_ptr;
 224
 225        unsigned int events;    /* events that have occurred */
 226
 227        struct comedi_cmd cmd;
 228
 229        wait_queue_head_t wait_head;
 230
 231        /* callback stuff */
 232        unsigned int cb_mask;
 233        int (*cb_func) (unsigned int flags, void *);
 234        void *cb_arg;
 235
 236        int (*inttrig) (struct comedi_device * dev, struct comedi_subdevice * s,
 237                        unsigned int x);
 238};
 239
 240struct comedi_driver {
 241        struct comedi_driver *next;
 242
 243        const char *driver_name;
 244        struct module *module;
 245        int (*attach) (struct comedi_device *, struct comedi_devconfig *);
 246        int (*detach) (struct comedi_device *);
 247
 248        /* number of elements in board_name and board_id arrays */
 249        unsigned int num_names;
 250        const char *const *board_name;
 251        /* offset in bytes from one board name pointer to the next */
 252        int offset;
 253};
 254
 255struct comedi_device {
 256        int use_count;
 257        struct comedi_driver *driver;
 258        void *private;
 259
 260        struct device *class_dev;
 261        int minor;
 262        /* hw_dev is passed to dma_alloc_coherent when allocating async buffers
 263         * for subdevices that have async_dma_dir set to something other than
 264         * DMA_NONE */
 265        struct device *hw_dev;
 266
 267        const char *board_name;
 268        const void *board_ptr;
 269        int attached;
 270        spinlock_t spinlock;
 271        struct mutex mutex;
 272        int in_request_module;
 273
 274        int n_subdevices;
 275        struct comedi_subdevice *subdevices;
 276
 277        /* dumb */
 278        unsigned long iobase;
 279        unsigned int irq;
 280
 281        struct comedi_subdevice *read_subdev;
 282        struct comedi_subdevice *write_subdev;
 283
 284        struct fasync_struct *async_queue;
 285
 286        void (*open) (struct comedi_device * dev);
 287        void (*close) (struct comedi_device * dev);
 288};
 289
 290struct comedi_device_file_info {
 291        struct comedi_device *device;
 292        struct comedi_subdevice *read_subdevice;
 293        struct comedi_subdevice *write_subdevice;
 294};
 295
 296#ifdef CONFIG_COMEDI_DEBUG
 297extern int comedi_debug;
 298#else
 299static const int comedi_debug;
 300#endif
 301
 302/*
 303 * function prototypes
 304 */
 305
 306void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
 307void comedi_error(const struct comedi_device *dev, const char *s);
 308
 309/* we can expand the number of bits used to encode devices/subdevices into
 310 the minor number soon, after more distros support > 8 bit minor numbers
 311 (like after Debian Etch gets released) */
 312enum comedi_minor_bits {
 313        COMEDI_DEVICE_MINOR_MASK = 0xf,
 314        COMEDI_SUBDEVICE_MINOR_MASK = 0xf0
 315};
 316static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4;
 317static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
 318
 319struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
 320
 321static inline struct comedi_subdevice *comedi_get_read_subdevice(const struct
 322                                                                 comedi_device_file_info
 323                                                                 *info)
 324{
 325        if (info->read_subdevice)
 326                return info->read_subdevice;
 327        if (info->device == NULL)
 328                return NULL;
 329        return info->device->read_subdev;
 330}
 331
 332static inline struct comedi_subdevice *comedi_get_write_subdevice(const struct
 333                                                                  comedi_device_file_info
 334                                                                  *info)
 335{
 336        if (info->write_subdevice)
 337                return info->write_subdevice;
 338        if (info->device == NULL)
 339                return NULL;
 340        return info->device->write_subdev;
 341}
 342
 343void comedi_device_detach(struct comedi_device *dev);
 344int comedi_device_attach(struct comedi_device *dev,
 345                         struct comedi_devconfig *it);
 346int comedi_driver_register(struct comedi_driver *);
 347int comedi_driver_unregister(struct comedi_driver *);
 348
 349void init_polling(void);
 350void cleanup_polling(void);
 351void start_polling(struct comedi_device *);
 352void stop_polling(struct comedi_device *);
 353
 354int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
 355                     unsigned long new_size);
 356
 357#ifdef CONFIG_PROC_FS
 358void comedi_proc_init(void);
 359void comedi_proc_cleanup(void);
 360#else
 361static inline void comedi_proc_init(void)
 362{
 363}
 364
 365static inline void comedi_proc_cleanup(void)
 366{
 367}
 368#endif
 369
 370/* subdevice runflags */
 371enum subdevice_runflags {
 372        SRF_USER = 0x00000001,
 373        SRF_RT = 0x00000002,
 374        /* indicates an COMEDI_CB_ERROR event has occurred since the last
 375         * command was started */
 376        SRF_ERROR = 0x00000004,
 377        SRF_RUNNING = 0x08000000
 378};
 379
 380/*
 381   various internal comedi functions
 382 */
 383
 384int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg);
 385int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist);
 386void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
 387                                   unsigned bits);
 388unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);
 389int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
 390               struct comedi_insn *insn, unsigned int *data);
 391
 392/* range stuff */
 393
 394#define RANGE(a, b)             {(a)*1e6, (b)*1e6, 0}
 395#define RANGE_ext(a, b)         {(a)*1e6, (b)*1e6, RF_EXTERNAL}
 396#define RANGE_mA(a, b)          {(a)*1e6, (b)*1e6, UNIT_mA}
 397#define RANGE_unitless(a, b)    {(a)*1e6, (b)*1e6, 0}   /* XXX */
 398#define BIP_RANGE(a)            {-(a)*1e6, (a)*1e6, 0}
 399#define UNI_RANGE(a)            {0, (a)*1e6, 0}
 400
 401extern const struct comedi_lrange range_bipolar10;
 402extern const struct comedi_lrange range_bipolar5;
 403extern const struct comedi_lrange range_bipolar2_5;
 404extern const struct comedi_lrange range_unipolar10;
 405extern const struct comedi_lrange range_unipolar5;
 406extern const struct comedi_lrange range_unknown;
 407
 408#define range_digital           range_unipolar5
 409
 410#if __GNUC__ >= 3
 411#define GCC_ZERO_LENGTH_ARRAY
 412#else
 413#define GCC_ZERO_LENGTH_ARRAY 0
 414#endif
 415
 416struct comedi_lrange {
 417        int length;
 418        struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
 419};
 420
 421/* some silly little inline functions */
 422
 423static inline int alloc_subdevices(struct comedi_device *dev,
 424                                   unsigned int num_subdevices)
 425{
 426        unsigned i;
 427
 428        dev->n_subdevices = num_subdevices;
 429        dev->subdevices =
 430            kcalloc(num_subdevices, sizeof(struct comedi_subdevice),
 431                    GFP_KERNEL);
 432        if (!dev->subdevices)
 433                return -ENOMEM;
 434        for (i = 0; i < num_subdevices; ++i) {
 435                dev->subdevices[i].device = dev;
 436                dev->subdevices[i].async_dma_dir = DMA_NONE;
 437                spin_lock_init(&dev->subdevices[i].spin_lock);
 438                dev->subdevices[i].minor = -1;
 439        }
 440        return 0;
 441}
 442
 443static inline int alloc_private(struct comedi_device *dev, int size)
 444{
 445        dev->private = kzalloc(size, GFP_KERNEL);
 446        if (!dev->private)
 447                return -ENOMEM;
 448        return 0;
 449}
 450
 451static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
 452{
 453        if (subd->subdev_flags & SDF_LSAMPL)
 454                return sizeof(unsigned int);
 455        else
 456                return sizeof(short);
 457}
 458
 459/* must be used in attach to set dev->hw_dev if you wish to dma directly
 460into comedi's buffer */
 461static inline void comedi_set_hw_dev(struct comedi_device *dev,
 462                                     struct device *hw_dev)
 463{
 464        if (dev->hw_dev)
 465                put_device(dev->hw_dev);
 466
 467        dev->hw_dev = hw_dev;
 468        if (dev->hw_dev) {
 469                dev->hw_dev = get_device(dev->hw_dev);
 470                BUG_ON(dev->hw_dev == NULL);
 471        }
 472}
 473
 474int comedi_buf_put(struct comedi_async *async, short x);
 475int comedi_buf_get(struct comedi_async *async, short *x);
 476
 477unsigned int comedi_buf_write_n_available(struct comedi_async *async);
 478unsigned int comedi_buf_write_alloc(struct comedi_async *async,
 479                                    unsigned int nbytes);
 480unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
 481                                           unsigned int nbytes);
 482unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes);
 483unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes);
 484unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes);
 485unsigned int comedi_buf_read_n_available(struct comedi_async *async);
 486void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
 487                          const void *source, unsigned int num_bytes);
 488void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
 489                            void *destination, unsigned int num_bytes);
 490static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async)
 491{
 492        return async->buf_write_alloc_count - async->buf_write_count;
 493}
 494
 495static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async)
 496{
 497        return async->buf_read_alloc_count - async->buf_read_count;
 498}
 499
 500void comedi_reset_async_buf(struct 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(struct comedi_device *dev,
 530                                 struct comedi_subdevice *s);
 531void comedi_free_subdevice_minor(struct comedi_subdevice *s);
 532int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
 533void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
 534struct usb_device;              /* forward declaration */
 535int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
 536void comedi_usb_auto_unconfig(struct usb_device *usbdev);
 537
 538#ifdef CONFIG_COMEDI_PCI_DRIVERS
 539#define CONFIG_COMEDI_PCI
 540#endif
 541#ifdef CONFIG_COMEDI_PCI_DRIVERS_MODULE
 542#define CONFIG_COMEDI_PCI
 543#endif
 544#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS
 545#define CONFIG_COMEDI_PCMCIA
 546#endif
 547#ifdef CONFIG_COMEDI_PCMCIA_DRIVERS_MODULE
 548#define CONFIG_COMEDI_PCMCIA
 549#endif
 550
 551#endif /* _COMEDIDEV_H */
 552