aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorFranky Lin <frankyl@broadcom.com>2011-11-04 17:23:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:14:05 -0500
commite12afb6c5d13ebff64d4a2feb97cce0c2d7e1128 (patch)
treeac43f2b0d1cfdeb743468a96fa3ee21637d26fb2 /drivers/net/wireless/brcm80211
parenta8a6c04586233e12551552c292797cb56b31dade (diff)
brcm80211: fmac: move chip drive strength related code to sdio_chip.c
This patch is part of the abstracting chip backplane handle code series. Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c117
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c112
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h3
3 files changed, 117 insertions, 115 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index e05c7845dbd7..d45fa32ac01a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3704,120 +3704,6 @@ fail:
3704 return false; 3704 return false;
3705} 3705}
3706 3706
3707/* SDIO Pad drive strength to select value mappings */
3708struct sdiod_drive_str {
3709 u8 strength; /* Pad Drive Strength in mA */
3710 u8 sel; /* Chip-specific select value */
3711};
3712
3713/* SDIO Drive Strength to sel value table for PMU Rev 1 */
3714static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
3715 {
3716 4, 0x2}, {
3717 2, 0x3}, {
3718 1, 0x0}, {
3719 0, 0x0}
3720 };
3721
3722/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
3723static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
3724 {
3725 12, 0x7}, {
3726 10, 0x6}, {
3727 8, 0x5}, {
3728 6, 0x4}, {
3729 4, 0x2}, {
3730 2, 0x1}, {
3731 0, 0x0}
3732 };
3733
3734/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
3735static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
3736 {
3737 32, 0x7}, {
3738 26, 0x6}, {
3739 22, 0x5}, {
3740 16, 0x4}, {
3741 12, 0x3}, {
3742 8, 0x2}, {
3743 4, 0x1}, {
3744 0, 0x0}
3745 };
3746
3747#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
3748
3749static char *brcmf_chipname(uint chipid, char *buf, uint len)
3750{
3751 const char *fmt;
3752
3753 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
3754 snprintf(buf, len, fmt, chipid);
3755 return buf;
3756}
3757
3758static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus,
3759 u32 drivestrength) {
3760 struct sdiod_drive_str *str_tab = NULL;
3761 u32 str_mask = 0;
3762 u32 str_shift = 0;
3763 char chn[8];
3764
3765 if (!(bus->ci->cccaps & CC_CAP_PMU))
3766 return;
3767
3768 switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
3769 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
3770 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
3771 str_mask = 0x30000000;
3772 str_shift = 28;
3773 break;
3774 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
3775 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
3776 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
3777 str_mask = 0x00003800;
3778 str_shift = 11;
3779 break;
3780 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
3781 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
3782 str_mask = 0x00003800;
3783 str_shift = 11;
3784 break;
3785 default:
3786 brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
3787 brcmf_chipname(bus->ci->chip, chn, 8),
3788 bus->ci->chiprev, bus->ci->pmurev);
3789 break;
3790 }
3791
3792 if (str_tab != NULL) {
3793 u32 drivestrength_sel = 0;
3794 u32 cc_data_temp;
3795 int i;
3796
3797 for (i = 0; str_tab[i].strength != 0; i++) {
3798 if (drivestrength >= str_tab[i].strength) {
3799 drivestrength_sel = str_tab[i].sel;
3800 break;
3801 }
3802 }
3803
3804 brcmf_sdcard_reg_write(bus->sdiodev,
3805 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
3806 4, 1);
3807 cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev,
3808 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
3809 cc_data_temp &= ~str_mask;
3810 drivestrength_sel <<= str_shift;
3811 cc_data_temp |= drivestrength_sel;
3812 brcmf_sdcard_reg_write(bus->sdiodev,
3813 CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
3814 4, cc_data_temp);
3815
3816 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
3817 drivestrength, cc_data_temp);
3818 }
3819}
3820
3821static bool 3707static bool
3822brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) 3708brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
3823{ 3709{
@@ -3867,7 +3753,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
3867 goto fail; 3753 goto fail;
3868 } 3754 }
3869 3755
3870 brcmf_sdbrcm_sdiod_drive_strength_init(bus, SDIO_DRIVE_STRENGTH); 3756 brcmf_sdio_chip_drivestrengthinit(bus->sdiodev, bus->ci,
3757 SDIO_DRIVE_STRENGTH);
3871 3758
3872 /* Get info on the SOCRAM cores... */ 3759 /* Get info on the SOCRAM cores... */
3873 bus->ramsize = bus->ci->ramsize; 3760 bus->ramsize = bus->ci->ramsize;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index ea12a4c3c2fd..e068107f5fae 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -52,6 +52,44 @@
52#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ 52#define SBIDH_VC_MASK 0xffff0000 /* vendor code */
53#define SBIDH_VC_SHIFT 16 53#define SBIDH_VC_SHIFT 16
54 54
55#define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
56/* SDIO Pad drive strength to select value mappings */
57struct sdiod_drive_str {
58 u8 strength; /* Pad Drive Strength in mA */
59 u8 sel; /* Chip-specific select value */
60};
61/* SDIO Drive Strength to sel value table for PMU Rev 1 */
62static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
63 {
64 4, 0x2}, {
65 2, 0x3}, {
66 1, 0x0}, {
67 0, 0x0}
68 };
69/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
70static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
71 {
72 12, 0x7}, {
73 10, 0x6}, {
74 8, 0x5}, {
75 6, 0x4}, {
76 4, 0x2}, {
77 2, 0x1}, {
78 0, 0x0}
79 };
80/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
81static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
82 {
83 32, 0x7}, {
84 26, 0x6}, {
85 22, 0x5}, {
86 16, 0x4}, {
87 12, 0x3}, {
88 8, 0x2}, {
89 4, 0x1}, {
90 0, 0x0}
91 };
92
55static u32 93static u32
56brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev, 94brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev,
57 u32 corebase) 95 u32 corebase)
@@ -363,3 +401,77 @@ brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
363 kfree(*ci_ptr); 401 kfree(*ci_ptr);
364 *ci_ptr = NULL; 402 *ci_ptr = NULL;
365} 403}
404
405static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
406{
407 const char *fmt;
408
409 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
410 snprintf(buf, len, fmt, chipid);
411 return buf;
412}
413
414void
415brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
416 struct chip_info *ci, u32 drivestrength)
417{
418 struct sdiod_drive_str *str_tab = NULL;
419 u32 str_mask = 0;
420 u32 str_shift = 0;
421 char chn[8];
422
423 if (!(ci->cccaps & CC_CAP_PMU))
424 return;
425
426 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
427 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
428 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
429 str_mask = 0x30000000;
430 str_shift = 28;
431 break;
432 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
433 case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
434 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
435 str_mask = 0x00003800;
436 str_shift = 11;
437 break;
438 case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
439 str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
440 str_mask = 0x00003800;
441 str_shift = 11;
442 break;
443 default:
444 brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
445 brcmf_sdio_chip_name(ci->chip, chn, 8),
446 ci->chiprev, ci->pmurev);
447 break;
448 }
449
450 if (str_tab != NULL) {
451 u32 drivestrength_sel = 0;
452 u32 cc_data_temp;
453 int i;
454
455 for (i = 0; str_tab[i].strength != 0; i++) {
456 if (drivestrength >= str_tab[i].strength) {
457 drivestrength_sel = str_tab[i].sel;
458 break;
459 }
460 }
461
462 brcmf_sdcard_reg_write(sdiodev,
463 CORE_CC_REG(ci->cccorebase, chipcontrol_addr),
464 4, 1);
465 cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
466 CORE_CC_REG(ci->cccorebase, chipcontrol_addr), 4);
467 cc_data_temp &= ~str_mask;
468 drivestrength_sel <<= str_shift;
469 cc_data_temp |= drivestrength_sel;
470 brcmf_sdcard_reg_write(sdiodev,
471 CORE_CC_REG(ci->cccorebase, chipcontrol_addr),
472 4, cc_data_temp);
473
474 brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
475 drivestrength, cc_data_temp);
476 }
477}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
index 13b09a49b7b0..e816bb69959c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h
@@ -142,5 +142,8 @@ extern void brcmf_sdio_chip_coredisable(struct brcmf_sdio_dev *sdiodev,
142extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, 142extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
143 struct chip_info **ci_ptr, u32 regs); 143 struct chip_info **ci_ptr, u32 regs);
144extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); 144extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr);
145extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
146 struct chip_info *ci,
147 u32 drivestrength);
145 148
146#endif /* _BRCMFMAC_SDIO_CHIP_H_ */ 149#endif /* _BRCMFMAC_SDIO_CHIP_H_ */