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_ */ |