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