blob: 1f4feaab21af28bd81721c42dfcdbbe7e962f5e5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*======================================================================
2
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======================================================================*/
37
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/init.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041#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
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <pcmcia/cs_types.h>
50#include <pcmcia/cs.h>
51#include <pcmcia/cistpl.h>
52#include <pcmcia/cisreg.h>
53#include <pcmcia/ds.h>
54#include "hisax_cfg.h"
55
56MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
57MODULE_AUTHOR("Marcus Niemann");
58MODULE_LICENSE("Dual MPL/GPL");
59
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
61/*====================================================================*/
62
63/* Parameters that can be set with 'insmod' */
64
65static int protocol = 2; /* EURO-ISDN Default */
66module_param(protocol, int, 0);
67
68/*====================================================================*/
69
70/*
71 The event() function is this driver's Card Services event handler.
72 It will be called by Card Services when an appropriate card status
73 event is received. The config() and release() entry points are
74 used to configure or release a socket, in response to card
75 insertion and ejection events. They are invoked from the sedlbauer
76 event handler.
77*/
78
Henne93b39a02010-03-25 12:05:29 +000079static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
Dominik Brodowskifba395e2006-03-31 17:21:06 +020080static void sedlbauer_release(struct pcmcia_device *link);
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82/*
83 The attach() and detach() entry points are used to create and destroy
84 "instances" of the driver, where each instance represents everything
85 needed to manage one actual PCMCIA card.
86*/
87
Henne93b39a02010-03-25 12:05:29 +000088static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Linus Torvalds1da177e2005-04-16 15:20:36 -070090typedef struct local_info_t {
Dominik Brodowskifd238232006-03-05 10:45:09 +010091 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 int stop;
93 int cardnr;
94} local_info_t;
95
96/*======================================================================
97
98 sedlbauer_attach() creates an "instance" of the driver, allocating
99 local data structures for one device. The device is registered
100 with Card Services.
101
102 The dev_link structure is initialized, but we don't actually
103 configure the card at this point -- we wait until we receive a
104 card insertion event.
105
106======================================================================*/
107
Henne93b39a02010-03-25 12:05:29 +0000108static int __devinit sedlbauer_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
110 local_info_t *local;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200111
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200112 dev_dbg(&link->dev, "sedlbauer_attach()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114 /* Allocate space for private device-specific data */
Burman Yan41f96932006-12-08 02:39:35 -0800115 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100116 if (!local) return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 local->cardnr = -1;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100118
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200119 local->p_dev = link;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100120 link->priv = local;
121
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 /*
123 General socket configuration defaults can go here. In this
124 client, we assume very little, and rely on the CIS for almost
125 everything. In most clients, many details (i.e., number, sizes,
126 and attributes of IO windows) are fixed by the nature of the
127 device, and can be hard-wired here.
128 */
129
130 /* from old sedl_cs
131 */
132 /* The io structure describes IO port mapping */
133 link->io.NumPorts1 = 8;
134 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
135 link->io.IOAddrLines = 3;
136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 link->conf.Attributes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 link->conf.IntType = INT_MEMORY_AND_IO;
139
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200140 return sedlbauer_config(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141} /* sedlbauer_attach */
142
143/*======================================================================
144
145 This deletes a driver "instance". The device is de-registered
146 with Card Services. If it has been released, all local data
147 structures are freed. Otherwise, the structures will be freed
148 when the device is released.
149
150======================================================================*/
151
Henne93b39a02010-03-25 12:05:29 +0000152static void __devexit sedlbauer_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200154 dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100156 ((local_info_t *)link->priv)->stop = 1;
157 sedlbauer_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100159 /* This points to the parent local_info_t struct */
160 kfree(link->priv);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161} /* sedlbauer_detach */
162
163/*======================================================================
164
165 sedlbauer_config() is scheduled to run after a CARD_INSERTION event
166 is received, to configure the PCMCIA socket, and to make the
167 device available to the system.
168
169======================================================================*/
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200170static int sedlbauer_config_check(struct pcmcia_device *p_dev,
171 cistpl_cftable_entry_t *cfg,
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200172 cistpl_cftable_entry_t *dflt,
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200173 unsigned int vcc,
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200174 void *priv_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175{
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200176 win_req_t *req = priv_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200178 if (cfg->index == 0)
179 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 /* Does this card need audio output? */
182 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200183 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
184 p_dev->conf.Status = CCSR_AUDIO_ENA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200186
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 /* Use power settings for Vcc and Vpp if present */
188 /* Note that the CIS values need to be rescaled */
189 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200190 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200191 return -ENODEV;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200192 } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200193 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200194 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200196
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200198 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200199 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
200 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200201
Dominik Brodowskieb141202010-03-07 12:21:16 +0100202 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 /* IO window settings */
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200205 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200206 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
207 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200208 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
209 if (!(io->flags & CISTPL_IO_8BIT))
210 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
211 if (!(io->flags & CISTPL_IO_16BIT))
212 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
213 p_dev->io.BasePort1 = io->win[0].base;
214 p_dev->io.NumPorts1 = io->win[0].len;
215 if (io->nwin > 1) {
216 p_dev->io.Attributes2 = p_dev->io.Attributes1;
217 p_dev->io.BasePort2 = io->win[1].base;
218 p_dev->io.NumPorts2 = io->win[1].len;
219 }
220 /* This reserves IO space but doesn't actually enable it */
221 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
222 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 }
224
225 /*
226 Now set up a common memory window, if needed. There is room
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200227 in the struct pcmcia_device structure for one memory window handle,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 but if the base addresses need to be saved, or if multiple
229 windows are needed, the info should go in the private data
230 structure for this device.
231
232 Note that the memory window base is a physical address, and
233 needs to be mapped to virtual space with ioremap() before it
234 is used.
235 */
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200236 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
237 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200238 memreq_t map;
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200239 req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
240 req->Attributes |= WIN_ENABLE;
241 req->Base = mem->win[0].host_addr;
242 req->Size = mem->win[0].len;
243 req->AccessSpeed = 0;
Dominik Brodowski6838b032009-11-03 01:31:52 +0100244 if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200245 return -ENODEV;
246 map.Page = 0;
247 map.CardOffset = mem->win[0].card_addr;
Magnus Damm868575d2006-12-13 19:46:43 +0900248 if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200249 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200251 return 0;
252}
Dominik Brodowski50db3fd2006-01-15 10:05:19 +0100253
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200254
255
Henne93b39a02010-03-25 12:05:29 +0000256static int __devinit sedlbauer_config(struct pcmcia_device *link)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200257{
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200258 win_req_t *req;
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200259 int ret;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200260 IsdnCard_t icard;
261
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200262 dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200263
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200264 req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
265 if (!req)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200266 return -ENOMEM;
267
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200268 /*
269 In this loop, we scan the CIS for configuration table entries,
270 each of which describes a valid card configuration, including
271 voltage, IO window, memory window, and interrupt settings.
272
273 We make no assumptions about the card to be configured: we use
274 just the information available in the CIS. In an ideal world,
275 this would work for any PCMCIA card, but it requires a complete
276 and accurate CIS. In practice, a driver usually "knows" most of
277 these things without consulting the CIS, and most client drivers
278 will only use the CIS to fill in implementation-defined details.
279 */
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200280 ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
281 if (ret)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200282 goto failed;
Dominik Brodowski50db3fd2006-01-15 10:05:19 +0100283
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 This actually configures the PCMCIA socket -- setting up
286 the I/O windows and the interrupt mapping, and putting the
287 card and host interface into "Memory and IO" mode.
288 */
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200289 ret = pcmcia_request_configuration(link, &link->conf);
290 if (ret)
291 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 /* Finally, report what we've done */
Dominik Brodowskided6a1a2010-03-20 19:35:12 +0100294 dev_info(&link->dev, "index 0x%02x:",
295 link->conf.ConfigIndex);
Dominik Brodowski70294b42006-01-15 12:43:16 +0100296 if (link->conf.Vpp)
297 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 if (link->conf.Attributes & CONF_ENABLE_IRQ)
Dominik Brodowskieb141202010-03-07 12:21:16 +0100299 printk(", irq %d", link->irq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 if (link->io.NumPorts1)
301 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
302 link->io.BasePort1+link->io.NumPorts1-1);
303 if (link->io.NumPorts2)
304 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
305 link->io.BasePort2+link->io.NumPorts2-1);
306 if (link->win)
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200307 printk(", mem 0x%06lx-0x%06lx", req->Base,
308 req->Base+req->Size-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 printk("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
Dominik Brodowskieb141202010-03-07 12:21:16 +0100311 icard.para[0] = link->irq;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 icard.para[1] = link->io.BasePort1;
313 icard.protocol = protocol;
314 icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
315
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200316 ret = hisax_init_pcmcia(link,
317 &(((local_info_t *)link->priv)->stop), &icard);
318 if (ret < 0) {
319 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
320 ret, link->io.BasePort1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 sedlbauer_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200322 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 } else
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200324 ((local_info_t *)link->priv)->cardnr = ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200326 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200328failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 sedlbauer_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200330 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331
332} /* sedlbauer_config */
333
334/*======================================================================
335
336 After a card is removed, sedlbauer_release() will unregister the
337 device, and release the PCMCIA configuration. If the device is
338 still open, this will be postponed until it is closed.
339
340======================================================================*/
341
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200342static void sedlbauer_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343{
344 local_info_t *local = link->priv;
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200345 dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346
347 if (local) {
348 if (local->cardnr >= 0) {
349 /* no unregister function with hisax */
350 HiSax_closecard(local->cardnr);
351 }
352 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200354 pcmcia_disable_device(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355} /* sedlbauer_release */
356
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200357static int sedlbauer_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100358{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100359 local_info_t *dev = link->priv;
360
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100361 dev->stop = 1;
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100362
363 return 0;
364}
365
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200366static int sedlbauer_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100367{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100368 local_info_t *dev = link->priv;
369
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100370 dev->stop = 0;
371
372 return 0;
373}
374
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Dominik Brodowski70799732005-06-27 16:28:41 -0700376static struct pcmcia_device_id sedlbauer_ids[] = {
Karsten Keil84d370b2005-09-14 14:19:13 -0700377 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
Dominik Brodowski70799732005-06-27 16:28:41 -0700378 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
379 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
380 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe),
381 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c),
382 PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae),
383/* PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/
384 PCMCIA_DEVICE_NULL
385};
386MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids);
387
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388static struct pcmcia_driver sedlbauer_driver = {
389 .owner = THIS_MODULE,
390 .drv = {
391 .name = "sedlbauer_cs",
392 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200393 .probe = sedlbauer_probe,
Henne93b39a02010-03-25 12:05:29 +0000394 .remove = __devexit_p(sedlbauer_detach),
Dominik Brodowski70799732005-06-27 16:28:41 -0700395 .id_table = sedlbauer_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100396 .suspend = sedlbauer_suspend,
397 .resume = sedlbauer_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398};
399
400static int __init init_sedlbauer_cs(void)
401{
402 return pcmcia_register_driver(&sedlbauer_driver);
403}
404
405static void __exit exit_sedlbauer_cs(void)
406{
407 pcmcia_unregister_driver(&sedlbauer_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408}
409
410module_init(init_sedlbauer_cs);
411module_exit(exit_sedlbauer_cs);