linux/drivers/staging/comedi/comedi_pcmcia.c
<<
>>
Prefs
   1/*
   2 * comedi_pcmcia.c
   3 * Comedi PCMCIA driver specific functions.
   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
  19#include <linux/kernel.h>
  20
  21#include <pcmcia/cistpl.h>
  22#include <pcmcia/ds.h>
  23
  24#include "comedidev.h"
  25
  26/**
  27 * comedi_to_pcmcia_dev() - comedi_device pointer to pcmcia_device pointer.
  28 * @dev: comedi_device struct
  29 */
  30struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev)
  31{
  32        return dev->hw_dev ? to_pcmcia_dev(dev->hw_dev) : NULL;
  33}
  34EXPORT_SYMBOL_GPL(comedi_to_pcmcia_dev);
  35
  36static int comedi_pcmcia_conf_check(struct pcmcia_device *link,
  37                                    void *priv_data)
  38{
  39        if (link->config_index == 0)
  40                return -EINVAL;
  41
  42        return pcmcia_request_io(link);
  43}
  44
  45/**
  46 * comedi_pcmcia_enable() - Request the regions and enable the PCMCIA device.
  47 * @dev: comedi_device struct
  48 * @conf_check: optional callback to check the pcmcia_device configuration
  49 *
  50 * The comedi PCMCIA driver needs to set the link->config_flags, as
  51 * appropriate for that driver, before calling this function in order
  52 * to allow pcmcia_loop_config() to do its internal autoconfiguration.
  53 */
  54int comedi_pcmcia_enable(struct comedi_device *dev,
  55                         int (*conf_check)(struct pcmcia_device *, void *))
  56{
  57        struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
  58        int ret;
  59
  60        if (!link)
  61                return -ENODEV;
  62
  63        if (!conf_check)
  64                conf_check = comedi_pcmcia_conf_check;
  65
  66        ret = pcmcia_loop_config(link, conf_check, NULL);
  67        if (ret)
  68                return ret;
  69
  70        return pcmcia_enable_device(link);
  71}
  72EXPORT_SYMBOL_GPL(comedi_pcmcia_enable);
  73
  74/**
  75 * comedi_pcmcia_disable() - Disable the PCMCIA device and release the regions.
  76 * @dev: comedi_device struct
  77 */
  78void comedi_pcmcia_disable(struct comedi_device *dev)
  79{
  80        struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
  81
  82        if (link)
  83                pcmcia_disable_device(link);
  84}
  85EXPORT_SYMBOL_GPL(comedi_pcmcia_disable);
  86
  87/**
  88 * comedi_pcmcia_auto_config() - Configure/probe a comedi PCMCIA driver.
  89 * @link: pcmcia_device struct
  90 * @driver: comedi_driver struct
  91 *
  92 * Typically called from the pcmcia_driver (*probe) function.
  93 */
  94int comedi_pcmcia_auto_config(struct pcmcia_device *link,
  95                              struct comedi_driver *driver)
  96{
  97        return comedi_auto_config(&link->dev, driver, 0);
  98}
  99EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_config);
 100
 101/**
 102 * comedi_pcmcia_auto_unconfig() - Unconfigure/remove a comedi PCMCIA driver.
 103 * @link: pcmcia_device struct
 104 *
 105 * Typically called from the pcmcia_driver (*remove) function.
 106 */
 107void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link)
 108{
 109        comedi_auto_unconfig(&link->dev);
 110}
 111EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_unconfig);
 112
 113/**
 114 * comedi_pcmcia_driver_register() - Register a comedi PCMCIA driver.
 115 * @comedi_driver: comedi_driver struct
 116 * @pcmcia_driver: pcmcia_driver struct
 117 *
 118 * This function is used for the module_init() of comedi USB drivers.
 119 * Do not call it directly, use the module_comedi_pcmcia_driver() helper
 120 * macro instead.
 121 */
 122int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,
 123                                  struct pcmcia_driver *pcmcia_driver)
 124{
 125        int ret;
 126
 127        ret = comedi_driver_register(comedi_driver);
 128        if (ret < 0)
 129                return ret;
 130
 131        ret = pcmcia_register_driver(pcmcia_driver);
 132        if (ret < 0) {
 133                comedi_driver_unregister(comedi_driver);
 134                return ret;
 135        }
 136
 137        return 0;
 138}
 139EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_register);
 140
 141/**
 142 * comedi_pcmcia_driver_unregister() - Unregister a comedi PCMCIA driver.
 143 * @comedi_driver: comedi_driver struct
 144 * @pcmcia_driver: pcmcia_driver struct
 145 *
 146 * This function is used for the module_exit() of comedi PCMCIA drivers.
 147 * Do not call it directly, use the module_comedi_pcmcia_driver() helper
 148 * macro instead.
 149 */
 150void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
 151                                     struct pcmcia_driver *pcmcia_driver)
 152{
 153        pcmcia_unregister_driver(pcmcia_driver);
 154        comedi_driver_unregister(comedi_driver);
 155}
 156EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister);
 157