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