diff options
Diffstat (limited to 'drivers/net/wireless/b43/pcmcia.c')
-rw-r--r-- | drivers/net/wireless/b43/pcmcia.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c new file mode 100644 index 000000000000..3e75a8a12c96 --- /dev/null +++ b/drivers/net/wireless/b43/pcmcia.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43 wireless driver | ||
4 | |||
5 | Copyright (c) 2007 Michael Buesch <mb@bu3sch.de> | ||
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 <linux/ssb/ssb.h> | ||
25 | |||
26 | #include <pcmcia/cs_types.h> | ||
27 | #include <pcmcia/cs.h> | ||
28 | #include <pcmcia/cistpl.h> | ||
29 | #include <pcmcia/ciscode.h> | ||
30 | #include <pcmcia/ds.h> | ||
31 | #include <pcmcia/cisreg.h> | ||
32 | |||
33 | static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = { | ||
34 | PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448), | ||
35 | PCMCIA_DEVICE_NULL, | ||
36 | }; | ||
37 | |||
38 | MODULE_DEVICE_TABLE(pcmcia, b43_pcmcia_tbl); | ||
39 | |||
40 | #ifdef CONFIG_PM | ||
41 | static int b43_pcmcia_suspend(struct pcmcia_device *dev) | ||
42 | { | ||
43 | //TODO | ||
44 | return 0; | ||
45 | } | ||
46 | |||
47 | static int b43_pcmcia_resume(struct pcmcia_device *dev) | ||
48 | { | ||
49 | //TODO | ||
50 | return 0; | ||
51 | } | ||
52 | #else /* CONFIG_PM */ | ||
53 | # define b43_pcmcia_suspend NULL | ||
54 | # define b43_pcmcia_resume NULL | ||
55 | #endif /* CONFIG_PM */ | ||
56 | |||
57 | static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) | ||
58 | { | ||
59 | struct ssb_bus *ssb; | ||
60 | win_req_t win; | ||
61 | memreq_t mem; | ||
62 | tuple_t tuple; | ||
63 | cisparse_t parse; | ||
64 | int err = -ENOMEM; | ||
65 | int res; | ||
66 | unsigned char buf[64]; | ||
67 | |||
68 | ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); | ||
69 | if (!ssb) | ||
70 | goto out; | ||
71 | |||
72 | err = -ENODEV; | ||
73 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
74 | tuple.Attributes = 0; | ||
75 | tuple.TupleData = buf; | ||
76 | tuple.TupleDataMax = sizeof(buf); | ||
77 | tuple.TupleOffset = 0; | ||
78 | |||
79 | res = pcmcia_get_first_tuple(dev, &tuple); | ||
80 | if (res != CS_SUCCESS) | ||
81 | goto err_kfree_ssb; | ||
82 | res = pcmcia_get_tuple_data(dev, &tuple); | ||
83 | if (res != CS_SUCCESS) | ||
84 | goto err_kfree_ssb; | ||
85 | res = pcmcia_parse_tuple(dev, &tuple, &parse); | ||
86 | if (res != CS_SUCCESS) | ||
87 | goto err_kfree_ssb; | ||
88 | |||
89 | dev->conf.ConfigBase = parse.config.base; | ||
90 | dev->conf.Present = parse.config.rmask[0]; | ||
91 | |||
92 | dev->io.BasePort2 = 0; | ||
93 | dev->io.NumPorts2 = 0; | ||
94 | dev->io.Attributes2 = 0; | ||
95 | |||
96 | win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; | ||
97 | win.Base = 0; | ||
98 | win.Size = SSB_CORE_SIZE; | ||
99 | win.AccessSpeed = 1000; | ||
100 | res = pcmcia_request_window(&dev, &win, &dev->win); | ||
101 | if (res != CS_SUCCESS) | ||
102 | goto err_kfree_ssb; | ||
103 | |||
104 | mem.CardOffset = 0; | ||
105 | mem.Page = 0; | ||
106 | res = pcmcia_map_mem_page(dev->win, &mem); | ||
107 | if (res != CS_SUCCESS) | ||
108 | goto err_kfree_ssb; | ||
109 | |||
110 | res = pcmcia_request_configuration(dev, &dev->conf); | ||
111 | if (res != CS_SUCCESS) | ||
112 | goto err_disable; | ||
113 | |||
114 | err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); | ||
115 | dev->priv = ssb; | ||
116 | |||
117 | out: | ||
118 | return err; | ||
119 | err_disable: | ||
120 | pcmcia_disable_device(dev); | ||
121 | err_kfree_ssb: | ||
122 | kfree(ssb); | ||
123 | return err; | ||
124 | } | ||
125 | |||
126 | static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev) | ||
127 | { | ||
128 | struct ssb_bus *ssb = dev->priv; | ||
129 | |||
130 | ssb_bus_unregister(ssb); | ||
131 | pcmcia_release_window(dev->win); | ||
132 | pcmcia_disable_device(dev); | ||
133 | kfree(ssb); | ||
134 | dev->priv = NULL; | ||
135 | } | ||
136 | |||
137 | static struct pcmcia_driver b43_pcmcia_driver = { | ||
138 | .owner = THIS_MODULE, | ||
139 | .drv = { | ||
140 | .name = "b43-pcmcia", | ||
141 | }, | ||
142 | .id_table = b43_pcmcia_tbl, | ||
143 | .probe = b43_pcmcia_probe, | ||
144 | .remove = b43_pcmcia_remove, | ||
145 | .suspend = b43_pcmcia_suspend, | ||
146 | .resume = b43_pcmcia_resume, | ||
147 | }; | ||
148 | |||
149 | int b43_pcmcia_init(void) | ||
150 | { | ||
151 | return pcmcia_register_driver(&b43_pcmcia_driver); | ||
152 | } | ||
153 | |||
154 | void b43_pcmcia_exit(void) | ||
155 | { | ||
156 | pcmcia_unregister_driver(&b43_pcmcia_driver); | ||
157 | } | ||