11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*** -*- linux-c -*- **********************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds     Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        Copyright 2000-2001 ATMEL Corporation.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        Copyright 2003 Simon Kelley.
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
85c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    This code was developed from version 2.1.1 of the Atmel drivers,
95c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    released by Atmel corp. under the GPL in December 2002. It also
105c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    includes code from the Linux aironet drivers (C) Benjamin Reed,
115c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    and the Linux PCMCIA package, (C) David Hinds.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
135c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    For all queries about this code, please contact the current author,
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    This program is free software; you can redistribute it and/or modify
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    it under the terms of the GNU General Public License as published by
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    the Free Software Foundation; either version 2 of the License, or
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    (at your option) any later version.
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    This software is distributed in the hope that it will be useful,
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    but WITHOUT ANY WARRANTY; without even the implied warranty of
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    GNU General Public License for more details.
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    You should have received a copy of the GNU General Public License
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    along with Atmel wireless lan drivers; if not, write to the Free Software
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds******************************************************************************/
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __IN_PCMCIA_PACKAGE__
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <pcmcia/k_compat.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ptrace.h>
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h>
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h>
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netdevice.h>
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/moduleparam.h>
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h>
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <pcmcia/cistpl.h>
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <pcmcia/cisreg.h>
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <pcmcia/ds.h>
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <pcmcia/ciscode.h>
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/wireless.h>
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "atmel.h"
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*====================================================================*/
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Simon Kelley");
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*====================================================================*/
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6515b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowskistatic int atmel_config(struct pcmcia_device *link);
66fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void atmel_release(struct pcmcia_device *link);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
68cc3b4866bee996c922e875b8c8efe9f0d8803aaeDominik Brodowskistatic void atmel_detach(struct pcmcia_device *p_dev);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct local_info_t {
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct net_device *eth_dev;
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} local_info_t;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7415b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowskistatic int atmel_probe(struct pcmcia_device *p_dev)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_info_t *local;
77f8cfa618dccbdc6dab5297f75779566a388a98fdDominik Brodowski
782caff14713d53abba273e6095495788e2720f756Dominik Brodowski	dev_dbg(&p_dev->dev, "atmel_attach()\n");
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Allocate space for private device-specific data */
81b69a3aa85cb7bda2eb6c5932a62c1337d0d6612cPanagiotis Issaris	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!local) {
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_ERR "atmel_cs: no memory for new device\n");
84f8cfa618dccbdc6dab5297f75779566a388a98fdDominik Brodowski		return -ENOMEM;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
86fd238232cd0ff4840ae6946bb338502154096d88Dominik Brodowski	p_dev->priv = local;
87f8cfa618dccbdc6dab5297f75779566a388a98fdDominik Brodowski
8815b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski	return atmel_config(p_dev);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} /* atmel_attach */
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
91fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void atmel_detach(struct pcmcia_device *link)
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
932caff14713d53abba273e6095495788e2720f756Dominik Brodowski	dev_dbg(&link->dev, "atmel_detach\n");
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
95e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski	atmel_release(link);
96b463581154f3f3eecda27cae60df813fefcd84d3Dominik Brodowski
97b4558ea93d66a43f7990d26f145fd4c54a01c9bfJesper Juhl	kfree(link->priv);
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Call-back function to interrogate PCMCIA-specific information
10125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi   about the current existence of the card */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int card_present(void *arg)
1039940ec3617fec1db13e589bbc3f37e37878c7683Dominik Brodowski{
104fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowski	struct pcmcia_device *link = (struct pcmcia_device *)arg;
1059940ec3617fec1db13e589bbc3f37e37878c7683Dominik Brodowski
1069940ec3617fec1db13e589bbc3f37e37878c7683Dominik Brodowski	if (pcmcia_dev_present(link))
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 1;
1089940ec3617fec1db13e589bbc3f37e37878c7683Dominik Brodowski
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11200990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowskistatic int atmel_config_check(struct pcmcia_device *p_dev, void *priv_data)
113b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski{
11400990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski	if (p_dev->config_index == 0)
11500990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski		return -EINVAL;
116b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski
11790abdc3b973229bae98dd96649d9f7106cc177a4Dominik Brodowski	return pcmcia_request_io(p_dev);
118b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski}
119b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski
12015b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowskistatic int atmel_config(struct pcmcia_device *link)
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	local_info_t *dev;
1232caff14713d53abba273e6095495788e2720f756Dominik Brodowski	int ret;
12425f8f54f6e178acfd503a95441b0ea05c525f751Joe Perches	const struct pcmcia_device_id *did;
125b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev = link->priv;
127dd2e5a156525f11754d9b1e0583f6bb49c253d62Dominik Brodowski	did = dev_get_drvdata(&link->dev);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1292caff14713d53abba273e6095495788e2720f756Dominik Brodowski	dev_dbg(&link->dev, "atmel_config\n");
1305c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
131440eed43e2a95bb842488755683716814da10f2bDominik Brodowski	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
13200990e7ce0b0e596fe41d9c64d6933ea70084003Dominik Brodowski		CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;
133440eed43e2a95bb842488755683716814da10f2bDominik Brodowski
1348e2fc39ddea7fe8c6798837da282db88a09af793Dominik Brodowski	if (pcmcia_loop_config(link, atmel_config_check, NULL))
135b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski		goto failed;
1365c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
137eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski	if (!link->irq) {
138eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski		dev_err(&link->dev, "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
139eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski		goto failed;
1402caff14713d53abba273e6095495788e2720f756Dominik Brodowski	}
1415c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
1421ac71e5a35eebee60cdcf15b3980bd94498f037bDominik Brodowski	ret = pcmcia_enable_device(link);
1432caff14713d53abba273e6095495788e2720f756Dominik Brodowski	if (ret)
1442caff14713d53abba273e6095495788e2720f756Dominik Brodowski		goto failed;
1455c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
1465c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov	((local_info_t*)link->priv)->eth_dev =
147eb14120f743d29744d9475bffec56ff4ad43a749Dominik Brodowski		init_atmel_card(link->irq,
1489a017a910346afd88ec2e065989903bf211a7d37Dominik Brodowski				link->resource[0]->start,
149b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley				did ? did->driver_info : ATMEL_FW_TYPE_NONE,
150dd2e5a156525f11754d9b1e0583f6bb49c253d62Dominik Brodowski				&link->dev,
1515c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov				card_present,
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				link);
1535c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov	if (!((local_info_t*)link->priv)->eth_dev)
1542caff14713d53abba273e6095495788e2720f756Dominik Brodowski			goto failed;
1555c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
1565c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov
15715b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski	return 0;
158e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski
159b54bf94bf91e4ca2a489eb02bca0424ddb55242aDominik Brodowski failed:
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	atmel_release(link);
16115b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski	return -ENODEV;
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
164fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic void atmel_release(struct pcmcia_device *link)
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
1675f2a71fcb7995633b335a1e380ac63a968e61320Dominik Brodowski
1682caff14713d53abba273e6095495788e2720f756Dominik Brodowski	dev_dbg(&link->dev, "atmel_release\n");
1695f2a71fcb7995633b335a1e380ac63a968e61320Dominik Brodowski
1705f2a71fcb7995633b335a1e380ac63a968e61320Dominik Brodowski	if (dev)
171b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley		stop_atmel_card(dev);
1725f2a71fcb7995633b335a1e380ac63a968e61320Dominik Brodowski	((local_info_t*)link->priv)->eth_dev = NULL;
1735f2a71fcb7995633b335a1e380ac63a968e61320Dominik Brodowski
174fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowski	pcmcia_disable_device(link);
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
177fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic int atmel_suspend(struct pcmcia_device *link)
17898e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski{
17998e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	local_info_t *local = link->priv;
18098e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
181e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski	netif_device_detach(local->eth_dev);
18298e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
18398e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	return 0;
18498e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski}
18598e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
186fba395eee7d3f342ca739c20f5b3ee635d0420a0Dominik Brodowskistatic int atmel_resume(struct pcmcia_device *link)
18798e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski{
18898e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	local_info_t *local = link->priv;
18998e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
190e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski	atmel_open(local->eth_dev);
191e2d4096365e06b9a3799afbadc28b4519c0b3526Dominik Brodowski	netif_device_attach(local->eth_dev);
19298e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
19398e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	return 0;
19498e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski}
19598e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*====================================================================*/
197b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley/* We use the driver_info field to store the correct firmware type for a card. */
198b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley
199b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley#define PCMCIA_DEVICE_MANF_CARD_INFO(manf, card, info) { \
200b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
201b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley			PCMCIA_DEV_ID_MATCH_CARD_ID, \
202b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.manf_id = (manf), \
203b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.card_id = (card), \
204b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley        .driver_info = (kernel_ulong_t)(info), }
205b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley
206b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley#define PCMCIA_DEVICE_PROD_ID12_INFO(v1, v2, vh1, vh2, info) { \
207b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
208b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley			PCMCIA_DEV_ID_MATCH_PROD_ID2, \
209b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.prod_id = { (v1), (v2), NULL, NULL }, \
210b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
211b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley        .driver_info = (kernel_ulong_t)(info), }
212b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley
21325f8f54f6e178acfd503a95441b0ea05c525f751Joe Perchesstatic const struct pcmcia_device_id atmel_ids[] = {
214b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
215b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
216b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
217b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_MANF_CARD_INFO(0xd601, 0x0007, ATMEL_FW_TYPE_502),
218b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9, ATMEL_FW_TYPE_502E),
219b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f, ATMEL_FW_TYPE_502),
220b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_D", 0xabda4164, 0x3675d704, ATMEL_FW_TYPE_502D),
221b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_E", 0xabda4164, 0x4172e792, ATMEL_FW_TYPE_502E),
222b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504_R", 0xabda4164, 0x917f3d72, ATMEL_FW_TYPE_504_2958),
223b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504", 0xabda4164, 0x5040670a, ATMEL_FW_TYPE_504),
224b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f, ATMEL_FW_TYPE_504A_2958),
225b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5, ATMEL_FW_TYPE_502),
226b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b, ATMEL_FW_TYPE_502E),
227b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6, ATMEL_FW_TYPE_502),
228b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN Card S", 0x5b878724, 0x5fba533a, ATMEL_FW_TYPE_504_2958),
229b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68, ATMEL_FW_TYPE_502),
230b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W", 0xc4f8b18b, 0x30f38774, ATMEL_FW_TYPE_502D),
231b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377, ATMEL_FW_TYPE_502),
232b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("Wireless", "PC_CARD", 0xa407ecdd, 0x119f6314, ATMEL_FW_TYPE_502D),
233b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4, ATMEL_FW_TYPE_502D),
234b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley	PCMCIA_DEVICE_PROD_ID12_INFO("LG", "LW2100N", 0xb474d43a, 0x6b1fec94, ATMEL_FW_TYPE_502E),
2354a17a119381a5467144b18eaa954ba324e8a140bDominik Brodowski	PCMCIA_DEVICE_NULL
2364a17a119381a5467144b18eaa954ba324e8a140bDominik Brodowski};
237b16a228d05a95b27d77d07a91688382f68ece8a7Simon Kelley
2384a17a119381a5467144b18eaa954ba324e8a140bDominik BrodowskiMODULE_DEVICE_TABLE(pcmcia, atmel_ids);
2394a17a119381a5467144b18eaa954ba324e8a140bDominik Brodowski
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pcmcia_driver atmel_driver = {
2411e212f3645a6b355de8c43a23376bc0e2ac49a63Dominik Brodowski	.owner		= THIS_MODULE,
2422e9b981a7c63ee8278df6823f8389d69dad1a499Dominik Brodowski	.name		= "atmel_cs",
24315b99ac1729503db9e6dc642a50b9b6cb3bf51f9Dominik Brodowski	.probe          = atmel_probe,
244cc3b4866bee996c922e875b8c8efe9f0d8803aaeDominik Brodowski	.remove		= atmel_detach,
2454a17a119381a5467144b18eaa954ba324e8a140bDominik Brodowski	.id_table	= atmel_ids,
24698e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	.suspend	= atmel_suspend,
24798e4c28b7ec390c2dad6a4c69d69629c0f7e8b10Dominik Brodowski	.resume		= atmel_resume,
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25006b3a1d12f41b592972643f8b84015d6c03dc576Dominik Brodowskistatic int __init atmel_cs_init(void)
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        return pcmcia_register_driver(&atmel_driver);
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
25506b3a1d12f41b592972643f8b84015d6c03dc576Dominik Brodowskistatic void __exit atmel_cs_cleanup(void)
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        pcmcia_unregister_driver(&atmel_driver);
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    This program is free software; you can redistribute it and/or
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    modify it under the terms of the GNU General Public License
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    as published by the Free Software Foundation; either version 2
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    of the License, or (at your option) any later version.
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    This program is distributed in the hope that it will be useful,
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    but WITHOUT ANY WARRANTY; without even the implied warranty of
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    GNU General Public License for more details.
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    In addition:
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    Redistribution and use in source and binary forms, with or without
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    modification, are permitted provided that the following conditions
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    are met:
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    1. Redistributions of source code must retain the above copyright
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds       notice, this list of conditions and the following disclaimer.
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    2. Redistributions in binary form must reproduce the above copyright
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds       notice, this list of conditions and the following disclaimer in the
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds       documentation and/or other materials provided with the distribution.
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    3. The name of the author may not be used to endorse or promote
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds       products derived from this software without specific prior written
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds       permission.
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2965c877fe58c5df19646204b144b978b99c2ef074fDmitry Torokhov    POSSIBILITY OF SUCH DAMAGE.
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(atmel_cs_init);
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(atmel_cs_cleanup);
301