1
0
Fork 0

zero-gravitas: set the BATLOWEN bit if not set when booting

optimizations
Martin T. H. Sandsmark 2017-07-31 15:20:23 +02:00
parent 3dc970231a
commit b703b09a7c
2 changed files with 91 additions and 2 deletions

View File

@ -105,6 +105,17 @@ DECLARE_GLOBAL_DATA_PTR;
#define BQ27441_FLAG_LOWCHARGE BIT(2)
#define BQ27441_FLAG_CRITCHARGE BIT(1)
#define BQ27441_FLAGS 0x06
#define BQ27441_OPCONFIG_1 0x40
#define BQ27441_OPCONFIG_2 0x41
#define BQ27441_OPCBATLOWEN_MASK 0x04
#define BQ27441_CONTROL_1 0x00
#define BQ27441_CONTROL_2 0x01
#define BQ27441_BLOCK_DATA_CHECKSUM 0x60
#define BQ27441_BLOCK_DATA_CONTROL 0x61
#define BQ27441_DATA_BLOCK_CLASS 0x3E
#define BQ27441_DATA_BLOCK 0x3F
#define SNVS_REG_LPCR 0x20CC038
#define SNVS_MASK_POWEROFF (BIT(5) | BIT(6) | BIT(0))
@ -445,6 +456,82 @@ int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
/**
* Set the BATLOWEN bit, to make sure the BQ27441 GPIO only triggers on battery
* low, not on every change in charge percentage.
*/
static void set_fuelgauge_gpio_behavior(void)
{
int ret, checksum, temporary;
uint16_t opconfig;
int tries;
I2C_SET_BUS(I2C_PMIC);
/* Unseal the fuel gauge for data access */
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_1, 0x00);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_2, 0x80);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_1, 0x00);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_2, 0x80);
/* setup fuel gauge state data block block for ram access */
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_BLOCK_DATA_CONTROL, 0x00);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_DATA_BLOCK_CLASS, 0x40);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_DATA_BLOCK, 0x00);
mdelay(1);
ret = i2c_read(BQ27441_I2C_ADDR, BQ27441_OPCONFIG_1, 1, &opconfig, sizeof(opconfig));
if (ret) {
printf("Failed to read opconfig from fuel gauge\n");
return;
}
if (be16_to_cpu(opconfig) & BQ27441_OPCBATLOWEN_MASK) {
printf("BQ27441_OPCBATLOWEN_MASK already set\n");
return;
}
/* read check sum */
checksum = i2c_reg_read(BQ27441_I2C_ADDR, BQ27441_BLOCK_DATA_CHECKSUM);
/* place the fuel gauge into config update */
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_1, 0x13);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_2, 0x00);
tries = 0;
while (!(i2c_reg_read(BQ27441_I2C_ADDR, BQ27441_FLAGS) & 0x10)) {
udelay(1000); /* sleep 1ms */
if (tries > 10) {
printf("Timeout while waiting for config update\n");
return;
}
tries++;
}
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_OPCONFIG_2,
((opconfig >> 8) | BQ27441_OPCBATLOWEN_MASK));
temporary = (255 - checksum
- (opconfig & 0xFF)
- ((opconfig >> 8) & 0xFF)) % 256;
checksum = 255 - ((temporary
+ (opconfig & 0xFF)
+ ((opconfig >> 8) |
BQ27441_OPCBATLOWEN_MASK)) % 256);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_BLOCK_DATA_CHECKSUM, checksum);
/* seal the fuel gauge before exit */
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_1, 0x20);
i2c_reg_write(BQ27441_I2C_ADDR, BQ27441_CONTROL_2, 0x00);
printf("Set fuel gauge behavior\n");
}
/*
* The percentage calculated by the fuel gauge isn't always very correct,
* so calculate it manually as well to be sure.
@ -633,6 +720,8 @@ int power_init_board(void)
snvs_poweroff();
}
set_fuelgauge_gpio_behavior();
wait_for_battery_charge(BATTERY_LEVEL_CRITICAL);
ret = power_pfuze100_init(I2C_PMIC);

View File

@ -75,7 +75,7 @@
"bootlimit=1\0" \
"por=undefined\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} " \
"systemd.crash_reboot=true " \
"systemd.crash_reboot=true memtest " \
"root=/dev/mmcblk1p${active_partition} rootwait rw por=${por};\0" \
"loadimage=ext4load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \
"loadfdt=ext4load mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
@ -107,7 +107,7 @@
"setenv mmcpart ${fallback_partition}; " \
"setenv bootargs console=${console},${baudrate} " \
"root=/dev/mmcblk1p${fallback_partition} rootwait rw " \
"systemd.log_level=debug systemd.log_target=kmsg " \
"systemd.log_level=debug systemd.log_target=kmsg memtest " \
"log_buf_len=1M printk.devkmsg systemd.journald.forward_to_console=1; " \
"run mmcboot;\0" \