Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /*====================================================================== |
2 | ||
475be4d8 JP |
3 | A Sedlbauer PCMCIA client driver |
4 | ||
5 | This driver is for the Sedlbauer Speed Star and Speed Star II, | |
6 | which are ISDN PCMCIA Cards. | |
7 | ||
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/ | |
12 | ||
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. | |
17 | ||
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. | |
21 | ||
22 | Modifications from dummy_cs.c are Copyright (C) 1999-2001 Marcus Niemann | |
23 | <maniemann@users.sourceforge.net>. All Rights Reserved. | |
24 | ||
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. | |
35 | ||
36 | ======================================================================*/ | |
1da177e4 LT |
37 | |
38 | #include <linux/kernel.h> | |
39 | #include <linux/module.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> | |
47 | #include <asm/system.h> | |
48 | ||
1da177e4 LT |
49 | #include <pcmcia/cistpl.h> |
50 | #include <pcmcia/cisreg.h> | |
51 | #include <pcmcia/ds.h> | |
52 | #include "hisax_cfg.h" | |
53 | ||
54 | MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards"); | |
55 | MODULE_AUTHOR("Marcus Niemann"); | |
56 | MODULE_LICENSE("Dual MPL/GPL"); | |
57 | ||
1da177e4 LT |
58 | |
59 | /*====================================================================*/ | |
60 | ||
61 | /* Parameters that can be set with 'insmod' */ | |
62 | ||
63 | static int protocol = 2; /* EURO-ISDN Default */ | |
64 | module_param(protocol, int, 0); | |
65 | ||
475be4d8 | 66 | static int sedlbauer_config(struct pcmcia_device *link) __devinit; |
fba395ee | 67 | static void sedlbauer_release(struct pcmcia_device *link); |
1da177e4 | 68 | |
93b39a0d | 69 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; |
1da177e4 | 70 | |
1da177e4 | 71 | typedef struct local_info_t { |
fd238232 | 72 | struct pcmcia_device *p_dev; |
475be4d8 JP |
73 | int stop; |
74 | int cardnr; | |
1da177e4 LT |
75 | } local_info_t; |
76 | ||
93b39a0d | 77 | static int __devinit sedlbauer_probe(struct pcmcia_device *link) |
1da177e4 | 78 | { |
475be4d8 | 79 | local_info_t *local; |
fba395ee | 80 | |
475be4d8 | 81 | dev_dbg(&link->dev, "sedlbauer_attach()\n"); |
1da177e4 | 82 | |
475be4d8 JP |
83 | /* Allocate space for private device-specific data */ |
84 | local = kzalloc(sizeof(local_info_t), GFP_KERNEL); | |
85 | if (!local) return -ENOMEM; | |
86 | local->cardnr = -1; | |
fd238232 | 87 | |
475be4d8 JP |
88 | local->p_dev = link; |
89 | link->priv = local; | |
fd238232 | 90 | |
475be4d8 | 91 | return sedlbauer_config(link); |
1da177e4 LT |
92 | } /* sedlbauer_attach */ |
93 | ||
93b39a0d | 94 | static void __devexit sedlbauer_detach(struct pcmcia_device *link) |
1da177e4 | 95 | { |
e773cfe1 | 96 | dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); |
1da177e4 | 97 | |
e2d40963 DB |
98 | ((local_info_t *)link->priv)->stop = 1; |
99 | sedlbauer_release(link); | |
1da177e4 | 100 | |
e2d40963 DB |
101 | /* This points to the parent local_info_t struct */ |
102 | kfree(link->priv); | |
1da177e4 LT |
103 | } /* sedlbauer_detach */ |
104 | ||
00990e7c | 105 | static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data) |
1da177e4 | 106 | { |
00990e7c DB |
107 | if (p_dev->config_index == 0) |
108 | return -EINVAL; | |
109 | ||
110 | p_dev->io_lines = 3; | |
111 | return pcmcia_request_io(p_dev); | |
5fcd4da0 DB |
112 | } |
113 | ||
93b39a0d | 114 | static int __devinit sedlbauer_config(struct pcmcia_device *link) |
5fcd4da0 | 115 | { |
475be4d8 JP |
116 | int ret; |
117 | IsdnCard_t icard; | |
118 | ||
119 | dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); | |
1da177e4 | 120 | |
475be4d8 JP |
121 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC | |
122 | CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; | |
123 | ||
124 | ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL); | |
125 | if (ret) | |
126 | goto failed; | |
127 | ||
128 | ret = pcmcia_enable_device(link); | |
129 | if (ret) | |
130 | goto failed; | |
131 | ||
132 | icard.para[0] = link->irq; | |
133 | icard.para[1] = link->resource[0]->start; | |
134 | icard.protocol = protocol; | |
135 | icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; | |
136 | ||
137 | ret = hisax_init_pcmcia(link, | |
138 | &(((local_info_t *)link->priv)->stop), &icard); | |
139 | if (ret < 0) { | |
140 | printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d with %pR\n", | |
141 | ret, link->resource[0]); | |
142 | sedlbauer_release(link); | |
143 | return -ENODEV; | |
144 | } else | |
145 | ((local_info_t *)link->priv)->cardnr = ret; | |
146 | ||
147 | return 0; | |
1da177e4 | 148 | |
5fcd4da0 | 149 | failed: |
475be4d8 JP |
150 | sedlbauer_release(link); |
151 | return -ENODEV; | |
1da177e4 LT |
152 | |
153 | } /* sedlbauer_config */ | |
154 | ||
fba395ee | 155 | static void sedlbauer_release(struct pcmcia_device *link) |
1da177e4 | 156 | { |
475be4d8 JP |
157 | local_info_t *local = link->priv; |
158 | dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link); | |
159 | ||
160 | if (local) { | |
161 | if (local->cardnr >= 0) { | |
162 | /* no unregister function with hisax */ | |
163 | HiSax_closecard(local->cardnr); | |
164 | } | |
1da177e4 | 165 | } |
1da177e4 | 166 | |
475be4d8 | 167 | pcmcia_disable_device(link); |
1da177e4 LT |
168 | } /* sedlbauer_release */ |
169 | ||
fba395ee | 170 | static int sedlbauer_suspend(struct pcmcia_device *link) |
98e4c28b | 171 | { |
98e4c28b DB |
172 | local_info_t *dev = link->priv; |
173 | ||
98e4c28b | 174 | dev->stop = 1; |
98e4c28b DB |
175 | |
176 | return 0; | |
177 | } | |
178 | ||
fba395ee | 179 | static int sedlbauer_resume(struct pcmcia_device *link) |
98e4c28b | 180 | { |
98e4c28b DB |
181 | local_info_t *dev = link->priv; |
182 | ||
98e4c28b DB |
183 | dev->stop = 0; |
184 | ||
185 | return 0; | |
186 | } | |
187 | ||
1da177e4 | 188 | |
25f8f54f | 189 | static const struct pcmcia_device_id sedlbauer_ids[] = { |
84d370b9 | 190 | PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), |
70799734 DB |
191 | PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90), |
192 | PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce), | |
193 | PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe), | |
194 | PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c), | |
195 | PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae), | |
196 | /* PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/ | |
197 | PCMCIA_DEVICE_NULL | |
198 | }; | |
199 | MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids); | |
200 | ||
1da177e4 LT |
201 | static struct pcmcia_driver sedlbauer_driver = { |
202 | .owner = THIS_MODULE, | |
2e9b981a | 203 | .name = "sedlbauer_cs", |
15b99ac1 | 204 | .probe = sedlbauer_probe, |
93b39a0d | 205 | .remove = __devexit_p(sedlbauer_detach), |
70799734 | 206 | .id_table = sedlbauer_ids, |
98e4c28b DB |
207 | .suspend = sedlbauer_suspend, |
208 | .resume = sedlbauer_resume, | |
1da177e4 LT |
209 | }; |
210 | ||
211 | static int __init init_sedlbauer_cs(void) | |
212 | { | |
213 | return pcmcia_register_driver(&sedlbauer_driver); | |
214 | } | |
215 | ||
216 | static void __exit exit_sedlbauer_cs(void) | |
217 | { | |
218 | pcmcia_unregister_driver(&sedlbauer_driver); | |
1da177e4 LT |
219 | } |
220 | ||
221 | module_init(init_sedlbauer_cs); | |
222 | module_exit(exit_sedlbauer_cs); |