Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
[deliverable/linux.git] / drivers / isdn / hisax / elsa_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
475be4d8 3 An elsa_cs PCMCIA client driver
1da177e4 4
475be4d8 5 This driver is for the Elsa PCM ISDN Cards, i.e. the MicroLink
1da177e4
LT
6
7
475be4d8
JP
8 The contents of this file are subject to the Mozilla Public
9 License Version 1.1 (the "License"); you may not use this file
10 except in compliance with the License. You may obtain a copy of
11 the License at http://www.mozilla.org/MPL/
1da177e4 12
475be4d8
JP
13 Software distributed under the License is distributed on an "AS
14 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15 implied. See the License for the specific language governing
16 rights and limitations under the License.
1da177e4 17
475be4d8
JP
18 The initial developer of the original code is David A. Hinds
19 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
20 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
1da177e4 21
475be4d8
JP
22 Modifications from dummy_cs.c are Copyright (C) 1999-2001 Klaus
23 Lichtenwalder <Lichtenwalder@ACM.org>. All Rights Reserved.
1da177e4 24
475be4d8
JP
25 Alternatively, the contents of this file may be used under the
26 terms of the GNU General Public License version 2 (the "GPL"), in
27 which case the provisions of the GPL are applicable instead of the
28 above. If you wish to allow the use of your version of this file
29 only under the terms of the GPL and not to allow others to use
30 your version of this file under the MPL, indicate your decision
31 by deleting the provisions above and replace them with the notice
32 and other provisions required by the GPL. If you do not delete
33 the provisions above, a recipient may use your version of this
34 file under either the MPL or the GPL.
1da177e4 35
475be4d8 36 ======================================================================*/
1da177e4
LT
37
38#include <linux/module.h>
39#include <linux/kernel.h>
40#include <linux/init.h>
1da177e4
LT
41#include <linux/ptrace.h>
42#include <linux/slab.h>
43#include <linux/string.h>
44#include <linux/timer.h>
45#include <linux/ioport.h>
46#include <asm/io.h>
1da177e4 47
1da177e4
LT
48#include <pcmcia/cistpl.h>
49#include <pcmcia/cisreg.h>
50#include <pcmcia/ds.h>
51#include "hisax_cfg.h"
52
53MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
54MODULE_AUTHOR("Klaus Lichtenwalder");
55MODULE_LICENSE("Dual MPL/GPL");
56
1da177e4
LT
57
58/*====================================================================*/
59
60/* Parameters that can be set with 'insmod' */
61
62static int protocol = 2; /* EURO-ISDN Default */
63module_param(protocol, int, 0);
64
ed5a84cd 65static int elsa_cs_config(struct pcmcia_device *link);
fba395ee 66static void elsa_cs_release(struct pcmcia_device *link);
ed5a84cd 67static void elsa_cs_detach(struct pcmcia_device *p_dev);
1da177e4 68
1da177e4 69typedef struct local_info_t {
fd238232 70 struct pcmcia_device *p_dev;
475be4d8
JP
71 int busy;
72 int cardnr;
1da177e4
LT
73} local_info_t;
74
ed5a84cd 75static int elsa_cs_probe(struct pcmcia_device *link)
1da177e4 76{
475be4d8 77 local_info_t *local;
1da177e4 78
475be4d8 79 dev_dbg(&link->dev, "elsa_cs_attach()\n");
1da177e4 80
475be4d8
JP
81 /* Allocate space for private device-specific data */
82 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
83 if (!local) return -ENOMEM;
fd238232 84
475be4d8
JP
85 local->p_dev = link;
86 link->priv = local;
fd238232 87
475be4d8 88 local->cardnr = -1;
1da177e4 89
475be4d8 90 return elsa_cs_config(link);
1da177e4
LT
91} /* elsa_cs_attach */
92
ed5a84cd 93static void elsa_cs_detach(struct pcmcia_device *link)
1da177e4 94{
e2d40963 95 local_info_t *info = link->priv;
1da177e4 96
e773cfe1 97 dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
1da177e4 98
e2d40963
DB
99 info->busy = 1;
100 elsa_cs_release(link);
1da177e4 101
e2d40963 102 kfree(info);
1da177e4
LT
103} /* elsa_cs_detach */
104
00990e7c 105static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data)
1da177e4 106{
5fcd4da0
DB
107 int j;
108
90abdc3b 109 p_dev->io_lines = 3;
00990e7c
DB
110 p_dev->resource[0]->end = 8;
111 p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH;
112 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
90abdc3b 113
00990e7c 114 if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) {
5fcd4da0 115 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
90abdc3b 116 if (!pcmcia_request_io(p_dev))
5fcd4da0
DB
117 return 0;
118 } else {
119 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
5fcd4da0 120 for (j = 0x2f0; j > 0x100; j -= 0x10) {
90abdc3b
DB
121 p_dev->resource[0]->start = j;
122 if (!pcmcia_request_io(p_dev))
5fcd4da0
DB
123 return 0;
124 }
125 }
126 return -ENODEV;
1da177e4
LT
127}
128
ed5a84cd 129static int elsa_cs_config(struct pcmcia_device *link)
1da177e4 130{
475be4d8
JP
131 int i;
132 IsdnCard_t icard;
133
134 dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
135
136 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
137
138 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
139 if (i != 0)
140 goto failed;
141
142 if (!link->irq)
143 goto failed;
144
145 i = pcmcia_enable_device(link);
146 if (i != 0)
147 goto failed;
148
149 icard.para[0] = link->irq;
150 icard.para[1] = link->resource[0]->start;
151 icard.protocol = protocol;
152 icard.typ = ISDN_CTYPE_ELSA_PCMCIA;
153
154 i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard);
155 if (i < 0) {
156 printk(KERN_ERR "elsa_cs: failed to initialize Elsa "
157 "PCMCIA %d with %pR\n", i, link->resource[0]);
158 elsa_cs_release(link);
159 } else
160 ((local_info_t *)link->priv)->cardnr = i;
161
162 return 0;
e773cfe1 163failed:
475be4d8
JP
164 elsa_cs_release(link);
165 return -ENODEV;
1da177e4
LT
166} /* elsa_cs_config */
167
fba395ee 168static void elsa_cs_release(struct pcmcia_device *link)
1da177e4 169{
475be4d8 170 local_info_t *local = link->priv;
1da177e4 171
475be4d8 172 dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
1da177e4 173
475be4d8
JP
174 if (local) {
175 if (local->cardnr >= 0) {
176 /* no unregister function with hisax */
177 HiSax_closecard(local->cardnr);
178 }
1da177e4 179 }
5f2a71fc 180
475be4d8 181 pcmcia_disable_device(link);
1da177e4
LT
182} /* elsa_cs_release */
183
fba395ee 184static int elsa_suspend(struct pcmcia_device *link)
98e4c28b 185{
98e4c28b
DB
186 local_info_t *dev = link->priv;
187
475be4d8 188 dev->busy = 1;
98e4c28b
DB
189
190 return 0;
191}
192
fba395ee 193static int elsa_resume(struct pcmcia_device *link)
98e4c28b 194{
98e4c28b
DB
195 local_info_t *dev = link->priv;
196
475be4d8 197 dev->busy = 0;
98e4c28b
DB
198
199 return 0;
200}
201
25f8f54f 202static const struct pcmcia_device_id elsa_ids[] = {
02ae38cf
DB
203 PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
204 PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257),
205 PCMCIA_DEVICE_NULL
206};
207MODULE_DEVICE_TABLE(pcmcia, elsa_ids);
208
1da177e4
LT
209static struct pcmcia_driver elsa_cs_driver = {
210 .owner = THIS_MODULE,
2e9b981a 211 .name = "elsa_cs",
15b99ac1 212 .probe = elsa_cs_probe,
ed5a84cd 213 .remove = elsa_cs_detach,
02ae38cf 214 .id_table = elsa_ids,
98e4c28b
DB
215 .suspend = elsa_suspend,
216 .resume = elsa_resume,
1da177e4 217};
0aae9c6a 218module_pcmcia_driver(elsa_cs_driver);
This page took 0.828653 seconds and 5 git commands to generate.