root/drivers/staging/isdn/avm/avm_cs.c

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

DEFINITIONS

This source file includes following definitions.
  1. avmcs_probe
  2. avmcs_detach
  3. avmcs_configcheck
  4. avmcs_config
  5. avmcs_release

   1 /* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
   2  *
   3  * A PCMCIA client driver for AVM B1/M1/M2
   4  *
   5  * Copyright 1999 by Carsten Paeth <calle@calle.de>
   6  *
   7  * This software may be used and distributed according to the terms
   8  * of the GNU General Public License, incorporated herein by reference.
   9  *
  10  */
  11 
  12 #include <linux/module.h>
  13 #include <linux/kernel.h>
  14 #include <linux/init.h>
  15 #include <linux/ptrace.h>
  16 #include <linux/string.h>
  17 #include <linux/tty.h>
  18 #include <linux/serial.h>
  19 #include <linux/major.h>
  20 #include <asm/io.h>
  21 
  22 #include <pcmcia/cistpl.h>
  23 #include <pcmcia/ciscode.h>
  24 #include <pcmcia/ds.h>
  25 #include <pcmcia/cisreg.h>
  26 
  27 #include <linux/skbuff.h>
  28 #include <linux/capi.h>
  29 #include <linux/b1lli.h>
  30 #include <linux/b1pcmcia.h>
  31 
  32 /*====================================================================*/
  33 
  34 MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
  35 MODULE_AUTHOR("Carsten Paeth");
  36 MODULE_LICENSE("GPL");
  37 
  38 /*====================================================================*/
  39 
  40 static int avmcs_config(struct pcmcia_device *link);
  41 static void avmcs_release(struct pcmcia_device *link);
  42 static void avmcs_detach(struct pcmcia_device *p_dev);
  43 
  44 static int avmcs_probe(struct pcmcia_device *p_dev)
  45 {
  46         /* General socket configuration */
  47         p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
  48         p_dev->config_index = 1;
  49         p_dev->config_regs = PRESENT_OPTION;
  50 
  51         return avmcs_config(p_dev);
  52 } /* avmcs_attach */
  53 
  54 
  55 static void avmcs_detach(struct pcmcia_device *link)
  56 {
  57         avmcs_release(link);
  58 } /* avmcs_detach */
  59 
  60 static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
  61 {
  62         p_dev->resource[0]->end = 16;
  63         p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
  64         p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
  65 
  66         return pcmcia_request_io(p_dev);
  67 }
  68 
  69 static int avmcs_config(struct pcmcia_device *link)
  70 {
  71         int i = -1;
  72         char devname[128];
  73         int cardtype;
  74         int (*addcard)(unsigned int port, unsigned irq);
  75 
  76         devname[0] = 0;
  77         if (link->prod_id[1])
  78                 strlcpy(devname, link->prod_id[1], sizeof(devname));
  79 
  80         /*
  81          * find IO port
  82          */
  83         if (pcmcia_loop_config(link, avmcs_configcheck, NULL))
  84                 return -ENODEV;
  85 
  86         do {
  87                 if (!link->irq) {
  88                         /* undo */
  89                         pcmcia_disable_device(link);
  90                         break;
  91                 }
  92 
  93                 /*
  94                  * configure the PCMCIA socket
  95                  */
  96                 i = pcmcia_enable_device(link);
  97                 if (i != 0) {
  98                         pcmcia_disable_device(link);
  99                         break;
 100                 }
 101 
 102         } while (0);
 103 
 104         if (devname[0]) {
 105                 char *s = strrchr(devname, ' ');
 106                 if (!s)
 107                         s = devname;
 108                 else s++;
 109                 if (strcmp("M1", s) == 0) {
 110                         cardtype = AVM_CARDTYPE_M1;
 111                 } else if (strcmp("M2", s) == 0) {
 112                         cardtype = AVM_CARDTYPE_M2;
 113                 } else {
 114                         cardtype = AVM_CARDTYPE_B1;
 115                 }
 116         } else
 117                 cardtype = AVM_CARDTYPE_B1;
 118 
 119         /* If any step failed, release any partially configured state */
 120         if (i != 0) {
 121                 avmcs_release(link);
 122                 return -ENODEV;
 123         }
 124 
 125 
 126         switch (cardtype) {
 127         case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
 128         case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
 129         default:
 130         case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
 131         }
 132         if ((i = (*addcard)(link->resource[0]->start, link->irq)) < 0) {
 133                 dev_err(&link->dev,
 134                         "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
 135                         (unsigned int) link->resource[0]->start, link->irq);
 136                 avmcs_release(link);
 137                 return -ENODEV;
 138         }
 139         return 0;
 140 
 141 } /* avmcs_config */
 142 
 143 
 144 static void avmcs_release(struct pcmcia_device *link)
 145 {
 146         b1pcmcia_delcard(link->resource[0]->start, link->irq);
 147         pcmcia_disable_device(link);
 148 } /* avmcs_release */
 149 
 150 
 151 static const struct pcmcia_device_id avmcs_ids[] = {
 152         PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
 153         PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430),
 154         PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a),
 155         PCMCIA_DEVICE_NULL
 156 };
 157 MODULE_DEVICE_TABLE(pcmcia, avmcs_ids);
 158 
 159 static struct pcmcia_driver avmcs_driver = {
 160         .owner  = THIS_MODULE,
 161         .name           = "avm_cs",
 162         .probe = avmcs_probe,
 163         .remove = avmcs_detach,
 164         .id_table = avmcs_ids,
 165 };
 166 module_pcmcia_driver(avmcs_driver);

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