[PATCH] pcmcia: remove unneeded Vcc pseudo setting
[safe/jmp/linux-2.6] / drivers / net / wireless / atmel_cs.c
1 /*** -*- linux-c -*- **********************************************************
2
3      Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4
5         Copyright 2000-2001 ATMEL Corporation.
6         Copyright 2003 Simon Kelley.
7
8     This code was developed from version 2.1.1 of the Atmel drivers, 
9     released by Atmel corp. under the GPL in December 2002. It also 
10     includes code from the Linux aironet drivers (C) Benjamin Reed, 
11     and the Linux PCMCIA package, (C) David Hinds. 
12
13     For all queries about this code, please contact the current author, 
14     Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
15
16     This program is free software; you can redistribute it and/or modify
17     it under the terms of the GNU General Public License as published by
18     the Free Software Foundation; either version 2 of the License, or
19     (at your option) any later version.
20
21     This software is distributed in the hope that it will be useful,
22     but WITHOUT ANY WARRANTY; without even the implied warranty of
23     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24     GNU General Public License for more details.
25
26     You should have received a copy of the GNU General Public License
27     along with Atmel wireless lan drivers; if not, write to the Free Software
28     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
30 ******************************************************************************/
31
32 #include <linux/config.h>
33 #ifdef __IN_PCMCIA_PACKAGE__
34 #include <pcmcia/k_compat.h>
35 #endif
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/ptrace.h>
40 #include <linux/slab.h>
41 #include <linux/string.h>
42 #include <linux/netdevice.h>
43 #include <linux/moduleparam.h>
44 #include <linux/device.h>
45
46 #include <pcmcia/cs_types.h>
47 #include <pcmcia/cs.h>
48 #include <pcmcia/cistpl.h>
49 #include <pcmcia/cisreg.h>
50 #include <pcmcia/ds.h>
51 #include <pcmcia/ciscode.h>
52
53 #include <asm/io.h>
54 #include <asm/system.h>
55 #include <linux/wireless.h>
56
57 #include "atmel.h"
58
59 /*
60    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
61    you do not define PCMCIA_DEBUG at all, all the debug code will be
62    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
63    be present but disabled -- but it can then be enabled for specific
64    modules at load time with a 'pc_debug=#' option to insmod.
65 */
66
67 #ifdef PCMCIA_DEBUG
68 static int pc_debug = PCMCIA_DEBUG;
69 module_param(pc_debug, int, 0);
70 static char *version = "$Revision: 1.2 $";
71 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
72 #else
73 #define DEBUG(n, args...)
74 #endif
75
76 /*====================================================================*/
77
78 MODULE_AUTHOR("Simon Kelley");
79 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
80 MODULE_LICENSE("GPL");
81 MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
82
83 /*====================================================================*/
84
85 /*
86    The event() function is this driver's Card Services event handler.
87    It will be called by Card Services when an appropriate card status
88    event is received.  The config() and release() entry points are
89    used to configure or release a socket, in response to card
90    insertion and ejection events.  They are invoked from the atmel_cs
91    event handler. 
92 */
93
94 static void atmel_config(dev_link_t *link);
95 static void atmel_release(dev_link_t *link);
96
97 /*
98    The attach() and detach() entry points are used to create and destroy
99    "instances" of the driver, where each instance represents everything
100    needed to manage one actual PCMCIA card.
101 */
102
103 static void atmel_detach(struct pcmcia_device *p_dev);
104
105 /*
106    You'll also need to prototype all the functions that will actually
107    be used to talk to your device.  See 'pcmem_cs' for a good example
108    of a fully self-sufficient driver; the other drivers rely more or
109    less on other parts of the kernel.
110 */
111
112 /*
113    A linked list of "instances" of the  atmelnet device.  Each actual
114    PCMCIA card corresponds to one device instance, and is described
115    by one dev_link_t structure (defined in ds.h).
116
117    You may not want to use a linked list for this -- for example, the
118    memory card driver uses an array of dev_link_t pointers, where minor
119    device numbers are used to derive the corresponding array index.
120 */
121
122 /*
123    A driver needs to provide a dev_node_t structure for each device
124    on a card.  In some cases, there is only one device per card (for
125    example, ethernet cards, modems).  In other cases, there may be
126    many actual or logical devices (SCSI adapters, memory cards with
127    multiple partitions).  The dev_node_t structures need to be kept
128    in a linked list starting at the 'dev' field of a dev_link_t
129    structure.  We allocate them in the card's private data structure,
130    because they generally shouldn't be allocated dynamically.
131
132    In this case, we also provide a flag to indicate if a device is
133    "stopped" due to a power management event, or card ejection.  The
134    device IO routines can use a flag like this to throttle IO to a
135    card that is not ready to accept it.
136 */
137    
138 typedef struct local_info_t {
139         dev_node_t      node;
140         struct net_device *eth_dev;
141 } local_info_t;
142
143 /*======================================================================
144   
145   atmel_attach() creates an "instance" of the driver, allocating
146   local data structures for one device.  The device is registered
147   with Card Services.
148   
149   The dev_link structure is initialized, but we don't actually
150   configure the card at this point -- we wait until we receive a
151   card insertion event.
152   
153   ======================================================================*/
154
155 static int atmel_attach(struct pcmcia_device *p_dev)
156 {
157         dev_link_t *link;
158         local_info_t *local;
159
160         DEBUG(0, "atmel_attach()\n");
161
162         /* Initialize the dev_link_t structure */
163         link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);
164         if (!link) {
165                 printk(KERN_ERR "atmel_cs: no memory for new device\n");
166                 return -ENOMEM;
167         }
168
169         /* Interrupt setup */
170         link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
171         link->irq.IRQInfo1 = IRQ_LEVEL_ID;
172         link->irq.Handler = NULL;
173
174         /*
175           General socket configuration defaults can go here.  In this
176           client, we assume very little, and rely on the CIS for almost
177           everything.  In most clients, many details (i.e., number, sizes,
178           and attributes of IO windows) are fixed by the nature of the
179           device, and can be hard-wired here.
180         */
181         link->conf.Attributes = 0;
182         link->conf.IntType = INT_MEMORY_AND_IO;
183
184         /* Allocate space for private device-specific data */
185         local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
186         if (!local) {
187                 printk(KERN_ERR "atmel_cs: no memory for new device\n");
188                 kfree (link);
189                 return -ENOMEM;
190         }
191         link->priv = local;
192
193         link->handle = p_dev;
194         p_dev->instance = link;
195
196         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
197         atmel_config(link);
198
199         return 0;
200 } /* atmel_attach */
201
202 /*======================================================================
203   
204   This deletes a driver "instance".  The device is de-registered
205   with Card Services.  If it has been released, all local data
206   structures are freed.  Otherwise, the structures will be freed
207   when the device is released.
208   
209   ======================================================================*/
210
211 static void atmel_detach(struct pcmcia_device *p_dev)
212 {
213         dev_link_t *link = dev_to_instance(p_dev);
214
215         DEBUG(0, "atmel_detach(0x%p)\n", link);
216
217         if (link->state & DEV_CONFIG)
218                 atmel_release(link);
219
220         kfree(link->priv);
221         kfree(link);
222 }
223
224 /*======================================================================
225   
226   atmel_config() is scheduled to run after a CARD_INSERTION event
227   is received, to configure the PCMCIA socket, and to make the
228   device available to the system.
229   
230   ======================================================================*/
231
232 #define CS_CHECK(fn, ret) \
233 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
234
235 /* Call-back function to interrogate PCMCIA-specific information
236    about the current existance of the card */
237 static int card_present(void *arg)
238
239         dev_link_t *link = (dev_link_t *)arg;
240         if (link->state & DEV_SUSPEND)
241                 return 0;
242         else if (link->state & DEV_PRESENT)
243                 return 1;
244         
245         return 0;
246 }
247
248 static void atmel_config(dev_link_t *link)
249 {
250         client_handle_t handle;
251         tuple_t tuple;
252         cisparse_t parse;
253         local_info_t *dev;
254         int last_fn, last_ret;
255         u_char buf[64];
256         struct pcmcia_device_id *did;
257
258         handle = link->handle;
259         dev = link->priv;
260         did = handle_to_dev(handle).driver_data;
261
262         DEBUG(0, "atmel_config(0x%p)\n", link);
263         
264         tuple.Attributes = 0;
265         tuple.TupleData = buf;
266         tuple.TupleDataMax = sizeof(buf);
267         tuple.TupleOffset = 0;
268         
269         /*
270           This reads the card's CONFIG tuple to find its configuration
271           registers.
272         */
273         tuple.DesiredTuple = CISTPL_CONFIG;
274         CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
275         CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
276         CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
277         link->conf.ConfigBase = parse.config.base;
278         link->conf.Present = parse.config.rmask[0];
279         
280         /* Configure card */
281         link->state |= DEV_CONFIG;
282         
283         /*
284           In this loop, we scan the CIS for configuration table entries,
285           each of which describes a valid card configuration, including
286           voltage, IO window, memory window, and interrupt settings.
287           
288           We make no assumptions about the card to be configured: we use
289           just the information available in the CIS.  In an ideal world,
290           this would work for any PCMCIA card, but it requires a complete
291           and accurate CIS.  In practice, a driver usually "knows" most of
292           these things without consulting the CIS, and most client drivers
293           will only use the CIS to fill in implementation-defined details.
294         */
295         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
296         CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
297         while (1) {
298                 cistpl_cftable_entry_t dflt = { 0 };
299                 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
300                 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
301                                 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
302                         goto next_entry;
303                 
304                 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
305                 if (cfg->index == 0) goto next_entry;
306                 link->conf.ConfigIndex = cfg->index;
307                 
308                 /* Does this card need audio output? */
309                 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
310                         link->conf.Attributes |= CONF_ENABLE_SPKR;
311                         link->conf.Status = CCSR_AUDIO_ENA;
312                 }
313                 
314                 /* Use power settings for Vcc and Vpp if present */
315                 /*  Note that the CIS values need to be rescaled */
316                 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
317                         link->conf.Vpp =
318                                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
319                 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
320                         link->conf.Vpp =
321                                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
322                 
323                 /* Do we need to allocate an interrupt? */
324                 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
325                         link->conf.Attributes |= CONF_ENABLE_IRQ;
326                 
327                 /* IO window settings */
328                 link->io.NumPorts1 = link->io.NumPorts2 = 0;
329                 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
330                         cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
331                         link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
332                         if (!(io->flags & CISTPL_IO_8BIT))
333                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
334                         if (!(io->flags & CISTPL_IO_16BIT))
335                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
336                         link->io.BasePort1 = io->win[0].base;
337                         link->io.NumPorts1 = io->win[0].len;
338                         if (io->nwin > 1) {
339                                 link->io.Attributes2 = link->io.Attributes1;
340                                 link->io.BasePort2 = io->win[1].base;
341                                 link->io.NumPorts2 = io->win[1].len;
342                         }
343                 }
344                 
345                 /* This reserves IO space but doesn't actually enable it */
346                 if (pcmcia_request_io(link->handle, &link->io) != 0)
347                         goto next_entry;
348
349                 /* If we got this far, we're cool! */
350                 break;
351                 
352         next_entry:
353                 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
354         }
355         
356         /*
357           Allocate an interrupt line.  Note that this does not assign a
358           handler to the interrupt, unless the 'Handler' member of the
359           irq structure is initialized.
360         */
361         if (link->conf.Attributes & CONF_ENABLE_IRQ)
362                 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
363         
364         /*
365           This actually configures the PCMCIA socket -- setting up
366           the I/O windows and the interrupt mapping, and putting the
367           card and host interface into "Memory and IO" mode.
368         */
369         CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
370         
371         if (link->irq.AssignedIRQ == 0) {
372                 printk(KERN_ALERT 
373                        "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
374                 goto cs_failed;
375         }
376        
377         ((local_info_t*)link->priv)->eth_dev = 
378                 init_atmel_card(link->irq.AssignedIRQ,
379                                 link->io.BasePort1,
380                                 did ? did->driver_info : ATMEL_FW_TYPE_NONE,
381                                 &handle_to_dev(handle),
382                                 card_present, 
383                                 link);
384         if (!((local_info_t*)link->priv)->eth_dev) 
385                         goto cs_failed;
386         
387         
388         /*
389           At this point, the dev_node_t structure(s) need to be
390           initialized and arranged in a linked list at link->dev.
391         */
392         strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
393         dev->node.major = dev->node.minor = 0;
394         link->dev = &dev->node;
395                         
396         link->state &= ~DEV_CONFIG_PENDING;
397         return;
398         
399  cs_failed:
400         cs_error(link->handle, last_fn, last_ret);
401         atmel_release(link);
402 }
403
404 /*======================================================================
405   
406   After a card is removed, atmel_release() will unregister the
407   device, and release the PCMCIA configuration.  If the device is
408   still open, this will be postponed until it is closed.
409   
410   ======================================================================*/
411
412 static void atmel_release(dev_link_t *link)
413 {
414         struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
415
416         DEBUG(0, "atmel_release(0x%p)\n", link);
417
418         if (dev)
419                 stop_atmel_card(dev);
420         ((local_info_t*)link->priv)->eth_dev = NULL;
421
422         pcmcia_disable_device(link->handle);
423 }
424
425 static int atmel_suspend(struct pcmcia_device *dev)
426 {
427         dev_link_t *link = dev_to_instance(dev);
428         local_info_t *local = link->priv;
429
430         if (link->state & DEV_CONFIG)
431                 netif_device_detach(local->eth_dev);
432
433         return 0;
434 }
435
436 static int atmel_resume(struct pcmcia_device *dev)
437 {
438         dev_link_t *link = dev_to_instance(dev);
439         local_info_t *local = link->priv;
440
441         if (link->state & DEV_CONFIG) {
442                 atmel_open(local->eth_dev);
443                 netif_device_attach(local->eth_dev);
444         }
445
446         return 0;
447 }
448
449 /*====================================================================*/
450 /* We use the driver_info field to store the correct firmware type for a card. */
451
452 #define PCMCIA_DEVICE_MANF_CARD_INFO(manf, card, info) { \
453         .match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
454                         PCMCIA_DEV_ID_MATCH_CARD_ID, \
455         .manf_id = (manf), \
456         .card_id = (card), \
457         .driver_info = (kernel_ulong_t)(info), }
458
459 #define PCMCIA_DEVICE_PROD_ID12_INFO(v1, v2, vh1, vh2, info) { \
460         .match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
461                         PCMCIA_DEV_ID_MATCH_PROD_ID2, \
462         .prod_id = { (v1), (v2), NULL, NULL }, \
463         .prod_id_hash = { (vh1), (vh2), 0, 0 }, \
464         .driver_info = (kernel_ulong_t)(info), }
465
466 static struct pcmcia_device_id atmel_ids[] = {
467         PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
468         PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
469         PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
470         PCMCIA_DEVICE_MANF_CARD_INFO(0xd601, 0x0007, ATMEL_FW_TYPE_502),
471         PCMCIA_DEVICE_PROD_ID12_INFO("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9, ATMEL_FW_TYPE_502E),
472         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f, ATMEL_FW_TYPE_502),
473         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_D", 0xabda4164, 0x3675d704, ATMEL_FW_TYPE_502D),
474         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_E", 0xabda4164, 0x4172e792, ATMEL_FW_TYPE_502E),
475         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504_R", 0xabda4164, 0x917f3d72, ATMEL_FW_TYPE_504_2958),
476         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504", 0xabda4164, 0x5040670a, ATMEL_FW_TYPE_504),
477         PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f, ATMEL_FW_TYPE_504A_2958),
478         PCMCIA_DEVICE_PROD_ID12_INFO("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5, ATMEL_FW_TYPE_502),
479         PCMCIA_DEVICE_PROD_ID12_INFO("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b, ATMEL_FW_TYPE_502E),
480         PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6, ATMEL_FW_TYPE_502),
481         PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN Card S", 0x5b878724, 0x5fba533a, ATMEL_FW_TYPE_504_2958),
482         PCMCIA_DEVICE_PROD_ID12_INFO("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68, ATMEL_FW_TYPE_502),
483         PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W", 0xc4f8b18b, 0x30f38774, ATMEL_FW_TYPE_502D),
484         PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377, ATMEL_FW_TYPE_502),
485         PCMCIA_DEVICE_PROD_ID12_INFO("Wireless", "PC_CARD", 0xa407ecdd, 0x119f6314, ATMEL_FW_TYPE_502D),
486         PCMCIA_DEVICE_PROD_ID12_INFO("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4, ATMEL_FW_TYPE_502D),
487         PCMCIA_DEVICE_PROD_ID12_INFO("LG", "LW2100N", 0xb474d43a, 0x6b1fec94, ATMEL_FW_TYPE_502E),
488         PCMCIA_DEVICE_NULL
489 };
490
491 MODULE_DEVICE_TABLE(pcmcia, atmel_ids);
492
493 static struct pcmcia_driver atmel_driver = {
494         .owner          = THIS_MODULE,
495         .drv            = {
496                 .name   = "atmel_cs",
497         },
498         .probe          = atmel_attach,
499         .remove         = atmel_detach,
500         .id_table       = atmel_ids,
501         .suspend        = atmel_suspend,
502         .resume         = atmel_resume,
503 };
504
505 static int atmel_cs_init(void)
506 {
507         return pcmcia_register_driver(&atmel_driver);
508 }
509
510 static void atmel_cs_cleanup(void)
511 {
512         pcmcia_unregister_driver(&atmel_driver);
513 }
514
515 /*
516     This program is free software; you can redistribute it and/or
517     modify it under the terms of the GNU General Public License
518     as published by the Free Software Foundation; either version 2
519     of the License, or (at your option) any later version.
520
521     This program is distributed in the hope that it will be useful,
522     but WITHOUT ANY WARRANTY; without even the implied warranty of
523     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
524     GNU General Public License for more details.
525
526     In addition:
527
528     Redistribution and use in source and binary forms, with or without
529     modification, are permitted provided that the following conditions
530     are met:
531
532     1. Redistributions of source code must retain the above copyright
533        notice, this list of conditions and the following disclaimer.
534     2. Redistributions in binary form must reproduce the above copyright
535        notice, this list of conditions and the following disclaimer in the
536        documentation and/or other materials provided with the distribution.
537     3. The name of the author may not be used to endorse or promote
538        products derived from this software without specific prior written
539        permission.
540
541     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
542     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
543     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
544     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
545     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
546     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
547     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
548     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
549     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
550     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
551     POSSIBILITY OF SUCH DAMAGE.    
552 */
553
554 module_init(atmel_cs_init);
555 module_exit(atmel_cs_cleanup);