Logo Search packages:      
Sourcecode: linux-fsl-imx51 version File versions  Download package

pmic_power.c

Go to the documentation of this file.
/*
 * Copyright 2004-2009 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 <linux/platform_device.h>
#include <linux/ioctl.h>
#include <linux/pmic_status.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <mach/pmic_power.h>

#include "pmic_power_defs.h"

#ifdef CONFIG_MXC_HWEVENT
#include <mach/hw_events.h>
#endif

#include <asm/mach-types.h>

#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.
 */
00092 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.
 */
00105 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.
 */
00116 void 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);

      pmic_write_reg(REG_POWER_CONTROL_0, value, mask);
}

/*!
 * This function sets the power control configuration.
 *
 * @param        pc_config   power control configuration.
 *
 * @return       This function returns PMIC_SUCCESS if successful.
 */
00134 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.
 */
00298 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.
 */
00418 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.
 */
00578 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.
 */
00739 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.
 */
00927 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,
                                &reg_val, PMIC_ALL_BITS));
      } else if (regulator == SW_SW1B) {
            CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_1,
                                &reg_val, PMIC_ALL_BITS));
      } else if (regulator == SW_SW2A) {
            CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_2,
                                &reg_val, PMIC_ALL_BITS));
      } else if (regulator == SW_SW2B) {
            CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_3,
                                &reg_val, PMIC_ALL_BITS));
      } else if (regulator == SW_SW3) {
            CHECK_ERROR(pmic_read_reg(REG_SWITCHERS_5,
                                &reg_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,
                                &reg_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,
                                &reg_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.
 */
01036 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.
 */
01092 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, &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.
 */
01153 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.
 */
01209 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, &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.
 */
01271 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.
 */
01353 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, &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.
 */
01459 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.
 */
01506 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, &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.
 */
01563 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.
 */
01607 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, &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.
 */
01664 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.
 */
01708 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, &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.
 */
01765 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.
 */
01792 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, &reg_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.
 */
01817 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.
 */
01979 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, &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.
 */
02174 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.
 */
02251 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.
 */
02328 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.
 */
02353 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,
                                &reg_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.
 */
02378 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.
 */
02403 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,
                                &reg_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.
 */
02428 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.
 */
02452 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,
                                &reg_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.
 */
02474 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,
                          &reg_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.
 */
02511 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.
 */
02605 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, &reg_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.
 */
02740 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.
 */
02758 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, &reg_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.
 */
02778 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.
 */
02808 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,
                                &reg_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.
 */
02836 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.
 */
02854 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, &reg_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.
 */
02873 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.
 */
02920 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, &reg_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.
 */
02972 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.
 */
03030 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.
 */
03043 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;
      struct pmic_platform_data *ppd;

      /* configure on/off button */
      gpio_power_key_active();

      ppd = pdev->dev.platform_data;
      if (ppd)
            irq = ppd->power_key_irq;
      else
            goto done;

      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);
      /* set power off hook to mc13783 power off */
      pm_power_off = pmic_power_off;
      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");

Generated by  Doxygen 1.6.0   Back to index