ar5312.c revision 1.3.4.3 1 1.3.4.3 yamt /* $NetBSD: ar5312.c,v 1.3.4.3 2007/09/03 14:27:54 yamt Exp $ */
2 1.3.4.2 yamt
3 1.3.4.2 yamt /*
4 1.3.4.2 yamt * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
5 1.3.4.2 yamt * Copyright (c) 2006 Garrett D'Amore.
6 1.3.4.2 yamt * All rights reserved.
7 1.3.4.2 yamt *
8 1.3.4.2 yamt * Portions of this code were written by Garrett D'Amore for the
9 1.3.4.2 yamt * Champaign-Urbana Community Wireless Network Project.
10 1.3.4.2 yamt *
11 1.3.4.2 yamt * Redistribution and use in source and binary forms, with or
12 1.3.4.2 yamt * without modification, are permitted provided that the following
13 1.3.4.2 yamt * conditions are met:
14 1.3.4.2 yamt * 1. Redistributions of source code must retain the above copyright
15 1.3.4.2 yamt * notice, this list of conditions and the following disclaimer.
16 1.3.4.2 yamt * 2. Redistributions in binary form must reproduce the above
17 1.3.4.2 yamt * copyright notice, this list of conditions and the following
18 1.3.4.2 yamt * disclaimer in the documentation and/or other materials provided
19 1.3.4.2 yamt * with the distribution.
20 1.3.4.2 yamt * 3. All advertising materials mentioning features or use of this
21 1.3.4.2 yamt * software must display the following acknowledgements:
22 1.3.4.2 yamt * This product includes software developed by the Urbana-Champaign
23 1.3.4.2 yamt * Independent Media Center.
24 1.3.4.2 yamt * This product includes software developed by Garrett D'Amore.
25 1.3.4.2 yamt * 4. Urbana-Champaign Independent Media Center's name and Garrett
26 1.3.4.2 yamt * D'Amore's name may not be used to endorse or promote products
27 1.3.4.2 yamt * derived from this software without specific prior written permission.
28 1.3.4.2 yamt *
29 1.3.4.2 yamt * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
30 1.3.4.2 yamt * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
31 1.3.4.2 yamt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 1.3.4.2 yamt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 1.3.4.2 yamt * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
34 1.3.4.2 yamt * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
35 1.3.4.2 yamt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 1.3.4.2 yamt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 1.3.4.2 yamt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 1.3.4.2 yamt * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 1.3.4.2 yamt * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 1.3.4.2 yamt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 1.3.4.2 yamt * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 1.3.4.2 yamt */
43 1.3.4.2 yamt
44 1.3.4.2 yamt /*
45 1.3.4.2 yamt * This file includes a bunch of implementation specific bits for
46 1.3.4.2 yamt * AR5312, which differents these from other members of the AR5315
47 1.3.4.2 yamt * family.
48 1.3.4.2 yamt */
49 1.3.4.2 yamt #include "opt_ddb.h"
50 1.3.4.2 yamt #include "opt_kgdb.h"
51 1.3.4.2 yamt
52 1.3.4.2 yamt #include "opt_memsize.h"
53 1.3.4.2 yamt #include <sys/param.h>
54 1.3.4.2 yamt #include <sys/systm.h>
55 1.3.4.2 yamt #include <sys/kernel.h>
56 1.3.4.2 yamt #include <sys/buf.h>
57 1.3.4.2 yamt
58 1.3.4.2 yamt #include <mips/cache.h>
59 1.3.4.2 yamt #include <mips/locore.h>
60 1.3.4.2 yamt #include <mips/cpuregs.h>
61 1.3.4.2 yamt
62 1.3.4.2 yamt #include <sys/socket.h> /* these three just to get ETHER_ADDR_LEN(!) */
63 1.3.4.2 yamt #include <net/if.h>
64 1.3.4.2 yamt #include <net/if_ether.h>
65 1.3.4.2 yamt
66 1.3.4.2 yamt #include <mips/atheros/include/ar5312reg.h>
67 1.3.4.2 yamt #include <mips/atheros/include/ar531xvar.h>
68 1.3.4.2 yamt #include <mips/atheros/include/arbusvar.h>
69 1.3.4.2 yamt #include "com.h"
70 1.3.4.2 yamt
71 1.3.4.2 yamt uint32_t
72 1.3.4.2 yamt ar531x_memsize(void)
73 1.3.4.2 yamt {
74 1.3.4.2 yamt uint32_t memsize;
75 1.3.4.2 yamt uint32_t memcfg, bank0, bank1;
76 1.3.4.2 yamt
77 1.3.4.2 yamt /*
78 1.3.4.2 yamt * Determine the memory size as established by system
79 1.3.4.2 yamt * firmware.
80 1.3.4.2 yamt *
81 1.3.4.2 yamt * NB: we allow compile time override
82 1.3.4.2 yamt */
83 1.3.4.2 yamt #if defined(MEMSIZE)
84 1.3.4.2 yamt memsize = MEMSIZE;
85 1.3.4.2 yamt #else
86 1.3.4.2 yamt memcfg = GETSDRAMREG(AR5312_SDRAMCTL_MEM_CFG1);
87 1.3.4.2 yamt bank0 = (memcfg & AR5312_MEM_CFG1_BANK0_MASK) >>
88 1.3.4.2 yamt AR5312_MEM_CFG1_BANK0_SHIFT;
89 1.3.4.2 yamt bank1 = (memcfg & AR5312_MEM_CFG1_BANK1_MASK) >>
90 1.3.4.2 yamt AR5312_MEM_CFG1_BANK1_SHIFT;
91 1.3.4.2 yamt
92 1.3.4.2 yamt memsize = (bank0 ? (1 << (bank0 + 1)) : 0) +
93 1.3.4.2 yamt (bank1 ? (1 << (bank1 + 1)) : 0);
94 1.3.4.2 yamt memsize <<= 20;
95 1.3.4.2 yamt #endif
96 1.3.4.2 yamt
97 1.3.4.2 yamt return (memsize);
98 1.3.4.2 yamt }
99 1.3.4.2 yamt
100 1.3.4.2 yamt void
101 1.3.4.2 yamt ar531x_wdog(uint32_t period)
102 1.3.4.2 yamt {
103 1.3.4.2 yamt
104 1.3.4.2 yamt if (period == 0) {
105 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_IGNORE);
106 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, 0);
107 1.3.4.2 yamt } else {
108 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, period);
109 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_RESET);
110 1.3.4.2 yamt }
111 1.3.4.2 yamt }
112 1.3.4.2 yamt
113 1.3.4.2 yamt const char *
114 1.3.4.2 yamt ar531x_cpuname(void)
115 1.3.4.2 yamt {
116 1.3.4.2 yamt uint32_t revision;
117 1.3.4.2 yamt
118 1.3.4.2 yamt revision = GETSYSREG(AR5312_SYSREG_REVISION);
119 1.3.4.2 yamt switch (AR5312_REVISION_MAJOR(revision)) {
120 1.3.4.2 yamt case AR5312_REVISION_MAJ_AR5311:
121 1.3.4.2 yamt return ("Atheros AR5311");
122 1.3.4.2 yamt case AR5312_REVISION_MAJ_AR5312:
123 1.3.4.2 yamt return ("Atheros AR5312");
124 1.3.4.2 yamt case AR5312_REVISION_MAJ_AR2313:
125 1.3.4.2 yamt return ("Atheros AR2313");
126 1.3.4.2 yamt case AR5312_REVISION_MAJ_AR5315:
127 1.3.4.2 yamt return ("Atheros AR5315");
128 1.3.4.2 yamt default:
129 1.3.4.2 yamt return ("Atheros AR531X");
130 1.3.4.2 yamt }
131 1.3.4.2 yamt }
132 1.3.4.2 yamt
133 1.3.4.2 yamt void
134 1.3.4.2 yamt ar531x_businit(void)
135 1.3.4.2 yamt
136 1.3.4.2 yamt {
137 1.3.4.2 yamt /*
138 1.3.4.2 yamt * Clear previous AHB errors
139 1.3.4.2 yamt */
140 1.3.4.2 yamt GETSYSREG(AR5312_SYSREG_AHBPERR);
141 1.3.4.2 yamt GETSYSREG(AR5312_SYSREG_AHBDMAE);
142 1.3.4.2 yamt }
143 1.3.4.2 yamt
144 1.3.4.2 yamt uint32_t
145 1.3.4.2 yamt ar531x_cpu_freq(void)
146 1.3.4.2 yamt {
147 1.3.4.2 yamt static uint32_t cpufreq;
148 1.3.4.2 yamt uint32_t wisoc = GETSYSREG(AR5312_SYSREG_REVISION);
149 1.3.4.2 yamt
150 1.3.4.2 yamt uint32_t predivmask;
151 1.3.4.2 yamt uint32_t predivshift;
152 1.3.4.2 yamt uint32_t multmask;
153 1.3.4.2 yamt uint32_t multshift;
154 1.3.4.2 yamt uint32_t doublermask;
155 1.3.4.2 yamt uint32_t divisor;
156 1.3.4.2 yamt uint32_t multiplier;
157 1.3.4.2 yamt uint32_t clockctl;
158 1.3.4.2 yamt
159 1.3.4.2 yamt const int predivide_table[4] = { 1, 2, 4, 5 };
160 1.3.4.2 yamt
161 1.3.4.2 yamt /* XXX: in theory we might be able to get clock from bootrom */
162 1.3.4.2 yamt
163 1.3.4.2 yamt /*
164 1.3.4.2 yamt * This logic looks at the clock control register and
165 1.3.4.2 yamt * determines the actual CPU frequency. These parts lack any
166 1.3.4.2 yamt * kind of real-time clock on them, but the cpu clocks should
167 1.3.4.2 yamt * be very accurate -- WiFi requires usec resolution timers.
168 1.3.4.2 yamt */
169 1.3.4.2 yamt
170 1.3.4.2 yamt if (cpufreq) {
171 1.3.4.2 yamt return cpufreq;
172 1.3.4.2 yamt }
173 1.3.4.2 yamt
174 1.3.4.2 yamt if (AR5312_REVISION_MAJOR(wisoc) == AR5312_REVISION_MAJ_AR2313) {
175 1.3.4.2 yamt predivmask = AR2313_CLOCKCTL_PREDIVIDE_MASK;
176 1.3.4.2 yamt predivshift = AR2313_CLOCKCTL_PREDIVIDE_SHIFT;
177 1.3.4.2 yamt multmask = AR2313_CLOCKCTL_MULTIPLIER_MASK;
178 1.3.4.2 yamt multshift = AR2313_CLOCKCTL_MULTIPLIER_SHIFT;
179 1.3.4.2 yamt doublermask = AR2313_CLOCKCTL_DOUBLER_MASK;
180 1.3.4.2 yamt } else {
181 1.3.4.2 yamt predivmask = AR5312_CLOCKCTL_PREDIVIDE_MASK;
182 1.3.4.2 yamt predivshift = AR5312_CLOCKCTL_PREDIVIDE_SHIFT;
183 1.3.4.2 yamt multmask = AR5312_CLOCKCTL_MULTIPLIER_MASK;
184 1.3.4.2 yamt multshift = AR5312_CLOCKCTL_MULTIPLIER_SHIFT;
185 1.3.4.2 yamt doublermask = AR5312_CLOCKCTL_DOUBLER_MASK;
186 1.3.4.2 yamt }
187 1.3.4.2 yamt
188 1.3.4.2 yamt /*
189 1.3.4.2 yamt * Note that the source clock involved here is a 40MHz.
190 1.3.4.2 yamt */
191 1.3.4.2 yamt
192 1.3.4.2 yamt clockctl = GETSYSREG(AR5312_SYSREG_CLOCKCTL);
193 1.3.4.2 yamt divisor = predivide_table[(clockctl & predivmask) >> predivshift];
194 1.3.4.2 yamt multiplier = (clockctl & multmask) >> multshift;
195 1.3.4.2 yamt
196 1.3.4.2 yamt if (clockctl & doublermask)
197 1.3.4.2 yamt multiplier <<= 1;
198 1.3.4.2 yamt
199 1.3.4.2 yamt cpufreq = (40000000 / divisor) * multiplier;
200 1.3.4.2 yamt
201 1.3.4.2 yamt return (cpufreq);
202 1.3.4.2 yamt }
203 1.3.4.2 yamt
204 1.3.4.2 yamt uint32_t
205 1.3.4.2 yamt ar531x_bus_freq(void)
206 1.3.4.2 yamt {
207 1.3.4.2 yamt return (ar531x_cpu_freq() / 4);
208 1.3.4.2 yamt }
209 1.3.4.2 yamt
210 1.3.4.2 yamt static void
211 1.3.4.2 yamt addprop_data(struct device *dev, const char *name, const uint8_t *data,
212 1.3.4.2 yamt int len)
213 1.3.4.2 yamt {
214 1.3.4.2 yamt prop_data_t pd;
215 1.3.4.2 yamt pd = prop_data_create_data(data, len);
216 1.3.4.2 yamt KASSERT(pd != NULL);
217 1.3.4.3 yamt if (prop_dictionary_set(device_properties(dev), name, pd) == false) {
218 1.3.4.2 yamt printf("WARNING: unable to set %s property for %s\n",
219 1.3.4.2 yamt name, device_xname(dev));
220 1.3.4.2 yamt }
221 1.3.4.2 yamt prop_object_release(pd);
222 1.3.4.2 yamt }
223 1.3.4.2 yamt
224 1.3.4.2 yamt static void
225 1.3.4.2 yamt addprop_integer(struct device *dev, const char *name, uint32_t val)
226 1.3.4.2 yamt {
227 1.3.4.2 yamt prop_number_t pn;
228 1.3.4.2 yamt pn = prop_number_create_integer(val);
229 1.3.4.2 yamt KASSERT(pn != NULL);
230 1.3.4.3 yamt if (prop_dictionary_set(device_properties(dev), name, pn) == false) {
231 1.3.4.2 yamt printf("WARNING: unable to set %s property for %s",
232 1.3.4.2 yamt name, device_xname(dev));
233 1.3.4.2 yamt }
234 1.3.4.2 yamt prop_object_release(pn);
235 1.3.4.2 yamt }
236 1.3.4.2 yamt
237 1.3.4.2 yamt void
238 1.3.4.2 yamt ar531x_device_register(struct device *dev, void *aux)
239 1.3.4.2 yamt {
240 1.3.4.2 yamt struct arbus_attach_args *aa = aux;
241 1.3.4.2 yamt const struct ar531x_boarddata *info;
242 1.3.4.2 yamt
243 1.3.4.2 yamt info = ar531x_board_info();
244 1.3.4.2 yamt if (info == NULL) {
245 1.3.4.2 yamt /* nothing known about this board! */
246 1.3.4.2 yamt return;
247 1.3.4.2 yamt }
248 1.3.4.2 yamt
249 1.3.4.2 yamt /*
250 1.3.4.2 yamt * We don't ever know the boot device. But that's because the
251 1.3.4.2 yamt * firmware only loads from the network.
252 1.3.4.2 yamt */
253 1.3.4.2 yamt
254 1.3.4.2 yamt /* Fetch the MAC addresses. */
255 1.3.4.2 yamt if (device_is_a(dev, "ae")) {
256 1.3.4.2 yamt const uint8_t *enet;
257 1.3.4.2 yamt
258 1.3.4.2 yamt if (aa->aa_addr == AR5312_ENET0_BASE)
259 1.3.4.2 yamt enet = info->enet0Mac;
260 1.3.4.2 yamt else if (aa->aa_addr == AR5312_ENET1_BASE)
261 1.3.4.2 yamt enet = info->enet1Mac;
262 1.3.4.2 yamt else
263 1.3.4.2 yamt return;
264 1.3.4.2 yamt
265 1.3.4.2 yamt addprop_data(dev, "mac-addr", enet, ETHER_ADDR_LEN);
266 1.3.4.2 yamt }
267 1.3.4.2 yamt
268 1.3.4.2 yamt if (device_is_a(dev, "ath")) {
269 1.3.4.2 yamt const uint8_t *enet;
270 1.3.4.2 yamt
271 1.3.4.2 yamt if (aa->aa_addr == AR5312_WLAN0_BASE)
272 1.3.4.2 yamt enet = info->wlan0Mac;
273 1.3.4.2 yamt else if (aa->aa_addr == AR5312_WLAN1_BASE)
274 1.3.4.2 yamt enet = info->wlan1Mac;
275 1.3.4.2 yamt else
276 1.3.4.2 yamt return;
277 1.3.4.2 yamt
278 1.3.4.2 yamt addprop_data(dev, "mac-addr", enet, ETHER_ADDR_LEN);
279 1.3.4.2 yamt
280 1.3.4.2 yamt addprop_integer(dev, "wmac-rev",
281 1.3.4.2 yamt AR5312_REVISION_WMAC(GETSYSREG(AR5312_SYSREG_REVISION)));
282 1.3.4.2 yamt
283 1.3.4.2 yamt }
284 1.3.4.2 yamt
285 1.3.4.2 yamt if (device_is_a(dev, "com")) {
286 1.3.4.2 yamt addprop_integer(dev, "frequency", ar531x_cpu_freq() / 4);
287 1.3.4.2 yamt }
288 1.3.4.2 yamt
289 1.3.4.2 yamt if (device_is_a(dev, "argpio")) {
290 1.3.4.2 yamt if (info->config & BD_RSTFACTORY) {
291 1.3.4.2 yamt addprop_integer(dev, "reset-pin",
292 1.3.4.2 yamt info->resetConfigGpio);
293 1.3.4.2 yamt }
294 1.3.4.2 yamt if (info->config & BD_SYSLED) {
295 1.3.4.2 yamt addprop_integer(dev, "sysled-pin",
296 1.3.4.2 yamt info->sysLedGpio);
297 1.3.4.2 yamt }
298 1.3.4.2 yamt }
299 1.3.4.2 yamt }
300 1.3.4.2 yamt
301 1.3.4.2 yamt int
302 1.3.4.2 yamt ar531x_enable_device(const struct ar531x_device *dev)
303 1.3.4.2 yamt {
304 1.3.4.2 yamt const struct ar531x_boarddata *info;
305 1.3.4.2 yamt
306 1.3.4.2 yamt info = ar531x_board_info();
307 1.3.4.2 yamt if (dev->mask && ((dev->mask & info->config) == 0)) {
308 1.3.4.2 yamt return -1;
309 1.3.4.2 yamt }
310 1.3.4.2 yamt if (dev->reset) {
311 1.3.4.2 yamt /* put device into reset */
312 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_RESETCTL,
313 1.3.4.2 yamt GETSYSREG(AR5312_SYSREG_RESETCTL) | dev->reset);
314 1.3.4.2 yamt
315 1.3.4.2 yamt delay(15000); /* XXX: tsleep? */
316 1.3.4.2 yamt
317 1.3.4.2 yamt /* take it out of reset */
318 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_RESETCTL,
319 1.3.4.2 yamt GETSYSREG(AR5312_SYSREG_RESETCTL) & ~dev->reset);
320 1.3.4.2 yamt
321 1.3.4.2 yamt delay(25);
322 1.3.4.2 yamt }
323 1.3.4.2 yamt if (dev->enable) {
324 1.3.4.2 yamt PUTSYSREG(AR5312_SYSREG_ENABLE,
325 1.3.4.2 yamt GETSYSREG(AR5312_SYSREG_ENABLE) | dev->enable);
326 1.3.4.2 yamt }
327 1.3.4.2 yamt return 0;
328 1.3.4.2 yamt }
329 1.3.4.2 yamt
330 1.3.4.2 yamt const struct ar531x_device *
331 1.3.4.2 yamt ar531x_get_devices(void)
332 1.3.4.2 yamt {
333 1.3.4.2 yamt static const struct ar531x_device devices[] = {
334 1.3.4.2 yamt {
335 1.3.4.2 yamt "ae",
336 1.3.4.2 yamt AR5312_ENET0_BASE, 0x100000,
337 1.3.4.2 yamt AR5312_IRQ_ENET0, -1,
338 1.3.4.2 yamt AR5312_BOARD_CONFIG_ENET0,
339 1.3.4.2 yamt AR5312_RESET_ENET0 | AR5312_RESET_PHY0,
340 1.3.4.2 yamt AR5312_ENABLE_ENET0
341 1.3.4.2 yamt },
342 1.3.4.2 yamt {
343 1.3.4.2 yamt "ae",
344 1.3.4.2 yamt AR5312_ENET1_BASE, 0x100000,
345 1.3.4.2 yamt AR5312_IRQ_ENET1, -1,
346 1.3.4.2 yamt AR5312_BOARD_CONFIG_ENET1,
347 1.3.4.2 yamt AR5312_RESET_ENET1 | AR5312_RESET_PHY1,
348 1.3.4.2 yamt AR5312_ENABLE_ENET1
349 1.3.4.2 yamt },
350 1.3.4.2 yamt {
351 1.3.4.2 yamt "com",
352 1.3.4.2 yamt AR5312_UART0_BASE, 0x1000,
353 1.3.4.2 yamt AR5312_IRQ_MISC, AR5312_MISC_IRQ_UART0,
354 1.3.4.2 yamt AR5312_BOARD_CONFIG_UART0,
355 1.3.4.2 yamt 0,
356 1.3.4.2 yamt 0,
357 1.3.4.2 yamt },
358 1.3.4.2 yamt {
359 1.3.4.2 yamt "com",
360 1.3.4.2 yamt AR5312_UART1_BASE, 0x1000,
361 1.3.4.2 yamt -1, -1,
362 1.3.4.2 yamt AR5312_BOARD_CONFIG_UART1,
363 1.3.4.2 yamt 0,
364 1.3.4.2 yamt 0,
365 1.3.4.2 yamt },
366 1.3.4.2 yamt {
367 1.3.4.2 yamt "ath",
368 1.3.4.2 yamt AR5312_WLAN0_BASE, 0x100000,
369 1.3.4.2 yamt AR5312_IRQ_WLAN0, -1,
370 1.3.4.2 yamt AR5312_BOARD_CONFIG_WLAN0,
371 1.3.4.2 yamt AR5312_RESET_WLAN0 |
372 1.3.4.2 yamt AR5312_RESET_WARM_WLAN0_MAC |
373 1.3.4.2 yamt AR5312_RESET_WARM_WLAN0_BB,
374 1.3.4.2 yamt AR5312_ENABLE_WLAN0
375 1.3.4.2 yamt },
376 1.3.4.2 yamt {
377 1.3.4.2 yamt "ath",
378 1.3.4.2 yamt AR5312_WLAN1_BASE, 0x100000,
379 1.3.4.2 yamt AR5312_IRQ_WLAN1, -1,
380 1.3.4.2 yamt AR5312_BOARD_CONFIG_WLAN1,
381 1.3.4.2 yamt AR5312_RESET_WLAN1 |
382 1.3.4.2 yamt AR5312_RESET_WARM_WLAN1_MAC |
383 1.3.4.2 yamt AR5312_RESET_WARM_WLAN1_BB,
384 1.3.4.2 yamt AR5312_ENABLE_WLAN1
385 1.3.4.2 yamt },
386 1.3.4.2 yamt {
387 1.3.4.2 yamt "athflash",
388 1.3.4.2 yamt AR5312_FLASH_BASE, 0,
389 1.3.4.2 yamt -1, -1,
390 1.3.4.2 yamt 0,
391 1.3.4.2 yamt 0,
392 1.3.4.2 yamt 0,
393 1.3.4.2 yamt },
394 1.3.4.2 yamt {
395 1.3.4.2 yamt "argpio", 0x1000,
396 1.3.4.2 yamt AR5312_GPIO_BASE,
397 1.3.4.2 yamt AR5312_IRQ_MISC, AR5312_MISC_IRQ_GPIO,
398 1.3.4.2 yamt 0,
399 1.3.4.2 yamt 0,
400 1.3.4.2 yamt 0
401 1.3.4.2 yamt },
402 1.3.4.2 yamt { NULL }
403 1.3.4.2 yamt };
404 1.3.4.2 yamt
405 1.3.4.2 yamt return devices;
406 1.3.4.2 yamt }
407 1.3.4.2 yamt
408