netfilter: xtables: add nfacct match to support extended accounting
[cascardo/linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / sdio_chip.c
1 /*
2  * Copyright (c) 2011 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /* ***** SDIO interface chip backplane handle functions ***** */
17
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/mmc/card.h>
21 #include <linux/ssb/ssb_regs.h>
22 #include <linux/bcma/bcma.h>
23
24 #include <chipcommon.h>
25 #include <brcm_hw_ids.h>
26 #include <brcmu_wifi.h>
27 #include <brcmu_utils.h>
28 #include <soc.h>
29 #include "dhd.h"
30 #include "dhd_dbg.h"
31 #include "sdio_host.h"
32 #include "sdio_chip.h"
33
34 /* chip core base & ramsize */
35 /* bcm4329 */
36 /* SDIO device core, ID 0x829 */
37 #define BCM4329_CORE_BUS_BASE           0x18011000
38 /* internal memory core, ID 0x80e */
39 #define BCM4329_CORE_SOCRAM_BASE        0x18003000
40 /* ARM Cortex M3 core, ID 0x82a */
41 #define BCM4329_CORE_ARM_BASE           0x18002000
42 #define BCM4329_RAMSIZE                 0x48000
43
44 #define SBCOREREV(sbidh) \
45         ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
46           ((sbidh) & SSB_IDHIGH_RCLO))
47
48 /* SOC Interconnect types (aka chip types) */
49 #define SOCI_SB         0
50 #define SOCI_AI         1
51
52 /* EROM CompIdentB */
53 #define CIB_REV_MASK            0xff000000
54 #define CIB_REV_SHIFT           24
55
56 #define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
57 /* SDIO Pad drive strength to select value mappings */
58 struct sdiod_drive_str {
59         u8 strength;    /* Pad Drive Strength in mA */
60         u8 sel;         /* Chip-specific select value */
61 };
62 /* SDIO Drive Strength to sel value table for PMU Rev 1 */
63 static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
64         {
65         4, 0x2}, {
66         2, 0x3}, {
67         1, 0x0}, {
68         0, 0x0}
69         };
70 /* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
71 static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
72         {
73         12, 0x7}, {
74         10, 0x6}, {
75         8, 0x5}, {
76         6, 0x4}, {
77         4, 0x2}, {
78         2, 0x1}, {
79         0, 0x0}
80         };
81 /* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
82 static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
83         {
84         32, 0x7}, {
85         26, 0x6}, {
86         22, 0x5}, {
87         16, 0x4}, {
88         12, 0x3}, {
89         8, 0x2}, {
90         4, 0x1}, {
91         0, 0x0}
92         };
93
94 u8
95 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
96 {
97         u8 idx;
98
99         for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
100                 if (coreid == ci->c_inf[idx].id)
101                         return idx;
102
103         return BRCMF_MAX_CORENUM;
104 }
105
106 static u32
107 brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
108                       struct chip_info *ci, u16 coreid)
109 {
110         u32 regdata;
111         u8 idx;
112
113         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
114
115         regdata = brcmf_sdcard_reg_read(sdiodev,
116                         CORE_SB(ci->c_inf[idx].base, sbidhigh), 4);
117         return SBCOREREV(regdata);
118 }
119
120 static u32
121 brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
122                       struct chip_info *ci, u16 coreid)
123 {
124         u8 idx;
125
126         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
127
128         return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
129 }
130
131 static bool
132 brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
133                        struct chip_info *ci, u16 coreid)
134 {
135         u32 regdata;
136         u8 idx;
137
138         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
139
140         regdata = brcmf_sdcard_reg_read(sdiodev,
141                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
142         regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
143                     SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
144         return (SSB_TMSLOW_CLOCK == regdata);
145 }
146
147 static bool
148 brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
149                        struct chip_info *ci, u16 coreid)
150 {
151         u32 regdata;
152         u8 idx;
153         bool ret;
154
155         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
156
157         regdata = brcmf_sdcard_reg_read(sdiodev,
158                                         ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
159         ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
160
161         regdata = brcmf_sdcard_reg_read(sdiodev,
162                                         ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
163                                         4);
164         ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
165
166         return ret;
167 }
168
169 static void
170 brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
171                           struct chip_info *ci, u16 coreid)
172 {
173         u32 regdata;
174         u8 idx;
175
176         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
177
178         regdata = brcmf_sdcard_reg_read(sdiodev,
179                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
180         if (regdata & SSB_TMSLOW_RESET)
181                 return;
182
183         regdata = brcmf_sdcard_reg_read(sdiodev,
184                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
185         if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
186                 /*
187                  * set target reject and spin until busy is clear
188                  * (preserve core-specific bits)
189                  */
190                 regdata = brcmf_sdcard_reg_read(sdiodev,
191                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
192                 brcmf_sdcard_reg_write(sdiodev,
193                                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
194                                 4, regdata | SSB_TMSLOW_REJECT);
195
196                 regdata = brcmf_sdcard_reg_read(sdiodev,
197                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
198                 udelay(1);
199                 SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
200                         CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4) &
201                         SSB_TMSHIGH_BUSY), 100000);
202
203                 regdata = brcmf_sdcard_reg_read(sdiodev,
204                         CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4);
205                 if (regdata & SSB_TMSHIGH_BUSY)
206                         brcmf_dbg(ERROR, "core state still busy\n");
207
208                 regdata = brcmf_sdcard_reg_read(sdiodev,
209                         CORE_SB(ci->c_inf[idx].base, sbidlow), 4);
210                 if (regdata & SSB_IDLOW_INITIATOR) {
211                         regdata = brcmf_sdcard_reg_read(sdiodev,
212                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) |
213                                 SSB_IMSTATE_REJECT;
214                         brcmf_sdcard_reg_write(sdiodev,
215                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
216                                 regdata);
217                         regdata = brcmf_sdcard_reg_read(sdiodev,
218                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4);
219                         udelay(1);
220                         SPINWAIT((brcmf_sdcard_reg_read(sdiodev,
221                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) &
222                                 SSB_IMSTATE_BUSY), 100000);
223                 }
224
225                 /* set reset and reject while enabling the clocks */
226                 brcmf_sdcard_reg_write(sdiodev,
227                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
228                         (SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
229                         SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
230                 regdata = brcmf_sdcard_reg_read(sdiodev,
231                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
232                 udelay(10);
233
234                 /* clear the initiator reject bit */
235                 regdata = brcmf_sdcard_reg_read(sdiodev,
236                         CORE_SB(ci->c_inf[idx].base, sbidlow), 4);
237                 if (regdata & SSB_IDLOW_INITIATOR) {
238                         regdata = brcmf_sdcard_reg_read(sdiodev,
239                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4) &
240                                 ~SSB_IMSTATE_REJECT;
241                         brcmf_sdcard_reg_write(sdiodev,
242                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
243                                 regdata);
244                 }
245         }
246
247         /* leave reset and reject asserted */
248         brcmf_sdcard_reg_write(sdiodev,
249                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
250                 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET));
251         udelay(1);
252 }
253
254 static void
255 brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
256                           struct chip_info *ci, u16 coreid)
257 {
258         u8 idx;
259         u32 regdata;
260
261         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
262
263         /* if core is already in reset, just return */
264         regdata = brcmf_sdcard_reg_read(sdiodev,
265                                         ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
266                                         4);
267         if ((regdata & BCMA_RESET_CTL_RESET) != 0)
268                 return;
269
270         brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
271                                4, 0);
272         regdata = brcmf_sdcard_reg_read(sdiodev,
273                                         ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
274         udelay(10);
275
276         brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
277                                4, BCMA_RESET_CTL_RESET);
278         udelay(1);
279 }
280
281 static void
282 brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
283                         struct chip_info *ci, u16 coreid)
284 {
285         u32 regdata;
286         u8 idx;
287
288         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
289
290         /*
291          * Must do the disable sequence first to work for
292          * arbitrary current core state.
293          */
294         brcmf_sdio_sb_coredisable(sdiodev, ci, coreid);
295
296         /*
297          * Now do the initialization sequence.
298          * set reset while enabling the clock and
299          * forcing them on throughout the core
300          */
301         brcmf_sdcard_reg_write(sdiodev,
302                         CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
303                         SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET);
304         regdata = brcmf_sdcard_reg_read(sdiodev,
305                                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
306         udelay(1);
307
308         /* clear any serror */
309         regdata = brcmf_sdcard_reg_read(sdiodev,
310                                 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4);
311         if (regdata & SSB_TMSHIGH_SERR)
312                 brcmf_sdcard_reg_write(sdiodev,
313                         CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), 4, 0);
314
315         regdata = brcmf_sdcard_reg_read(sdiodev,
316                                 CORE_SB(ci->c_inf[idx].base, sbimstate), 4);
317         if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
318                 brcmf_sdcard_reg_write(sdiodev,
319                         CORE_SB(ci->c_inf[idx].base, sbimstate), 4,
320                         regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO));
321
322         /* clear reset and allow it to propagate throughout the core */
323         brcmf_sdcard_reg_write(sdiodev,
324                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4,
325                 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK);
326         regdata = brcmf_sdcard_reg_read(sdiodev,
327                                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
328         udelay(1);
329
330         /* leave clock enabled */
331         brcmf_sdcard_reg_write(sdiodev,
332                                CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
333                                4, SSB_TMSLOW_CLOCK);
334         regdata = brcmf_sdcard_reg_read(sdiodev,
335                                 CORE_SB(ci->c_inf[idx].base, sbtmstatelow), 4);
336         udelay(1);
337 }
338
339 static void
340 brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
341                         struct chip_info *ci, u16 coreid)
342 {
343         u8 idx;
344         u32 regdata;
345
346         idx = brcmf_sdio_chip_getinfidx(ci, coreid);
347
348         /* must disable first to work for arbitrary current core state */
349         brcmf_sdio_ai_coredisable(sdiodev, ci, coreid);
350
351         /* now do initialization sequence */
352         brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
353                                4, BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
354         regdata = brcmf_sdcard_reg_read(sdiodev,
355                                         ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
356         brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
357                                4, 0);
358         udelay(1);
359
360         brcmf_sdcard_reg_write(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
361                                4, BCMA_IOCTL_CLK);
362         regdata = brcmf_sdcard_reg_read(sdiodev,
363                                         ci->c_inf[idx].wrapbase+BCMA_IOCTL, 4);
364         udelay(1);
365 }
366
367 static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
368                                        struct chip_info *ci, u32 regs)
369 {
370         u32 regdata;
371
372         /*
373          * Get CC core rev
374          * Chipid is assume to be at offset 0 from regs arg
375          * For different chiptypes or old sdio hosts w/o chipcommon,
376          * other ways of recognition should be added here.
377          */
378         ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
379         ci->c_inf[0].base = regs;
380         regdata = brcmf_sdcard_reg_read(sdiodev,
381                         CORE_CC_REG(ci->c_inf[0].base, chipid), 4);
382         ci->chip = regdata & CID_ID_MASK;
383         ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
384         ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
385
386         brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
387
388         /* Address of cores for new chips should be added here */
389         switch (ci->chip) {
390         case BCM4329_CHIP_ID:
391                 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
392                 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
393                 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
394                 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
395                 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
396                 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
397                 ci->ramsize = BCM4329_RAMSIZE;
398                 break;
399         default:
400                 brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip);
401                 return -ENODEV;
402         }
403
404         switch (ci->socitype) {
405         case SOCI_SB:
406                 ci->iscoreup = brcmf_sdio_sb_iscoreup;
407                 ci->corerev = brcmf_sdio_sb_corerev;
408                 ci->coredisable = brcmf_sdio_sb_coredisable;
409                 ci->resetcore = brcmf_sdio_sb_resetcore;
410                 break;
411         case SOCI_AI:
412                 ci->iscoreup = brcmf_sdio_ai_iscoreup;
413                 ci->corerev = brcmf_sdio_ai_corerev;
414                 ci->coredisable = brcmf_sdio_ai_coredisable;
415                 ci->resetcore = brcmf_sdio_ai_resetcore;
416                 break;
417         default:
418                 brcmf_dbg(ERROR, "socitype %u not supported\n", ci->socitype);
419                 return -ENODEV;
420         }
421
422         return 0;
423 }
424
425 static int
426 brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
427 {
428         int err = 0;
429         u8 clkval, clkset;
430
431         /* Try forcing SDIO core to do ALPAvail request only */
432         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
433         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
434                                SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
435         if (err) {
436                 brcmf_dbg(ERROR, "error writing for HT off\n");
437                 return err;
438         }
439
440         /* If register supported, wait for ALPAvail and then force ALP */
441         /* This may take up to 15 milliseconds */
442         clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
443                                        SBSDIO_FUNC1_CHIPCLKCSR, NULL);
444
445         if ((clkval & ~SBSDIO_AVBITS) != clkset) {
446                 brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
447                           clkset, clkval);
448                 return -EACCES;
449         }
450
451         SPINWAIT(((clkval = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_1,
452                                 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
453                         !SBSDIO_ALPAV(clkval)),
454                         PMU_MAX_TRANSITION_DLY);
455         if (!SBSDIO_ALPAV(clkval)) {
456                 brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n",
457                           clkval);
458                 return -EBUSY;
459         }
460
461         clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
462         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
463                                SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
464         udelay(65);
465
466         /* Also, disable the extra SDIO pull-ups */
467         brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
468                                SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
469
470         return 0;
471 }
472
473 static void
474 brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
475                              struct chip_info *ci)
476 {
477         /* get chipcommon rev */
478         ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
479
480         /* get chipcommon capabilites */
481         ci->c_inf[0].caps =
482                 brcmf_sdcard_reg_read(sdiodev,
483                 CORE_CC_REG(ci->c_inf[0].base, capabilities), 4);
484
485         /* get pmu caps & rev */
486         if (ci->c_inf[0].caps & CC_CAP_PMU) {
487                 ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
488                         CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4);
489                 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
490         }
491
492         ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
493
494         brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
495                   ci->c_inf[0].rev, ci->pmurev,
496                   ci->c_inf[1].rev, ci->c_inf[1].id);
497
498         /*
499          * Make sure any on-chip ARM is off (in case strapping is wrong),
500          * or downloaded code was already running.
501          */
502         ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3);
503 }
504
505 int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
506                            struct chip_info **ci_ptr, u32 regs)
507 {
508         int ret;
509         struct chip_info *ci;
510
511         brcmf_dbg(TRACE, "Enter\n");
512
513         /* alloc chip_info_t */
514         ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
515         if (!ci)
516                 return -ENOMEM;
517
518         ret = brcmf_sdio_chip_buscoreprep(sdiodev);
519         if (ret != 0)
520                 goto err;
521
522         ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs);
523         if (ret != 0)
524                 goto err;
525
526         brcmf_sdio_chip_buscoresetup(sdiodev, ci);
527
528         brcmf_sdcard_reg_write(sdiodev,
529                 CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0);
530         brcmf_sdcard_reg_write(sdiodev,
531                 CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0);
532
533         *ci_ptr = ci;
534         return 0;
535
536 err:
537         kfree(ci);
538         return ret;
539 }
540
541 void
542 brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
543 {
544         brcmf_dbg(TRACE, "Enter\n");
545
546         kfree(*ci_ptr);
547         *ci_ptr = NULL;
548 }
549
550 static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
551 {
552         const char *fmt;
553
554         fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
555         snprintf(buf, len, fmt, chipid);
556         return buf;
557 }
558
559 void
560 brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
561                                   struct chip_info *ci, u32 drivestrength)
562 {
563         struct sdiod_drive_str *str_tab = NULL;
564         u32 str_mask = 0;
565         u32 str_shift = 0;
566         char chn[8];
567
568         if (!(ci->c_inf[0].caps & CC_CAP_PMU))
569                 return;
570
571         switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
572         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
573                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
574                 str_mask = 0x30000000;
575                 str_shift = 28;
576                 break;
577         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
578         case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
579                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
580                 str_mask = 0x00003800;
581                 str_shift = 11;
582                 break;
583         case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
584                 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
585                 str_mask = 0x00003800;
586                 str_shift = 11;
587                 break;
588         default:
589                 brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
590                           brcmf_sdio_chip_name(ci->chip, chn, 8),
591                           ci->chiprev, ci->pmurev);
592                 break;
593         }
594
595         if (str_tab != NULL) {
596                 u32 drivestrength_sel = 0;
597                 u32 cc_data_temp;
598                 int i;
599
600                 for (i = 0; str_tab[i].strength != 0; i++) {
601                         if (drivestrength >= str_tab[i].strength) {
602                                 drivestrength_sel = str_tab[i].sel;
603                                 break;
604                         }
605                 }
606
607                 brcmf_sdcard_reg_write(sdiodev,
608                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
609                         4, 1);
610                 cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
611                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4);
612                 cc_data_temp &= ~str_mask;
613                 drivestrength_sel <<= str_shift;
614                 cc_data_temp |= drivestrength_sel;
615                 brcmf_sdcard_reg_write(sdiodev,
616                         CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
617                         4, cc_data_temp);
618
619                 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
620                           drivestrength, cc_data_temp);
621         }
622 }