1 /* $Id: teles_cs.c,v 1.1.2.2 2004/01/25 15:07:06 keil Exp $ */
2 /*======================================================================
4 A teles S0 PCMCIA client driver
6 Based on skeleton by David Hinds, dhinds@allegro.stanford.edu
7 Written by Christof Petig, christof.petig@wtal.de
9 Also inspired by ELSA PCMCIA driver
10 by Klaus Lichtenwalder <Lichtenwalder@ACM.org>
12 Extensions to new hisax_pcmcia by Karsten Keil
14 minor changes to be compatible with kernel 2.4.x
15 by Jan.Schubert@GMX.li
17 ======================================================================*/
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/ptrace.h>
23 #include <linux/slab.h>
24 #include <linux/string.h>
25 #include <linux/timer.h>
26 #include <linux/ioport.h>
28 #include <asm/system.h>
30 #include <pcmcia/cistpl.h>
31 #include <pcmcia/cisreg.h>
32 #include <pcmcia/ds.h>
33 #include "hisax_cfg.h"
35 MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
36 MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
37 MODULE_LICENSE("GPL");
40 /*====================================================================*/
42 /* Parameters that can be set with 'insmod' */
44 static int protocol
= 2; /* EURO-ISDN Default */
45 module_param(protocol
, int, 0);
47 static int teles_cs_config(struct pcmcia_device
*link
) __devinit
;
48 static void teles_cs_release(struct pcmcia_device
*link
);
49 static void teles_detach(struct pcmcia_device
*p_dev
) __devexit
;
51 typedef struct local_info_t
{
52 struct pcmcia_device
*p_dev
;
57 static int __devinit
teles_probe(struct pcmcia_device
*link
)
61 dev_dbg(&link
->dev
, "teles_attach()\n");
63 /* Allocate space for private device-specific data */
64 local
= kzalloc(sizeof(local_info_t
), GFP_KERNEL
);
65 if (!local
) return -ENOMEM
;
71 link
->config_flags
|= CONF_ENABLE_IRQ
| CONF_AUTO_SET_IO
;
73 return teles_cs_config(link
);
76 static void __devexit
teles_detach(struct pcmcia_device
*link
)
78 local_info_t
*info
= link
->priv
;
80 dev_dbg(&link
->dev
, "teles_detach(0x%p)\n", link
);
83 teles_cs_release(link
);
88 static int teles_cs_configcheck(struct pcmcia_device
*p_dev
, void *priv_data
)
93 p_dev
->resource
[0]->end
= 96;
94 p_dev
->resource
[0]->flags
&= IO_DATA_PATH_WIDTH
;
95 p_dev
->resource
[0]->flags
|= IO_DATA_PATH_WIDTH_AUTO
;
97 if ((p_dev
->resource
[0]->end
) && p_dev
->resource
[0]->start
) {
98 printk(KERN_INFO
"(teles_cs: looks like the 96 model)\n");
99 if (!pcmcia_request_io(p_dev
))
102 printk(KERN_INFO
"(teles_cs: looks like the 97 model)\n");
103 for (j
= 0x2f0; j
> 0x100; j
-= 0x10) {
104 p_dev
->resource
[0]->start
= j
;
105 if (!pcmcia_request_io(p_dev
))
112 static int __devinit
teles_cs_config(struct pcmcia_device
*link
)
117 dev_dbg(&link
->dev
, "teles_config(0x%p)\n", link
);
119 i
= pcmcia_loop_config(link
, teles_cs_configcheck
, NULL
);
126 i
= pcmcia_enable_device(link
);
130 icard
.para
[0] = link
->irq
;
131 icard
.para
[1] = link
->resource
[0]->start
;
132 icard
.protocol
= protocol
;
133 icard
.typ
= ISDN_CTYPE_TELESPCMCIA
;
135 i
= hisax_init_pcmcia(link
, &(((local_info_t
*)link
->priv
)->busy
), &icard
);
137 printk(KERN_ERR
"teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
138 i
, (unsigned int) link
->resource
[0]->start
);
139 teles_cs_release(link
);
143 ((local_info_t
*)link
->priv
)->cardnr
= i
;
147 teles_cs_release(link
);
149 } /* teles_cs_config */
151 static void teles_cs_release(struct pcmcia_device
*link
)
153 local_info_t
*local
= link
->priv
;
155 dev_dbg(&link
->dev
, "teles_cs_release(0x%p)\n", link
);
158 if (local
->cardnr
>= 0) {
159 /* no unregister function with hisax */
160 HiSax_closecard(local
->cardnr
);
164 pcmcia_disable_device(link
);
165 } /* teles_cs_release */
167 static int teles_suspend(struct pcmcia_device
*link
)
169 local_info_t
*dev
= link
->priv
;
176 static int teles_resume(struct pcmcia_device
*link
)
178 local_info_t
*dev
= link
->priv
;
186 static const struct pcmcia_device_id teles_ids
[] = {
187 PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
190 MODULE_DEVICE_TABLE(pcmcia
, teles_ids
);
192 static struct pcmcia_driver teles_cs_driver
= {
193 .owner
= THIS_MODULE
,
195 .probe
= teles_probe
,
196 .remove
= __devexit_p(teles_detach
),
197 .id_table
= teles_ids
,
198 .suspend
= teles_suspend
,
199 .resume
= teles_resume
,
202 static int __init
init_teles_cs(void)
204 return pcmcia_register_driver(&teles_cs_driver
);
207 static void __exit
exit_teles_cs(void)
209 pcmcia_unregister_driver(&teles_cs_driver
);
212 module_init(init_teles_cs
);
213 module_exit(exit_teles_cs
);