root/drivers/usb/host/sl811_cs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. release_platform_dev
  2. sl811_hc_init
  3. sl811_cs_detach
  4. sl811_cs_release
  5. sl811_cs_config_check
  6. sl811_cs_config
  7. sl811_cs_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * PCMCIA driver for SL811HS (as found in REX-CFU1U)
   4  * Filename: sl811_cs.c
   5  * Author:   Yukio Yamamoto
   6  *
   7  *  Port to sl811-hcd and 2.6.x by
   8  *    Botond Botyanszki <boti@rocketmail.com>
   9  *    Simon Pickering
  10  *
  11  *  Last update: 2005-05-12
  12  */
  13 
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 #include <linux/ptrace.h>
  17 #include <linux/slab.h>
  18 #include <linux/string.h>
  19 #include <linux/timer.h>
  20 #include <linux/ioport.h>
  21 #include <linux/platform_device.h>
  22 
  23 #include <pcmcia/cistpl.h>
  24 #include <pcmcia/cisreg.h>
  25 #include <pcmcia/ds.h>
  26 
  27 #include <linux/usb/sl811.h>
  28 
  29 MODULE_AUTHOR("Botond Botyanszki");
  30 MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6");
  31 MODULE_LICENSE("GPL");
  32 
  33 
  34 /*====================================================================*/
  35 /* MACROS                                                             */
  36 /*====================================================================*/
  37 
  38 #define INFO(args...) printk(KERN_INFO "sl811_cs: " args)
  39 
  40 /*====================================================================*/
  41 /* VARIABLES                                                          */
  42 /*====================================================================*/
  43 
  44 typedef struct local_info_t {
  45         struct pcmcia_device    *p_dev;
  46 } local_info_t;
  47 
  48 static void sl811_cs_release(struct pcmcia_device * link);
  49 
  50 /*====================================================================*/
  51 
  52 static void release_platform_dev(struct device * dev)
  53 {
  54         dev_dbg(dev, "sl811_cs platform_dev release\n");
  55         dev->parent = NULL;
  56 }
  57 
  58 static struct sl811_platform_data platform_data = {
  59         .potpg          = 100,
  60         .power          = 50,           /* == 100mA */
  61         // .reset       = ... FIXME:  invoke CF reset on the card
  62 };
  63 
  64 static struct resource resources[] = {
  65         [0] = {
  66                 .flags  = IORESOURCE_IRQ,
  67         },
  68         [1] = {
  69                 // .name   = "address",
  70                 .flags  = IORESOURCE_IO,
  71         },
  72         [2] = {
  73                 // .name   = "data",
  74                 .flags  = IORESOURCE_IO,
  75         },
  76 };
  77 
  78 extern struct platform_driver sl811h_driver;
  79 
  80 static struct platform_device platform_dev = {
  81         .id                     = -1,
  82         .dev = {
  83                 .platform_data = &platform_data,
  84                 .release       = release_platform_dev,
  85         },
  86         .resource               = resources,
  87         .num_resources          = ARRAY_SIZE(resources),
  88 };
  89 
  90 static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
  91                          int irq)
  92 {
  93         if (platform_dev.dev.parent)
  94                 return -EBUSY;
  95         platform_dev.dev.parent = parent;
  96 
  97         /* finish seting up the platform device */
  98         resources[0].start = irq;
  99 
 100         resources[1].start = base_addr;
 101         resources[1].end = base_addr;
 102 
 103         resources[2].start = base_addr + 1;
 104         resources[2].end   = base_addr + 1;
 105 
 106         /* The driver core will probe for us.  We know sl811-hcd has been
 107          * initialized already because of the link order dependency created
 108          * by referencing "sl811h_driver".
 109          */
 110         platform_dev.name = sl811h_driver.driver.name;
 111         return platform_device_register(&platform_dev);
 112 }
 113 
 114 /*====================================================================*/
 115 
 116 static void sl811_cs_detach(struct pcmcia_device *link)
 117 {
 118         dev_dbg(&link->dev, "sl811_cs_detach\n");
 119 
 120         sl811_cs_release(link);
 121 
 122         /* This points to the parent local_info_t struct */
 123         kfree(link->priv);
 124 }
 125 
 126 static void sl811_cs_release(struct pcmcia_device * link)
 127 {
 128         dev_dbg(&link->dev, "sl811_cs_release\n");
 129 
 130         pcmcia_disable_device(link);
 131         platform_device_unregister(&platform_dev);
 132 }
 133 
 134 static int sl811_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
 135 {
 136         if (p_dev->config_index == 0)
 137                 return -EINVAL;
 138 
 139         return pcmcia_request_io(p_dev);
 140 }
 141 
 142 
 143 static int sl811_cs_config(struct pcmcia_device *link)
 144 {
 145         struct device           *parent = &link->dev;
 146         int                     ret;
 147 
 148         dev_dbg(&link->dev, "sl811_cs_config\n");
 149 
 150         link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
 151                 CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO;
 152 
 153         if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
 154                 goto failed;
 155 
 156         /* require an IRQ and two registers */
 157         if (resource_size(link->resource[0]) < 2)
 158                 goto failed;
 159 
 160         if (!link->irq)
 161                 goto failed;
 162 
 163         ret = pcmcia_enable_device(link);
 164         if (ret)
 165                 goto failed;
 166 
 167         if (sl811_hc_init(parent, link->resource[0]->start, link->irq)
 168                         < 0) {
 169 failed:
 170                 printk(KERN_WARNING "sl811_cs_config failed\n");
 171                 sl811_cs_release(link);
 172                 return  -ENODEV;
 173         }
 174         return 0;
 175 }
 176 
 177 static int sl811_cs_probe(struct pcmcia_device *link)
 178 {
 179         local_info_t *local;
 180 
 181         local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
 182         if (!local)
 183                 return -ENOMEM;
 184         local->p_dev = link;
 185         link->priv = local;
 186 
 187         return sl811_cs_config(link);
 188 }
 189 
 190 static const struct pcmcia_device_id sl811_ids[] = {
 191         PCMCIA_DEVICE_MANF_CARD(0xc015, 0x0001), /* RATOC USB HOST CF+ Card */
 192         PCMCIA_DEVICE_NULL,
 193 };
 194 MODULE_DEVICE_TABLE(pcmcia, sl811_ids);
 195 
 196 static struct pcmcia_driver sl811_cs_driver = {
 197         .owner          = THIS_MODULE,
 198         .name           = "sl811_cs",
 199         .probe          = sl811_cs_probe,
 200         .remove         = sl811_cs_detach,
 201         .id_table       = sl811_ids,
 202 };
 203 module_pcmcia_driver(sl811_cs_driver);

/* [<][>][^][v][top][bottom][index][help] */