sl811_cs.c revision eb14120f743d29744d9475bffec56ff4ad43a749
1c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/* 2c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * PCMCIA driver for SL811HS (as found in REX-CFU1U) 3c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Filename: sl811_cs.c 4c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Author: Yukio Yamamoto 5c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * 6c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Port to sl811-hcd and 2.6.x by 7c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Botond Botyanszki <boti@rocketmail.com> 8c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Simon Pickering 9c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * 10c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell * Last update: 2005-05-12 11c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell */ 12c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 13c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/kernel.h> 14c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/module.h> 15c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/init.h> 16c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/ptrace.h> 17c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/slab.h> 18c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/string.h> 19c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/timer.h> 20c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <linux/ioport.h> 21d052d1beff706920e82c5d55006b08e256b5df09Russell King#include <linux/platform_device.h> 22c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 23c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <pcmcia/cs_types.h> 24c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <pcmcia/cs.h> 25c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <pcmcia/cistpl.h> 26c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <pcmcia/cisreg.h> 27c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#include <pcmcia/ds.h> 28c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 29325a4af60dc945bf2da9cbcdbabb276e312b297cDavid Brownell#include <linux/usb/sl811.h> 30c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 31c6de2b64eb575a3f9326969ec5fcdc6032b38e42David BrownellMODULE_AUTHOR("Botond Botyanszki"); 32c6de2b64eb575a3f9326969ec5fcdc6032b38e42David BrownellMODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); 33c6de2b64eb575a3f9326969ec5fcdc6032b38e42David BrownellMODULE_LICENSE("GPL"); 34c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 35c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 36c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 37c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/* MACROS */ 38c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 39c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 40c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell#define INFO(args...) printk(KERN_INFO "sl811_cs: " args) 41c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 42c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 43c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/* VARIABLES */ 44c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 45c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 46c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic const char driver_name[DEV_NAME_LEN] = "sl811_cs"; 47c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 48c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownelltypedef struct local_info_t { 49fd238232cd0ff4840ae6946bb338502154096d88Dominik Brodowski struct pcmcia_device *p_dev; 50c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell dev_node_t node; 51c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} local_info_t; 52c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 53fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void sl811_cs_release(struct pcmcia_device * link); 54cc3b4866bee996c922e875b8c8efe9f0d8803aaeDominik Brodowski 55c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 56c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 57c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic void release_platform_dev(struct device * dev) 58c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 599b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski dev_dbg(dev, "sl811_cs platform_dev release\n"); 60c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell dev->parent = NULL; 61c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 62c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 63c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic struct sl811_platform_data platform_data = { 64c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .potpg = 100, 65c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .power = 50, /* == 100mA */ 66c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell // .reset = ... FIXME: invoke CF reset on the card 67c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell}; 68c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 69c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic struct resource resources[] = { 70c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell [0] = { 71c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .flags = IORESOURCE_IRQ, 72c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell }, 73c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell [1] = { 74c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell // .name = "address", 75c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .flags = IORESOURCE_IO, 76c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell }, 77c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell [2] = { 78c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell // .name = "data", 79c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .flags = IORESOURCE_IO, 80c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell }, 81c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell}; 82c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 83a0c53f1dca10acc93462339cbd0bf24b10d60a13David Brownellextern struct platform_driver sl811h_driver; 84c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 85c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic struct platform_device platform_dev = { 86c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .id = -1, 87c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .dev = { 88c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .platform_data = &platform_data, 89c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .release = release_platform_dev, 90c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell }, 91c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .resource = resources, 92c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .num_resources = ARRAY_SIZE(resources), 93c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell}; 94c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 95d39bd56452b509f8d6054883b8a0129950ba50ccDominik Brodowskistatic int sl811_hc_init(struct device *parent, resource_size_t base_addr, 96d39bd56452b509f8d6054883b8a0129950ba50ccDominik Brodowski int irq) 97c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 98c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell if (platform_dev.dev.parent) 99c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell return -EBUSY; 100c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell platform_dev.dev.parent = parent; 101c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 102c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell /* finish seting up the platform device */ 103c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell resources[0].start = irq; 104c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 105c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell resources[1].start = base_addr; 106c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell resources[1].end = base_addr; 107c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 108c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell resources[2].start = base_addr + 1; 109c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell resources[2].end = base_addr + 1; 110c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 111c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell /* The driver core will probe for us. We know sl811-hcd has been 112c9a50cc9318772e62d56f2a9172bdfda72bdacbeDavid Brownell * initialized already because of the link order dependency created 113c9a50cc9318772e62d56f2a9172bdfda72bdacbeDavid Brownell * by referencing "sl811h_driver". 114c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell */ 115a0c53f1dca10acc93462339cbd0bf24b10d60a13David Brownell platform_dev.name = sl811h_driver.driver.name; 116c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell return platform_device_register(&platform_dev); 117c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 118c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 119c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 120c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 121fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void sl811_cs_detach(struct pcmcia_device *link) 122c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 1239b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski dev_dbg(&link->dev, "sl811_cs_detach\n"); 124c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 125e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski sl811_cs_release(link); 126c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 127c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell /* This points to the parent local_info_t struct */ 128c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell kfree(link->priv); 129c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 130c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 131fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void sl811_cs_release(struct pcmcia_device * link) 132c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 1339b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski dev_dbg(&link->dev, "sl811_cs_release\n"); 134c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 135fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowski pcmcia_disable_device(link); 136c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell platform_device_unregister(&platform_dev); 137c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 138c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 13984e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowskistatic int sl811_cs_config_check(struct pcmcia_device *p_dev, 14084e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski cistpl_cftable_entry_t *cfg, 1418e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski cistpl_cftable_entry_t *dflt, 142ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski unsigned int vcc, 14384e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski void *priv_data) 14484e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski{ 14584e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski if (cfg->index == 0) 14684e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski return -ENODEV; 14784e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 14884e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski /* Use power settings for Vcc and Vpp if present */ 14984e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski /* Note that the CIS values need to be rescaled */ 15084e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { 151ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) 15284e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski return -ENODEV; 1538e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) { 154ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc) 15584e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski return -ENODEV; 15684e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski } 15784e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 15884e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 15984e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->conf.Vpp = 16084e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 1618e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) 16284e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->conf.Vpp = 1638e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; 16484e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 16584e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski /* we need an interrupt */ 166eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski p_dev->conf.Attributes |= CONF_ENABLE_IRQ; 16784e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 16884e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski /* IO window settings */ 16984e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; 1708e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { 1718e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; 17284e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 17384e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 17484e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 17584e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->io.BasePort1 = io->win[0].base; 17684e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski p_dev->io.NumPorts1 = io->win[0].len; 17784e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 17884e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski return pcmcia_request_io(p_dev, &p_dev->io); 17984e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski } 18084e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski pcmcia_disable_device(p_dev); 18184e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski return -ENODEV; 18284e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski} 18384e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 18484e2d34004dcd0c90d1af43a143511b334f11a4dDominik Brodowski 18515b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowskistatic int sl811_cs_config(struct pcmcia_device *link) 186c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 187dd2e5a156525f11754d9b1e0583f6bb49c253d62Dominik Brodowski struct device *parent = &link->dev; 188c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell local_info_t *dev = link->priv; 1899b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski int ret; 190c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 1919b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski dev_dbg(&link->dev, "sl811_cs_config\n"); 192c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 193ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) 194ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski goto failed; 195c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 196c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell /* require an IRQ and two registers */ 197c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) 198ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski goto failed; 199eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski 200eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (!link->irq) 201ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski goto failed; 202c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 2039b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski ret = pcmcia_request_configuration(link, &link->conf); 2049b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski if (ret) 2059b44de2015ff4a2ed1d56efedfcc72b917d356a6Dominik Brodowski goto failed; 206c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 207c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell sprintf(dev->node.dev_name, driver_name); 208c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell dev->node.major = dev->node.minor = 0; 209fd238232cd0ff4840ae6946bb338502154096d88Dominik Brodowski link->dev_node = &dev->node; 210c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 21170294b468302fd7a0a99dad935c7ba5322989345Dominik Brodowski printk(KERN_INFO "%s: index 0x%02x: ", 21270294b468302fd7a0a99dad935c7ba5322989345Dominik Brodowski dev->node.dev_name, link->conf.ConfigIndex); 21370294b468302fd7a0a99dad935c7ba5322989345Dominik Brodowski if (link->conf.Vpp) 21470294b468302fd7a0a99dad935c7ba5322989345Dominik Brodowski printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); 215eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski printk(", irq %d", link->irq); 216c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell printk(", io 0x%04x-0x%04x", link->io.BasePort1, 217c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell link->io.BasePort1+link->io.NumPorts1-1); 218c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell printk("\n"); 219c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 220eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski if (sl811_hc_init(parent, link->io.BasePort1, link->irq) 221c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell < 0) { 222ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowskifailed: 223ad913c11928f51abb6174f165db8d8d205b22e21Dominik Brodowski printk(KERN_WARNING "sl811_cs_config failed\n"); 224c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell sl811_cs_release(link); 22515b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski return -ENODEV; 226c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell } 22715b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski return 0; 228c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 229c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 23015b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowskistatic int sl811_cs_probe(struct pcmcia_device *link) 231c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 232c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell local_info_t *local; 233c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 234dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 235c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell if (!local) 236f8cfa618dccbdc6dab5297f75779566a388a98fdDominik Brodowski return -ENOMEM; 237fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowski local->p_dev = link; 238c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell link->priv = local; 239c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 240c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell link->conf.Attributes = 0; 241c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell link->conf.IntType = INT_MEMORY_AND_IO; 242c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 24315b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski return sl811_cs_config(link); 244c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 245c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 24622f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownellstatic struct pcmcia_device_id sl811_ids[] = { 24722f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownell PCMCIA_DEVICE_MANF_CARD(0xc015, 0x0001), /* RATOC USB HOST CF+ Card */ 24822f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownell PCMCIA_DEVICE_NULL, 24922f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownell}; 25022f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid BrownellMODULE_DEVICE_TABLE(pcmcia, sl811_ids); 25122f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownell 252c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic struct pcmcia_driver sl811_cs_driver = { 253c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .owner = THIS_MODULE, 254c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .drv = { 255c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell .name = (char *)driver_name, 256c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell }, 25715b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski .probe = sl811_cs_probe, 258cc3b4866bee996c922e875b8c8efe9f0d8803aaeDominik Brodowski .remove = sl811_cs_detach, 25922f3a8f5fc94be4dd31c4c5ec1d1dc2b9c83a8acDavid Brownell .id_table = sl811_ids, 260c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell}; 261c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 262c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell/*====================================================================*/ 263c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 264c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic int __init init_sl811_cs(void) 265c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 266c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell return pcmcia_register_driver(&sl811_cs_driver); 267c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 268c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellmodule_init(init_sl811_cs); 269c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell 270c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellstatic void __exit exit_sl811_cs(void) 271c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell{ 272c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell pcmcia_unregister_driver(&sl811_cs_driver); 273c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownell} 274c6de2b64eb575a3f9326969ec5fcdc6032b38e42David Brownellmodule_exit(exit_sl811_cs); 275