/***************************************************************************** 函 数 名 : hi6559_volt_onoff_err_test 功能描述 : 电源使能异常流程测试 输入参数 : 无 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ s32 hi6559_volt_onoff_err_test(void) { s32 iret = 0; s32 result = BSP_PMU_OK; PMIC_HI6559_VLTGS_TABLE *hi6559_volt_table = (PMIC_HI6559_VLTGS_TABLE *)SHM_PMU_VOLTTABLE_ADDR; /* 异常id */ iret = bsp_hi6559_volt_enable(PMIC_HI6559_VOLT_MIN - 1);/*lint !e415 !e831*/ if(BSP_PMU_PARA_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_enable err id test error!\n"); result = BSP_PMU_ERROR; } /* 异常id */ iret = bsp_hi6559_volt_disable(PMIC_HI6559_VOLT_MAX + 1);/*lint !e415 !e831*/ if(BSP_PMU_PARA_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_disable err id test error!\n"); result = BSP_PMU_ERROR; } /* 异常id */ iret = bsp_hi6559_volt_is_enabled(PMIC_HI6559_VOLT_MIN - 1);/*lint !e415 !e831*/ if(BSP_PMU_PARA_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_is_enabled err id test error!\n"); result = BSP_PMU_ERROR; } /* 人为改写table前的魔幻数 */ hi6559_volt_table->magic_start = 0xa0a0a0; iret = bsp_hi6559_volt_enable(mode_set_get_test[0]);/*lint !e415 !e831*/ if(BSP_PMU_VOLTTABLE_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_enable err table test error!\n"); result = BSP_PMU_ERROR; } iret = bsp_hi6559_volt_disable(mode_set_get_test[0]);/*lint !e415 !e831*/ if(BSP_PMU_VOLTTABLE_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_disable err table test error!\n"); result = BSP_PMU_ERROR; } iret = bsp_hi6559_volt_is_enabled(mode_set_get_test[0]);/*lint !e415 !e831*/ if(BSP_PMU_VOLTTABLE_ERROR != iret) { pmic_print_error("bsp_hi6559_volt_is_enabled err table test error!\n"); result = BSP_PMU_ERROR; } /* 恢复table前的魔幻数 */ hi6559_volt_table->magic_start = SHM_PMU_VOLTTABLE_MAGIC_START_DATA; return result; }
/***************************************************************************** 函 数 名 : hi6559_otp_handle 功能描述 : 过温处理函数 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_otp_handle(void* para) { s32 i = 0; para = para; pmic_print_error("hi6559:temperature overflow (>125℃)!\n"); /*由nv控制过温是否关闭*/ pmu_hi6559_om_data[0] |= (0x01 << HI6559_OTMP_125_OFFSET); /*根据nv配置,决定是否关闭非核心电源,后续增加产品形态相关特殊处理*/ if(pmu_exc_pro.ulOtpCurIsOff) { for(i = PMIC_HI6559_VOLT_MIN; i < PMIC_HI6559_VOLT_MAX; i++) { if(pmu_exc_pro.VoltProConfig[i].VoltOtpIsOff) { pmic_print_error("hi6559:volt id %d will be closed !\n",i); bsp_hi6559_volt_disable(i); } } } if(pmu_exc_pro.ulOtpIsRst) { pmic_print_error("hi6559:system will be restart!\n"); system_error(DRV_ERRNO_PMU_OVER_TEMP, PMU_STATE_OVER_TEMP, 0, NULL, 0); } /* 记录om log */ /* hi6559_om_log_save(PMU_OM_LOG_EXC); */ print2file(PMU_OM_LOG, "pmu_hi6559:temperature overflow (>125℃)!\n"); /*clear np int */ bsp_hi6559_reg_write(HI6559_NP_SCP_RECORD1_OFFSET, (0x01 << HI6559_OTMP_125_OFFSET)); pmic_print_error("\n**********hi6559_otp_isr**********\n"); return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_volt_disable_test 功能描述 : 电源disable测试 输入参数 : 无 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ s32 hi6559_volt_disable_test(void) { s32 j = 0, ret = BSP_PMU_OK; s32 test_num = (sizeof(volt_onoff_test)/sizeof(int)); for(j = 0;j < test_num; j++) { ret = bsp_hi6559_volt_disable(volt_onoff_test[j]); if(ret) { pmic_print_error("\nERROR: volt%d: disable failed,ret %d!\n", volt_onoff_test[j], ret); } if(0 == bsp_hi6559_volt_is_enabled(volt_onoff_test[j])) { pmic_print_error("\nERROR: volt%d: is still enabled failed!\n", volt_onoff_test[j]); return volt_onoff_test[j]; } } pmic_print_info("hi6559_volt_disable_test ok!!\n",volt_onoff_test[j]); return BSP_PMU_OK; }
/***************************************************************************** 函 数 名 : hi6559_ocp_scp_handle 功能描述 : 过流处理函数 输入参数 : @para 参数指针 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_ocp_scp_handle(void* para) { u32 volt_need_off = 0; u32 *pmu_ocp_flag = (u32 *)SHM_PMU_OCP_INFO_ADDR; /* 过流,需要关闭的过流源 */ s32 ret = ERROR; u8 a_ucRecordReg[HI6559_NP_OCP_SCP_REG_NUM] = {0}; /* 过流寄存器读取值 */ u8 i = 0; u8 j = 0; /*lint --e{690,831}*/ para = para; pmic_print_error("******* hi6559_current_overflow! **********\n"); for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++) { bsp_hi6559_reg_read((HI6559_NP_SCP_RECORD1_OFFSET + i), &a_ucRecordReg[i]); /* 在中断处理任务中,是否需要加锁? */ pmu_hi6559_om_data[i + 3] |= a_ucRecordReg[i]; } /* 检查所有SCP_RECORD和OCP_RECORD中的状态, 根据nv配置进行安全处理 */ /* BUCK短路检查,0x18寄存器 */ for (j = 0; j < HI6559_NP_SCP_RECORD1_CONT_NUM; j++) { if (a_ucRecordReg[0] & (u8)((u32)0x1 << reg_np_scp_record1_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_scp_record1_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s short !\n", reg_np_scp_record1_cont[j].cont); } } /* BUCK过流检查,0x19寄存器 */ for (j = 0; j < HI6559_NP_OCP_RECORD1_CONT_NUM; j++) { if (a_ucRecordReg[1] & (u8)((u32)0x1 << reg_np_ocp_record1_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record1_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record1_cont[j].cont); } } /* LDO1~8过流检查,0x1A寄存器 */ for (j = 0; j < HI6559_NP_OCP_RECORD2_CONT_NUM; j++) { if (a_ucRecordReg[2] & (u8)((u32)0x1 << reg_np_ocp_record2_cont[j].bit_ofs)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id); *pmu_ocp_flag |= ((u32)0x1 << reg_np_ocp_record2_cont[j].volt_id); print2file(PMU_OM_LOG,"pmu_hi6559:%s overflow !\n", reg_np_ocp_record2_cont[j].cont); } } /* ldo9~14过流,寄存器0x1B */ for (j = 0; j < HI6559_NP_OCP_RECORD3_CONT_NUM; j++) { if (a_ucRecordReg[3] & (u8)((u32)0x1 << j)) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j)); *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO09 + j)); print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO09 + j - 1); } } /* ldo22~24过流,寄存器0x1C */ for(j = 0; j < HI6559_NP_OCP_RECORD4_CONT_NUM; j++) { if (a_ucRecordReg[4] & (u8)((u32)0x1 << (j + 5))) /*lint !e690,!e831*/ { volt_need_off |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j)); *pmu_ocp_flag |= ((u32)0x1 << (PMIC_HI6559_LDO22 + j)); print2file(PMU_OM_LOG,"pmu_hi6559:LDO %d overflow !\n", PMIC_HI6559_LDO22 + j + 6); } } /* lvs7过流,寄存器0x1D */ if(a_ucRecordReg[5] & (u8)((u32)0x1 << HI6559_LVS07_BIT_OFFSET)) { volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS07); *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS07); print2file(PMU_OM_LOG,"pmu_hi6559:LVS7 overflow !\n"); } /* lvs9过流,寄存器0x1E */ if(a_ucRecordReg[6] & (u8)((u32)0x1 << HI6559_LVS09_BIT_OFFSET)) { volt_need_off |= ((u32)0x1 << PMIC_HI6559_LVS09); *pmu_ocp_flag |= ((u32)0x1 << PMIC_HI6559_LVS09); print2file(PMU_OM_LOG,"pmu_hi6559:LVS09 overflow !\n"); } /* 异常信息发给C核 */ if(volt_need_off) { ret = bsp_icc_send(ICC_CPU_MODEM, PA_RF_ICC_CHN_ID, (u8*)&volt_need_off, sizeof(u32)); if(sizeof(u32) != (u32)ret) { pmic_print_error("bsp_icc_send failed, ret = %d!\n", ret); } } /* 根据NV值确认是否需要关闭过流的电源 */ for(j = PMIC_HI6559_VOLT_MIN; j <= PMIC_HI6559_VOLT_MAX; j++) { if(pmu_exc_pro.ulOcpIsOff) { if(volt_need_off & ((u32)0x1 << j)) { pmic_print_error("hi6559:volt id %d overflow !\n", j); /* 需要关闭过流的电压源,则关闭 */ if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsOff) { pmic_print_error("hi6559:volt id %d will be closed !\n", j); bsp_hi6559_volt_disable(j); } /* 过流需要重启,则重启 */ if(pmu_exc_pro.VoltProConfig[j].VoltOcpIsRst) { pmic_print_error("hi6559:system will be restart!\n"); system_error(DRV_ERRNO_PMU_OVER_CUR, PMU_STATE_OVER_CUR, j, (char *)&volt_need_off, (u32)sizeof(volt_need_off)); } } } else { if(volt_need_off & ((u32)0x1 << j)) { pmic_print_error("hi6559:volt id %d overflow !\n", j); } } } /*清除非下电中断状态寄存器*/ for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++) { bsp_hi6559_reg_write((HI6559_NP_SCP_RECORD1_OFFSET + i), a_ucRecordReg[i]); /*lint !e661*/ } return;/*lint !e438*/ }
/***************************************************************************** 函 数 名 : hi6559_irq_wk_handler 功能描述 : 输入参数 : 无 输出参数 : 无 返 回 值 : 无 *****************************************************************************/ void hi6559_irq_wk_handler(void) { u32 reg = 0; u8 i = 0, reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg_tmp = 0; u8 flag = 0; /*power 键按下和抬起中断同时过来的标志*/ /* 读所有中断 */ bsp_hi6559_reg_read(HI6559_IRQ1_OFFSET, ®1); bsp_hi6559_reg_read(HI6559_IRQ2_OFFSET, ®2); bsp_hi6559_reg_read(HI6559_IRQ3_OFFSET, ®3); bsp_hi6559_reg_read(HI6559_IRQ4_OFFSET, ®4); reg = ((u32)reg1 | ((u32)reg2 << HI6559_IRQM2_BASE_OFFSET) | ((u32)reg3 << HI6559_IRQM3_BASE_OFFSET) | ((u32)reg4 << HI6559_IRQM4_BASE_OFFSET)); /* 按键中断press和release中断同时发生,则flag置1 */ if (unlikely(0x60 == (0x60 & reg1))) { /*lint !e730*/ flag = 1; } /* 逐个寄存器清中断 */ if (reg1) { bsp_hi6559_reg_write(HI6559_IRQ1_OFFSET, reg1); } if (reg2) { if (reg2 & 0x01) /* 发生了过流/短路中断 */ { for(i = 0; i < HI6559_NP_OCP_SCP_REG_NUM; i++) { /* 清除短路/过流中断状态寄存器 */ bsp_hi6559_reg_read(HI6559_IRQ2_OFFSET, ®_tmp); if(reg_tmp) { bsp_hi6559_reg_write((HI6559_SCP_RECORD1_OFFSET + i), 0xFF); } } } bsp_hi6559_reg_write(HI6559_IRQ2_OFFSET, reg2); } if (reg3) { bsp_hi6559_reg_write(HI6559_IRQ3_OFFSET, reg3); } if (reg4) { /* sim拔出中断,使用拔出的下跳沿 */ if(reg4 & 0x04) { /* 先关闭电源再清中断,否则热插拔功能失效,修改为任务队列,故可以使用锁 */ /* 后续需分析是否会引起任务处理时间长,影响中断响应 */ bsp_hi6559_volt_disable(PMIC_HI6559_LDO09); } bsp_hi6559_reg_write(HI6559_IRQ4_OFFSET, reg4); } if (reg) { for (i = 0; i < HI6559_IRQ_NR; i++) { if ((1 == flag) && (5 == i)) { /* 按键中断press和release中断同时发生,先处理press中断,这样更符合逻辑 */ Hi6559IrqInfo[6].cnt++; if (NULL != Hi6559IrqInfo[6].routine) Hi6559IrqInfo[6].routine(Hi6559IrqInfo[6].data); Hi6559IrqInfo[5].cnt++; if (NULL != Hi6559IrqInfo[5].routine) Hi6559IrqInfo[5].routine(Hi6559IrqInfo[5].data); i = i + 2; } if (reg & ((u32)1 << i)) { Hi6559IrqInfo[i].cnt++; /* 中断处理 */ if (NULL != Hi6559IrqInfo[i].routine) { Hi6559IrqInfo[i].routine(Hi6559IrqInfo[i].data); } } } } pmic_print_info("**********hi6559_irq_wk_handler**********\n"); hi6559_irq_enable(); return; }