aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGábor Stefanik <netrolller.3d@gmail.com>2009-08-26 14:51:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:53 -0400
commit06e4da268c0e8f3b8408403d65e47d2885a78ff2 (patch)
tree971fffcefbe06c5bba590953a06ced39947f1198
parent68ec53292c7f09056152efa9a6ee2591c794f08c (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.c10
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c94
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h10
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
31static 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
31struct pmu0_plltab_entry { 46struct 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
525void 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
575void 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
601EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
602EXPORT_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 */
630extern void ssb_pmu_init(struct ssb_chipcommon *cc); 630extern void ssb_pmu_init(struct ssb_chipcommon *cc);
631 631
632enum ssb_pmu_ldo_volt_id {
633 LDO_PAREF = 0,
634 LDO_VOLT1,
635 LDO_VOLT2,
636 LDO_VOLT3,
637};
638
639void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
640 enum ssb_pmu_ldo_volt_id id, u32 voltage);
641void 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_ */