diff options
| author | Gábor Stefanik <netrolller.3d@gmail.com> | 2009-08-26 14:51:26 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2009-08-28 14:40:53 -0400 |
| commit | 06e4da268c0e8f3b8408403d65e47d2885a78ff2 (patch) | |
| tree | 971fffcefbe06c5bba590953a06ced39947f1198 | |
| parent | 68ec53292c7f09056152efa9a6ee2591c794f08c (diff) | |
ssb: Implement PMU LDO control and use it in b43
Implement the "PMU LDO set voltage" and "PMU LDO PA ref enable"
functions, and use them during LP-PHY baseband init in b43.
Signed-off-by: Gábor Stefanik <netrolller.3d@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/b43/phy_lp.c | 10 | ||||
| -rw-r--r-- | drivers/ssb/driver_chipcommon_pmu.c | 94 | ||||
| -rw-r--r-- | include/linux/ssb/ssb_driver_chipcommon.h | 10 |
3 files changed, 107 insertions, 7 deletions
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 1a57d3390e92..80f245c04042 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
| @@ -234,19 +234,15 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 234 | if ((bus->sprom.boardflags_lo & B43_BFL_FEM) && | 234 | if ((bus->sprom.boardflags_lo & B43_BFL_FEM) && |
| 235 | ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | 235 | ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || |
| 236 | (bus->sprom.boardflags_hi & B43_BFH_PAREF))) { | 236 | (bus->sprom.boardflags_hi & B43_BFH_PAREF))) { |
| 237 | /* TODO: | 237 | ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28); |
| 238 | * Set the LDO voltage to 0x0028 - FIXME: What is this? | 238 | ssb_pmu_set_ldo_paref(&bus->chipco, true); |
| 239 | * Call sb_pmu_set_ldo_voltage with 4 and the LDO voltage | ||
| 240 | * as arguments | ||
| 241 | * Call sb_pmu_paref_ldo_enable with argument TRUE | ||
| 242 | */ | ||
| 243 | if (dev->phy.rev == 0) { | 239 | if (dev->phy.rev == 0) { |
| 244 | b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT, | 240 | b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT, |
| 245 | 0xFFCF, 0x0010); | 241 | 0xFFCF, 0x0010); |
| 246 | } | 242 | } |
| 247 | b43_lptab_write(dev, B43_LPTAB16(11, 7), 60); | 243 | b43_lptab_write(dev, B43_LPTAB16(11, 7), 60); |
| 248 | } else { | 244 | } else { |
| 249 | //TODO: Call ssb_pmu_paref_ldo_enable with argument FALSE | 245 | ssb_pmu_set_ldo_paref(&bus->chipco, false); |
| 250 | b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT, | 246 | b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT, |
| 251 | 0xFFCF, 0x0020); | 247 | 0xFFCF, 0x0020); |
| 252 | b43_lptab_write(dev, B43_LPTAB16(11, 7), 100); | 248 | b43_lptab_write(dev, B43_LPTAB16(11, 7), 100); |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index 4aaddeec55a2..64abd11f6fbb 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
| @@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct ssb_chipcommon *cc, | |||
| 28 | chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value); | 28 | chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc, | ||
| 32 | u32 offset, u32 mask, u32 set) | ||
| 33 | { | ||
| 34 | u32 value; | ||
| 35 | |||
| 36 | chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR); | ||
| 37 | chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset); | ||
| 38 | chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR); | ||
| 39 | value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA); | ||
| 40 | value &= mask; | ||
| 41 | value |= set; | ||
| 42 | chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value); | ||
| 43 | chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA); | ||
| 44 | } | ||
| 45 | |||
| 31 | struct pmu0_plltab_entry { | 46 | struct pmu0_plltab_entry { |
| 32 | u16 freq; /* Crystal frequency in kHz.*/ | 47 | u16 freq; /* Crystal frequency in kHz.*/ |
| 33 | u8 xf; /* Crystal frequency value for PMU control */ | 48 | u8 xf; /* Crystal frequency value for PMU control */ |
| @@ -506,3 +521,82 @@ void ssb_pmu_init(struct ssb_chipcommon *cc) | |||
| 506 | ssb_pmu_pll_init(cc); | 521 | ssb_pmu_pll_init(cc); |
| 507 | ssb_pmu_resources_init(cc); | 522 | ssb_pmu_resources_init(cc); |
| 508 | } | 523 | } |
| 524 | |||
| 525 | void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, | ||
| 526 | enum ssb_pmu_ldo_volt_id id, u32 voltage) | ||
| 527 | { | ||
| 528 | struct ssb_bus *bus = cc->dev->bus; | ||
| 529 | u32 addr, shift, mask; | ||
| 530 | |||
| 531 | switch (bus->chip_id) { | ||
| 532 | case 0x4328: | ||
| 533 | case 0x5354: | ||
| 534 | switch (id) { | ||
| 535 | case LDO_VOLT1: | ||
| 536 | addr = 2; | ||
| 537 | shift = 25; | ||
| 538 | mask = 0xF; | ||
| 539 | break; | ||
| 540 | case LDO_VOLT2: | ||
| 541 | addr = 3; | ||
| 542 | shift = 1; | ||
| 543 | mask = 0xF; | ||
| 544 | break; | ||
| 545 | case LDO_VOLT3: | ||
| 546 | addr = 3; | ||
| 547 | shift = 9; | ||
| 548 | mask = 0xF; | ||
| 549 | break; | ||
| 550 | case LDO_PAREF: | ||
| 551 | addr = 3; | ||
| 552 | shift = 17; | ||
| 553 | mask = 0x3F; | ||
| 554 | break; | ||
| 555 | default: | ||
| 556 | SSB_WARN_ON(1); | ||
| 557 | return; | ||
| 558 | } | ||
| 559 | break; | ||
| 560 | case 0x4312: | ||
| 561 | if (SSB_WARN_ON(id != LDO_PAREF)) | ||
| 562 | return; | ||
| 563 | addr = 0; | ||
| 564 | shift = 21; | ||
| 565 | mask = 0x3F; | ||
| 566 | break; | ||
| 567 | default: | ||
| 568 | return; | ||
| 569 | } | ||
| 570 | |||
| 571 | ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift), | ||
| 572 | (voltage & mask) << shift); | ||
| 573 | } | ||
| 574 | |||
| 575 | void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on) | ||
| 576 | { | ||
| 577 | struct ssb_bus *bus = cc->dev->bus; | ||
| 578 | int ldo; | ||
| 579 | |||
| 580 | switch (bus->chip_id) { | ||
| 581 | case 0x4312: | ||
| 582 | ldo = SSB_PMURES_4312_PA_REF_LDO; | ||
| 583 | break; | ||
| 584 | case 0x4328: | ||
| 585 | ldo = SSB_PMURES_4328_PA_REF_LDO; | ||
| 586 | break; | ||
| 587 | case 0x5354: | ||
| 588 | ldo = SSB_PMURES_5354_PA_REF_LDO; | ||
| 589 | break; | ||
| 590 | default: | ||
| 591 | return; | ||
| 592 | } | ||
| 593 | |||
| 594 | if (on) | ||
| 595 | chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo); | ||
| 596 | else | ||
| 597 | chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo)); | ||
| 598 | chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read? | ||
| 599 | } | ||
| 600 | |||
| 601 | EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); | ||
| 602 | EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); | ||
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h index d3b1d18922f2..4e27acf0a92f 100644 --- a/include/linux/ssb/ssb_driver_chipcommon.h +++ b/include/linux/ssb/ssb_driver_chipcommon.h | |||
| @@ -629,5 +629,15 @@ extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc, | |||
| 629 | /* PMU support */ | 629 | /* PMU support */ |
| 630 | extern void ssb_pmu_init(struct ssb_chipcommon *cc); | 630 | extern void ssb_pmu_init(struct ssb_chipcommon *cc); |
| 631 | 631 | ||
| 632 | enum ssb_pmu_ldo_volt_id { | ||
| 633 | LDO_PAREF = 0, | ||
| 634 | LDO_VOLT1, | ||
| 635 | LDO_VOLT2, | ||
| 636 | LDO_VOLT3, | ||
| 637 | }; | ||
| 638 | |||
| 639 | void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc, | ||
| 640 | enum ssb_pmu_ldo_volt_id id, u32 voltage); | ||
| 641 | void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on); | ||
| 632 | 642 | ||
| 633 | #endif /* LINUX_SSB_CHIPCO_H_ */ | 643 | #endif /* LINUX_SSB_CHIPCO_H_ */ |
