AXP PMU rewrite (again)

I noticed a few mistakes in the old driver code and it was in
need of an overhaul anyway... I decided to scale things back,
simplify the code and remove most of the debug menus, netting
a nice code size savings.

One new feature is an advanced debug menu which is accessible
by recompiling the code with AXP_EXTRA_DEBUG. It adds quite a
bit of code size and isn't useful other than for development
so it must be manually enabled by editing the source.

Change-Id: I30e17c1194c14823decd726a574ed14451d4cb2d
This commit is contained in:
Aidan MacDonald 2021-12-05 14:30:03 +00:00
parent b774699560
commit 2d89143962
12 changed files with 1354 additions and 900 deletions

View file

@ -23,7 +23,7 @@
#include "button.h"
#include "touchscreen.h"
#include "ft6x06.h"
#include "axp-pmu.h"
#include "axp192.h"
#include "kernel.h"
#include "backlight.h"
#include "powermgmt.h"
@ -57,7 +57,7 @@ static void hp_detect_init(void)
{
/* TODO: replace this copy paste cruft with an API in axp-pmu */
static struct timeout tmo;
static const uint8_t gpio_reg = AXP192_REG_GPIOSTATE1;
static const uint8_t gpio_reg = AXP_REG_GPIOLEVEL1;
static i2c_descriptor desc = {
.slave_addr = AXP_PMU_ADDR,
.bus_cond = I2C_START | I2C_STOP,
@ -72,10 +72,10 @@ static void hp_detect_init(void)
};
/* Headphone detect is wired to AXP192 GPIO: set it to input state */
i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO1FUNCTION, 0x01);
axp_set_gpio_function(1, AXP_GPIO_INPUT);
/* Get an initial reading before startup */
int r = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR, gpio_reg);
int r = axp_read(gpio_reg);
if(r >= 0)
hp_detect_reg = r;

View file

@ -22,7 +22,7 @@
#include "power.h"
#include "adc.h"
#include "system.h"
#include "axp-pmu.h"
#include "axp192.h"
#ifdef HAVE_CW2015
# include "cw2015.h"
#endif
@ -73,24 +73,30 @@ const unsigned short percent_to_volt_charge[11] =
void power_init(void)
{
i2c_x1000_set_freq(AXP_PMU_BUS, I2C_FREQ_400K);
axp_init();
#ifdef HAVE_CW2015
cw2015_init();
#endif
/* Change supply voltage from the default of 1250 mV to 1200 mV,
* this matches the original firmware's settings. Didn't observe
* any obviously bad behavior at 1250 mV, but better to be safe. */
axp_supply_set_voltage(AXP_SUPPLY_DCDC2, 1200);
/* Set DCDC2 to 1.2 V to match OF settings. */
axp_set_supply_voltage(AXP_SUPPLY_DCDC2, 1200);
/* For now, just turn everything on... definitely the touchscreen
* is powered by one of the outputs */
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_PWROUTPUTCTRL1, 0, 0x05, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_PWROUTPUTCTRL2, 0, 0x0f, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL);
/* Power on required supplies */
axp_set_enabled_supplies(
(1 << AXP_SUPPLY_DCDC1) | /* SD bus (3.3 V) */
(1 << AXP_SUPPLY_DCDC2) | /* LCD (1.2 V) */
(1 << AXP_SUPPLY_DCDC3) | /* CPU (1.8 V) */
(1 << AXP_SUPPLY_LDO2) | /* Touchscreen (3.3 V) */
(1 << AXP_SUPPLY_LDO3)); /* not sure (2.5 V) */
/* Enable required ADCs */
axp_set_enabled_adcs(
(1 << AXP_ADC_BATTERY_VOLTAGE) |
(1 << AXP_ADC_CHARGE_CURRENT) |
(1 << AXP_ADC_DISCHARGE_CURRENT) |
(1 << AXP_ADC_VBUS_VOLTAGE) |
(1 << AXP_ADC_VBUS_CURRENT) |
(1 << AXP_ADC_INTERNAL_TEMP) |
(1 << AXP_ADC_APS_VOLTAGE));
/* Delay to give power output time to stabilize */
mdelay(20);
@ -111,23 +117,28 @@ void power_off(void)
bool charging_state(void)
{
return axp_battery_status() == AXP_BATT_CHARGING;
return axp_is_charging();
}
unsigned int power_input_status(void)
{
return axp_power_input_status();
}
int _battery_voltage(void)
{
/* CW2015 can also read battery voltage, but the AXP consistently
* reads ~20-30 mV higher so I suspect it's the "real" voltage. */
return axp_adc_read(ADC_BATTERY_VOLTAGE);
return axp_read_adc(AXP_ADC_BATTERY_VOLTAGE);
}
#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
int _battery_current(void)
{
if(charging_state())
return axp_adc_read(ADC_CHARGE_CURRENT);
return axp_read_adc(AXP_ADC_CHARGE_CURRENT);
else
return axp_adc_read(ADC_DISCHARGE_CURRENT);
return axp_read_adc(AXP_ADC_DISCHARGE_CURRENT);
}
#endif