1 /* $Id: avm_cs.c,v 1.4.6.3 2001/09/23 22:24:33 kai Exp $
3 * A PCMCIA client driver for AVM B1/M1/M2
5 * Copyright 1999 by Carsten Paeth <calle@calle.de>
7 * This software may be used and distributed according to the terms
8 * of the GNU General Public License, incorporated herein by reference.
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>
22 #include <pcmcia/cistpl.h>
23 #include <pcmcia/ciscode.h>
24 #include <pcmcia/ds.h>
25 #include <pcmcia/cisreg.h>
27 #include <linux/skbuff.h>
28 #include <linux/capi.h>
29 #include <linux/b1lli.h>
30 #include <linux/b1pcmcia.h>
32 /*====================================================================*/
34 MODULE_DESCRIPTION("CAPI4Linux: PCMCIA client driver for AVM B1/M1/M2");
35 MODULE_AUTHOR("Carsten Paeth");
36 MODULE_LICENSE("GPL");
38 /*====================================================================*/
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
);
44 static int avmcs_probe(struct pcmcia_device
*p_dev
)
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
;
51 return avmcs_config(p_dev
);
55 static void avmcs_detach(struct pcmcia_device
*link
)
60 static int avmcs_configcheck(struct pcmcia_device
*p_dev
, void *priv_data
)
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
;
66 return pcmcia_request_io(p_dev
);
69 static int avmcs_config(struct pcmcia_device
*link
)
74 int (*addcard
)(unsigned int port
, unsigned irq
);
78 strlcpy(devname
, link
->prod_id
[1], sizeof(devname
));
83 if (pcmcia_loop_config(link
, avmcs_configcheck
, NULL
))
89 pcmcia_disable_device(link
);
94 * configure the PCMCIA socket
96 i
= pcmcia_enable_device(link
);
98 pcmcia_disable_device(link
);
105 char *s
= strrchr(devname
, ' ');
109 if (strcmp("M1", s
) == 0) {
110 cardtype
= AVM_CARDTYPE_M1
;
111 } else if (strcmp("M2", s
) == 0) {
112 cardtype
= AVM_CARDTYPE_M2
;
114 cardtype
= AVM_CARDTYPE_B1
;
117 cardtype
= AVM_CARDTYPE_B1
;
119 /* If any step failed, release any partially configured state */
127 case AVM_CARDTYPE_M1
: addcard
= b1pcmcia_addcard_m1
; break;
128 case AVM_CARDTYPE_M2
: addcard
= b1pcmcia_addcard_m2
; break;
130 case AVM_CARDTYPE_B1
: addcard
= b1pcmcia_addcard_b1
; break;
132 if ((i
= (*addcard
)(link
->resource
[0]->start
, link
->irq
)) < 0) {
134 "avm_cs: failed to add AVM-Controller at i/o %#x, irq %d\n",
135 (unsigned int) link
->resource
[0]->start
, link
->irq
);
144 static void avmcs_release(struct pcmcia_device
*link
)
146 b1pcmcia_delcard(link
->resource
[0]->start
, link
->irq
);
147 pcmcia_disable_device(link
);
148 } /* avmcs_release */
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),
157 MODULE_DEVICE_TABLE(pcmcia
, avmcs_ids
);
159 static struct pcmcia_driver avmcs_driver
= {
160 .owner
= THIS_MODULE
,
162 .probe
= avmcs_probe
,
163 .remove
= avmcs_detach
,
164 .id_table
= avmcs_ids
,
166 module_pcmcia_driver(avmcs_driver
);