blob: 09a48f9d6aa17898199e019a3af4f01959385750 [file] [log] [blame]
/*
* Copyright (C) 2014 Marvell International Ltd.
* Fenghang Yin <yinfh@marvell.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/marvell88pm_pmic.h>
#include <power/88pm830.h>
#include <power/battery.h>
#include <errno.h>
#define MARVELL_PMIC_BATTERY "88pm830_battery"
static int pm830_enable_bat_det(struct pmic *p, int enable)
{
u32 val;
pmic_reg_read(p, PM830_REG_CHG_BAT_DET, &val);
if (!!enable)
val |= PM830_BAT_DET_EN;
else
val &= ~PM830_BAT_DET_EN;
pmic_reg_write(p, PM830_REG_CHG_BAT_DET, val);
return 0;
}
static int pm830_enable_bat_priority(struct pmic *p, int enable)
{
u32 val;
pmic_reg_read(p, PM830_REG_CHG_CTRL3, &val);
if (!!enable)
val |= PM830_BAT_PRTY_EN;
else
val &= ~PM830_BAT_PRTY_EN;
pmic_reg_write(p, PM830_REG_CHG_CTRL3, val);
return 0;
}
/*
* the method used to get power up mode for 88pm830:
* step 1. set BD_EN, if battery present, it's BATTERY_MODE
* step 2. clear BD_PRTY_EN, if VBAT is valid, it's POWER_SUPPLY_MODE
* step 3. clear BD_EN, set BD_PRTY_EN, if VBAT is valid, it's EXTERNAL_POWER_MODE
* step 4. if it's CHARGER_ONLY_MODE, system will shutdown in step 3
*/
int pm830_get_powerup_mode(void)
{
int ret;
struct pmic *p_bat, *p;
p_bat = pmic_get(MARVELL_PMIC_BATTERY);
if (!p_bat) {
printf("find battery failed\n");
return INVALID_MODE;
}
p = p_bat->pbat->chrg;
/* disable the auto battery detection circuit */
pm830_enable_bat_det(p, 0);
pm830_enable_bat_priority(p, 0);
ret = p_bat->chrg->chrg_bat_present(p);
if (!!ret) {
/* it's battery mode */
ret = BATTERY_MODE;
goto handler;
}
p_bat->fg->fg_battery_update(p_bat->pbat->fg, p_bat, 0);
if (p_bat->pbat->bat->voltage_uV > POWER_OFF_THRESHOLD) {
/* it's power supply mode */
ret = POWER_SUPPLY_MODE;
goto handler;
}
printf("if you are in charger-only mode, system will power-off now.\n");
/* set BD_PRTY_EN */
pm830_enable_bat_priority(p, 1);
p_bat->fg->fg_battery_update(p_bat->pbat->fg, p_bat, 0);
if (p_bat->pbat->bat->voltage_uV > POWER_OFF_THRESHOLD) {
/* it's external power mode */
ret = EXTERNAL_POWER_MODE;
goto handler;
} else {
/*
* the program will not run to here, since if it's charger only mode, the system
* already power off
*/
ret = CHARGER_ONLY_MODE;
}
handler:
switch (ret) {
case BATTERY_MODE:
/* in order to handle dead battery case, use charger to supply system */
printf("battery mode\n");
break;
case POWER_SUPPLY_MODE:
case EXTERNAL_POWER_MODE:
printf("power-supply mode\n");
/* use battery supply system */
pm830_enable_bat_priority(p, 1);
break;
case CHARGER_ONLY_MODE:
default:
break;
}
return ret;
}