Merge master.kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[pandora-kernel.git] / drivers / isdn / hisax / sedlbauer_cs.c
1 /*======================================================================
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>
41 #include <linux/sched.h>
42 #include <linux/ptrace.h>
43 #include <linux/slab.h>
44 #include <linux/string.h>
45 #include <linux/timer.h>
46 #include <linux/ioport.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
49
50 #include <pcmcia/cs_types.h>
51 #include <pcmcia/cs.h>
52 #include <pcmcia/cistpl.h>
53 #include <pcmcia/cisreg.h>
54 #include <pcmcia/ds.h>
55 #include "hisax_cfg.h"
56
57 MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
58 MODULE_AUTHOR("Marcus Niemann");
59 MODULE_LICENSE("Dual MPL/GPL");
60
61 /*
62    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
63    you do not define PCMCIA_DEBUG at all, all the debug code will be
64    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
65    be present but disabled -- but it can then be enabled for specific
66    modules at load time with a 'pc_debug=#' option to insmod.
67 */
68
69 #ifdef PCMCIA_DEBUG
70 static int pc_debug = PCMCIA_DEBUG;
71 module_param(pc_debug, int, 0);
72 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); 
73 static char *version =
74 "sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
75 #else
76 #define DEBUG(n, args...)
77 #endif
78
79
80 /*====================================================================*/
81
82 /* Parameters that can be set with 'insmod' */
83
84 static int protocol = 2;        /* EURO-ISDN Default */
85 module_param(protocol, int, 0);
86
87 /*====================================================================*/
88
89 /*
90    The event() function is this driver's Card Services event handler.
91    It will be called by Card Services when an appropriate card status
92    event is received.  The config() and release() entry points are
93    used to configure or release a socket, in response to card
94    insertion and ejection events.  They are invoked from the sedlbauer
95    event handler. 
96 */
97
98 static int sedlbauer_config(struct pcmcia_device *link);
99 static void sedlbauer_release(struct pcmcia_device *link);
100
101 /*
102    The attach() and detach() entry points are used to create and destroy
103    "instances" of the driver, where each instance represents everything
104    needed to manage one actual PCMCIA card.
105 */
106
107 static void sedlbauer_detach(struct pcmcia_device *p_dev);
108
109 /*
110    You'll also need to prototype all the functions that will actually
111    be used to talk to your device.  See 'memory_cs' for a good example
112    of a fully self-sufficient driver; the other drivers rely more or
113    less on other parts of the kernel.
114 */
115
116 /*
117    A driver needs to provide a dev_node_t structure for each device
118    on a card.  In some cases, there is only one device per card (for
119    example, ethernet cards, modems).  In other cases, there may be
120    many actual or logical devices (SCSI adapters, memory cards with
121    multiple partitions).  The dev_node_t structures need to be kept
122    in a linked list starting at the 'dev' field of a struct pcmcia_device
123    structure.  We allocate them in the card's private data structure,
124    because they generally shouldn't be allocated dynamically.
125
126    In this case, we also provide a flag to indicate if a device is
127    "stopped" due to a power management event, or card ejection.  The
128    device IO routines can use a flag like this to throttle IO to a
129    card that is not ready to accept it.
130 */
131    
132 typedef struct local_info_t {
133         struct pcmcia_device    *p_dev;
134     dev_node_t          node;
135     int                 stop;
136     int                 cardnr;
137 } local_info_t;
138
139 /*======================================================================
140
141     sedlbauer_attach() creates an "instance" of the driver, allocating
142     local data structures for one device.  The device is registered
143     with Card Services.
144
145     The dev_link structure is initialized, but we don't actually
146     configure the card at this point -- we wait until we receive a
147     card insertion event.
148     
149 ======================================================================*/
150
151 static int sedlbauer_probe(struct pcmcia_device *link)
152 {
153     local_info_t *local;
154
155     DEBUG(0, "sedlbauer_attach()\n");
156
157     /* Allocate space for private device-specific data */
158     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
159     if (!local) return -ENOMEM;
160     memset(local, 0, sizeof(local_info_t));
161     local->cardnr = -1;
162
163     local->p_dev = link;
164     link->priv = local;
165
166     /* Interrupt setup */
167     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
168     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
169     link->irq.Handler = NULL;
170
171     /*
172       General socket configuration defaults can go here.  In this
173       client, we assume very little, and rely on the CIS for almost
174       everything.  In most clients, many details (i.e., number, sizes,
175       and attributes of IO windows) are fixed by the nature of the
176       device, and can be hard-wired here.
177     */
178
179     /* from old sedl_cs 
180     */
181     /* The io structure describes IO port mapping */
182     link->io.NumPorts1 = 8;
183     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
184     link->io.IOAddrLines = 3;
185
186     link->conf.Attributes = 0;
187     link->conf.IntType = INT_MEMORY_AND_IO;
188
189     return sedlbauer_config(link);
190 } /* sedlbauer_attach */
191
192 /*======================================================================
193
194     This deletes a driver "instance".  The device is de-registered
195     with Card Services.  If it has been released, all local data
196     structures are freed.  Otherwise, the structures will be freed
197     when the device is released.
198
199 ======================================================================*/
200
201 static void sedlbauer_detach(struct pcmcia_device *link)
202 {
203         DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
204
205         ((local_info_t *)link->priv)->stop = 1;
206         sedlbauer_release(link);
207
208         /* This points to the parent local_info_t struct */
209         kfree(link->priv);
210 } /* sedlbauer_detach */
211
212 /*======================================================================
213
214     sedlbauer_config() is scheduled to run after a CARD_INSERTION event
215     is received, to configure the PCMCIA socket, and to make the
216     device available to the system.
217     
218 ======================================================================*/
219 #define CS_CHECK(fn, ret) \
220 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
221
222 static int sedlbauer_config(struct pcmcia_device *link)
223 {
224     local_info_t *dev = link->priv;
225     tuple_t tuple;
226     cisparse_t parse;
227     int last_fn, last_ret;
228     u8 buf[64];
229     config_info_t conf;
230     win_req_t req;
231     memreq_t map;
232     IsdnCard_t  icard;
233
234     DEBUG(0, "sedlbauer_config(0x%p)\n", link);
235
236     tuple.Attributes = 0;
237     tuple.TupleData = buf;
238     tuple.TupleDataMax = sizeof(buf);
239     tuple.TupleOffset = 0;
240
241     CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
242
243     /*
244       In this loop, we scan the CIS for configuration table entries,
245       each of which describes a valid card configuration, including
246       voltage, IO window, memory window, and interrupt settings.
247
248       We make no assumptions about the card to be configured: we use
249       just the information available in the CIS.  In an ideal world,
250       this would work for any PCMCIA card, but it requires a complete
251       and accurate CIS.  In practice, a driver usually "knows" most of
252       these things without consulting the CIS, and most client drivers
253       will only use the CIS to fill in implementation-defined details.
254     */
255     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
256     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
257     while (1) {
258         cistpl_cftable_entry_t dflt = { 0 };
259         cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
260         if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
261                 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
262             goto next_entry;
263
264         if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
265         if (cfg->index == 0) goto next_entry;
266         link->conf.ConfigIndex = cfg->index;
267         
268         /* Does this card need audio output? */
269         if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
270             link->conf.Attributes |= CONF_ENABLE_SPKR;
271             link->conf.Status = CCSR_AUDIO_ENA;
272         }
273         
274         /* Use power settings for Vcc and Vpp if present */
275         /*  Note that the CIS values need to be rescaled */
276         if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
277             if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
278                 goto next_entry;
279         } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
280             if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
281                 goto next_entry;
282         }
283             
284         if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
285             link->conf.Vpp =
286                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
287         else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
288             link->conf.Vpp =
289                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
290         
291         /* Do we need to allocate an interrupt? */
292         if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
293             link->conf.Attributes |= CONF_ENABLE_IRQ;
294         
295         /* IO window settings */
296         link->io.NumPorts1 = link->io.NumPorts2 = 0;
297         if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
298             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
299             link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
300             if (!(io->flags & CISTPL_IO_8BIT))
301                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
302             if (!(io->flags & CISTPL_IO_16BIT))
303                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
304 /* new in dummy.cs 2001/01/28 MN 
305             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
306 */
307             link->io.BasePort1 = io->win[0].base;
308             link->io.NumPorts1 = io->win[0].len;
309             if (io->nwin > 1) {
310                 link->io.Attributes2 = link->io.Attributes1;
311                 link->io.BasePort2 = io->win[1].base;
312                 link->io.NumPorts2 = io->win[1].len;
313             }
314             /* This reserves IO space but doesn't actually enable it */
315             if (pcmcia_request_io(link, &link->io) != 0)
316                 goto next_entry;
317         }
318
319         /*
320           Now set up a common memory window, if needed.  There is room
321           in the struct pcmcia_device structure for one memory window handle,
322           but if the base addresses need to be saved, or if multiple
323           windows are needed, the info should go in the private data
324           structure for this device.
325
326           Note that the memory window base is a physical address, and
327           needs to be mapped to virtual space with ioremap() before it
328           is used.
329         */
330         if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
331             cistpl_mem_t *mem =
332                 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
333             req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
334             req.Attributes |= WIN_ENABLE;
335             req.Base = mem->win[0].host_addr;
336             req.Size = mem->win[0].len;
337 /* new in dummy.cs 2001/01/28 MN 
338             if (req.Size < 0x1000)
339                 req.Size = 0x1000;
340 */
341             req.AccessSpeed = 0;
342             if (pcmcia_request_window(&link, &req, &link->win) != 0)
343                 goto next_entry;
344             map.Page = 0; map.CardOffset = mem->win[0].card_addr;
345             if (pcmcia_map_mem_page(link->win, &map) != 0)
346                 goto next_entry;
347         }
348         /* If we got this far, we're cool! */
349         break;
350
351     next_entry:
352         CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
353     }
354
355     /*
356        Allocate an interrupt line.  Note that this does not assign a
357        handler to the interrupt, unless the 'Handler' member of the
358        irq structure is initialized.
359     */
360     if (link->conf.Attributes & CONF_ENABLE_IRQ)
361         CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
362         
363     /*
364        This actually configures the PCMCIA socket -- setting up
365        the I/O windows and the interrupt mapping, and putting the
366        card and host interface into "Memory and IO" mode.
367     */
368     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
369
370     /*
371       At this point, the dev_node_t structure(s) need to be
372       initialized and arranged in a linked list at link->dev.
373     */
374     sprintf(dev->node.dev_name, "sedlbauer");
375     dev->node.major = dev->node.minor = 0;
376     link->dev_node = &dev->node;
377
378     /* Finally, report what we've done */
379     printk(KERN_INFO "%s: index 0x%02x:",
380            dev->node.dev_name, link->conf.ConfigIndex);
381     if (link->conf.Vpp)
382         printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
383     if (link->conf.Attributes & CONF_ENABLE_IRQ)
384         printk(", irq %d", link->irq.AssignedIRQ);
385     if (link->io.NumPorts1)
386         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
387                link->io.BasePort1+link->io.NumPorts1-1);
388     if (link->io.NumPorts2)
389         printk(" & 0x%04x-0x%04x", link->io.BasePort2,
390                link->io.BasePort2+link->io.NumPorts2-1);
391     if (link->win)
392         printk(", mem 0x%06lx-0x%06lx", req.Base,
393                req.Base+req.Size-1);
394     printk("\n");
395
396     icard.para[0] = link->irq.AssignedIRQ;
397     icard.para[1] = link->io.BasePort1;
398     icard.protocol = protocol;
399     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
400     
401     last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
402     if (last_ret < 0) {
403         printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
404                 last_ret, link->io.BasePort1);
405         sedlbauer_release(link);
406         return -ENODEV;
407     } else
408         ((local_info_t*)link->priv)->cardnr = last_ret;
409
410     return 0;
411
412 cs_failed:
413     cs_error(link, last_fn, last_ret);
414     sedlbauer_release(link);
415     return -ENODEV;
416
417 } /* sedlbauer_config */
418
419 /*======================================================================
420
421     After a card is removed, sedlbauer_release() will unregister the
422     device, and release the PCMCIA configuration.  If the device is
423     still open, this will be postponed until it is closed.
424     
425 ======================================================================*/
426
427 static void sedlbauer_release(struct pcmcia_device *link)
428 {
429     local_info_t *local = link->priv;
430     DEBUG(0, "sedlbauer_release(0x%p)\n", link);
431
432     if (local) {
433         if (local->cardnr >= 0) {
434             /* no unregister function with hisax */
435             HiSax_closecard(local->cardnr);
436         }
437     }
438
439     pcmcia_disable_device(link);
440 } /* sedlbauer_release */
441
442 static int sedlbauer_suspend(struct pcmcia_device *link)
443 {
444         local_info_t *dev = link->priv;
445
446         dev->stop = 1;
447
448         return 0;
449 }
450
451 static int sedlbauer_resume(struct pcmcia_device *link)
452 {
453         local_info_t *dev = link->priv;
454
455         dev->stop = 0;
456
457         return 0;
458 }
459
460
461 static struct pcmcia_device_id sedlbauer_ids[] = {
462         PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
463         PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
464         PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
465         PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe),
466         PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (c) 93-95 VK", 0x81fb79f5, 0xe4e9bc12, 0xb391ab4c),
467         PCMCIA_DEVICE_PROD_ID12("HST High Soft Tech GmbH", "Saphir II B", 0xd79e0b84, 0x21d083ae),
468 /*      PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", 0x81fb79f5), */ /* too generic*/
469         PCMCIA_DEVICE_NULL
470 };
471 MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids);
472
473 static struct pcmcia_driver sedlbauer_driver = {
474         .owner          = THIS_MODULE,
475         .drv            = {
476                 .name   = "sedlbauer_cs",
477         },
478         .probe          = sedlbauer_probe,
479         .remove         = sedlbauer_detach,
480         .id_table       = sedlbauer_ids,
481         .suspend        = sedlbauer_suspend,
482         .resume         = sedlbauer_resume,
483 };
484
485 static int __init init_sedlbauer_cs(void)
486 {
487         return pcmcia_register_driver(&sedlbauer_driver);
488 }
489
490 static void __exit exit_sedlbauer_cs(void)
491 {
492         pcmcia_unregister_driver(&sedlbauer_driver);
493 }
494
495 module_init(init_sedlbauer_cs);
496 module_exit(exit_sedlbauer_cs);