// SPDX-License-Identifier: GPL-2.0+1/*2* comedi_pcmcia.c3* Comedi PCMCIA driver specific functions.4*5* COMEDI - Linux Control and Measurement Device Interface6* Copyright (C) 1997-2000 David A. Schleef <[email protected]>7*/89#include <linux/module.h>10#include <linux/kernel.h>11#include <linux/comedi/comedi_pcmcia.h>1213/**14* comedi_to_pcmcia_dev() - Return PCMCIA device attached to COMEDI device15* @dev: COMEDI device.16*17* Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a18* a &struct device embedded in a &struct pcmcia_device.19*20* Return: Attached PCMCIA device if @dev->hw_dev is non-%NULL.21* Return %NULL if @dev->hw_dev is %NULL.22*/23struct pcmcia_device *comedi_to_pcmcia_dev(struct comedi_device *dev)24{25return dev->hw_dev ? to_pcmcia_dev(dev->hw_dev) : NULL;26}27EXPORT_SYMBOL_GPL(comedi_to_pcmcia_dev);2829static int comedi_pcmcia_conf_check(struct pcmcia_device *link,30void *priv_data)31{32if (link->config_index == 0)33return -EINVAL;3435return pcmcia_request_io(link);36}3738/**39* comedi_pcmcia_enable() - Request the regions and enable the PCMCIA device40* @dev: COMEDI device.41* @conf_check: Optional callback to check each configuration option of the42* PCMCIA device and request I/O regions.43*44* Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a a45* &struct device embedded in a &struct pcmcia_device. The comedi PCMCIA46* driver needs to set the 'config_flags' member in the &struct pcmcia_device,47* as appropriate for that driver, before calling this function in order to48* allow pcmcia_loop_config() to do its internal autoconfiguration.49*50* If @conf_check is %NULL it is set to a default function. If is51* passed to pcmcia_loop_config() and should return %0 if the configuration52* is valid and I/O regions requested successfully, otherwise it should return53* a negative error value. The default function returns -%EINVAL if the54* 'config_index' member is %0, otherwise it calls pcmcia_request_io() and55* returns the result.56*57* If the above configuration check passes, pcmcia_enable_device() is called58* to set up and activate the PCMCIA device.59*60* If this function returns an error, comedi_pcmcia_disable() should be called61* to release requested resources.62*63* Return:64* 0 on success,65* -%ENODEV id @dev->hw_dev is %NULL,66* a negative error number from pcmcia_loop_config() if it fails,67* or a negative error number from pcmcia_enable_device() if it fails.68*/69int comedi_pcmcia_enable(struct comedi_device *dev,70int (*conf_check)(struct pcmcia_device *p_dev,71void *priv_data))72{73struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);74int ret;7576if (!link)77return -ENODEV;7879if (!conf_check)80conf_check = comedi_pcmcia_conf_check;8182ret = pcmcia_loop_config(link, conf_check, NULL);83if (ret)84return ret;8586return pcmcia_enable_device(link);87}88EXPORT_SYMBOL_GPL(comedi_pcmcia_enable);8990/**91* comedi_pcmcia_disable() - Disable the PCMCIA device and release the regions92* @dev: COMEDI device.93*94* Assuming @dev->hw_dev is non-%NULL, it is assumed to be pointing to a95* a &struct device embedded in a &struct pcmcia_device. Call96* pcmcia_disable_device() to disable and clean up the PCMCIA device.97*/98void comedi_pcmcia_disable(struct comedi_device *dev)99{100struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);101102if (link)103pcmcia_disable_device(link);104}105EXPORT_SYMBOL_GPL(comedi_pcmcia_disable);106107/**108* comedi_pcmcia_auto_config() - Configure/probe a PCMCIA COMEDI device109* @link: PCMCIA device.110* @driver: Registered COMEDI driver.111*112* Typically called from the pcmcia_driver (*probe) function. Auto-configure113* a COMEDI device, using a pointer to the &struct device embedded in *@link114* as the hardware device. The @driver's "auto_attach" handler may call115* comedi_to_pcmcia_dev() on the passed in COMEDI device to recover @link.116*117* Return: The result of calling comedi_auto_config() (0 on success, or a118* negative error number on failure).119*/120int comedi_pcmcia_auto_config(struct pcmcia_device *link,121struct comedi_driver *driver)122{123return comedi_auto_config(&link->dev, driver, 0);124}125EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_config);126127/**128* comedi_pcmcia_auto_unconfig() - Unconfigure/remove a PCMCIA COMEDI device129* @link: PCMCIA device.130*131* Typically called from the pcmcia_driver (*remove) function.132* Auto-unconfigure a COMEDI device attached to this PCMCIA device, using a133* pointer to the &struct device embedded in *@link as the hardware device.134* The COMEDI driver's "detach" handler will be called during unconfiguration135* of the COMEDI device.136*137* Note that the COMEDI device may have already been unconfigured using the138* %COMEDI_DEVCONFIG ioctl, in which case this attempt to unconfigure it139* again should be ignored.140*/141void comedi_pcmcia_auto_unconfig(struct pcmcia_device *link)142{143comedi_auto_unconfig(&link->dev);144}145EXPORT_SYMBOL_GPL(comedi_pcmcia_auto_unconfig);146147/**148* comedi_pcmcia_driver_register() - Register a PCMCIA COMEDI driver149* @comedi_driver: COMEDI driver to be registered.150* @pcmcia_driver: PCMCIA driver to be registered.151*152* This function is used for the module_init() of PCMCIA COMEDI driver modules153* to register the COMEDI driver and the PCMCIA driver. Do not call it154* directly, use the module_comedi_pcmcia_driver() helper macro instead.155*156* Return: 0 on success, or a negative error number on failure.157*/158int comedi_pcmcia_driver_register(struct comedi_driver *comedi_driver,159struct pcmcia_driver *pcmcia_driver)160{161int ret;162163ret = comedi_driver_register(comedi_driver);164if (ret < 0)165return ret;166167ret = pcmcia_register_driver(pcmcia_driver);168if (ret < 0) {169comedi_driver_unregister(comedi_driver);170return ret;171}172173return 0;174}175EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_register);176177/**178* comedi_pcmcia_driver_unregister() - Unregister a PCMCIA COMEDI driver179* @comedi_driver: COMEDI driver to be registered.180* @pcmcia_driver: PCMCIA driver to be registered.181*182* This function is called from the module_exit() of PCMCIA COMEDI driver183* modules to unregister the PCMCIA driver and the COMEDI driver. Do not call184* it directly, use the module_comedi_pcmcia_driver() helper macro instead.185*/186void comedi_pcmcia_driver_unregister(struct comedi_driver *comedi_driver,187struct pcmcia_driver *pcmcia_driver)188{189pcmcia_unregister_driver(pcmcia_driver);190comedi_driver_unregister(comedi_driver);191}192EXPORT_SYMBOL_GPL(comedi_pcmcia_driver_unregister);193194static int __init comedi_pcmcia_init(void)195{196return 0;197}198module_init(comedi_pcmcia_init);199200static void __exit comedi_pcmcia_exit(void)201{202}203module_exit(comedi_pcmcia_exit);204205MODULE_AUTHOR("https://www.comedi.org");206MODULE_DESCRIPTION("Comedi PCMCIA interface module");207MODULE_LICENSE("GPL");208209210