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