blob: 71b3ddef03bb790836d7d5ff63a24e8261329eb0 [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
90/*
91 You'll also need to prototype all the functions that will actually
92 be used to talk to your device. See 'memory_cs' for a good example
93 of a fully self-sufficient driver; the other drivers rely more or
94 less on other parts of the kernel.
95*/
96
97/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070098 A driver needs to provide a dev_node_t structure for each device
99 on a card. In some cases, there is only one device per card (for
100 example, ethernet cards, modems). In other cases, there may be
101 many actual or logical devices (SCSI adapters, memory cards with
102 multiple partitions). The dev_node_t structures need to be kept
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200103 in a linked list starting at the 'dev' field of a struct pcmcia_device
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104 structure. We allocate them in the card's private data structure,
105 because they generally shouldn't be allocated dynamically.
106
107 In this case, we also provide a flag to indicate if a device is
108 "stopped" due to a power management event, or card ejection. The
109 device IO routines can use a flag like this to throttle IO to a
110 card that is not ready to accept it.
111*/
112
113typedef struct local_info_t {
Dominik Brodowskifd238232006-03-05 10:45:09 +0100114 struct pcmcia_device *p_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 dev_node_t node;
116 int stop;
117 int cardnr;
118} local_info_t;
119
120/*======================================================================
121
122 sedlbauer_attach() creates an "instance" of the driver, allocating
123 local data structures for one device. The device is registered
124 with Card Services.
125
126 The dev_link structure is initialized, but we don't actually
127 configure the card at this point -- we wait until we receive a
128 card insertion event.
129
130======================================================================*/
131
Henne93b39a02010-03-25 12:05:29 +0000132static int __devinit sedlbauer_probe(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
134 local_info_t *local;
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200135
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200136 dev_dbg(&link->dev, "sedlbauer_attach()\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137
138 /* Allocate space for private device-specific data */
Burman Yan41f96932006-12-08 02:39:35 -0800139 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
Dominik Brodowskif8cfa612005-11-14 21:25:51 +0100140 if (!local) return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141 local->cardnr = -1;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100142
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200143 local->p_dev = link;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100144 link->priv = local;
145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 /* Interrupt setup */
Dominik Brodowskie15c1c12009-11-28 18:12:06 +0100147 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 link->irq.Handler = NULL;
149
150 /*
151 General socket configuration defaults can go here. In this
152 client, we assume very little, and rely on the CIS for almost
153 everything. In most clients, many details (i.e., number, sizes,
154 and attributes of IO windows) are fixed by the nature of the
155 device, and can be hard-wired here.
156 */
157
158 /* from old sedl_cs
159 */
160 /* The io structure describes IO port mapping */
161 link->io.NumPorts1 = 8;
162 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
163 link->io.IOAddrLines = 3;
164
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 link->conf.Attributes = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 link->conf.IntType = INT_MEMORY_AND_IO;
167
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200168 return sedlbauer_config(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169} /* sedlbauer_attach */
170
171/*======================================================================
172
173 This deletes a driver "instance". The device is de-registered
174 with Card Services. If it has been released, all local data
175 structures are freed. Otherwise, the structures will be freed
176 when the device is released.
177
178======================================================================*/
179
Henne93b39a02010-03-25 12:05:29 +0000180static void __devexit sedlbauer_detach(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181{
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200182 dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100184 ((local_info_t *)link->priv)->stop = 1;
185 sedlbauer_release(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Dominik Brodowskie2d40962006-03-02 00:09:29 +0100187 /* This points to the parent local_info_t struct */
188 kfree(link->priv);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189} /* sedlbauer_detach */
190
191/*======================================================================
192
193 sedlbauer_config() is scheduled to run after a CARD_INSERTION event
194 is received, to configure the PCMCIA socket, and to make the
195 device available to the system.
196
197======================================================================*/
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200198static int sedlbauer_config_check(struct pcmcia_device *p_dev,
199 cistpl_cftable_entry_t *cfg,
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200200 cistpl_cftable_entry_t *dflt,
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200201 unsigned int vcc,
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200202 void *priv_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203{
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200204 win_req_t *req = priv_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200206 if (cfg->index == 0)
207 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 /* Does this card need audio output? */
210 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200211 p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
212 p_dev->conf.Status = CCSR_AUDIO_ENA;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200214
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215 /* Use power settings for Vcc and Vpp if present */
216 /* Note that the CIS values need to be rescaled */
217 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200218 if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200219 return -ENODEV;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200220 } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200221 if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200222 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200224
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200226 p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200227 else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
228 p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200229
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 /* Do we need to allocate an interrupt? */
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200231 if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200232 p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
233
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 /* IO window settings */
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200235 p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200236 if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
237 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200238 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
239 if (!(io->flags & CISTPL_IO_8BIT))
240 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
241 if (!(io->flags & CISTPL_IO_16BIT))
242 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
243 p_dev->io.BasePort1 = io->win[0].base;
244 p_dev->io.NumPorts1 = io->win[0].len;
245 if (io->nwin > 1) {
246 p_dev->io.Attributes2 = p_dev->io.Attributes1;
247 p_dev->io.BasePort2 = io->win[1].base;
248 p_dev->io.NumPorts2 = io->win[1].len;
249 }
250 /* This reserves IO space but doesn't actually enable it */
251 if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
252 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 }
254
255 /*
256 Now set up a common memory window, if needed. There is room
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200257 in the struct pcmcia_device structure for one memory window handle,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 but if the base addresses need to be saved, or if multiple
259 windows are needed, the info should go in the private data
260 structure for this device.
261
262 Note that the memory window base is a physical address, and
263 needs to be mapped to virtual space with ioremap() before it
264 is used.
265 */
Dominik Brodowski8e2fc392008-08-02 15:30:31 +0200266 if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
267 cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200268 memreq_t map;
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200269 req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
270 req->Attributes |= WIN_ENABLE;
271 req->Base = mem->win[0].host_addr;
272 req->Size = mem->win[0].len;
273 req->AccessSpeed = 0;
Dominik Brodowski6838b032009-11-03 01:31:52 +0100274 if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200275 return -ENODEV;
276 map.Page = 0;
277 map.CardOffset = mem->win[0].card_addr;
Magnus Damm868575d2006-12-13 19:46:43 +0900278 if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200279 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 }
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200281 return 0;
282}
Dominik Brodowski50db3fd2006-01-15 10:05:19 +0100283
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200284
285
Henne93b39a02010-03-25 12:05:29 +0000286static int __devinit sedlbauer_config(struct pcmcia_device *link)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200287{
288 local_info_t *dev = link->priv;
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200289 win_req_t *req;
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200290 int ret;
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200291 IsdnCard_t icard;
292
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200293 dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200294
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200295 req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
296 if (!req)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200297 return -ENOMEM;
298
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200299 /*
300 In this loop, we scan the CIS for configuration table entries,
301 each of which describes a valid card configuration, including
302 voltage, IO window, memory window, and interrupt settings.
303
304 We make no assumptions about the card to be configured: we use
305 just the information available in the CIS. In an ideal world,
306 this would work for any PCMCIA card, but it requires a complete
307 and accurate CIS. In practice, a driver usually "knows" most of
308 these things without consulting the CIS, and most client drivers
309 will only use the CIS to fill in implementation-defined details.
310 */
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200311 ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
312 if (ret)
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200313 goto failed;
Dominik Brodowski50db3fd2006-01-15 10:05:19 +0100314
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 /*
316 Allocate an interrupt line. Note that this does not assign a
317 handler to the interrupt, unless the 'Handler' member of the
318 irq structure is initialized.
319 */
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200320 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
321 ret = pcmcia_request_irq(link, &link->irq);
322 if (ret)
323 goto failed;
324 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325
326 /*
327 This actually configures the PCMCIA socket -- setting up
328 the I/O windows and the interrupt mapping, and putting the
329 card and host interface into "Memory and IO" mode.
330 */
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200331 ret = pcmcia_request_configuration(link, &link->conf);
332 if (ret)
333 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
335 /*
336 At this point, the dev_node_t structure(s) need to be
337 initialized and arranged in a linked list at link->dev.
338 */
339 sprintf(dev->node.dev_name, "sedlbauer");
340 dev->node.major = dev->node.minor = 0;
Dominik Brodowskifd238232006-03-05 10:45:09 +0100341 link->dev_node = &dev->node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343 /* Finally, report what we've done */
Dominik Brodowski70294b42006-01-15 12:43:16 +0100344 printk(KERN_INFO "%s: index 0x%02x:",
345 dev->node.dev_name, link->conf.ConfigIndex);
346 if (link->conf.Vpp)
347 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 if (link->conf.Attributes & CONF_ENABLE_IRQ)
349 printk(", irq %d", link->irq.AssignedIRQ);
350 if (link->io.NumPorts1)
351 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
352 link->io.BasePort1+link->io.NumPorts1-1);
353 if (link->io.NumPorts2)
354 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
355 link->io.BasePort2+link->io.NumPorts2-1);
356 if (link->win)
Dominik Brodowskiad913c12008-08-02 16:12:00 +0200357 printk(", mem 0x%06lx-0x%06lx", req->Base,
358 req->Base+req->Size-1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 printk("\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361 icard.para[0] = link->irq.AssignedIRQ;
362 icard.para[1] = link->io.BasePort1;
363 icard.protocol = protocol;
364 icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
365
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200366 ret = hisax_init_pcmcia(link,
367 &(((local_info_t *)link->priv)->stop), &icard);
368 if (ret < 0) {
369 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
370 ret, link->io.BasePort1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 sedlbauer_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200372 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 } else
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200374 ((local_info_t *)link->priv)->cardnr = ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200376 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Dominik Brodowski5fcd4da2008-07-29 08:38:55 +0200378failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 sedlbauer_release(link);
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200380 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
382} /* sedlbauer_config */
383
384/*======================================================================
385
386 After a card is removed, sedlbauer_release() will unregister the
387 device, and release the PCMCIA configuration. If the device is
388 still open, this will be postponed until it is closed.
389
390======================================================================*/
391
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200392static void sedlbauer_release(struct pcmcia_device *link)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393{
394 local_info_t *local = link->priv;
Dominik Brodowskie773cfe2009-10-24 15:50:13 +0200395 dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
397 if (local) {
398 if (local->cardnr >= 0) {
399 /* no unregister function with hisax */
400 HiSax_closecard(local->cardnr);
401 }
402 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200404 pcmcia_disable_device(link);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405} /* sedlbauer_release */
406
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200407static int sedlbauer_suspend(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100408{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100409 local_info_t *dev = link->priv;
410
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100411 dev->stop = 1;
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100412
413 return 0;
414}
415
Dominik Brodowskifba395e2006-03-31 17:21:06 +0200416static int sedlbauer_resume(struct pcmcia_device *link)
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100417{
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100418 local_info_t *dev = link->priv;
419
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100420 dev->stop = 0;
421
422 return 0;
423}
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Dominik Brodowski70799732005-06-27 16:28:41 -0700426static struct pcmcia_device_id sedlbauer_ids[] = {
Karsten Keil84d370b2005-09-14 14:19:13 -0700427 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
Dominik Brodowski70799732005-06-27 16:28:41 -0700428 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
429 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
430 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe),
431 PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c),
432 PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae),
433/* PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/
434 PCMCIA_DEVICE_NULL
435};
436MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids);
437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438static struct pcmcia_driver sedlbauer_driver = {
439 .owner = THIS_MODULE,
440 .drv = {
441 .name = "sedlbauer_cs",
442 },
Dominik Brodowski15b99ac2006-03-31 17:26:06 +0200443 .probe = sedlbauer_probe,
Henne93b39a02010-03-25 12:05:29 +0000444 .remove = __devexit_p(sedlbauer_detach),
Dominik Brodowski70799732005-06-27 16:28:41 -0700445 .id_table = sedlbauer_ids,
Dominik Brodowski98e4c282005-11-14 21:21:18 +0100446 .suspend = sedlbauer_suspend,
447 .resume = sedlbauer_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448};
449
450static int __init init_sedlbauer_cs(void)
451{
452 return pcmcia_register_driver(&sedlbauer_driver);
453}
454
455static void __exit exit_sedlbauer_cs(void)
456{
457 pcmcia_unregister_driver(&sedlbauer_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458}
459
460module_init(init_sedlbauer_cs);
461module_exit(exit_sedlbauer_cs);