/* * mem_power_off_nommu * * Description:config wakeup signal. * turn off power for cpu-1v2, int-1v2, vcc-3v3 , but avcc-3v , dram-1v5. * turn off 2*[csi ldo(low dropout regulator)] * * Arguments : none; * * Returns : 0: succeed; * -1: failed; */ __s32 mem_power_off_nommu(void) { __u8 reg_val = 0; /*config wakeup signal*/ /*°Ñ31H¼Ä´æÆ÷µÄbit3(°´¼ü¡¢gpio»½ÐÑλ)ÖÃ1*/ if(0 != twi_byte_rw_nommu(TWI_OP_RD, AXP_ADDR,0x31, ®_val)){ return -1; } reg_val |= 0x08; if(twi_byte_rw_nommu(TWI_OP_WR, AXP_ADDR,0x31, ®_val)){ return -1; } #if 1 /*power off*/ /*°Ñ12H¼Ä´æÆ÷µÄbit0¡¢1¡¢3¡¢4¡¢6ÖÃ0*/ if(twi_byte_rw_nommu(TWI_OP_RD, AXP_ADDR,0x12, ®_val)){ return -1; } reg_val &= ~0x5b; if(twi_byte_rw_nommu(TWI_OP_WR, AXP_ADDR,0x12, ®_val)){ return -1; } #endif #if 0 /*power off*/ /*°Ñ12H¼Ä´æÆ÷µÄbit1¡¢3¡¢4¡¢6ÖÃ0*/ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,0x12, ®_val)){ return -1; } reg_val &= ~0x5a; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,0x12, ®_val)){ return -1; } #endif /* cpu enter sleep, wait wakeup by interrupt */ asm("WFI"); /*never get here. *when reach here, mean twi transfer err, and cpu are not shut down. * wfi have been changed. */ //while(1); return -1; }
void standby_restore_env(struct sys_reg_t *restore_env) { /*restore 24M and LDO*/ aw_writel(restore_env->cmu_regs.aud_hosc,SW_CCM_AUDIO_HOSC_PLL_REG); //standby_delay(50); /*COREPLL to 24M*/ aw_writel((aw_readl(SW_CCM_AHB_APB_CFG_REG)&BUS_CCLK_MASK)|BUS_CCLK_24M,SW_CCM_AHB_APB_CFG_REG); standby_delay(50); /*restore core power*/ #if EN_POWER_D twi_byte_rw(TWI_OP_WR,0x34,0x23,&data[0]); standby_twi_exit(); #endif /* restore cmu regs*/ aw_writel(restore_env->cmu_regs.core_pll,SW_CCM_CORE_VE_PLL_REG); aw_writel(restore_env->cmu_regs.ddr_pll,SW_CCM_SDRAM_PLL_REG); aw_writel(restore_env->cmu_regs.bus_clk,SW_CCM_AHB_APB_CFG_REG); #if MODIFY_AHB_APB_EN aw_writel(restore_env->cmu_regs.ahb_clk,SW_CCM_AHB_GATE_REG); aw_writel(restore_env->cmu_regs.apb_clk,SW_CCM_APB_GATE_REG); #endif }
void standby_enter_low(void) { /*sdram self-refresh*/ aw_writel(aw_readl(SW_DRAM_SDR_CTL_REG)|SDR_ENTER_SELFRFH,SW_DRAM_SDR_CTL_REG); while(!(aw_readl(SW_DRAM_SDR_CTL_REG)&SDR_SELFRFH_STATUS)); /*gate off sdram*/ aw_writel(aw_readl(SW_CCM_SDRAM_PLL_REG)&~SDR_CLOCK_GATE_EN,SW_CCM_SDRAM_PLL_REG); /*disable VE pll*/ aw_writel(aw_readl(SW_CCM_CORE_VE_PLL_REG)&~(1<<15),SW_CCM_CORE_VE_PLL_REG); /*COREPLL to 24M*/ aw_writel((aw_readl(SW_CCM_AHB_APB_CFG_REG)&BUS_CCLK_MASK)|BUS_CCLK_24M,SW_CCM_AHB_APB_CFG_REG); standby_delay(100); /*down core power*/ #if EN_POWER_D standby_twi_init(0); twi_byte_rw(TWI_OP_RD,0x34,0x23,&data[0]); data[2] = 0x0C; // 1V twi_byte_rw(TWI_OP_WR,0x34,0x23,&data[2]); #endif /*COREPLL to 32K*/ aw_writel((aw_readl(SW_CCM_AHB_APB_CFG_REG)&BUS_CCLK_MASK)|BUS_CCLK_32K,SW_CCM_AHB_APB_CFG_REG); standby_delay(50); /*disable HOSC and LDO*/ aw_writel(aw_readl(SW_CCM_AUDIO_HOSC_PLL_REG)&~(1|(1<<15)),SW_CCM_AUDIO_HOSC_PLL_REG); #if MODIFY_AHB_APB_EN aw_writel((1<<13)|(1<<16)|(1),SW_CCM_AHB_GATE_REG); aw_writel((1<<5)|1,SW_CCM_APB_GATE_REG); #endif }
/* ********************************************************************************************************* * standby_get_voltage * *Description: get voltage for standby; * *Arguments : type voltage type, defined as "enum power_vol_type_e"; * *Return : voltage value, based on "mv"; * *Notes : * ********************************************************************************************************* */ __u32 standby_get_voltage(enum power_vol_type_e type) { struct axp_info *info = 0; __u8 val, mask; info = find_info(type); if (info == 0) { return -1; } twi_byte_rw(TWI_OP_RD,AXP_ADDR,info->vol_reg, &val); mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; val = (val & mask) >> info->vol_shift; if (type != POWER_VOL_LDO4) return info->min_uV + info->step_uV * val; else return axp20_ldo4_data[val]*1000; }
/* ********************************************************************************************************* * standby_power_exit * * Description: exit power for standby. * * Arguments : none; * * Returns : result; ********************************************************************************************************* */ __s32 standby_power_exit(void) { __u8 reg_val; twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQ4, ®_val); twi_byte_rw(TWI_OP_WR, AXP_ADDR,0x0E, ®_val); #if(AXP_WAKEUP & AXP_WAKEUP_KEY) /* disable pek long/short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val &= ~0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); #endif #if(AXP_WAKEUP & AXP_WAKEUP_LOWBATT) /* disable low voltage warning */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN4, ®_val); reg_val &= ~0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN4, ®_val); #endif standby_twi_exit(); return 0; }
/* ********************************************************************************************************* * standby_power_init * * Description: init power for standby. * * Arguments : none; * * Returns : result; ********************************************************************************************************* */ __s32 standby_power_init(__u32 wakeup_src) { __u8 reg_val; standby_twi_init(AXP_IICBUS); if(wakeup_src & AXP_WAKEUP_KEY) { /* enable pek long/short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val |= 0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); } if(wakeup_src & AXP_WAKEUP_LONG_KEY) { /* enable pek long */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val |= 0x01; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); /*pek long period setting: 1s*/ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_PEK, ®_val); reg_val &= 0xcf; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_PEK, ®_val); } if(wakeup_src & AXP_WAKEUP_SHORT_KEY) { /* enable pek short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val |= 0x02; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); } if(wakeup_src & AXP_WAKEUP_DESCEND) { /* enable pek desend trigger */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val); reg_val |= 0x20; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val); } if(wakeup_src & AXP_WAKEUP_ASCEND) { /* enable pek ascend trigger */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val); reg_val |= 0x40; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val); } if(wakeup_src & AXP_WAKEUP_LOWBATT) { /* enable low voltage warning */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN4, ®_val); reg_val |= 0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN4, ®_val); /* clear pending */ reg_val |= 0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQ4, ®_val); } if(wakeup_src & AXP_WAKEUP_USB) { /* enable usb plug-in / plug-out */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN1, ®_val); reg_val |= 0x03<<2; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN1, ®_val); } if(wakeup_src & AXP_WAKEUP_AC) { /* enable ac plug-in / plug-out */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN1, ®_val); reg_val |= 0x03<<5; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN1, ®_val); } return 0; }
/* ********************************************************************************************************* * standby_power_exit * * Description: exit power for standby. * * Arguments : none; * * Returns : result; ********************************************************************************************************* */ __s32 standby_power_exit(__u32 wakeup_src) { __u8 reg_val; twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQ4, ®_val); twi_byte_rw(TWI_OP_WR, AXP_ADDR,0x0E, ®_val); if(wakeup_src & AXP_WAKEUP_KEY) { /* disable pek long/short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val &= ~0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); } if(wakeup_src & AXP_WAKEUP_LONG_KEY) { /* enable pek long/short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val &= ~0x01; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); } if(wakeup_src & AXP_WAKEUP_SHORT_KEY) { /* enable pek long/short */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val); reg_val &= ~0x02; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val); } if(wakeup_src & AXP_WAKEUP_DESCEND) { /* disable pek desend trigger */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val); reg_val &= ~0x20; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val); } if(wakeup_src & AXP_WAKEUP_ASCEND) { /* disable pek desend trigger */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val); reg_val &= ~0x40; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val); } if(wakeup_src & AXP_WAKEUP_LOWBATT) { /* disable low voltage warning */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN4, ®_val); reg_val &= ~0x03; twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN4, ®_val); } if(wakeup_src & AXP_WAKEUP_USB) { /* disable usb plug-in / plug-out */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN1, ®_val); reg_val &= ~(0x03<<2); twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN1, ®_val); } if(wakeup_src & AXP_WAKEUP_AC) { /* disable ac plug-in / plug-out */ twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN1, ®_val); reg_val &= ~(0x03<<5); twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN1, ®_val); } standby_twi_exit(); return 0; }
/* ********************************************************************************************************* * mem_power_exit * * Description: exit power for mem. * * Arguments : none; * * Returns : 0: succeed; * -1: failed; ********************************************************************************************************* */ __s32 mem_power_exit(__u32 wakeup_src) { __u8 reg_val; //setup_env(); /* disable power key long/short */ if(wakeup_src & AXP_WAKEUP_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val &= ~0x03; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*enable power key short: bit1*/ if(wakeup_src & AXP_WAKEUP_SHORT_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val &= ~0x02; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*enable power key long: bit0*/ if(wakeup_src & AXP_WAKEUP_LONG_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val &= ~0x01; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*°Ñ44H¼Ä´æÆ÷µÄbit6(°´¼üÉÏÉýÑØ´¥·¢)ÖÃ1*/ if(wakeup_src & AXP_WAKEUP_ASCEND){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } reg_val &= ~0x40; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } } /*°Ñ44H¼Ä´æÆ÷µÄbit5(ϽµÑØ´¥·¢)ÖÃ1*/ if(wakeup_src & AXP_WAKEUP_DESCEND){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } reg_val &= ~0x20; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } } /* enable low voltage warning */ if(wakeup_src & AXP_WAKEUP_LOWBATT){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN4, ®_val)){ return -1; } reg_val &= ~0x03; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN4, ®_val)){ return -1; } } return 0; }
/* ********************************************************************************************************* * mem_power_init * * Description: init power for mem. * * Arguments : none; * * Returns : 0: succeed; * -1: failed; ********************************************************************************************************* */ __s32 mem_power_init(__u32 wakeup_src) { __u8 reg_val; save_mem_status(TWI_TRANSFER_STATUS ); /* enable power key long/short */ if(wakeup_src & AXP_WAKEUP_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val |= 0x03; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*enable power key short: bit1*/ if(wakeup_src & AXP_WAKEUP_SHORT_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val |= 0x02; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*enable power key long: bit0*/ if(wakeup_src & AXP_WAKEUP_LONG_KEY){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN3, ®_val)){ return -1; } reg_val |= 0x01; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN3, ®_val) ){ return -1; } } /*°Ñ44H¼Ä´æÆ÷µÄbit6(°´¼üÉÏÉýÑØ´¥·¢)ÖÃ1*/ if(wakeup_src & AXP_WAKEUP_ASCEND){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } reg_val |= 0x40; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } } /*°Ñ44H¼Ä´æÆ÷µÄbit5(ϽµÑØ´¥·¢)ÖÃ1*/ if(wakeup_src & AXP_WAKEUP_DESCEND){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } reg_val |= 0x20; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN5, ®_val)){ return -1; } } /* enable low voltage warning */ if(wakeup_src & AXP_WAKEUP_LOWBATT){ if(twi_byte_rw(TWI_OP_RD, AXP_ADDR,AXP20_IRQEN4, ®_val)){ return -1; } reg_val |= 0x03; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQEN4, ®_val)){ return -1; } /* clear pending */ reg_val = 0x03; if(twi_byte_rw(TWI_OP_WR, AXP_ADDR,AXP20_IRQ4, ®_val)){ return -1; } } return 0; }