Device migrations and driver improvements (#576)

This commit is contained in:
Ken Van Hoeylandt
2026-07-22 21:11:12 +02:00
committed by GitHub
parent 2fbc44466a
commit a3fda9ad8f
100 changed files with 707 additions and 3838 deletions
@@ -3,3 +3,64 @@ description: X-Powers AXP192 power management IC
include: ["i2c-device.yaml"]
compatible: "x-powers,axp192"
properties:
dcdc1-voltage:
type: int
default: 0
description: DCDC1 rail voltage in mV (700-3500). 0 leaves the voltage untouched.
dcdc1-enable:
type: boolean
default: false
description: >
Enable the DCDC1 rail. Unconditionally applied like any other boolean devicetree property -
false actively disables it, so a board whose SoC is powered from DCDC1 must set this.
dcdc2-voltage:
type: int
default: 0
description: DCDC2 rail voltage in mV (700-2275). 0 leaves the voltage untouched.
dcdc2-enable:
type: boolean
default: false
description: Enable the DCDC2 rail. See dcdc1-enable for why false actively disables it.
dcdc3-voltage:
type: int
default: 0
description: DCDC3 rail voltage in mV (700-3500). 0 leaves the voltage untouched.
dcdc3-enable:
type: boolean
default: false
description: Enable the DCDC3 rail. See dcdc1-enable for why false actively disables it.
ldo2-voltage:
type: int
default: 0
description: LDO2 rail voltage in mV (1800-3300). 0 leaves the voltage untouched.
ldo2-enable:
type: boolean
default: false
description: Enable the LDO2 rail. See dcdc1-enable for why false actively disables it.
ldo3-voltage:
type: int
default: 0
description: LDO3 rail voltage in mV (1800-3300). 0 leaves the voltage untouched.
ldo3-enable:
type: boolean
default: false
description: Enable the LDO3 rail. See dcdc1-enable for why false actively disables it.
exten-enable:
type: boolean
default: false
description: >
Enable the EXTEN output switch. No voltage control (see AXP192_RAIL_EXTEN); see
dcdc1-enable for why false actively disables it.
gpio1-pwm:
type: boolean
default: false
description: Configure GPIO1 as the PWM1 output instead of GPIO/ADC input/output.
gpio1-pwm1-duty-cycle:
type: int
default: 0
min: 0
max: 255
description: >
PWM1 duty cycle (0 = always low, 255 = always high). Only applied when gpio1-pwm is set.
@@ -15,6 +15,32 @@ extern "C" {
struct Axp192Config {
/** Address on bus */
uint8_t address;
/**
* Rail voltage/enable settings, applied once at driver start (see axp192_set_rail_voltage()/
* axp192_set_rail_enabled()). Each "enable" flag is unconditionally applied - false (the yaml
* default) actively disables the rail, same as every other boolean devicetree property in
* this codebase (e.g. reset-active-high, swap-xy: absence means false, not "leave alone").
* A board must explicitly set every rail it needs kept on, including ones a board's hardware
* happens to power up with by default (e.g. DCDC1, which is the SoC's own supply on some
* boards) - see m5stack-core2's devicetree for a worked example. Voltage of 0 means "don't
* call axp192_set_rail_voltage() for this rail" (0mV is outside every rail's valid range).
*/
uint16_t dcdc1_voltage_mv;
bool dcdc1_enable;
uint16_t dcdc2_voltage_mv;
bool dcdc2_enable;
uint16_t dcdc3_voltage_mv;
bool dcdc3_enable;
uint16_t ldo2_voltage_mv;
bool ldo2_enable;
uint16_t ldo3_voltage_mv;
bool ldo3_enable;
/** EXTEN has no voltage control (see AXP192_RAIL_EXTEN), hence no exten_voltage_mv field. */
bool exten_enable;
/** Configures GPIO1 as the PWM1 output (see axp192_set_gpio1_pwm1_output()). */
bool gpio1_pwm;
/** Applied only when gpio1_pwm is true (see axp192_set_pwm1_duty_cycle()). */
uint8_t gpio1_pwm1_duty_cycle;
};
/** Switchable/adjustable power rails of the AXP192. */
+64
View File
@@ -12,6 +12,7 @@
#include <new>
#define GET_CONFIG(device) (static_cast<const Axp192Config*>((device)->config))
constexpr auto* TAG = "AXP192";
/** Reference: https://github.com/tuupola/axp192 (register map and ADC/voltage formulas) */
static constexpr uint8_t REG_MODE_CHGSTATUS = 0x01U; // bit6: battery is charging
@@ -404,10 +405,73 @@ static void destroy_power_supply_child(Device* child) {
// endregion
// region Devicetree-configured bring-up
static error_t apply_rail_config(Device* device, Axp192Rail rail, uint16_t voltage_mv, bool enable) {
if (voltage_mv != 0U) {
error_t error = axp192_set_rail_voltage(device, rail, voltage_mv);
if (error != ERROR_NONE) {
return error;
}
}
return axp192_set_rail_enabled(device, rail, enable);
}
// Applies the devicetree's rail voltage/enable and GPIO1 PWM settings, replacing what boards
// (e.g. m5stack-core2) used to do by hand via a device_listener after DEVICE_EVENT_STARTED.
static error_t apply_devicetree_config(Device* device) {
const auto* config = GET_CONFIG(device);
error_t error = apply_rail_config(device, AXP192_RAIL_DCDC1, config->dcdc1_voltage_mv, config->dcdc1_enable);
if (error != ERROR_NONE) {
return error;
}
error = apply_rail_config(device, AXP192_RAIL_DCDC2, config->dcdc2_voltage_mv, config->dcdc2_enable);
if (error != ERROR_NONE) {
return error;
}
error = apply_rail_config(device, AXP192_RAIL_DCDC3, config->dcdc3_voltage_mv, config->dcdc3_enable);
if (error != ERROR_NONE) {
return error;
}
error = apply_rail_config(device, AXP192_RAIL_LDO2, config->ldo2_voltage_mv, config->ldo2_enable);
if (error != ERROR_NONE) {
return error;
}
error = apply_rail_config(device, AXP192_RAIL_LDO3, config->ldo3_voltage_mv, config->ldo3_enable);
if (error != ERROR_NONE) {
return error;
}
error = axp192_set_rail_enabled(device, AXP192_RAIL_EXTEN, config->exten_enable);
if (error != ERROR_NONE) {
return error;
}
if (config->gpio1_pwm) {
error = axp192_set_pwm1_duty_cycle(device, config->gpio1_pwm1_duty_cycle);
if (error != ERROR_NONE) {
return error;
}
error = axp192_set_gpio1_pwm1_output(device);
if (error != ERROR_NONE) {
return error;
}
}
return ERROR_NONE;
}
// endregion
static error_t start(Device* device) {
auto* parent = device_get_parent(device);
check(device_get_type(parent) == &I2C_CONTROLLER_TYPE);
if (apply_devicetree_config(device) != ERROR_NONE) {
LOG_E(TAG, "Failed to apply devicetree-configured rail/GPIO1 settings");
return ERROR_RESOURCE;
}
auto* internal = new(std::nothrow) Axp192Internal();
if (internal == nullptr) {
return ERROR_OUT_OF_MEMORY;