Files
tactility/Tactility/Source/hal/power/PowerDevice.cpp
T
Ken Van Hoeylandt 50c0a14a93 New kernel drivers and more (#560)
- Added kernel base drivers for: display, pointer (touch, mouse, etc.), keyboard, adc, power supply and backlight
- Implement new kernel driver modules: `st7789-module` and `gt911-module`
- Implement ESP32 ADC "oneshot" kernel driver
- Implement ESP32  backlight kernel driver with ledc API
- Implemented `battery-sense` driver that allows for voltage measurement and creates a power supply child device
- Updated github actions
- Updated flash scripts
- Fix for esp32 legacy driver conflict with ADC
- Created separate `lilygo-tdeck` and `lilygo-tdeck-plus` devices
- Created `lilygo-module` with LilyGO kernel drivers
- Fix for intermittent errors in build related to code generation of `devicetree.c`
- `lvgl-module` can now map kernel drivers onto LVGL devices
- Created `KernelDisplayApp` as a mirror of `HalDisplayApp` (formerly `DisplayApp`)
- Removed `struct` and `enum` prefix in a lot of kernel driver cpp source files
- `lilygo-tdeck` and `lilygo-tdeck-plus` are now fully relying on kernel drivers and don't use any of the old HAL
2026-07-12 00:29:12 +02:00

173 lines
5.5 KiB
C++

// SPDX-License-Identifier: Apache-2.0
#include <Tactility/hal/power/PowerDevice.h>
#include <tactility/check.h>
#include <tactility/device.h>
#include <tactility/driver.h>
#include <tactility/drivers/power_supply.h>
#include <format>
namespace tt::hal::power {
#define GET_POWER_DEVICE(device) (static_cast<PowerDevice*>(device_get_driver_data(device)))
static PowerDevice::MetricType toMetricType(PowerSupplyProperty property) {
switch (property) {
case POWER_SUPPLY_PROP_IS_CHARGING:
return PowerDevice::MetricType::IsCharging;
case POWER_SUPPLY_PROP_CURRENT:
return PowerDevice::MetricType::Current;
case POWER_SUPPLY_PROP_VOLTAGE:
return PowerDevice::MetricType::BatteryVoltage;
case POWER_SUPPLY_PROP_CAPACITY:
default:
return PowerDevice::MetricType::ChargeLevel;
}
}
static int toIntValue(PowerDevice::MetricType type, const PowerDevice::MetricData& data) {
switch (type) {
case PowerDevice::MetricType::IsCharging:
return data.valueAsBool ? 1 : 0;
case PowerDevice::MetricType::Current:
return data.valueAsInt32;
case PowerDevice::MetricType::BatteryVoltage:
return static_cast<int>(data.valueAsUint32);
case PowerDevice::MetricType::ChargeLevel:
default:
return data.valueAsUint8;
}
}
static bool apiSupportsProperty(::Device* device, PowerSupplyProperty property) {
return GET_POWER_DEVICE(device)->supportsMetric(toMetricType(property));
}
static error_t apiGetProperty(::Device* device, PowerSupplyProperty property, PowerSupplyPropertyValue* outValue) {
auto* power_device = GET_POWER_DEVICE(device);
auto metric_type = toMetricType(property);
if (!power_device->supportsMetric(metric_type)) {
return ERROR_NOT_SUPPORTED;
}
PowerDevice::MetricData data;
if (!power_device->getMetric(metric_type, data)) {
return ERROR_NOT_FOUND;
}
outValue->int_value = toIntValue(metric_type, data);
return ERROR_NONE;
}
static bool apiSupportsChargeControl(::Device* device) {
return GET_POWER_DEVICE(device)->supportsChargeControl();
}
static bool apiIsAllowedToCharge(::Device* device) {
return GET_POWER_DEVICE(device)->isAllowedToCharge();
}
static error_t apiSetAllowedToCharge(::Device* device, bool allowed) {
auto* power_device = GET_POWER_DEVICE(device);
if (!power_device->supportsChargeControl()) {
return ERROR_NOT_SUPPORTED;
}
power_device->setAllowedToCharge(allowed);
return ERROR_NONE;
}
static bool apiSupportsQuickCharge(::Device* device) {
return GET_POWER_DEVICE(device)->supportsQuickCharge();
}
static bool apiIsQuickChargeEnabled(::Device* device) {
return GET_POWER_DEVICE(device)->isQuickChargeEnabled();
}
static error_t apiSetQuickChargeEnabled(::Device* device, bool enabled) {
auto* power_device = GET_POWER_DEVICE(device);
if (!power_device->supportsQuickCharge()) {
return ERROR_NOT_SUPPORTED;
}
power_device->setQuickChargeEnabled(enabled);
return ERROR_NONE;
}
static bool apiSupportsPowerOff(::Device* device) {
return GET_POWER_DEVICE(device)->supportsPowerOff();
}
static error_t apiPowerOff(::Device* device) {
auto* power_device = GET_POWER_DEVICE(device);
if (!power_device->supportsPowerOff()) {
return ERROR_NOT_SUPPORTED;
}
power_device->powerOff();
return ERROR_NONE;
}
static error_t startDevice(::Device*) { return ERROR_NONE; }
static error_t stopDevice(::Device*) { return ERROR_NONE; }
static PowerSupplyApi powerSupplyApi {
.supports_property = apiSupportsProperty,
.get_property = apiGetProperty,
.supports_charge_control = apiSupportsChargeControl,
.is_allowed_to_charge = apiIsAllowedToCharge,
.set_allowed_to_charge = apiSetAllowedToCharge,
.supports_quick_charge = apiSupportsQuickCharge,
.is_quick_charge_enabled = apiIsQuickChargeEnabled,
.set_quick_charge_enabled = apiSetQuickChargeEnabled,
.supports_power_off = apiSupportsPowerOff,
.power_off = apiPowerOff,
};
static const char* powerSupplyCompatible[] = { "hal-power-device", nullptr };
static Driver powerSupplyDriver {
.name = "hal-power-device",
.compatible = powerSupplyCompatible,
.start_device = startDevice,
.stop_device = stopDevice,
.api = &powerSupplyApi,
.device_type = &POWER_SUPPLY_TYPE,
.owner = nullptr,
.internal = nullptr,
};
/** Registers the "hal-power-device" driver with the kernel on first use. */
static Driver& getPowerSupplyDriver() {
static const bool registered = [] {
check(driver_construct_add(&powerSupplyDriver) == ERROR_NONE);
return true;
}();
(void)registered;
return powerSupplyDriver;
}
void PowerDevice::createPowerSupplyDevice() {
kernelDeviceName = std::format("power-supply-{}", getId());
kernelDevice.name = kernelDeviceName.c_str();
check(device_construct(&kernelDevice) == ERROR_NONE);
check(device_add(&kernelDevice) == ERROR_NONE);
device_set_driver(&kernelDevice, &getPowerSupplyDriver());
check(device_start(&kernelDevice) == ERROR_NONE);
device_set_driver_data(&kernelDevice, this);
}
void PowerDevice::destroyPowerSupplyDevice() {
device_set_driver_data(&kernelDevice, nullptr);
check(device_stop(&kernelDevice) == ERROR_NONE);
check(device_remove(&kernelDevice) == ERROR_NONE);
check(device_destruct(&kernelDevice) == ERROR_NONE);
}
PowerDevice::PowerDevice() {
createPowerSupplyDevice();
}
PowerDevice::~PowerDevice() {
destroyPowerSupplyDevice();
}
}