Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2
  3  Broadcom B43 wireless driver
  4
  5  Copyright (c) 2007 Michael Buesch <m@bues.ch>
  6
  7  This program is free software; you can redistribute it and/or modify
  8  it under the terms of the GNU General Public License as published by
  9  the Free Software Foundation; either version 2 of the License, or
 10  (at your option) any later version.
 11
 12  This program is distributed in the hope that it will be useful,
 13  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  GNU General Public License for more details.
 16
 17  You should have received a copy of the GNU General Public License
 18  along with this program; see the file COPYING.  If not, write to
 19  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
 20  Boston, MA 02110-1301, USA.
 21
 22*/
 23
 24#include "pcmcia.h"
 25
 26#include <linux/ssb/ssb.h>
 27#include <linux/slab.h>
 28
 29#include <pcmcia/cistpl.h>
 30#include <pcmcia/ciscode.h>
 31#include <pcmcia/ds.h>
 32#include <pcmcia/cisreg.h>
 33
 34
 35static const struct pcmcia_device_id b43_pcmcia_tbl[] = {
 36	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
 37	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
 38	PCMCIA_DEVICE_NULL,
 39};
 40
 41MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl);
 42
 43#ifdef CONFIG_PM
 44static int b43_pcmcia_suspend(struct pcmcia_device *dev)
 45{
 46	struct ssb_bus *ssb = dev->priv;
 47
 48	return ssb_bus_suspend(ssb);
 49}
 50
 51static int b43_pcmcia_resume(struct pcmcia_device *dev)
 52{
 53	struct ssb_bus *ssb = dev->priv;
 54
 55	return ssb_bus_resume(ssb);
 56}
 57#else /* CONFIG_PM */
 58# define b43_pcmcia_suspend		NULL
 59# define b43_pcmcia_resume		NULL
 60#endif /* CONFIG_PM */
 61
 62static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
 63{
 64	struct ssb_bus *ssb;
 65	int err = -ENOMEM;
 66	int res = 0;
 67
 68	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
 69	if (!ssb)
 70		goto out_error;
 71
 72	err = -ENODEV;
 73
 74	dev->config_flags |= CONF_ENABLE_IRQ;
 75
 76	dev->resource[2]->flags |=  WIN_ENABLE | WIN_DATA_WIDTH_16 |
 77			 WIN_USE_WAIT;
 78	dev->resource[2]->start = 0;
 79	dev->resource[2]->end = SSB_CORE_SIZE;
 80	res = pcmcia_request_window(dev, dev->resource[2], 250);
 81	if (res != 0)
 82		goto err_kfree_ssb;
 83
 84	res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
 85	if (res != 0)
 86		goto err_disable;
 87
 88	if (!dev->irq)
 89		goto err_disable;
 90
 91	res = pcmcia_enable_device(dev);
 92	if (res != 0)
 93		goto err_disable;
 94
 95	err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
 96	if (err)
 97		goto err_disable;
 98	dev->priv = ssb;
 99
100	return 0;
101
102err_disable:
103	pcmcia_disable_device(dev);
104err_kfree_ssb:
105	kfree(ssb);
106out_error:
107	printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
108	       res, err);
109	return err;
110}
111
112static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev)
113{
114	struct ssb_bus *ssb = dev->priv;
115
116	ssb_bus_unregister(ssb);
117	pcmcia_disable_device(dev);
118	kfree(ssb);
119	dev->priv = NULL;
120}
121
122static struct pcmcia_driver b43_pcmcia_driver = {
123	.owner		= THIS_MODULE,
124	.name		= "b43-pcmcia",
125	.id_table	= b43_pcmcia_tbl,
126	.probe		= b43_pcmcia_probe,
127	.remove		= __devexit_p(b43_pcmcia_remove),
128	.suspend	= b43_pcmcia_suspend,
129	.resume		= b43_pcmcia_resume,
130};
131
132int b43_pcmcia_init(void)
133{
134	return pcmcia_register_driver(&b43_pcmcia_driver);
135}
136
137void b43_pcmcia_exit(void)
138{
139	pcmcia_unregister_driver(&b43_pcmcia_driver);
140}