1
0
Fork 0

board: power off automatically if battery is low and not charging

optimizations
Martin T. H. Sandsmark 2017-02-10 17:20:17 +01:00
parent 89394643ee
commit d177e67478
2 changed files with 97 additions and 32 deletions

View File

@ -103,6 +103,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define BQ27441_FLAG_LOWCHARGE BIT(2)
#define BQ27441_FLAG_CRITCHARGE BIT(1)
#define SNVS_REG_LPCR 0x20CC038
#define SNVS_MASK_POWEROFF (BIT(5) | BIT(6) | BIT(0))
/* For the BQ24133 charger */
#define BQ24133_CHRGR_OK IMX_GPIO_NR(4, 1)
#define USB_POWER_UP IMX_GPIO_NR(4, 6)
@ -119,7 +122,9 @@ int dram_init(void)
static iomux_v3_cfg_t const charger_pads[] = {
/* CHRGR_OK */
MX6_PAD_KEY_ROW4__GPIO_4_1 | MUX_PAD_CTRL(CHRGSTAT_PAD_CTRL),
};
static iomux_v3_cfg_t const usb_power_up_pads[] = {
/* USB_POWER_UP */
MX6_PAD_KEY_COL7__GPIO_4_6 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
@ -377,6 +382,7 @@ struct i2c_pads_info i2c_pad_info1 = {
.gp = IMX_GPIO_NR(3, 12),
},
};
#undef PC
static void pfuze100_dump(struct pmic *p)
{
@ -417,9 +423,41 @@ static void pfuze100_dump(struct pmic *p)
printf("First SW4 voltage from reg: %x\n", reg);
}
static int check_battery(void)
static void snvs_poweroff(void)
{
int voltage, full_charge, charge, flags, percent;
writel(SNVS_MASK_POWEROFF, SNVS_REG_LPCR);
while (1) {
udelay(500000);
printf("Should have halted!\n");
}
}
int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
snvs_poweroff();
return 0;
}
static int get_battery_charge(void)
{
int ret;
uint8_t message[2];
I2C_SET_BUS(I2C_PMIC);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_PERCENT, 1, message, sizeof(message));
if (ret) {
printf("Failed to read charge from fuel gauge\n");
return -1;
}
return get_unaligned_le16(message);
}
static void battery_dump(void)
{
int voltage, full_charge, charge;
int ret;
uint8_t message[2];
@ -428,34 +466,39 @@ static int check_battery(void)
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_VOLTAGE, 1, message, sizeof(message));
if (ret) {
printf("Failed to read voltage from fuel gauge\n");
return -1;
return;
}
voltage = get_unaligned_le16(message);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_CHARGE, 1, message, sizeof(message));
if (ret) {
printf("Failed to read charge from fuel gauge\n");
return -1;
return;
}
charge = get_unaligned_le16(message);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_FULL_CHARGE, 1, message, sizeof(message));
if (ret) {
printf("Failed to read full charge from fuel gauge\n");
return -1;
return;
}
full_charge = get_unaligned_le16(message);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_PERCENT, 1, message, sizeof(message));
if (ret) {
printf("Failed to read percent charge from fuel gauge\n");
return -1;
}
percent = get_unaligned_le16(message);
printf("Battery full charge: %d mAh\n", full_charge);
printf("Battery charge: %d mAh\n", charge);
printf("Battery voltage: %d mV\n", voltage);
}
static int check_battery(void)
{
int ret, flags;
uint8_t message[2];
I2C_SET_BUS(I2C_PMIC);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_REG_FLAGS, 1, message, sizeof(message));
if (ret) {
printf("Failed to read full charge from fuel gauge\n");
printf("Failed to read flags from fuel gauge\n");
return -1;
}
flags = get_unaligned_le16(message);
@ -463,29 +506,30 @@ static int check_battery(void)
if (flags & BQ27441_FLAG_DISCHARGE) {
printf("Battery discharging\n");
}
if (flags & BQ27441_FLAG_UNDERTEMP) {
printf("Battery undertemp condition detected\n");
printf("Battery undertemp condition detected, powering off\n");
return -1;
}
if (flags & BQ27441_FLAG_OVERTEMP) {
printf("Battery overtemp condition detected\n");
return -1;
}
if (flags & BQ27441_FLAG_FASTCHARGE) {
printf("Battery fastcharge available\n");
}
if (flags & BQ27441_FLAG_FULLCHARGE) {
if (flags & BQ27441_FLAG_CRITCHARGE) {
printf("Battery critically low, powering off\n");
return -1;
} else if (flags & BQ27441_FLAG_LOWCHARGE) {
printf("Battery low charge\n");
} else if (flags & BQ27441_FLAG_FULLCHARGE) {
printf("Battery full charge\n");
}
if (flags & BQ27441_FLAG_LOWCHARGE) {
printf("Battery low charge\n");
}
if (flags & BQ27441_FLAG_CRITCHARGE) {
printf("Battery critically low charge\n");
}
printf("Battery full charge: %d mAh\n", full_charge);
printf("Battery charge: %d mAh\n", charge);
printf("Battery voltage: %d mV\n", voltage);
printf("Battery charge: %d%%\n", percent);
return 0;
}
@ -496,12 +540,14 @@ static int check_charger_status(void)
int cmd_check_battery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
check_battery();
battery_dump();
if (check_charger_status()) {
printf("Charging\n");
} else {
printf("Not charging\n");
}
check_battery();
printf("Battery charge: %d%%\n", get_battery_charge());
return 0;
}
@ -513,9 +559,16 @@ int power_init_board(void)
struct pmic *p;
unsigned int reg;
u32 id;
int ret;
int ret, battery_charge;
unsigned char offset, i, switch_num;
/* Disable the circuitry that automatically
* powers up the board when USB is plugged in */
SETUP_IOMUX_PADS(usb_power_up_pads);
gpio_request(USB_POWER_UP, "usb_power_up");
gpio_direction_output(USB_POWER_UP, 1);
udelay(500000);
/* Set up charger */
SETUP_IOMUX_PADS(charger_pads);
gpio_request(BQ24133_CHRGR_OK, "bq24133_chrgr_ok");
@ -526,6 +579,22 @@ int power_init_board(void)
printf("Not charging\n");
}
while ((battery_charge = get_battery_charge()) < 5) {
if (!check_charger_status()) {
printf("Battery critical, not charging, powering off\n");
snvs_poweroff();
}
printf("Battery low, charging, current charge: %d%%\n", battery_charge);
/* Sleep for one second */
udelay(1000000);
}
if (check_battery() < 0) {
printf("Error when checking battery state, powering off\n");
snvs_poweroff();
}
ret = power_pfuze100_init(I2C_PMIC);
if (ret)
return ret;
@ -608,12 +677,6 @@ int power_init_board(void)
/* Dump some values from registers for debugging */
pfuze100_dump(p);
check_battery();
/* Power is OK, disable the circuitry that automatically
* powers up the board when USB is plugged in */
gpio_request(USB_POWER_UP, "usb_power_up");
gpio_direction_output(USB_POWER_UP, 1);
return ret;
}

View File

@ -21,6 +21,8 @@
#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */
#define CONFIG_CMD_POWEROFF
#define CONFIG_MXC_EPDC
#define CONFIG_WAVEFORM_BUF_SIZE SZ_4M
#define CONFIG_SPLASH_SCREEN