1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-03 17:52:07 +02:00

power: axp818: Add various helper functions for accessing AXP81x PMIC status

These will be used by the upcomming `axp` command.

Signed-off-by: Ondrej Jirman <megous@megous.com>
This commit is contained in:
Ondrej Jirman
2018-07-09 07:32:37 +02:00
parent bf8d675ba8
commit 2dfa2ae65b
2 changed files with 294 additions and 0 deletions

View File

@@ -311,3 +311,225 @@ int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* not reached */
return 0;
}
// battery/charger related functions
int axp_is_charging(bool* charging)
{
int ret;
u8 cs;
ret = pmic_bus_read(AXP_CHARGER_STATUS, &cs);
if (ret)
return ret;
*charging = (cs & AXP_CHARGER_STATUS_CHARGING);
return 0;
}
int axp_is_vbus_present(bool* vbus)
{
int ret;
u8 ps;
ret = pmic_bus_read(AXP_POWER_STATUS, &ps);
if (ret)
return ret;
*vbus = (ps & AXP_POWER_STATUS_VBUS_PRESENT) &&
(ps & AXP_POWER_STATUS_VBUS_VALID);
return 0;
}
int axp_is_battery_present(bool* vbus)
{
int ret;
u8 cs;
ret = pmic_bus_read(AXP_CHARGER_STATUS, &cs);
if (ret)
return ret;
*vbus = (cs & AXP_CHARGER_STATUS_BAT_PRESENT_VALID) &&
(cs & AXP_CHARGER_STATUS_BAT_PRESENT);
return 0;
}
int axp_clear_startup_reason(void)
{
return pmic_bus_write(AXP_POWER_UP_DOWN_REASON, 0xff);
}
static int axp_read_adc(u8 addr_msb, u8 addr_lsb, u32* raw)
{
u8 val;
int ret;
ret = pmic_bus_read(addr_lsb, &val);
if (ret)
return ret;
*raw = val & 0xf;
ret = pmic_bus_read(addr_msb, &val);
if (ret)
return ret;
*raw |= (u32)val << 4;
return 0;
}
int axp_get_battery_voltage(int* uV)
{
u32 raw;
int ret;
ret = axp_read_adc(AXP_AD_BAT_VOLTAGE_MSB8, AXP_AD_BAT_VOLTAGE_LSB4,
&raw);
if (ret)
return ret;
*uV = (raw) * 1100;
return 0;
}
int axp_get_battery_current(int* uA)
{
u32 raw;
int ret;
bool charging;
ret = axp_is_charging(&charging);
if (ret)
return ret;
if (charging)
ret = axp_read_adc(AXP_AD_BAT_CHG_CURRENT_MSB8,
AXP_AD_BAT_CHG_CURRENT_LSB4, &raw);
else
ret = axp_read_adc(AXP_AD_BAT_DIS_CURRENT_MSB8,
AXP_AD_BAT_DIS_CURRENT_LSB4, &raw);
if (ret)
return ret;
*uA = raw * 1000;
return 0;
}
int axp_battery_get_capacity(int* capacity)
{
int ret;
u8 val;
ret = pmic_bus_read(AXP_BATTERY_CAPACITY, &val);
if (ret)
return ret;
if (!(val & 0x80))
return -EINVAL;
*capacity = val & 0x7f;
return 0;
}
struct {
u8 vbus_i;
int mA;
} vbus_currents[] = {
{ AXP_CHARGER_CTRL3_VBUS_I_100, 100 },
{ AXP_CHARGER_CTRL3_VBUS_I_500, 500 },
{ AXP_CHARGER_CTRL3_VBUS_I_900, 900 },
{ AXP_CHARGER_CTRL3_VBUS_I_1500, 1500 },
{ AXP_CHARGER_CTRL3_VBUS_I_2000, 2000 },
{ AXP_CHARGER_CTRL3_VBUS_I_2500, 2500 },
{ AXP_CHARGER_CTRL3_VBUS_I_3000, 3000 },
{ AXP_CHARGER_CTRL3_VBUS_I_3500, 3500 },
{ AXP_CHARGER_CTRL3_VBUS_I_4000, 4000 },
};
int axp_usb_get_max_current(int* mA)
{
int i, ret;
u8 val;
ret = pmic_bus_read(AXP_CHARGER_CTRL3, &val);
if (ret)
return ret;
val &= AXP_CHARGER_CTRL3_VBUS_I_MASK;
*mA = 4000;
for (i = 0; i < ARRAY_SIZE(vbus_currents); i++) {
if (vbus_currents[i].vbus_i == val) {
*mA = vbus_currents[i].mA;
break;
}
}
return 0;
}
int axp_usb_set_max_current(int mA)
{
int i, ret;
u8 val;
ret = pmic_bus_read(AXP_CHARGER_CTRL3, &val);
if (ret)
return ret;
val &= ~AXP_CHARGER_CTRL3_VBUS_I_MASK;
for (i = ARRAY_SIZE(vbus_currents) - 1; i >= 0; i--) {
if (vbus_currents[i].mA <= mA || i == 0) {
val |= vbus_currents[i].vbus_i;
break;
}
}
return pmic_bus_write(AXP_CHARGER_CTRL3, val);
}
int axp_led_set_charger_controlled(void)
{
int ret;
u8 val;
ret = pmic_bus_read(AXP_CHGLED, &val);
if (ret)
return ret;
val |= AXP_CHGLED_CTRL_CHARGER;
return pmic_bus_write(AXP_CHGLED, val);
}
int axp_led_set(bool on)
{
int ret;
u8 val;
ret = pmic_bus_read(AXP_CHGLED, &val);
if (ret)
return ret;
val &= ~(AXP_CHGLED_CTRL_CHARGER | AXP_CHGLED_SETUP_MASK);
val |= on ? AXP_CHGLED_SETUP_ON : AXP_CHGLED_SETUP_OFF;
return pmic_bus_write(AXP_CHGLED, val);
}
int axp_pok_set_quick(void)
{
int ret;
u8 val;
ret = pmic_bus_read(AXP_POK, &val);
if (ret)
return ret;
val &= ~(AXP_POK_ON_MASK | AXP_POK_OFF_MASK);
val |= AXP_POK_ON_128MS | AXP_POK_OFF_4S;
return pmic_bus_write(AXP_POK, val);
}

View File

@@ -60,6 +60,10 @@
/* For axp_gpio.c */
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_VBUS_PRESENT (1 << 5)
#define AXP_POWER_STATUS_VBUS_VALID (1 << 4)
#define AXP_POWER_STATUS_VBAT_GT_3_5V (1 << 3)
#define AXP_POWER_STATUS_VBUS_STARTUP (1 << 0)
#define AXP_VBUS_IPSOUT 0x30
#define AXP_VBUS_IPSOUT_DRIVEBUS (1 << 2)
#define AXP_MISC_CTRL 0x8f
@@ -74,5 +78,73 @@
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0
#define AXP_CHARGER_STATUS 0x01
#define AXP_CHARGER_STATUS_BAT_PRESENT (1 << 5)
#define AXP_CHARGER_STATUS_BAT_PRESENT_VALID (1 << 4)
#define AXP_CHARGER_STATUS_CHARGING (1 << 6)
#define AXP_CHARGER_STATUS_OVER_TEMP (1 << 7)
#define AXP_POWER_UP_DOWN_REASON 0x02
#define AXP_POWER_UP_REASON_POK (1 << 0)
#define AXP_POWER_UP_REASON_CHARGER (1 << 1)
#define AXP_POWER_UP_REASON_GLOBAL_RESET (1 << 3)
#define AXP_POWER_UP_REASON_COLD_RESET (1 << 4)
#define AXP_POWER_DOWN_REASON_UVLO (1 << 5)
#define AXP_POWER_DOWN_REASON_COLD_OFF (1 << 6)
#define AXP_POWER_DOWN_REASON_POK_OR (1 << 7)
#define AXP_CHGLED 0x32
#define AXP_CHGLED_CTRL_CHARGER (1 << 3)
#define AXP_CHGLED_SETUP_MASK (0x3 << 4)
#define AXP_CHGLED_SETUP_OFF (0 << 4)
#define AXP_CHGLED_SETUP_BLINK_FAST (1 << 4)
#define AXP_CHGLED_SETUP_BLINK_SLOW (2 << 4)
#define AXP_CHGLED_SETUP_ON (3 << 4)
#define AXP_POK 0x36
#define AXP_POK_ON_MASK (3 << 6)
#define AXP_POK_ON_128MS (0 << 6)
#define AXP_POK_ON_1S (1 << 6)
#define AXP_POK_ON_2S (2 << 6)
#define AXP_POK_ON_3S (3 << 6)
#define AXP_POK_OFF_MASK (3 << 0)
#define AXP_POK_OFF_4S (0 << 6)
#define AXP_POK_OFF_6S (1 << 6)
#define AXP_POK_OFF_8S (2 << 6)
#define AXP_POK_OFF_10S (3 << 6)
#define AXP_CHARGER_CTRL3 0x35
#define AXP_CHARGER_CTRL3_VBUS_I_MASK 0xf0
#define AXP_CHARGER_CTRL3_VBUS_I_100 0x00
#define AXP_CHARGER_CTRL3_VBUS_I_500 0x10
#define AXP_CHARGER_CTRL3_VBUS_I_900 0x20
#define AXP_CHARGER_CTRL3_VBUS_I_1500 0x30
#define AXP_CHARGER_CTRL3_VBUS_I_2000 0x40
#define AXP_CHARGER_CTRL3_VBUS_I_2500 0x50
#define AXP_CHARGER_CTRL3_VBUS_I_3000 0x60
#define AXP_CHARGER_CTRL3_VBUS_I_3500 0x70
#define AXP_CHARGER_CTRL3_VBUS_I_4000 0x80
#define AXP_AD_BAT_VOLTAGE_MSB8 0x78
#define AXP_AD_BAT_VOLTAGE_LSB4 0x79
#define AXP_AD_BAT_CHG_CURRENT_MSB8 0x7a
#define AXP_AD_BAT_CHG_CURRENT_LSB4 0x7b
#define AXP_AD_BAT_DIS_CURRENT_MSB8 0x7c
#define AXP_AD_BAT_DIS_CURRENT_LSB4 0x7d
#define AXP_BATTERY_CAPACITY 0xb9
int axp_gpio0_enable_ldo_set_voltage(u32 mV);
int axp_is_charging(bool* charging);
int axp_is_vbus_present(bool* vbus);
int axp_is_battery_present(bool* vbus);
int axp_clear_startup_reason(void);
int axp_get_battery_voltage(int* uV);
int axp_get_battery_current(int* uA);
int axp_battery_get_capacity(int* capacity);
int axp_usb_get_max_current(int* mA);
int axp_usb_set_max_current(int mA);
int axp_led_set_charger_controlled(void);
int axp_led_set(bool on);
int axp_pok_set_quick(void);