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/module.h>
  20#include <linux/kernel.h>
  21
  22#include "comedi_pcmcia.h"
  23
  24/**
  25 * comedi_to_pcmcia_dev() - Return PCMCIA device attached to COMEDI device
  26 * @dev: COMEDI device.
  27 *
  28 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
  29 * a &struct device embedded in a &struct pcmcia_device.
  30 *
  31 * Return: Attached PCMCIA device if @dev->hw_dev is non-%NULL.
  32 * Return %NULL if @dev->hw_dev is %NULL.
  33 */
  34struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev)
  35{
  36        return dev->hw_dev ? to_pcmcia_dev(dev->hw_dev) : NULL;
  37}
  38EXPORT_SYMBOL_GPL(comedi_to_pcmcia_dev);
  39
  40static int comedi_pcmcia_conf_check(struct pcmcia_device *link,
  41                                    void *priv_data)
  42{
  43        if (link->config_index == 0)
  44                return -EINVAL;
  45
  46        return pcmcia_request_io(link);
  47}
  48
  49/**
  50 * comedi_pcmcia_enable() - Request the regions and enable the PCMCIA device
  51 * @dev: COMEDI device.
  52 * @conf_check: Optional callback to check each configuration option of the
  53 *      PCMCIA device and request I/O regions.
  54 *
  55 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a a
  56 * &struct device embedded in a &struct pcmcia_device.  The comedi PCMCIA
  57 * driver needs to set the 'config_flags' member in the &struct pcmcia_device,
  58 * as appropriate for that driver, before calling this function in order to
  59 * allow pcmcia_loop_config() to do its internal autoconfiguration.
  60 *
  61 * If @conf_check is %NULL it is set to a default function.  If is
  62 * passed to pcmcia_loop_config() and should return %0 if the configuration
  63 * is valid and I/O regions requested successfully, otherwise it should return
  64 * a negative error value.  The default function returns -%EINVAL if the
  65 * 'config_index' member is %0, otherwise it calls pcmcia_request_io() and
  66 * returns the result.
  67 *
  68 * If the above configuration check passes, pcmcia_enable_device() is called
  69 * to set up and activate the PCMCIA device.
  70 *
  71 * If this function returns an error, comedi_pcmcia_disable() should be called
  72 * to release requested resources.
  73 *
  74 * Return:
  75 *      0 on success,
  76 *      -%ENODEV id @dev->hw_dev is %NULL,
  77 *      a negative error number from pcmcia_loop_config() if it fails,
  78 *      or a negative error number from pcmcia_enable_device() if it fails.
  79 */
  80int comedi_pcmcia_enable(struct comedi_device *dev,
  81                         int (*conf_check)(struct pcmcia_device *, void *))
  82{
  83        struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
  84        int ret;
  85
  86        if (!link)
  87                return -ENODEV;
  88
  89        if (!conf_check)
  90                conf_check = comedi_pcmcia_conf_check;
  91
  92        ret = pcmcia_loop_config(link, conf_check, NULL);
  93        if (ret)
  94                return ret;
  95
  96        return pcmcia_enable_device(link);
  97}
  98EXPORT_SYMBOL_GPL(comedi_pcmcia_enable);
  99
 100/**
 101 * comedi_pcmcia_disable() - Disable the PCMCIA device and release the regions
 102 * @dev: COMEDI device.
 103 *
 104 * Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a
 105 * a &struct device embedded in a &struct pcmcia_device.  Call
 106 * pcmcia_disable_device() to disable and clean up the PCMCIA device.
 107 */
 108void comedi_pcmcia_disable(struct comedi_device *dev)
 109{
 110        struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
 111
 112        if (link)
 113                pcmcia_disable_device(link);
 114}
 115EXPORT_SYMBOL_GPL(comedi_pcmcia_disable);
 116
 117/**
 118 * comedi_pcmcia_auto_config() - Configure/probe a PCMCIA COMEDI device
 119 * @link: PCMCIA device.
 120 * @driver: Registered COMEDI driver.
 121 *
 122 * Typically called from the pcmcia_driver (*probe) function.  Auto-configure
 123 * a COMEDI device, using a pointer to the &struct device embedded in *@link
 124 * as the hardware device.  The @driver's "auto_attach" handler may call
 125 * comedi_to_pcmcia_dev() on the passed in COMEDI device to recover @link.
 126 *
 127 * Return: The result of calling comedi_auto_config() (0 on success, or a
 128 * negative error number on failure).
 129 */
 130int comedi_pcmcia_auto_config(struct pcmcia_device *link,
 131                              struct comedi_driver *driver)
 132{
 133        return comedi_auto_config(&link->dev, driver, 0);
 134}
 135EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_config);
 136
 137/**
 138 * comedi_pcmcia_auto_unconfig() - Unconfigure/remove a PCMCIA COMEDI device
 139 * @link: PCMCIA device.
 140 *
 141 * Typically called from the pcmcia_driver (*remove) function.
 142 * Auto-unconfigure a COMEDI device attached to this PCMCIA device, using a
 143 * pointer to the &struct device embedded in *@link as the hardware device.
 144 * The COMEDI driver's "detach" handler will be called during unconfiguration
 145 * of the COMEDI device.
 146 *
 147 * Note that the COMEDI device may have already been unconfigured using the
 148 * %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it
 149 * again should be ignored.
 150 */
 151void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link)
 152{
 153        comedi_auto_unconfig(&link->dev);
 154}
 155EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_unconfig);
 156
 157/**
 158 * comedi_pcmcia_driver_register() - Register a PCMCIA COMEDI driver
 159 * @comedi_driver: COMEDI driver to be registered.
 160 * @pcmcia_driver: PCMCIA driver to be registered.
 161 *
 162 * This function is used for the module_init() of PCMCIA COMEDI driver modules
 163 * to register the COMEDI driver and the PCMCIA driver.  Do not call it
 164 * directly, use the module_comedi_pcmcia_driver() helper macro instead.
 165 *
 166 * Return: 0 on success, or a negative error number on failure.
 167 */
 168int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,
 169                                  struct pcmcia_driver *pcmcia_driver)
 170{
 171        int ret;
 172
 173        ret = comedi_driver_register(comedi_driver);
 174        if (ret < 0)
 175                return ret;
 176
 177        ret = pcmcia_register_driver(pcmcia_driver);
 178        if (ret < 0) {
 179                comedi_driver_unregister(comedi_driver);
 180                return ret;
 181        }
 182
 183        return 0;
 184}
 185EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_register);
 186
 187/**
 188 * comedi_pcmcia_driver_unregister() - Unregister a PCMCIA COMEDI driver
 189 * @comedi_driver: COMEDI driver to be registered.
 190 * @pcmcia_driver: PCMCIA driver to be registered.
 191 *
 192 * This function is called from the module_exit() of PCMCIA COMEDI driver
 193 * modules to unregister the PCMCIA driver and the COMEDI driver.  Do not call
 194 * it directly, use the module_comedi_pcmcia_driver() helper macro instead.
 195 */
 196void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,
 197                                     struct pcmcia_driver *pcmcia_driver)
 198{
 199        pcmcia_unregister_driver(pcmcia_driver);
 200        comedi_driver_unregister(comedi_driver);
 201}
 202EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister);
 203
 204static int __init comedi_pcmcia_init(void)
 205{
 206        return 0;
 207}
 208module_init(comedi_pcmcia_init);
 209
 210static void __exit comedi_pcmcia_exit(void)
 211{
 212}
 213module_exit(comedi_pcmcia_exit);
 214
 215MODULE_AUTHOR("http://www.comedi.org");
 216MODULE_DESCRIPTION("Comedi PCMCIA interface module");
 217MODULE_LICENSE("GPL");
 218