/* * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved. */ /* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */ /*! * @file mc13783/pmic_power.c * @brief This is the main file of PMIC(mc13783) Power driver. * * @ingroup PMIC_POWER */ /* * Includes */ #include #include #include #include #include #include #include #include "pmic_power_defs.h" #ifdef CONFIG_MXC_HWEVENT #include #endif #include #define MC13783_REGCTRL_GPOx_MASK 0x18000 static bool VBKUP1_EN = false; static bool VBKUP2_EN = false; /* * Power Pmic API */ /* EXPORTED FUNCTIONS */ EXPORT_SYMBOL(pmic_power_off); EXPORT_SYMBOL(pmic_power_set_pc_config); EXPORT_SYMBOL(pmic_power_get_pc_config); EXPORT_SYMBOL(pmic_power_regulator_on); EXPORT_SYMBOL(pmic_power_regulator_off); EXPORT_SYMBOL(pmic_power_regulator_set_voltage); EXPORT_SYMBOL(pmic_power_regulator_get_voltage); EXPORT_SYMBOL(pmic_power_regulator_set_config); EXPORT_SYMBOL(pmic_power_regulator_get_config); EXPORT_SYMBOL(pmic_power_vbkup2_auto_en); EXPORT_SYMBOL(pmic_power_get_vbkup2_auto_state); EXPORT_SYMBOL(pmic_power_bat_det_en); EXPORT_SYMBOL(pmic_power_get_bat_det_state); EXPORT_SYMBOL(pmic_power_vib_pin_en); EXPORT_SYMBOL(pmic_power_gets_vib_pin_state); EXPORT_SYMBOL(pmic_power_get_power_mode_sense); EXPORT_SYMBOL(pmic_power_set_regen_assig); EXPORT_SYMBOL(pmic_power_get_regen_assig); EXPORT_SYMBOL(pmic_power_set_regen_inv); EXPORT_SYMBOL(pmic_power_get_regen_inv); EXPORT_SYMBOL(pmic_power_esim_v_en); EXPORT_SYMBOL(pmic_power_gets_esim_v_state); EXPORT_SYMBOL(pmic_power_set_auto_reset_en); EXPORT_SYMBOL(pmic_power_get_auto_reset_en); EXPORT_SYMBOL(pmic_power_set_conf_button); EXPORT_SYMBOL(pmic_power_get_conf_button); EXPORT_SYMBOL(pmic_power_event_sub); EXPORT_SYMBOL(pmic_power_event_unsub); /*! * This function is called to put the power in a low power state. * Switching off the platform cannot be decided by * the power module. It has to be handled by the * client application. * * @param pdev the device structure used to give information on which power * device (0 through 3 channels) to suspend * @param state the power state the device is entering * * @return The function always returns 0. */ static int pmic_power_suspend(struct platform_device *pdev, pm_message_t state) { return 0; }; /*! * This function is called to resume the power from a low power state. * * @param pdev the device structure used to give information on which power * device (0 through 3 channels) to suspend * * @return The function always returns 0. */ static int pmic_power_resume(struct platform_device *pdev) { return 0; }; /*! * This function sets user power off in power control register and thus powers * off the phone. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_off(void) { unsigned int mask, value; mask = BITFMASK(MC13783_PWRCTRL_USER_OFF_SPI); value = BITFVAL(MC13783_PWRCTRL_USER_OFF_SPI, MC13783_PWRCTRL_USER_OFF_SPI_ENABLE); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_0, value, mask)); return PMIC_SUCCESS; } /*! * This function sets the power control configuration. * * @param pc_config power control configuration. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_set_pc_config(t_pc_config * pc_config) { unsigned int pwrctrl_val_reg0 = 0; unsigned int pwrctrl_val_reg1 = 0; unsigned int pwrctrl_mask_reg0 = 0; unsigned int pwrctrl_mask_reg1 = 0; if (pc_config == NULL) { return PMIC_PARAMETER_ERROR; } if (pc_config->pc_enable != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_PCEN, MC13783_PWRCTRL_PCEN_ENABLE); pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_PCT, pc_config->pc_timer); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_PCEN, MC13783_PWRCTRL_PCEN_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_PCEN); pwrctrl_mask_reg1 |= BITFMASK(MC13783_PWRCTRL_PCT); if (pc_config->pc_count_enable != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_PC_COUNT_EN, MC13783_PWRCTRL_PC_COUNT_EN_ENABLE); pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_PC_COUNT, pc_config->pc_count); pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_PC_MAX_CNT, pc_config->pc_max_count); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_PC_COUNT_EN, MC13783_PWRCTRL_PC_COUNT_EN_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_PC_COUNT_EN); pwrctrl_mask_reg1 |= BITFMASK(MC13783_PWRCTRL_PC_MAX_CNT) | BITFMASK(MC13783_PWRCTRL_PC_COUNT); if (pc_config->warm_enable != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_WARM_EN, MC13783_PWRCTRL_WARM_EN_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_WARM_EN, MC13783_PWRCTRL_WARM_EN_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_WARM_EN); if (pc_config->user_off_pc != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_USER_OFF_PC, MC13783_PWRCTRL_USER_OFF_PC_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_WARM_EN, MC13783_PWRCTRL_USER_OFF_PC_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_USER_OFF_PC); if (pc_config->clk_32k_user_off != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_32OUT_USER_OFF, MC13783_PWRCTRL_32OUT_USER_OFF_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_32OUT_USER_OFF, MC13783_PWRCTRL_32OUT_USER_OFF_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_32OUT_USER_OFF); if (pc_config->clk_32k_enable != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_32OUT_EN, MC13783_PWRCTRL_32OUT_EN_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_32OUT_EN, MC13783_PWRCTRL_32OUT_EN_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_32OUT_EN); if (pc_config->en_vbkup1 != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP1_EN, MC13783_PWRCTRL_VBKUP_ENABLE); VBKUP1_EN = true; } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP1_EN, MC13783_PWRCTRL_VBKUP_DISABLE); VBKUP1_EN = false; } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_VBKUP1_EN); if (pc_config->en_vbkup2 != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP2_EN, MC13783_PWRCTRL_VBKUP_ENABLE); VBKUP2_EN = true; } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP2_EN, MC13783_PWRCTRL_VBKUP_DISABLE); VBKUP2_EN = false; } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_VBKUP2_EN); if (pc_config->auto_en_vbkup1 != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP1_AUTO_EN, MC13783_PWRCTRL_VBKUP_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP1_AUTO_EN, MC13783_PWRCTRL_VBKUP_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_VBKUP1_AUTO_EN); if (pc_config->auto_en_vbkup2 != false) { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP2_AUTO_EN, MC13783_PWRCTRL_VBKUP_ENABLE); } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP2_AUTO_EN, MC13783_PWRCTRL_VBKUP_DISABLE); } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_VBKUP2_AUTO_EN); if (VBKUP1_EN != false) { if (pc_config->vhold_voltage > 3 || pc_config->vhold_voltage < 0) { return PMIC_PARAMETER_ERROR; } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP1, pc_config->vhold_voltage); } } if (VBKUP2_EN != false) { if (pc_config->vhold_voltage > 3 || pc_config->vhold_voltage < 0) { return PMIC_PARAMETER_ERROR; } else { pwrctrl_val_reg0 |= BITFVAL(MC13783_PWRCTRL_VBKUP2, pc_config->vhold_voltage2); } } pwrctrl_mask_reg0 |= BITFMASK(MC13783_PWRCTRL_VBKUP1) | BITFMASK(MC13783_PWRCTRL_VBKUP2); if (pc_config->mem_allon != false) { pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_MEM_ALLON, MC13783_PWRCTRL_MEM_ALLON_ENABLE); pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_MEM_TMR, pc_config->mem_timer); } else { pwrctrl_val_reg1 |= BITFVAL(MC13783_PWRCTRL_MEM_ALLON, MC13783_PWRCTRL_MEM_ALLON_DISABLE); } pwrctrl_mask_reg1 |= BITFMASK(MC13783_PWRCTRL_MEM_ALLON) | BITFMASK(MC13783_PWRCTRL_MEM_TMR); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_0, pwrctrl_val_reg0, pwrctrl_mask_reg0)); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_1, pwrctrl_val_reg1, pwrctrl_mask_reg1)); return PMIC_SUCCESS; } /*! * This function retrives the power control configuration. * * @param pc_config pointer to power control configuration. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_get_pc_config(t_pc_config * pc_config) { unsigned int pwrctrl_val_reg0 = 0; unsigned int pwrctrl_val_reg1 = 0; if (pc_config == NULL) { return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_0, &pwrctrl_val_reg0, PMIC_ALL_BITS)); CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_1, &pwrctrl_val_reg1, PMIC_ALL_BITS)); if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_PCEN) == MC13783_PWRCTRL_PCEN_ENABLE) { pc_config->pc_enable = true; pc_config->pc_timer = BITFEXT(pwrctrl_val_reg1, MC13783_PWRCTRL_PCT); } else { pc_config->pc_enable = false; pc_config->pc_timer = 0; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_PC_COUNT_EN) == MC13783_PWRCTRL_PCEN_ENABLE) { pc_config->pc_count_enable = true; pc_config->pc_count = BITFEXT(pwrctrl_val_reg1, MC13783_PWRCTRL_PC_COUNT); pc_config->pc_max_count = BITFEXT(pwrctrl_val_reg1, MC13783_PWRCTRL_PC_MAX_CNT); } else { pc_config->pc_count_enable = false; pc_config->pc_count = 0; pc_config->pc_max_count = 0; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_WARM_EN) == MC13783_PWRCTRL_WARM_EN_ENABLE) { pc_config->warm_enable = true; } else { pc_config->warm_enable = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_USER_OFF_PC) == MC13783_PWRCTRL_USER_OFF_PC_ENABLE) { pc_config->user_off_pc = true; } else { pc_config->user_off_pc = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_32OUT_USER_OFF) == MC13783_PWRCTRL_32OUT_USER_OFF_ENABLE) { pc_config->clk_32k_user_off = true; } else { pc_config->clk_32k_user_off = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_32OUT_EN) == MC13783_PWRCTRL_32OUT_EN_ENABLE) { pc_config->clk_32k_enable = true; } else { pc_config->clk_32k_enable = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP1_AUTO_EN) == MC13783_PWRCTRL_VBKUP_ENABLE) { pc_config->auto_en_vbkup1 = true; } else { pc_config->auto_en_vbkup1 = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP2_AUTO_EN) == MC13783_PWRCTRL_VBKUP_ENABLE) { pc_config->auto_en_vbkup2 = true; } else { pc_config->auto_en_vbkup2 = false; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP1_EN) == MC13783_PWRCTRL_VBKUP_ENABLE) { pc_config->en_vbkup1 = true; pc_config->vhold_voltage = BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP1); } else { pc_config->en_vbkup1 = false; pc_config->vhold_voltage = 0; } if (BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP2_EN) == MC13783_PWRCTRL_VBKUP_ENABLE) { pc_config->en_vbkup2 = true; pc_config->vhold_voltage2 = BITFEXT(pwrctrl_val_reg0, MC13783_PWRCTRL_VBKUP2); } else { pc_config->en_vbkup2 = false; pc_config->vhold_voltage2 = 0; } if (BITFEXT(pwrctrl_val_reg1, MC13783_PWRCTRL_MEM_ALLON) == MC13783_PWRCTRL_MEM_ALLON_ENABLE) { pc_config->mem_allon = true; pc_config->mem_timer = BITFEXT(pwrctrl_val_reg1, MC13783_PWRCTRL_MEM_TMR); } else { pc_config->mem_allon = false; pc_config->mem_timer = 0; } return PMIC_SUCCESS; } /*! * This function turns on a regulator. * * @param regulator The regulator to be truned on. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_on(t_pmic_regulator regulator) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_PLL: reg_val = BITFVAL(MC13783_SWCTRL_PLL_EN, MC13783_SWCTRL_PLL_EN_ENABLE); reg_mask = BITFMASK(MC13783_SWCTRL_PLL_EN); reg = REG_SWITCHERS_4; break; case SW_SW3: reg_val = BITFVAL(MC13783_SWCTRL_SW3_EN, MC13783_SWCTRL_SW3_EN_ENABLE); reg_mask = BITFMASK(MC13783_SWCTRL_SW3_EN); reg = REG_SWITCHERS_5; break; case REGU_VAUDIO: reg_val = BITFVAL(MC13783_REGCTRL_VAUDIO_EN, MC13783_REGCTRL_VAUDIO_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VAUDIO_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOHI: reg_val = BITFVAL(MC13783_REGCTRL_VIOHI_EN, MC13783_REGCTRL_VIOHI_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VIOHI_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOLO: reg_val = BITFVAL(MC13783_REGCTRL_VIOLO_EN, MC13783_REGCTRL_VIOLO_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VIOLO_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VDIG: reg_val = BITFVAL(MC13783_REGCTRL_VDIG_EN, MC13783_REGCTRL_VDIG_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VDIG_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VGEN: reg_val = BITFVAL(MC13783_REGCTRL_VGEN_EN, MC13783_REGCTRL_VGEN_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VGEN_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFDIG: reg_val = BITFVAL(MC13783_REGCTRL_VRFDIG_EN, MC13783_REGCTRL_VRFDIG_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFDIG_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFREF: reg_val = BITFVAL(MC13783_REGCTRL_VRFREF_EN, MC13783_REGCTRL_VRFREF_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFREF_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFCP: reg_val = BITFVAL(MC13783_REGCTRL_VRFCP_EN, MC13783_REGCTRL_VRFCP_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFCP_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VSIM: reg_val = BITFVAL(MC13783_REGCTRL_VSIM_EN, MC13783_REGCTRL_VSIM_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VSIM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VESIM: reg_val = BITFVAL(MC13783_REGCTRL_VESIM_EN, MC13783_REGCTRL_VESIM_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VESIM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VCAM: reg_val = BITFVAL(MC13783_REGCTRL_VCAM_EN, MC13783_REGCTRL_VCAM_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VCAM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRFBG: reg_val = BITFVAL(MC13783_REGCTRL_VRFBG_EN, MC13783_REGCTRL_VRFBG_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFBG_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VVIB: reg_val = BITFVAL(MC13783_REGCTRL_VVIB_EN, MC13783_REGCTRL_VVIB_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VVIB_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF1: reg_val = BITFVAL(MC13783_REGCTRL_VRF1_EN, MC13783_REGCTRL_VRF1_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRF1_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF2: reg_val = BITFVAL(MC13783_REGCTRL_VRF2_EN, MC13783_REGCTRL_VRF2_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRF2_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC1: reg_val = BITFVAL(MC13783_REGCTRL_VMMC1_EN, MC13783_REGCTRL_VMMC1_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC1_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC2: reg_val = BITFVAL(MC13783_REGCTRL_VMMC2_EN, MC13783_REGCTRL_VMMC2_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC2_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_GPO1: reg_val = BITFVAL(MC13783_REGCTRL_GPO1_EN, MC13783_REGCTRL_GPO1_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO1_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO2: reg_val = BITFVAL(MC13783_REGCTRL_GPO2_EN, MC13783_REGCTRL_GPO2_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO2_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO3: reg_val = BITFVAL(MC13783_REGCTRL_GPO3_EN, MC13783_REGCTRL_GPO3_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO3_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO4: reg_val = BITFVAL(MC13783_REGCTRL_GPO4_EN, MC13783_REGCTRL_GPO4_EN_ENABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO4_EN); reg = REG_POWER_MISCELLANEOUS; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function turns off a regulator. * * @param regulator The regulator to be truned off. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_off(t_pmic_regulator regulator) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_PLL: reg_val = BITFVAL(MC13783_SWCTRL_PLL_EN, MC13783_SWCTRL_PLL_EN_DISABLE); reg_mask = BITFMASK(MC13783_SWCTRL_PLL_EN); reg = REG_SWITCHERS_4; break; case SW_SW3: reg_val = BITFVAL(MC13783_SWCTRL_SW3_EN, MC13783_SWCTRL_SW3_EN_DISABLE); reg_mask = BITFMASK(MC13783_SWCTRL_SW3_EN); reg = REG_SWITCHERS_5; break; case REGU_VAUDIO: reg_val = BITFVAL(MC13783_REGCTRL_VAUDIO_EN, MC13783_REGCTRL_VAUDIO_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VAUDIO_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOHI: reg_val = BITFVAL(MC13783_REGCTRL_VIOHI_EN, MC13783_REGCTRL_VIOHI_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VIOHI_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOLO: reg_val = BITFVAL(MC13783_REGCTRL_VIOLO_EN, MC13783_REGCTRL_VIOLO_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VIOLO_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VDIG: reg_val = BITFVAL(MC13783_REGCTRL_VDIG_EN, MC13783_REGCTRL_VDIG_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VDIG_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VGEN: reg_val = BITFVAL(MC13783_REGCTRL_VGEN_EN, MC13783_REGCTRL_VGEN_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VGEN_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFDIG: reg_val = BITFVAL(MC13783_REGCTRL_VRFDIG_EN, MC13783_REGCTRL_VRFDIG_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFDIG_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFREF: reg_val = BITFVAL(MC13783_REGCTRL_VRFREF_EN, MC13783_REGCTRL_VRFREF_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFREF_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFCP: reg_val = BITFVAL(MC13783_REGCTRL_VRFCP_EN, MC13783_REGCTRL_VRFCP_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFCP_EN); reg = REG_REGULATOR_MODE_0; break; case REGU_VSIM: reg_val = BITFVAL(MC13783_REGCTRL_VSIM_EN, MC13783_REGCTRL_VSIM_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VSIM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VESIM: reg_val = BITFVAL(MC13783_REGCTRL_VESIM_EN, MC13783_REGCTRL_VESIM_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VESIM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VCAM: reg_val = BITFVAL(MC13783_REGCTRL_VCAM_EN, MC13783_REGCTRL_VCAM_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VCAM_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRFBG: reg_val = BITFVAL(MC13783_REGCTRL_VRFBG_EN, MC13783_REGCTRL_VRFBG_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRFBG_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VVIB: reg_val = BITFVAL(MC13783_REGCTRL_VVIB_EN, MC13783_REGCTRL_VVIB_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VVIB_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF1: reg_val = BITFVAL(MC13783_REGCTRL_VRF1_EN, MC13783_REGCTRL_VRF1_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRF1_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF2: reg_val = BITFVAL(MC13783_REGCTRL_VRF2_EN, MC13783_REGCTRL_VRF2_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VRF2_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC1: reg_val = BITFVAL(MC13783_REGCTRL_VMMC1_EN, MC13783_REGCTRL_VMMC1_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC1_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC2: reg_val = BITFVAL(MC13783_REGCTRL_VMMC2_EN, MC13783_REGCTRL_VMMC2_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC2_EN); reg = REG_REGULATOR_MODE_1; break; case REGU_GPO1: reg_val = BITFVAL(MC13783_REGCTRL_GPO1_EN, MC13783_REGCTRL_GPO1_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO1_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO2: reg_val = BITFVAL(MC13783_REGCTRL_GPO2_EN, MC13783_REGCTRL_GPO2_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO2_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO3: reg_val = BITFVAL(MC13783_REGCTRL_GPO3_EN, MC13783_REGCTRL_GPO3_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO3_EN); reg = REG_POWER_MISCELLANEOUS; break; case REGU_GPO4: reg_val = BITFVAL(MC13783_REGCTRL_GPO4_EN, MC13783_REGCTRL_GPO4_EN_DISABLE); reg_mask = BITFMASK(MC13783_REGCTRL_GPO4_EN); reg = REG_POWER_MISCELLANEOUS; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function sets the regulator output voltage. * * @param regulator The regulator to be configured. * @param voltage The regulator output voltage. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_set_voltage(t_pmic_regulator regulator, t_regulator_voltage voltage) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: if ((voltage.sw1a < SW1A_0_9V) || (voltage.sw1a > SW1A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1A, voltage.sw1a); reg_mask = BITFMASK(MC13783_SWSET_SW1A); reg = REG_SWITCHERS_0; break; case SW_SW1B: if ((voltage.sw1b < SW1B_0_9V) || (voltage.sw1b > SW1B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1B, voltage.sw1b); reg_mask = BITFMASK(MC13783_SWSET_SW1B); reg = REG_SWITCHERS_1; break; case SW_SW2A: if ((voltage.sw2a < SW2A_0_9V) || (voltage.sw2a > SW2A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2A, voltage.sw1a); reg_mask = BITFMASK(MC13783_SWSET_SW2A); reg = REG_SWITCHERS_2; break; case SW_SW2B: if ((voltage.sw2b < SW2B_0_9V) || (voltage.sw2b > SW2B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2B, voltage.sw2b); reg_mask = BITFMASK(MC13783_SWSET_SW1A); reg = REG_SWITCHERS_3; break; case SW_SW3: if (voltage.sw3 != SW3_5V) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW3, voltage.sw3); reg_mask = BITFMASK(MC13783_SWSET_SW3); reg = REG_SWITCHERS_5; break; case REGU_VIOLO: if ((voltage.violo < VIOLO_1_2V) || (voltage.violo > VIOLO_1_8V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VIOLO, voltage.violo); reg_mask = BITFMASK(MC13783_REGSET_VIOLO); reg = REG_REGULATOR_SETTING_0; break; case REGU_VDIG: if ((voltage.vdig < VDIG_1_2V) || (voltage.vdig > VDIG_1_8V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VDIG, voltage.vdig); reg_mask = BITFMASK(MC13783_REGSET_VDIG); reg = REG_REGULATOR_SETTING_0; break; case REGU_VGEN: if ((voltage.vgen < VGEN_1_2V) || (voltage.vgen > VGEN_2_4V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VGEN, voltage.vgen); reg_mask = BITFMASK(MC13783_REGSET_VGEN); reg = REG_REGULATOR_SETTING_0; break; case REGU_VRFDIG: if ((voltage.vrfdig < VRFDIG_1_2V) || (voltage.vrfdig > VRFDIG_1_875V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VRFDIG, voltage.vrfdig); reg_mask = BITFMASK(MC13783_REGSET_VRFDIG); reg = REG_REGULATOR_SETTING_0; break; case REGU_VRFREF: if ((voltage.vrfref < VRFREF_2_475V) || (voltage.vrfref > VRFREF_2_775V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VRFREF, voltage.vrfref); reg_mask = BITFMASK(MC13783_REGSET_VRFREF); reg = REG_REGULATOR_SETTING_0; break; case REGU_VRFCP: if ((voltage.vrfcp < VRFCP_2_7V) || (voltage.vrfcp > VRFCP_2_775V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VRFCP, voltage.vrfcp); reg_mask = BITFMASK(MC13783_REGSET_VRFCP); reg = REG_REGULATOR_SETTING_0; break; case REGU_VSIM: if ((voltage.vsim < VSIM_1_8V) || (voltage.vsim > VSIM_2_9V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VSIM, voltage.vsim); reg_mask = BITFMASK(MC13783_REGSET_VSIM); reg = REG_REGULATOR_SETTING_0; break; case REGU_VESIM: if ((voltage.vesim < VESIM_1_8V) || (voltage.vesim > VESIM_2_9V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VESIM, voltage.vesim); reg_mask = BITFMASK(MC13783_REGSET_VESIM); reg = REG_REGULATOR_SETTING_0; break; case REGU_VCAM: if ((voltage.vcam < VCAM_1_5V) || (voltage.vcam > VCAM_3V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VCAM, voltage.vcam); reg_mask = BITFMASK(MC13783_REGSET_VCAM); reg = REG_REGULATOR_SETTING_0; break; case REGU_VVIB: if ((voltage.vvib < VVIB_1_3V) || (voltage.vvib > VVIB_3V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VVIB, voltage.vvib); reg_mask = BITFMASK(MC13783_REGSET_VVIB); reg = REG_REGULATOR_SETTING_1; break; case REGU_VRF1: if ((voltage.vrf1 < VRF1_1_5V) || (voltage.vrf1 > VRF1_2_775V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VRF1, voltage.vrf1); reg_mask = BITFMASK(MC13783_REGSET_VRF1); reg = REG_REGULATOR_SETTING_1; break; case REGU_VRF2: if ((voltage.vrf2 < VRF2_1_5V) || (voltage.vrf2 > VRF2_2_775V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VRF2, voltage.vrf2); reg_mask = BITFMASK(MC13783_REGSET_VRF2); reg = REG_REGULATOR_SETTING_1; break; case REGU_VMMC1: if ((voltage.vmmc1 < VMMC1_1_6V) || (voltage.vmmc1 > VMMC1_3V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VMMC1, voltage.vmmc1); reg_mask = BITFMASK(MC13783_REGSET_VMMC1); reg = REG_REGULATOR_SETTING_1; break; case REGU_VMMC2: if ((voltage.vmmc2 < VMMC2_1_6V) || (voltage.vmmc2 > VMMC2_3V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGSET_VMMC2, voltage.vmmc2); reg_mask = BITFMASK(MC13783_REGSET_VMMC2); reg = REG_REGULATOR_SETTING_1; break; case REGU_VAUDIO: case REGU_VIOHI: case REGU_VRFBG: case REGU_GPO1: case REGU_GPO2: case REGU_GPO3: case REGU_GPO4: default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function retrives the regulator output voltage. * * @param regulator The regulator to be truned off. * @param voltage Pointer to regulator output voltage. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_get_voltage(t_pmic_regulator regulator, t_regulator_voltage * voltage) { unsigned int reg_val = 0; if (regulator == SW_SW1A) { CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_0, ®_val, PMIC_ALL_BITS)); } else if (regulator == SW_SW1B) { CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_1, ®_val, PMIC_ALL_BITS)); } else if (regulator == SW_SW2A) { CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_2, ®_val, PMIC_ALL_BITS)); } else if (regulator == SW_SW2B) { CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_3, ®_val, PMIC_ALL_BITS)); } else if (regulator == SW_SW3) { CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_5, ®_val, PMIC_ALL_BITS)); } else if ((regulator == REGU_VIOLO) || (regulator == REGU_VDIG) || (regulator == REGU_VGEN) || (regulator == REGU_VRFDIG) || (regulator == REGU_VRFREF) || (regulator == REGU_VRFCP) || (regulator == REGU_VSIM) || (regulator == REGU_VESIM) || (regulator == REGU_VCAM)) { CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_0, ®_val, PMIC_ALL_BITS)); } else if ((regulator == REGU_VVIB) || (regulator == REGU_VRF1) || (regulator == REGU_VRF2) || (regulator == REGU_VMMC1) || (regulator == REGU_VMMC2)) { CHECK_ERROR(pmic_read_reg(REG_REGULATOR_SETTING_1, ®_val, PMIC_ALL_BITS)); } switch (regulator) { case SW_SW1A: voltage->sw1a = BITFEXT(reg_val, MC13783_SWSET_SW1A); break; case SW_SW1B: voltage->sw1b = BITFEXT(reg_val, MC13783_SWSET_SW1B); break; case SW_SW2A: voltage->sw2a = BITFEXT(reg_val, MC13783_SWSET_SW2A); break; case SW_SW2B: voltage->sw2b = BITFEXT(reg_val, MC13783_SWSET_SW2B); break; case SW_SW3: voltage->sw3 = BITFEXT(reg_val, MC13783_SWSET_SW3); break; case REGU_VIOLO: voltage->violo = BITFEXT(reg_val, MC13783_REGSET_VIOLO); break; case REGU_VDIG: voltage->vdig = BITFEXT(reg_val, MC13783_REGSET_VDIG); break; case REGU_VGEN: voltage->vgen = BITFEXT(reg_val, MC13783_REGSET_VGEN); break; case REGU_VRFDIG: voltage->vrfdig = BITFEXT(reg_val, MC13783_REGSET_VRFDIG); break; case REGU_VRFREF: voltage->vrfref = BITFEXT(reg_val, MC13783_REGSET_VRFREF); break; case REGU_VRFCP: voltage->vrfcp = BITFEXT(reg_val, MC13783_REGSET_VRFCP); break; case REGU_VSIM: voltage->vsim = BITFEXT(reg_val, MC13783_REGSET_VSIM); break; case REGU_VESIM: voltage->vesim = BITFEXT(reg_val, MC13783_REGSET_VESIM); break; case REGU_VCAM: voltage->vcam = BITFEXT(reg_val, MC13783_REGSET_VCAM); break; case REGU_VVIB: voltage->vvib = BITFEXT(reg_val, MC13783_REGSET_VVIB); break; case REGU_VRF1: voltage->vrf1 = BITFEXT(reg_val, MC13783_REGSET_VRF1); break; case REGU_VRF2: voltage->vrf2 = BITFEXT(reg_val, MC13783_REGSET_VRF2); break; case REGU_VMMC1: voltage->vmmc1 = BITFEXT(reg_val, MC13783_REGSET_VMMC1); break; case REGU_VMMC2: voltage->vmmc2 = BITFEXT(reg_val, MC13783_REGSET_VMMC2); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function sets the DVS voltage * * @param regulator The regulator to be configured. * @param dvs The switch Dynamic Voltage Scaling * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_dvs(t_pmic_regulator regulator, t_regulator_voltage dvs) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: if ((dvs.sw1a < SW1A_0_9V) || (dvs.sw1a > SW1A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1A_DVS, dvs.sw1a); reg_mask = BITFMASK(MC13783_SWSET_SW1A_DVS); reg = REG_SWITCHERS_0; break; case SW_SW1B: if ((dvs.sw1b < SW1B_0_9V) || (dvs.sw1b > SW1B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1B_DVS, dvs.sw1b); reg_mask = BITFMASK(MC13783_SWSET_SW1B_DVS); reg = REG_SWITCHERS_1; break; case SW_SW2A: if ((dvs.sw2a < SW2A_0_9V) || (dvs.sw2a > SW2A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2A_DVS, dvs.sw2a); reg_mask = BITFMASK(MC13783_SWSET_SW2A_DVS); reg = REG_SWITCHERS_2; break; case SW_SW2B: if ((dvs.sw2b < SW2B_0_9V) || (dvs.sw2b > SW2B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2B_DVS, dvs.sw2b); reg_mask = BITFMASK(MC13783_SWSET_SW2B_DVS); reg = REG_SWITCHERS_3; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the DVS voltage * * @param regulator The regulator to be handled. * @param dvs The switch Dynamic Voltage Scaling * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_dvs(t_pmic_regulator regulator, t_regulator_voltage * dvs) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_mask = BITFMASK(MC13783_SWSET_SW1A_DVS); reg = REG_SWITCHERS_0; break; case SW_SW1B: reg_mask = BITFMASK(MC13783_SWSET_SW1B_DVS); reg = REG_SWITCHERS_1; break; case SW_SW2A: reg_mask = BITFMASK(MC13783_SWSET_SW2A_DVS); reg = REG_SWITCHERS_2; break; case SW_SW2B: reg_mask = BITFMASK(MC13783_SWSET_SW2B_DVS); reg = REG_SWITCHERS_3; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: *dvs = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW1A_DVS); break; case SW_SW1B: *dvs = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW1B_DVS); break; case SW_SW2A: *dvs = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW2A_DVS); break; case SW_SW2B: *dvs = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW2B_DVS); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function sets the standiby voltage * * @param regulator The regulator to be configured. * @param stby The switch standby voltage * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_stby(t_pmic_regulator regulator, t_regulator_voltage stby) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: if ((stby.sw1a < SW1A_0_9V) || (stby.sw1a > SW1A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1A_STDBY, stby.sw1a); reg_mask = BITFMASK(MC13783_SWSET_SW1A_STDBY); reg = REG_SWITCHERS_0; break; case SW_SW1B: if ((stby.sw1b < SW1B_0_9V) || (stby.sw1b > SW1B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW1B_STDBY, stby.sw1b); reg_mask = BITFMASK(MC13783_SWSET_SW1B_STDBY); reg = REG_SWITCHERS_1; break; case SW_SW2A: if ((stby.sw2a < SW2A_0_9V) || (stby.sw2a > SW2A_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2A_STDBY, stby.sw2a); reg_mask = BITFMASK(MC13783_SWSET_SW2A_STDBY); reg = REG_SWITCHERS_2; break; case SW_SW2B: if ((stby.sw2b < SW2B_0_9V) || (stby.sw2b > SW2B_2_2V)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWSET_SW2B_STDBY, stby.sw2b); reg_mask = BITFMASK(MC13783_SWSET_SW2B_STDBY); reg = REG_SWITCHERS_3; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the standiby voltage * * @param regulator The regulator to be handled. * @param stby The switch standby voltage * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_stby(t_pmic_regulator regulator, t_regulator_voltage * stby) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_mask = BITFMASK(MC13783_SWSET_SW1A_STDBY); reg = REG_SWITCHERS_0; break; case SW_SW1B: reg_mask = BITFMASK(MC13783_SWSET_SW1B_STDBY); reg = REG_SWITCHERS_1; break; case SW_SW2A: reg_mask = BITFMASK(MC13783_SWSET_SW2A_STDBY); reg = REG_SWITCHERS_2; break; case SW_SW2B: reg_mask = BITFMASK(MC13783_SWSET_SW2B_STDBY); reg = REG_SWITCHERS_3; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: *stby = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW1A_STDBY); break; case SW_SW1B: *stby = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW1B_STDBY); break; case SW_SW2A: *stby = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW2A_STDBY); break; case SW_SW2B: *stby = (t_regulator_voltage) BITFEXT(reg_val, MC13783_SWSET_SW2B_STDBY); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function sets the switchers mode. * * @param regulator The regulator to be configured. * @param mode The switcher mode * @param stby Switch between main and standby. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_mode(t_pmic_regulator regulator, t_regulator_sw_mode mode, bool stby) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; unsigned int l_mode; if (mode == SYNC_RECT) { l_mode = MC13783_SWCTRL_SW_MODE_SYNC_RECT_EN; } else if (mode == NO_PULSE_SKIP) { l_mode = MC13783_SWCTRL_SW_MODE_PULSE_NO_SKIP_EN; } else if (mode == PULSE_SKIP) { l_mode = MC13783_SWCTRL_SW_MODE_PULSE_SKIP_EN; } else if (mode == LOW_POWER) { l_mode = MC13783_SWCTRL_SW_MODE_LOW_POWER_EN; } else { return PMIC_PARAMETER_ERROR; } switch (regulator) { case SW_SW1A: if (stby) { reg_val = BITFVAL(MC13783_SWCTRL_SW1A_STBY_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_STBY_MODE); } else { reg_val = BITFVAL(MC13783_SWCTRL_SW1A_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_MODE); } reg = REG_SWITCHERS_4; break; case SW_SW1B: if (stby) { reg_val = BITFVAL(MC13783_SWCTRL_SW1B_STBY_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_STBY_MODE); } else { reg_val = BITFVAL(MC13783_SWCTRL_SW1B_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_MODE); } reg = REG_SWITCHERS_4; break; case SW_SW2A: if (stby) { reg_val = BITFVAL(MC13783_SWCTRL_SW2A_STBY_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_STBY_MODE); } else { reg_val = BITFVAL(MC13783_SWCTRL_SW2A_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_MODE); } reg = REG_SWITCHERS_5; break; case SW_SW2B: if (stby) { reg_val = BITFVAL(MC13783_SWCTRL_SW2B_STBY_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_STBY_MODE); } else { reg_val = BITFVAL(MC13783_SWCTRL_SW2B_MODE, l_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_MODE); } reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the switchers mode. * * @param regulator The regulator to be handled. * @param mode The switcher mode. * @param stby Switch between main and standby. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_mode(t_pmic_regulator regulator, t_regulator_sw_mode * mode, bool stby) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg = 0; unsigned int l_mode = 0; switch (regulator) { case SW_SW1A: if (stby) { reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_STBY_MODE); } else { reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_MODE); } reg = REG_SWITCHERS_4; break; case SW_SW1B: if (stby) { reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_STBY_MODE); } else { reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_MODE); } reg = REG_SWITCHERS_4; break; case SW_SW2A: if (stby) { reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_STBY_MODE); } else { reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_MODE); } reg = REG_SWITCHERS_5; break; case SW_SW2B: if (stby) { reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_STBY_MODE); } else { reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_MODE); } reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: if (stby) { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1A_STBY_MODE); } else { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1A_MODE); } break; case SW_SW1B: if (stby) { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1B_STBY_MODE); } else { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1B_MODE); } break; case SW_SW2A: if (stby) { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2A_STBY_MODE); } else { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2A_MODE); } break; case SW_SW2B: if (stby) { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_STBY_MODE); } else { l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_MODE); } break; default: return PMIC_PARAMETER_ERROR; } if (l_mode == MC13783_SWCTRL_SW_MODE_SYNC_RECT_EN) { *mode = SYNC_RECT; } else if (l_mode == MC13783_SWCTRL_SW_MODE_PULSE_NO_SKIP_EN) { *mode = NO_PULSE_SKIP; } else if (l_mode == MC13783_SWCTRL_SW_MODE_PULSE_SKIP_EN) { *mode = PULSE_SKIP; } else if (l_mode == MC13783_SWCTRL_SW_MODE_LOW_POWER_EN) { *mode = LOW_POWER; } else { return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function sets the switch dvs speed * * @param regulator The regulator to be configured. * @param speed The dvs speed. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_dvs_speed(t_pmic_regulator regulator, t_switcher_dvs_speed speed) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; if (speed > 3 || speed < 0) { return PMIC_PARAMETER_ERROR; } switch (regulator) { case SW_SW1A: reg_val = BITFVAL(MC13783_SWCTRL_SW1A_DVS_SPEED, speed); reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_DVS_SPEED); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_DVS_SPEED, speed); reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_DVS_SPEED); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_val = BITFVAL(MC13783_SWCTRL_SW2A_DVS_SPEED, speed); reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_DVS_SPEED); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_DVS_SPEED, speed); reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_DVS_SPEED); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the switch dvs speed * * @param regulator The regulator to be handled. * @param speed The dvs speed. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_dvs_speed(t_pmic_regulator regulator, t_switcher_dvs_speed * speed) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_DVS_SPEED); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_DVS_SPEED); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_DVS_SPEED); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_DVS_SPEED); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: *speed = BITFEXT(reg_val, MC13783_SWCTRL_SW1A_DVS_SPEED); break; case SW_SW1B: *speed = BITFEXT(reg_val, MC13783_SWCTRL_SW1B_DVS_SPEED); break; case SW_SW2A: *speed = BITFEXT(reg_val, MC13783_SWCTRL_SW2A_DVS_SPEED); break; case SW_SW2B: *speed = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_DVS_SPEED); break; default: break; } return PMIC_SUCCESS; } /*! * This function sets the switch panic mode * * @param regulator The regulator to be configured. * @param panic_mode Enable or disable panic mode * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_panic_mode(t_pmic_regulator regulator, bool panic_mode) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_val = BITFVAL(MC13783_SWCTRL_SW1A_PANIC_MODE, panic_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_PANIC_MODE); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_PANIC_MODE, panic_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_PANIC_MODE); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_val = BITFVAL(MC13783_SWCTRL_SW2A_PANIC_MODE, panic_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_PANIC_MODE); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_PANIC_MODE, panic_mode); reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_PANIC_MODE); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the switch panic mode * * @param regulator The regulator to be handled * @param panic_mode Enable or disable panic mode * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_panic_mode(t_pmic_regulator regulator, bool * panic_mode) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_PANIC_MODE); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_PANIC_MODE); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_PANIC_MODE); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_PANIC_MODE); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: *panic_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1A_PANIC_MODE); break; case SW_SW1B: *panic_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW1B_PANIC_MODE); break; case SW_SW2A: *panic_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2A_PANIC_MODE); break; case SW_SW2B: *panic_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_PANIC_MODE); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function sets the switch softstart mode * * @param regulator The regulator to be configured. * @param softstart Enable or disable softstart. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_softstart(t_pmic_regulator regulator, bool softstart) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_val = BITFVAL(MC13783_SWCTRL_SW1A_SOFTSTART, softstart); reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_SOFTSTART); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_SOFTSTART, softstart); reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_SOFTSTART); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_val = BITFVAL(MC13783_SWCTRL_SW2A_SOFTSTART, softstart); reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_SOFTSTART); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_val = BITFVAL(MC13783_SWCTRL_SW2B_SOFTSTART, softstart); reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_SOFTSTART); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the switch softstart mode * * @param regulator The regulator to be handled * @param softstart Enable or disable softstart. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_softstart(t_pmic_regulator regulator, bool * softstart) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; switch (regulator) { case SW_SW1A: reg_mask = BITFMASK(MC13783_SWCTRL_SW1A_SOFTSTART); reg = REG_SWITCHERS_4; break; case SW_SW1B: reg_mask = BITFMASK(MC13783_SWCTRL_SW1B_SOFTSTART); reg = REG_SWITCHERS_4; break; case SW_SW2A: reg_mask = BITFMASK(MC13783_SWCTRL_SW2A_SOFTSTART); reg = REG_SWITCHERS_5; break; case SW_SW2B: reg_mask = BITFMASK(MC13783_SWCTRL_SW2B_SOFTSTART); reg = REG_SWITCHERS_5; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW1A: *softstart = BITFEXT(reg_val, MC13783_SWCTRL_SW1A_SOFTSTART); break; case SW_SW1B: *softstart = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_SOFTSTART); break; case SW_SW2A: *softstart = BITFEXT(reg_val, MC13783_SWCTRL_SW2A_SOFTSTART); break; case SW_SW2B: *softstart = BITFEXT(reg_val, MC13783_SWCTRL_SW2B_SOFTSTART); break; default: break; } return PMIC_SUCCESS; } /*! * This function sets the PLL multiplication factor * * @param regulator The regulator to be configured. * @param factor The multiplication factor. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_set_factor(t_pmic_regulator regulator, t_switcher_factor factor) { unsigned int reg_val = 0, reg_mask = 0; if (regulator != SW_PLL) { return PMIC_PARAMETER_ERROR; } if (factor < FACTOR_28 || factor > FACTOR_35) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_SWCTRL_PLL_FACTOR, factor); reg_mask = BITFMASK(MC13783_SWCTRL_PLL_FACTOR); CHECK_ERROR(pmic_write_reg(REG_SWITCHERS_4, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the PLL multiplication factor * * @param regulator The regulator to be handled * @param factor The multiplication factor. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_switcher_get_factor(t_pmic_regulator regulator, t_switcher_factor * factor) { unsigned int reg_val = 0, reg_mask = 0; if (regulator != SW_PLL) { return PMIC_PARAMETER_ERROR; } reg_mask = BITFMASK(MC13783_SWCTRL_PLL_FACTOR); CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_4, ®_val, reg_mask)); *factor = BITFEXT(reg_val, MC13783_SWCTRL_PLL_FACTOR); return PMIC_SUCCESS; } /*! * This function enables or disables low power mode. * * @param regulator The regulator to be configured. * @param lp_mode Select nominal or low power mode. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_set_lp_mode(t_pmic_regulator regulator, t_regulator_lp_mode lp_mode) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; unsigned int l_mode, l_stby; if (lp_mode == LOW_POWER_DISABLED) { l_mode = MC13783_REGTRL_LP_MODE_DISABLE; l_stby = MC13783_REGTRL_STBY_MODE_DISABLE; } else if (lp_mode == LOW_POWER_CTRL_BY_PIN) { l_mode = MC13783_REGTRL_LP_MODE_DISABLE; l_stby = MC13783_REGTRL_STBY_MODE_ENABLE; } else if (lp_mode == LOW_POWER_EN) { l_mode = MC13783_REGTRL_LP_MODE_ENABLE; l_stby = MC13783_REGTRL_STBY_MODE_DISABLE; } else if (lp_mode == LOW_POWER_AND_LOW_POWER_CTRL_BY_PIN) { l_mode = MC13783_REGTRL_LP_MODE_ENABLE; l_stby = MC13783_REGTRL_STBY_MODE_ENABLE; } else { return PMIC_PARAMETER_ERROR; } switch (regulator) { case SW_SW3: reg_val = BITFVAL(MC13783_SWCTRL_SW3_MODE, l_mode) | BITFVAL(MC13783_SWCTRL_SW3_STBY, l_stby); reg_mask = BITFMASK(MC13783_SWCTRL_SW3_MODE) | BITFMASK(MC13783_SWCTRL_SW3_STBY); reg = REG_SWITCHERS_5; break; case REGU_VAUDIO: reg_val = BITFVAL(MC13783_REGCTRL_VAUDIO_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VAUDIO_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VAUDIO_MODE) | BITFMASK(MC13783_REGCTRL_VAUDIO_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOHI: reg_val = BITFVAL(MC13783_REGCTRL_VIOHI_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VIOHI_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VIOHI_MODE) | BITFMASK(MC13783_REGCTRL_VIOHI_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOLO: reg_val = BITFVAL(MC13783_REGCTRL_VIOLO_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VIOLO_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VIOLO_MODE) | BITFMASK(MC13783_REGCTRL_VIOLO_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VDIG: reg_val = BITFVAL(MC13783_REGCTRL_VDIG_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VDIG_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VDIG_MODE) | BITFMASK(MC13783_REGCTRL_VDIG_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VGEN: reg_val = BITFVAL(MC13783_REGCTRL_VGEN_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VGEN_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VGEN_MODE) | BITFMASK(MC13783_REGCTRL_VGEN_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFDIG: reg_val = BITFVAL(MC13783_REGCTRL_VRFDIG_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VRFDIG_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VRFDIG_MODE) | BITFMASK(MC13783_REGCTRL_VRFDIG_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFREF: reg_val = BITFVAL(MC13783_REGCTRL_VRFREF_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VRFREF_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VRFREF_MODE) | BITFMASK(MC13783_REGCTRL_VRFREF_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFCP: reg_val = BITFVAL(MC13783_REGCTRL_VRFCP_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VRFCP_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VRFCP_MODE) | BITFMASK(MC13783_REGCTRL_VRFCP_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VSIM: reg_val = BITFVAL(MC13783_REGCTRL_VSIM_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VSIM_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VSIM_MODE) | BITFMASK(MC13783_REGCTRL_VSIM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VESIM: reg_val = BITFVAL(MC13783_REGCTRL_VESIM_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VESIM_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VESIM_MODE) | BITFMASK(MC13783_REGCTRL_VESIM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VCAM: reg_val = BITFVAL(MC13783_REGCTRL_VCAM_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VCAM_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VCAM_MODE) | BITFMASK(MC13783_REGCTRL_VCAM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRFBG: if ((lp_mode == LOW_POWER) || (lp_mode == LOW_POWER_AND_LOW_POWER_CTRL_BY_PIN)) { return PMIC_PARAMETER_ERROR; } reg_val = BITFVAL(MC13783_REGCTRL_VRFBG_STBY, l_mode); reg_mask = BITFMASK(MC13783_REGCTRL_VRFBG_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF1: reg_val = BITFVAL(MC13783_REGCTRL_VRF1_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VRF1_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VRF1_MODE) | BITFMASK(MC13783_REGCTRL_VRF1_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF2: reg_val = BITFVAL(MC13783_REGCTRL_VRF2_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VRF2_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VRF2_MODE) | BITFMASK(MC13783_REGCTRL_VRF2_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC1: reg_val = BITFVAL(MC13783_REGCTRL_VMMC1_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VMMC1_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC1_MODE) | BITFMASK(MC13783_REGCTRL_VMMC1_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC2: reg_val = BITFVAL(MC13783_REGCTRL_VMMC2_MODE, l_mode) | BITFVAL(MC13783_REGCTRL_VMMC2_STBY, l_stby); reg_mask = BITFMASK(MC13783_REGCTRL_VMMC2_MODE) | BITFMASK(MC13783_REGCTRL_VMMC2_STBY); reg = REG_REGULATOR_MODE_1; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(reg, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets low power mode. * * @param regulator The regulator to be handled * @param lp_mode Select nominal or low power mode. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_get_lp_mode(t_pmic_regulator regulator, t_regulator_lp_mode * lp_mode) { unsigned int reg_val = 0, reg_mask = 0; unsigned int reg; unsigned int l_mode, l_stby; switch (regulator) { case SW_SW3: reg_mask = BITFMASK(MC13783_SWCTRL_SW3_MODE) | BITFMASK(MC13783_SWCTRL_SW3_STBY); reg = REG_SWITCHERS_5; break; case REGU_VAUDIO: reg_mask = BITFMASK(MC13783_REGCTRL_VAUDIO_MODE) | BITFMASK(MC13783_REGCTRL_VAUDIO_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOHI: reg_mask = BITFMASK(MC13783_REGCTRL_VIOHI_MODE) | BITFMASK(MC13783_REGCTRL_VIOHI_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VIOLO: reg_mask = BITFMASK(MC13783_REGCTRL_VIOLO_MODE) | BITFMASK(MC13783_REGCTRL_VIOLO_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VDIG: reg_mask = BITFMASK(MC13783_REGCTRL_VDIG_MODE) | BITFMASK(MC13783_REGCTRL_VDIG_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VGEN: reg_mask = BITFMASK(MC13783_REGCTRL_VGEN_MODE) | BITFMASK(MC13783_REGCTRL_VGEN_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFDIG: reg_mask = BITFMASK(MC13783_REGCTRL_VRFDIG_MODE) | BITFMASK(MC13783_REGCTRL_VRFDIG_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFREF: reg_mask = BITFMASK(MC13783_REGCTRL_VRFREF_MODE) | BITFMASK(MC13783_REGCTRL_VRFREF_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VRFCP: reg_mask = BITFMASK(MC13783_REGCTRL_VRFCP_MODE) | BITFMASK(MC13783_REGCTRL_VRFCP_STBY); reg = REG_REGULATOR_MODE_0; break; case REGU_VSIM: reg_mask = BITFMASK(MC13783_REGCTRL_VSIM_MODE) | BITFMASK(MC13783_REGCTRL_VSIM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VESIM: reg_mask = BITFMASK(MC13783_REGCTRL_VESIM_MODE) | BITFMASK(MC13783_REGCTRL_VESIM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VCAM: reg_mask = BITFMASK(MC13783_REGCTRL_VCAM_MODE) | BITFMASK(MC13783_REGCTRL_VCAM_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRFBG: reg_mask = BITFMASK(MC13783_REGCTRL_VRFBG_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF1: reg_mask = BITFMASK(MC13783_REGCTRL_VRF1_MODE) | BITFMASK(MC13783_REGCTRL_VRF1_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VRF2: reg_mask = BITFMASK(MC13783_REGCTRL_VRF2_MODE) | BITFMASK(MC13783_REGCTRL_VRF2_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC1: reg_mask = BITFMASK(MC13783_REGCTRL_VMMC1_MODE) | BITFMASK(MC13783_REGCTRL_VMMC1_STBY); reg = REG_REGULATOR_MODE_1; break; case REGU_VMMC2: reg_mask = BITFMASK(MC13783_REGCTRL_VMMC2_MODE) | BITFMASK(MC13783_REGCTRL_VMMC2_STBY); reg = REG_REGULATOR_MODE_1; break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(reg, ®_val, reg_mask)); switch (regulator) { case SW_SW3: l_mode = BITFEXT(reg_val, MC13783_SWCTRL_SW3_MODE); l_stby = BITFEXT(reg_val, MC13783_SWCTRL_SW3_STBY); break; case REGU_VAUDIO: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VAUDIO_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VAUDIO_STBY); break; case REGU_VIOHI: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VIOHI_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VIOHI_STBY); break; case REGU_VIOLO: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VIOLO_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VIOLO_STBY); break; case REGU_VDIG: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VDIG_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VDIG_STBY); break; case REGU_VGEN: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VGEN_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VGEN_STBY); break; case REGU_VRFDIG: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VRFDIG_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRFDIG_STBY); break; case REGU_VRFREF: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VRFREF_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRFREF_STBY); break; case REGU_VRFCP: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VRFCP_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRFCP_STBY); break; case REGU_VSIM: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VSIM_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VSIM_STBY); break; case REGU_VESIM: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VESIM_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VESIM_STBY); break; case REGU_VCAM: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VCAM_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VCAM_STBY); break; case REGU_VRFBG: l_mode = MC13783_REGTRL_LP_MODE_DISABLE; l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRFBG_STBY); break; case REGU_VRF1: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VRF1_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRF1_STBY); break; case REGU_VRF2: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VRF2_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VRF2_STBY); break; case REGU_VMMC1: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VMMC1_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VMMC1_STBY); break; case REGU_VMMC2: l_mode = BITFEXT(reg_val, MC13783_REGCTRL_VMMC2_MODE); l_stby = BITFEXT(reg_val, MC13783_REGCTRL_VMMC2_STBY); break; default: return PMIC_PARAMETER_ERROR; } if ((l_mode == MC13783_REGTRL_LP_MODE_DISABLE) && (l_stby == MC13783_REGTRL_STBY_MODE_DISABLE)) { *lp_mode = LOW_POWER_DISABLED; } else if ((l_mode == MC13783_REGTRL_LP_MODE_DISABLE) && (l_stby == MC13783_REGTRL_STBY_MODE_ENABLE)) { *lp_mode = LOW_POWER_CTRL_BY_PIN; } else if ((l_mode == MC13783_REGTRL_LP_MODE_ENABLE) && (l_stby == MC13783_REGTRL_STBY_MODE_DISABLE)) { *lp_mode = LOW_POWER_EN; } else { *lp_mode = LOW_POWER_AND_LOW_POWER_CTRL_BY_PIN; } return PMIC_SUCCESS; } /*! * This function sets the regulator configuration. * * @param regulator The regulator to be configured. * @param config The regulator output configuration. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_set_config(t_pmic_regulator regulator, t_regulator_config * config) { if (config == NULL) { return PMIC_ERROR; } switch (regulator) { case SW_SW1A: case SW_SW1B: case SW_SW2A: case SW_SW2B: CHECK_ERROR(pmic_power_regulator_set_voltage (regulator, config->voltage)); CHECK_ERROR(pmic_power_switcher_set_dvs (regulator, config->voltage_lvs)); CHECK_ERROR(pmic_power_switcher_set_stby (regulator, config->voltage_stby)); CHECK_ERROR(pmic_power_switcher_set_mode (regulator, config->mode, false)); CHECK_ERROR(pmic_power_switcher_set_mode (regulator, config->stby_mode, true)); CHECK_ERROR(pmic_power_switcher_set_dvs_speed (regulator, config->dvs_speed)); CHECK_ERROR(pmic_power_switcher_set_panic_mode (regulator, config->panic_mode)); CHECK_ERROR(pmic_power_switcher_set_softstart (regulator, config->softstart)); break; case SW_PLL: CHECK_ERROR(pmic_power_switcher_set_factor (regulator, config->factor)); break; case SW_SW3: case REGU_VIOLO: case REGU_VDIG: case REGU_VGEN: case REGU_VRFDIG: case REGU_VRFREF: case REGU_VRFCP: case REGU_VSIM: case REGU_VESIM: case REGU_VCAM: case REGU_VRF1: case REGU_VRF2: case REGU_VMMC1: case REGU_VMMC2: CHECK_ERROR(pmic_power_regulator_set_voltage (regulator, config->voltage)); CHECK_ERROR(pmic_power_regulator_set_lp_mode (regulator, config->lp_mode)); break; case REGU_VVIB: CHECK_ERROR(pmic_power_regulator_set_voltage (regulator, config->voltage)); break; case REGU_VAUDIO: case REGU_VIOHI: case REGU_VRFBG: CHECK_ERROR(pmic_power_regulator_set_lp_mode (regulator, config->lp_mode)); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function retrives the regulator output configuration. * * @param regulator The regulator to be truned off. * @param config Pointer to regulator configuration. * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_regulator_get_config(t_pmic_regulator regulator, t_regulator_config * config) { if (config == NULL) { return PMIC_ERROR; } switch (regulator) { case SW_SW1A: case SW_SW1B: case SW_SW2A: case SW_SW2B: CHECK_ERROR(pmic_power_regulator_get_voltage (regulator, &config->voltage)); CHECK_ERROR(pmic_power_switcher_get_dvs (regulator, &config->voltage_lvs)); CHECK_ERROR(pmic_power_switcher_get_stby (regulator, &config->voltage_stby)); CHECK_ERROR(pmic_power_switcher_get_mode (regulator, &config->mode, false)); CHECK_ERROR(pmic_power_switcher_get_mode (regulator, &config->stby_mode, true)); CHECK_ERROR(pmic_power_switcher_get_dvs_speed (regulator, &config->dvs_speed)); CHECK_ERROR(pmic_power_switcher_get_panic_mode (regulator, &config->panic_mode)); CHECK_ERROR(pmic_power_switcher_get_softstart (regulator, &config->softstart)); break; case SW_PLL: CHECK_ERROR(pmic_power_switcher_get_factor (regulator, &config->factor)); break; case SW_SW3: case REGU_VIOLO: case REGU_VDIG: case REGU_VGEN: case REGU_VRFDIG: case REGU_VRFREF: case REGU_VRFCP: case REGU_VSIM: case REGU_VESIM: case REGU_VCAM: case REGU_VRF1: case REGU_VRF2: case REGU_VMMC1: case REGU_VMMC2: CHECK_ERROR(pmic_power_regulator_get_voltage (regulator, &config->voltage)); CHECK_ERROR(pmic_power_regulator_get_lp_mode (regulator, &config->lp_mode)); break; case REGU_VVIB: CHECK_ERROR(pmic_power_regulator_get_voltage (regulator, &config->voltage)); break; case REGU_VAUDIO: case REGU_VIOHI: case REGU_VRFBG: CHECK_ERROR(pmic_power_regulator_get_lp_mode (regulator, &config->lp_mode)); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function enables automatically VBKUP2 in the memory hold modes. * Only on mc13783 2.0 or higher * * @param en if true, enable VBKUP2AUTOMH * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_vbkup2_auto_en(bool en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_val = BITFVAL(MC13783_REGCTRL_VBKUP2AUTOMH, en); reg_mask = BITFMASK(MC13783_REGCTRL_VBKUP2AUTOMH); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_0, reg_val, reg_mask)); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function gets state of automatically VBKUP2. * Only on mc13783 2.0 or higher * * @param en if true, VBKUP2AUTOMH is enabled * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_get_vbkup2_auto_state(bool * en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_mask = BITFMASK(MC13783_REGCTRL_VBKUP2AUTOMH); CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_0, ®_val, reg_mask)); *en = BITFEXT(reg_val, MC13783_REGCTRL_VBKUP2AUTOMH); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function enables battery detect function. * Only on mc13783 2.0 or higher * * @param en if true, enable BATTDETEN * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_bat_det_en(bool en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_val = BITFVAL(MC13783_REGCTRL_BATTDETEN, en); reg_mask = BITFMASK(MC13783_REGCTRL_BATTDETEN); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_0, reg_val, reg_mask)); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function gets state of battery detect function. * Only on mc13783 2.0 or higher * * @param en if true, BATTDETEN is enabled * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_get_bat_det_state(bool * en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_mask = BITFMASK(MC13783_REGCTRL_BATTDETEN); CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_0, ®_val, reg_mask)); *en = BITFEXT(reg_val, MC13783_REGCTRL_BATTDETEN); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function enables control of VVIB by VIBEN pin. * Only on mc13783 2.0 or higher * * @param en if true, enable VIBPINCTRL * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_vib_pin_en(bool en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_val = BITFVAL(MC13783_REGCTRL_VIBPINCTRL, en); reg_mask = BITFMASK(MC13783_REGCTRL_VIBPINCTRL); CHECK_ERROR(pmic_write_reg(REG_POWER_MISCELLANEOUS, reg_val, reg_mask)); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function gets state of control of VVIB by VIBEN pin. * Only on mc13783 2.0 or higher * @param en if true, VIBPINCTRL is enabled * * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_gets_vib_pin_state(bool * en) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_mask = BITFMASK(MC13783_REGCTRL_VIBPINCTRL); CHECK_ERROR(pmic_read_reg(REG_POWER_MISCELLANEOUS, ®_val, reg_mask)); *en = BITFEXT(reg_val, MC13783_REGCTRL_VIBPINCTRL); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function returns power up sense value * * @param p_up_sense value of power up sense * @return This function returns PMIC_SUCCESS if successful. */ PMIC_STATUS pmic_power_get_power_mode_sense(struct t_p_up_sense * p_up_sense) { unsigned int reg_value = 0; CHECK_ERROR(pmic_read_reg(REG_POWER_UP_MODE_SENSE, ®_value, PMIC_ALL_BITS)); p_up_sense->state_ictest = (STATE_ICTEST_MASK & reg_value); p_up_sense->state_clksel = ((STATE_CLKSEL_MASK & reg_value) >> STATE_CLKSEL_BIT); p_up_sense->state_pums1 = ((STATE_PUMS1_MASK & reg_value) >> STATE_PUMS1_BITS); p_up_sense->state_pums2 = ((STATE_PUMS2_MASK & reg_value) >> STATE_PUMS2_BITS); p_up_sense->state_pums3 = ((STATE_PUMS3_MASK & reg_value) >> STATE_PUMS3_BITS); p_up_sense->state_chrgmode0 = ((STATE_CHRGM1_MASK & reg_value) >> STATE_CHRGM1_BITS); p_up_sense->state_chrgmode1 = ((STATE_CHRGM2_MASK & reg_value) >> STATE_CHRGM2_BITS); p_up_sense->state_umod = ((STATE_UMOD_MASK & reg_value) >> STATE_UMOD_BITS); p_up_sense->state_usben = ((STATE_USBEN_MASK & reg_value) >> STATE_USBEN_BIT); p_up_sense->state_sw_1a1b_joined = ((STATE_SW1A_J_B_MASK & reg_value) >> STATE_SW1A_J_B_BIT); p_up_sense->state_sw_2a2b_joined = ((STATE_SW2A_J_B_MASK & reg_value) >> STATE_SW2A_J_B_BIT); return PMIC_SUCCESS; } /*! * This function configures the Regen assignment for all regulator * * @param regulator type of regulator * @param en_dis if true, the regulator is enabled by regen. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_set_regen_assig(t_pmic_regulator regulator, bool en_dis) { unsigned int reg_val = 0, reg_mask = 0; switch (regulator) { case REGU_VAUDIO: reg_val = BITFVAL(MC13783_REGGEN_VAUDIO, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VAUDIO); break; case REGU_VIOHI: reg_val = BITFVAL(MC13783_REGGEN_VIOHI, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VIOHI); break; case REGU_VIOLO: reg_val = BITFVAL(MC13783_REGGEN_VIOLO, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VIOLO); break; case REGU_VDIG: reg_val = BITFVAL(MC13783_REGGEN_VDIG, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VDIG); break; case REGU_VGEN: reg_val = BITFVAL(MC13783_REGGEN_VGEN, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VGEN); break; case REGU_VRFDIG: reg_val = BITFVAL(MC13783_REGGEN_VRFDIG, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRFDIG); break; case REGU_VRFREF: reg_val = BITFVAL(MC13783_REGGEN_VRFREF, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRFREF); break; case REGU_VRFCP: reg_val = BITFVAL(MC13783_REGGEN_VRFCP, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRFCP); break; case REGU_VCAM: reg_val = BITFVAL(MC13783_REGGEN_VCAM, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VCAM); break; case REGU_VRFBG: reg_val = BITFVAL(MC13783_REGGEN_VRFBG, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRFBG); break; case REGU_VRF1: reg_val = BITFVAL(MC13783_REGGEN_VRF1, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRF1); break; case REGU_VRF2: reg_val = BITFVAL(MC13783_REGGEN_VRF2, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VRF2); break; case REGU_VMMC1: reg_val = BITFVAL(MC13783_REGGEN_VMMC1, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VMMC1); break; case REGU_VMMC2: reg_val = BITFVAL(MC13783_REGGEN_VMMC2, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_VMMC2); break; case REGU_GPO1: reg_val = BITFVAL(MC13783_REGGEN_GPO1, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_GPO1); break; case REGU_GPO2: reg_val = BITFVAL(MC13783_REGGEN_GPO2, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_GPO2); break; case REGU_GPO3: reg_val = BITFVAL(MC13783_REGGEN_GPO3, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_GPO3); break; case REGU_GPO4: reg_val = BITFVAL(MC13783_REGGEN_GPO4, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_GPO4); break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(REG_REGEN_ASSIGNMENT, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the Regen assignment for all regulator * * @param regulator type of regulator * @param en_dis return value, if true : * the regulator is enabled by regen. * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_get_regen_assig(t_pmic_regulator regulator, bool * en_dis) { unsigned int reg_val = 0, reg_mask = 0; switch (regulator) { case REGU_VAUDIO: reg_mask = BITFMASK(MC13783_REGGEN_VAUDIO); break; case REGU_VIOHI: reg_mask = BITFMASK(MC13783_REGGEN_VIOHI); break; case REGU_VIOLO: reg_mask = BITFMASK(MC13783_REGGEN_VIOLO); break; case REGU_VDIG: reg_mask = BITFMASK(MC13783_REGGEN_VDIG); break; case REGU_VGEN: reg_mask = BITFMASK(MC13783_REGGEN_VGEN); break; case REGU_VRFDIG: reg_mask = BITFMASK(MC13783_REGGEN_VRFDIG); break; case REGU_VRFREF: reg_mask = BITFMASK(MC13783_REGGEN_VRFREF); break; case REGU_VRFCP: reg_mask = BITFMASK(MC13783_REGGEN_VRFCP); break; case REGU_VCAM: reg_mask = BITFMASK(MC13783_REGGEN_VCAM); break; case REGU_VRFBG: reg_mask = BITFMASK(MC13783_REGGEN_VRFBG); break; case REGU_VRF1: reg_mask = BITFMASK(MC13783_REGGEN_VRF1); break; case REGU_VRF2: reg_mask = BITFMASK(MC13783_REGGEN_VRF2); break; case REGU_VMMC1: reg_mask = BITFMASK(MC13783_REGGEN_VMMC1); break; case REGU_VMMC2: reg_mask = BITFMASK(MC13783_REGGEN_VMMC2); break; case REGU_GPO1: reg_mask = BITFMASK(MC13783_REGGEN_GPO1); break; case REGU_GPO2: reg_mask = BITFMASK(MC13783_REGGEN_GPO2); break; case REGU_GPO3: reg_mask = BITFMASK(MC13783_REGGEN_GPO3); break; case REGU_GPO4: reg_mask = BITFMASK(MC13783_REGGEN_GPO4); break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(REG_REGEN_ASSIGNMENT, ®_val, reg_mask)); switch (regulator) { case REGU_VAUDIO: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VAUDIO); break; case REGU_VIOHI: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VIOHI); break; case REGU_VIOLO: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VIOLO); break; case REGU_VDIG: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VDIG); break; case REGU_VGEN: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VGEN); break; case REGU_VRFDIG: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRFDIG); break; case REGU_VRFREF: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRFREF); break; case REGU_VRFCP: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRFCP); break; case REGU_VCAM: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VCAM); break; case REGU_VRFBG: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRFBG); break; case REGU_VRF1: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRF1); break; case REGU_VRF2: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VRF2); break; case REGU_VMMC1: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VMMC1); break; case REGU_VMMC2: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_VMMC2); break; case REGU_GPO1: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_GPO1); break; case REGU_GPO2: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_GPO2); break; case REGU_GPO3: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_GPO3); break; case REGU_GPO4: *en_dis = BITFEXT(reg_val, MC13783_REGGEN_GPO4); break; default: break; } return PMIC_SUCCESS; } /*! * This function sets the Regen polarity. * * @param en_dis If true regen is inverted. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_set_regen_inv(bool en_dis) { unsigned int reg_val = 0, reg_mask = 0; reg_val = BITFVAL(MC13783_REGGEN_INV, en_dis); reg_mask = BITFMASK(MC13783_REGGEN_INV); CHECK_ERROR(pmic_write_reg(REG_REGEN_ASSIGNMENT, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets the Regen polarity. * * @param en_dis If true regen is inverted. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_get_regen_inv(bool * en_dis) { unsigned int reg_val = 0, reg_mask = 0; reg_mask = BITFMASK(MC13783_REGGEN_INV); CHECK_ERROR(pmic_read_reg(REG_REGEN_ASSIGNMENT, ®_val, reg_mask)); *en_dis = BITFEXT(reg_val, MC13783_REGGEN_INV); return PMIC_SUCCESS; } /*! * This function enables esim control voltage. * Only on mc13783 2.0 or higher * * @param vesim if true, enable VESIMESIMEN * @param vmmc1 if true, enable VMMC1ESIMEN * @param vmmc2 if true, enable VMMC2ESIMEN * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_esim_v_en(bool vesim, bool vmmc1, bool vmmc2) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_val = BITFVAL(MC13783_REGGEN_VESIMESIM, vesim) | BITFVAL(MC13783_REGGEN_VMMC1ESIM, vesim) | BITFVAL(MC13783_REGGEN_VMMC2ESIM, vesim); reg_mask = BITFMASK(MC13783_REGGEN_VESIMESIM) | BITFMASK(MC13783_REGGEN_VMMC1ESIM) | BITFMASK(MC13783_REGGEN_VMMC2ESIM); CHECK_ERROR(pmic_write_reg(REG_REGEN_ASSIGNMENT, reg_val, reg_mask)); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function gets esim control voltage values. * Only on mc13783 2.0 or higher * * @param vesim if true, enable VESIMESIMEN * @param vmmc1 if true, enable VMMC1ESIMEN * @param vmmc2 if true, enable VMMC2ESIMEN * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_gets_esim_v_state(bool * vesim, bool * vmmc1, bool * vmmc2) { unsigned int reg_val = 0, reg_mask = 0; pmic_version_t mc13783_ver; mc13783_ver = pmic_get_version(); if (mc13783_ver.revision >= 20) { reg_mask = BITFMASK(MC13783_REGGEN_VESIMESIM) | BITFMASK(MC13783_REGGEN_VMMC1ESIM) | BITFMASK(MC13783_REGGEN_VMMC2ESIM); CHECK_ERROR(pmic_read_reg(REG_REGEN_ASSIGNMENT, ®_val, reg_mask)); *vesim = BITFEXT(reg_val, MC13783_REGGEN_VESIMESIM); *vmmc1 = BITFEXT(reg_val, MC13783_REGGEN_VMMC1ESIM); *vmmc2 = BITFEXT(reg_val, MC13783_REGGEN_VMMC2ESIM); return PMIC_SUCCESS; } else { return PMIC_NOT_SUPPORTED; } } /*! * This function enables auto reset after a system reset. * * @param en if true, the auto reset is enabled * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_set_auto_reset_en(bool en) { unsigned int reg_val = 0, reg_mask = 0; reg_val = BITFVAL(MC13783_AUTO_RESTART, en); reg_mask = BITFMASK(MC13783_AUTO_RESTART); CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_2, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets auto reset configuration. * * @param en if true, the auto reset is enabled * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_get_auto_reset_en(bool * en) { unsigned int reg_val = 0, reg_mask = 0; reg_mask = BITFMASK(MC13783_AUTO_RESTART); CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_2, ®_val, reg_mask)); *en = BITFEXT(reg_val, MC13783_AUTO_RESTART); return PMIC_SUCCESS; } /*! * This function configures a system reset on a button. * * @param bt type of button. * @param sys_rst if true, enable the system reset on this button * @param deb_time sets the debounce time on this button pin * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_set_conf_button(t_button bt, bool sys_rst, int deb_time) { int max_val = 0; unsigned int reg_val = 0, reg_mask = 0; max_val = (1 << MC13783_DEB_BT_ON1B_WID) - 1; if (deb_time > max_val) { return PMIC_PARAMETER_ERROR; } switch (bt) { case BT_ON1B: reg_val = BITFVAL(MC13783_EN_BT_ON1B, sys_rst) | BITFVAL(MC13783_DEB_BT_ON1B, deb_time); reg_mask = BITFMASK(MC13783_EN_BT_ON1B) | BITFMASK(MC13783_DEB_BT_ON1B); break; case BT_ON2B: reg_val = BITFVAL(MC13783_EN_BT_ON2B, sys_rst) | BITFVAL(MC13783_DEB_BT_ON2B, deb_time); reg_mask = BITFMASK(MC13783_EN_BT_ON2B) | BITFMASK(MC13783_DEB_BT_ON2B); break; case BT_ON3B: reg_val = BITFVAL(MC13783_EN_BT_ON3B, sys_rst) | BITFVAL(MC13783_DEB_BT_ON3B, deb_time); reg_mask = BITFMASK(MC13783_EN_BT_ON3B) | BITFMASK(MC13783_DEB_BT_ON3B); break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_write_reg(REG_POWER_CONTROL_2, reg_val, reg_mask)); return PMIC_SUCCESS; } /*! * This function gets configuration of a button. * * @param bt type of button. * @param sys_rst if true, the system reset is enabled on this button * @param deb_time gets the debounce time on this button pin * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_get_conf_button(t_button bt, bool * sys_rst, int *deb_time) { unsigned int reg_val = 0, reg_mask = 0; switch (bt) { case BT_ON1B: reg_mask = BITFMASK(MC13783_EN_BT_ON1B) | BITFMASK(MC13783_DEB_BT_ON1B); break; case BT_ON2B: reg_mask = BITFMASK(MC13783_EN_BT_ON2B) | BITFMASK(MC13783_DEB_BT_ON2B); break; case BT_ON3B: reg_mask = BITFMASK(MC13783_EN_BT_ON3B) | BITFMASK(MC13783_DEB_BT_ON3B); break; default: return PMIC_PARAMETER_ERROR; } CHECK_ERROR(pmic_read_reg(REG_POWER_CONTROL_2, ®_val, reg_mask)); switch (bt) { case BT_ON1B: *sys_rst = BITFEXT(reg_val, MC13783_EN_BT_ON1B); *deb_time = BITFEXT(reg_val, MC13783_DEB_BT_ON1B); break; case BT_ON2B: *sys_rst = BITFEXT(reg_val, MC13783_EN_BT_ON2B); *deb_time = BITFEXT(reg_val, MC13783_DEB_BT_ON2B); break; case BT_ON3B: *sys_rst = BITFEXT(reg_val, MC13783_EN_BT_ON3B); *deb_time = BITFEXT(reg_val, MC13783_DEB_BT_ON3B); break; default: return PMIC_PARAMETER_ERROR; } return PMIC_SUCCESS; } /*! * This function is used to un/subscribe on power event IT. * * @param event type of event. * @param callback event callback function. * @param sub define if Un/subscribe event. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_event(t_pwr_int event, void *callback, bool sub) { pmic_event_callback_t power_callback; type_event power_event; power_callback.func = callback; power_callback.param = NULL; switch (event) { case PWR_IT_BPONI: power_event = EVENT_BPONI; break; case PWR_IT_LOBATLI: power_event = EVENT_LOBATLI; break; case PWR_IT_LOBATHI: power_event = EVENT_LOBATHI; break; case PWR_IT_ONOFD1I: power_event = EVENT_ONOFD1I; break; case PWR_IT_ONOFD2I: power_event = EVENT_ONOFD2I; break; case PWR_IT_ONOFD3I: power_event = EVENT_ONOFD3I; break; case PWR_IT_SYSRSTI: power_event = EVENT_SYSRSTI; break; case PWR_IT_PWRRDYI: power_event = EVENT_PWRRDYI; break; case PWR_IT_PCI: power_event = EVENT_PCI; break; case PWR_IT_WARMI: power_event = EVENT_WARMI; break; default: return PMIC_PARAMETER_ERROR; } if (sub == true) { CHECK_ERROR(pmic_event_subscribe(power_event, power_callback)); } else { CHECK_ERROR(pmic_event_unsubscribe (power_event, power_callback)); } return PMIC_SUCCESS; } /*! * This function is used to subscribe on power event IT. * * @param event type of event. * @param callback event callback function. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_event_sub(t_pwr_int event, void *callback) { return pmic_power_event(event, callback, true); } /*! * This function is used to un subscribe on power event IT. * * @param event type of event. * @param callback event callback function. * * @return This function returns 0 if successful. */ PMIC_STATUS pmic_power_event_unsub(t_pwr_int event, void *callback) { return pmic_power_event(event, callback, false); } void pmic_power_key_callback(void) { #ifdef CONFIG_MXC_HWEVENT /*read the power key is pressed or up */ t_sensor_bits sense; struct mxc_hw_event event = { HWE_POWER_KEY, 0 }; pmic_get_sensors(&sense); if (sense.sense_onofd1s) { pr_debug("PMIC Power key up\n"); event.args = PWRK_UNPRESS; } else { pr_debug("PMIC Power key pressed\n"); event.args = PWRK_PRESS; } /* send hw event */ hw_event_send(HWE_DEF_PRIORITY, &event); #endif } static irqreturn_t power_key_int(int irq, void *dev_id) { pr_info(KERN_INFO "on-off key pressed\n"); return 0; } extern void gpio_power_key_active(void); /* * Init and Exit */ static int pmic_power_probe(struct platform_device *pdev) { int irq, ret; /* configure on/off button */ gpio_power_key_active(); irq = (int)pdev->dev.platform_data; if (irq == 0) { pr_info(KERN_INFO "PMIC Power has no platform data\n"); goto done; } set_irq_type(irq, IRQF_TRIGGER_RISING); ret = request_irq(irq, power_key_int, 0, "power_key", 0); if (ret) pr_info(KERN_ERR "register on-off key interrupt failed\n"); set_irq_wake(irq, 1); done: pr_info(KERN_INFO "PMIC Power successfully probed\n"); return 0; } static struct platform_driver pmic_power_driver_ldm = { .driver = { .name = "pmic_power", }, .suspend = pmic_power_suspend, .resume = pmic_power_resume, .probe = pmic_power_probe, .remove = NULL, }; static int __init pmic_power_init(void) { pr_debug("PMIC Power driver loading..\n"); pmic_power_event_sub(PWR_IT_ONOFD1I, pmic_power_key_callback); return platform_driver_register(&pmic_power_driver_ldm); } static void __exit pmic_power_exit(void) { pmic_power_event_unsub(PWR_IT_ONOFD1I, pmic_power_key_callback); platform_driver_unregister(&pmic_power_driver_ldm); pr_debug("PMIC Power driver successfully unloaded\n"); } /* * Module entry points */ subsys_initcall_sync(pmic_power_init); module_exit(pmic_power_exit); MODULE_DESCRIPTION("pmic_power driver"); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_LICENSE("GPL");