diff --git a/libraries/libstratosphere/include/stratosphere/powctl/powctl_types.hpp b/libraries/libstratosphere/include/stratosphere/powctl/powctl_types.hpp
index ae65dbe13..ebb26ec2c 100644
--- a/libraries/libstratosphere/include/stratosphere/powctl/powctl_types.hpp
+++ b/libraries/libstratosphere/include/stratosphere/powctl/powctl_types.hpp
@@ -33,6 +33,7 @@ namespace ams::powctl {
};
enum ChargeCurrentState {
+ ChargeCurrentState_Unknown = 0x0,
ChargeCurrentState_NotCharging = 0x1,
ChargeCurrentState_ChargingForce20Percent = 0x2,
ChargeCurrentState_Charging = 0x3,
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.cpp
new file mode 100644
index 000000000..2e3b6dd00
--- /dev/null
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
+#include "powctl_battery_driver.hpp"
+
+namespace ams::powctl::impl::board::nintendo_nx {
+
+ /* Generic API. */
+ void BatteryDriver::InitializeDriver() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ void BatteryDriver::FinalizeDriver() {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetDeviceSystemEvent(os::SystemEventType **out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ /* Check that we support event handlers. */
+ R_UNLESS(this->IsEventHandlerEnabled(), powctl::ResultNotAvailable());
+
+ *out = device->SafeCastTo().GetSystemEvent();
+ return ResultSuccess();
+ }
+
+ Result BatteryDriver::SetDeviceInterruptEnabled(IDevice *device, bool enable) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ /* Set the interrupt enable. */
+ device->SafeCastTo().SetInterruptEnabled(enable);
+
+ return ResultSuccess();
+ }
+
+ Result BatteryDriver::GetDeviceErrorStatus(u32 *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetDeviceErrorStatus(IDevice *device, u32 status) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatterySocRep(float *out_percent, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatterySocVf(float *out_percent, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryFullCapacity(int *out_mah, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryRemainingCapacity(int *out_mah, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryPercentageFullThreshold(IDevice *device, float percentage) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryAverageCurrent(int *out_ma, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryCurrent(int *out_ma, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryInternalState(void *dst, size_t *out_size, IDevice *device, size_t dst_size) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryInternalState(IDevice *device, const void *src, size_t src_size) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryNeedToRestoreParameters(bool *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryNeedToRestoreParameters(IDevice *device, bool en) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::IsBatteryI2cShutdownEnabled(bool *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryI2cShutdownEnabled(IDevice *device, bool en) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::IsBatteryPresent(bool *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryCycles(int *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryCycles(IDevice *device, int cycles) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryAge(float *out_percent, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryTemperature(float *out_c, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryMaximumTemperature(float *out_c, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryTemperatureMinimumAlertThreshold(IDevice *device, float c) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryTemperatureMaximumAlertThreshold(IDevice *device, float c) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryVCell(int *out_mv, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryAverageVCell(int *out_mv, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryAverageVCellTime(TimeSpan *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryVoltageMinimumAlertThreshold(IDevice *device, int mv) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::GetBatteryOpenCircuitVoltage(int *out_mv, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result BatteryDriver::SetBatteryVoltageMaximumAlertThreshold(IDevice *device, int mv) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+}
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.hpp
new file mode 100644
index 000000000..6e327cd29
--- /dev/null
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_battery_driver.hpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+#include "../../powctl_i_power_control_driver.hpp"
+#include "powctl_interrupt_event_handler.hpp"
+
+namespace ams::powctl::impl::board::nintendo_nx {
+
+ class BatteryDevice : public powctl::impl::IDevice {
+ NON_COPYABLE(BatteryDevice);
+ NON_MOVEABLE(BatteryDevice);
+ AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo_nx::BatteryDevice, ::ams::powctl::impl::IDevice);
+ private:
+ bool use_event_handler;
+ std::optional event_handler;
+ os::SystemEventType system_event;
+ public:
+ BatteryDevice(bool ev);
+
+ os::SystemEventType *GetSystemEvent() { return std::addressof(this->system_event); }
+
+ void SetInterruptEnabled(bool en) {
+ if (this->use_event_handler) {
+ this->event_handler->SetInterruptEnabled(en);
+ }
+ }
+ };
+
+ class BatteryDriver : public IPowerControlDriver {
+ NON_COPYABLE(BatteryDriver);
+ NON_MOVEABLE(BatteryDriver);
+ AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo_nx::BatteryDriver, ::ams::powctl::impl::IPowerControlDriver);
+ public:
+ BatteryDriver(bool ev) : IPowerControlDriver(ev) { /* ... */ }
+
+ /* Generic API. */
+ virtual void InitializeDriver() override;
+ virtual void FinalizeDriver() override;
+
+ virtual Result GetDeviceSystemEvent(os::SystemEventType **out, IDevice *device) override;
+ virtual Result SetDeviceInterruptEnabled(IDevice *device, bool enable) override;
+
+ virtual Result GetDeviceErrorStatus(u32 *out, IDevice *device) override;
+ virtual Result SetDeviceErrorStatus(IDevice *device, u32 status) override;
+
+ /* Battery API. */
+ virtual Result GetBatterySocRep(float *out_percent, IDevice *device) override;
+
+ virtual Result GetBatterySocVf(float *out_percent, IDevice *device) override;
+
+ virtual Result GetBatteryFullCapacity(int *out_mah, IDevice *device) override;
+ virtual Result GetBatteryRemainingCapacity(int *out_mah, IDevice *device) override;
+
+ virtual Result SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) override;
+ virtual Result SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) override;
+ virtual Result SetBatteryPercentageFullThreshold(IDevice *device, float percentage) override;
+
+ virtual Result GetBatteryAverageCurrent(int *out_ma, IDevice *device) override;
+ virtual Result GetBatteryCurrent(int *out_ma, IDevice *device) override;
+
+ virtual Result GetBatteryInternalState(void *dst, size_t *out_size, IDevice *device, size_t dst_size) override;
+ virtual Result SetBatteryInternalState(IDevice *device, const void *src, size_t src_size) override;
+
+ virtual Result GetBatteryNeedToRestoreParameters(bool *out, IDevice *device) override;
+ virtual Result SetBatteryNeedToRestoreParameters(IDevice *device, bool en) override;
+
+ virtual Result IsBatteryI2cShutdownEnabled(bool *out, IDevice *device) override;
+ virtual Result SetBatteryI2cShutdownEnabled(IDevice *device, bool en) override;
+
+ virtual Result IsBatteryPresent(bool *out, IDevice *device) override;
+
+ virtual Result GetBatteryCycles(int *out, IDevice *device) override;
+ virtual Result SetBatteryCycles(IDevice *device, int cycles) override;
+
+ virtual Result GetBatteryAge(float *out_percent, IDevice *device) override;
+
+ virtual Result GetBatteryTemperature(float *out_c, IDevice *device) override;
+ virtual Result GetBatteryMaximumTemperature(float *out_c, IDevice *device) override;
+
+ virtual Result SetBatteryTemperatureMinimumAlertThreshold(IDevice *device, float c) override;
+ virtual Result SetBatteryTemperatureMaximumAlertThreshold(IDevice *device, float c) override;
+
+ virtual Result GetBatteryVCell(int *out_mv, IDevice *device) override;
+ virtual Result GetBatteryAverageVCell(int *out_mv, IDevice *device) override;
+
+ virtual Result GetBatteryAverageVCellTime(TimeSpan *out, IDevice *device) override;
+
+ virtual Result SetBatteryVoltageMinimumAlertThreshold(IDevice *device, int mv) override;
+
+ virtual Result GetBatteryOpenCircuitVoltage(int *out_mv, IDevice *device) override;
+
+ virtual Result SetBatteryVoltageMaximumAlertThreshold(IDevice *device, int mv) override;
+
+ /* Unsupported Charger API. */
+ virtual Result GetChargerChargeCurrentState(ChargeCurrentState *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerChargeCurrentState(IDevice *device, ChargeCurrentState state) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerFastChargeCurrentLimit(int *out_ma, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerFastChargeCurrentLimit(IDevice *device, int ma) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerChargeVoltageLimit(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerChargeVoltageLimit(IDevice *device, int mv) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetChargerChargerConfiguration(IDevice *device, ChargerConfiguration cfg) override { return powctl::ResultNotSupported(); }
+
+ virtual Result IsChargerHiZEnabled(bool *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerHiZEnabled(IDevice *device, bool en) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerInputCurrentLimit(int *out_ma, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerInputCurrentLimit(IDevice *device, int ma) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerInputVoltageLimit(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerInputVoltageLimit(IDevice *device, int mv) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerChargerStatus(ChargerStatus *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result IsChargerWatchdogTimerEnabled(bool *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerWatchdogTimerEnabled(IDevice *device, bool en) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetChargerWatchdogTimerTimeout(IDevice *device, TimeSpan timeout) override { return powctl::ResultNotSupported(); }
+ virtual Result ResetChargerWatchdogTimer(IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerBatteryCompensation(int *out_mo, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerBatteryCompensation(IDevice *device, int mo) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetChargerVoltageClamp(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetChargerVoltageClamp(IDevice *device, int mv) override { return powctl::ResultNotSupported(); }
+ };
+
+}
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_board_impl.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_board_impl.cpp
index 0339ca6d9..4c8114312 100644
--- a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_board_impl.cpp
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_board_impl.cpp
@@ -14,13 +14,39 @@
* along with this program. If not, see .
*/
#include
+#include "../../powctl_device_management.hpp"
#include "powctl_board_impl.hpp"
+#include "powctl_battery_driver.hpp"
+#include "powctl_charger_driver.hpp"
namespace ams::powctl::impl::board::nintendo_nx {
+ namespace {
+
+ constinit std::optional g_charger_driver;
+ constinit std::optional g_battery_driver;
+
+ void InitializeChargerDriver(bool use_event_handlers) {
+ /* Create the charger driver. */
+ g_charger_driver.emplace(use_event_handlers);
+
+ /* Register the driver. */
+ powctl::impl::RegisterDriver(std::addressof(*g_charger_driver));
+ }
+
+ void InitializeBatteryDriver(bool use_event_handlers) {
+ /* Create the battery driver. */
+ g_battery_driver.emplace(use_event_handlers);
+
+ /* Register the driver. */
+ powctl::impl::RegisterDriver(std::addressof(*g_battery_driver));
+ }
+
+ }
+
void Initialize(bool use_event_handlers) {
- /* TODO */
- AMS_ABORT();
+ InitializeChargerDriver(use_event_handlers);
+ InitializeBatteryDriver(use_event_handlers);
}
void Finalize() {
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp
new file mode 100644
index 000000000..655a4de46
--- /dev/null
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_bq24193_driver.hpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+
+namespace ams::powctl::impl::board::nintendo_nx {
+
+ namespace bq24193 {
+
+ enum ChargerConfiguration {
+ ChargerConfiguration_ChargeDisable = 0,
+ ChargerConfiguration_ChargeBattery = 1,
+ ChargerConfiguration_Otg = 2,
+ };
+
+ enum ChargerStatus {
+ ChargerStatus_NotCharging = 0,
+ ChargerStatus_PreCharge = 1,
+ ChargerStatus_FastCharging = 2,
+ ChargerStatus_ChargeTerminationDone = 3,
+ };
+
+ }
+
+ class Bq24193Driver {
+ private:
+ os::SdkMutex mutex;
+ int init_count;
+ i2c::I2cSession i2c_session;
+ private:
+ Result InitializeSession();
+ public:
+ Bq24193Driver() : mutex(), init_count(0), i2c_session() {
+ /* ... */
+ }
+
+ void Initialize() {
+ std::scoped_lock lk(this->mutex);
+ R_ABORT_UNLESS(this->InitializeSession());
+ }
+
+ Result GetForce20PercentChargeCurrent(bool *out);
+ Result SetForce20PercentChargeCurrent(bool en);
+
+ Result GetFastChargeCurrentLimit(int *out_ma);
+ Result SetFastChargeCurrentLimit(int ma);
+
+ Result GetChargeVoltageLimit(int *out_mv);
+ Result SetChargeVoltageLimit(int mv);
+
+ Result SetChargerConfiguration(bq24193::ChargerConfiguration cfg);
+
+ Result IsHiZEnabled(bool *out);
+ Result SetHiZEnabled(bool en);
+
+ Result GetInputCurrentLimit(int *out_ma);
+ Result SetInputCurrentLimit(int ma);
+
+ Result GetInputVoltageLimit(int *out_mv);
+ Result SetInputVoltageLimit(int mv);
+
+ Result GetChargerStatus(bq24193::ChargerStatus *out);
+
+ Result ResetWatchdogTimer();
+ Result SetWatchdogTimerSetting(int seconds);
+
+ Result GetBatteryCompensation(int *out_mo);
+ Result SetBatteryCompensation(int mo);
+
+ Result GetVoltageClamp(int *out_mv);
+ Result SetVoltageClamp(int mv);
+ };
+
+}
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp
new file mode 100644
index 000000000..71ddd59b1
--- /dev/null
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.cpp
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
+#include "../../powctl_device_management.hpp"
+#include "powctl_retry_helper.hpp"
+#include "powctl_charger_driver.hpp"
+#include "powctl_bq24193_driver.hpp"
+
+namespace ams::powctl::impl::board::nintendo_nx {
+
+ namespace {
+
+ constinit std::optional g_charger_device;
+
+ Bq24193Driver &GetBq24193Driver() {
+ static Bq24193Driver s_bq24193_driver;
+ return s_bq24193_driver;
+ }
+
+ }
+
+ /* Generic API. */
+ void ChargerDriver::InitializeDriver() {
+ /* Initialize Bq24193Driver */
+ GetBq24193Driver().Initialize();
+
+ /* Initialize gpio library. */
+ gpio::Initialize();
+
+ /* Create charger device. */
+ g_charger_device.emplace(this->IsEventHandlerEnabled());
+
+ /* Open the device's gpio session. */
+ R_ABORT_UNLESS(gpio::OpenSession(g_charger_device->GetPadSession(), gpio::DeviceCode_BattChgEnableN));
+
+ /* Configure the gpio session as output. */
+ gpio::SetDirection(g_charger_device->GetPadSession(), gpio::Direction_Output);
+
+ /* Register our device. */
+ this->RegisterDevice(std::addressof(*g_charger_device));
+
+ /* Register the charger device's code. */
+ R_ABORT_UNLESS(powctl::impl::RegisterDeviceCode(powctl::DeviceCode_Bq24193, std::addressof(*g_charger_device)));
+ }
+
+ void ChargerDriver::FinalizeDriver() {
+ /* Unregister the charger device code. */
+ powctl::impl::UnregisterDeviceCode(powctl::DeviceCode_Bq24193);
+
+ /* Unregister our device. */
+ this->UnregisterDevice(std::addressof(*g_charger_device));
+
+ /* Close the device's gpio session. */
+ gpio::CloseSession(g_charger_device->GetPadSession());
+
+ /* Destroy the charger device. */
+ g_charger_device = std::nullopt;
+ }
+
+ Result ChargerDriver::GetDeviceSystemEvent(os::SystemEventType **out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ /* Check that we support event handlers. */
+ R_UNLESS(this->IsEventHandlerEnabled(), powctl::ResultNotAvailable());
+
+ *out = device->SafeCastTo().GetSystemEvent();
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetDeviceInterruptEnabled(IDevice *device, bool enable) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ /* Set the interrupt enable. */
+ device->SafeCastTo().SetInterruptEnabled(enable);
+
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetDeviceErrorStatus(u32 *out, IDevice *device) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ Result ChargerDriver::SetDeviceErrorStatus(IDevice *device, u32 status) {
+ /* TODO */
+ AMS_ABORT();
+ }
+
+ /* Charger API. */
+ Result ChargerDriver::GetChargerChargeCurrentState(ChargeCurrentState *out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ /* Check if we're not charging. */
+ if (gpio::GetValue(device->SafeCastTo().GetPadSession()) == gpio::GpioValue_High) {
+ *out = ChargeCurrentState_NotCharging;
+ } else {
+ /* Get force 20 percent charge state. */
+ bool force_20_percent;
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetForce20PercentChargeCurrent(std::addressof(force_20_percent)));
+
+ /* Set output appropriately. */
+ if (force_20_percent) {
+ *out = ChargeCurrentState_ChargingForce20Percent;
+ } else {
+ *out = ChargeCurrentState_Charging;
+ }
+ }
+
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerChargeCurrentState(IDevice *device, ChargeCurrentState state) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ switch (state) {
+ case ChargeCurrentState_NotCharging:
+ gpio::SetValue(device->SafeCastTo().GetPadSession(), gpio::GpioValue_High);
+ break;
+ case ChargeCurrentState_ChargingForce20Percent:
+ case ChargeCurrentState_Charging:
+ gpio::SetValue(device->SafeCastTo().GetPadSession(), gpio::GpioValue_Low);
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetForce20PercentChargeCurrent(state == ChargeCurrentState_ChargingForce20Percent));
+ break;
+ case ChargeCurrentState_Unknown:
+ return powctl::ResultInvalidArgument();
+ }
+
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerFastChargeCurrentLimit(int *out_ma, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_ma != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetFastChargeCurrentLimit(out_ma));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerFastChargeCurrentLimit(IDevice *device, int ma) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetFastChargeCurrentLimit(ma));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerChargeVoltageLimit(int *out_mv, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_mv != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargeVoltageLimit(out_mv));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerChargeVoltageLimit(IDevice *device, int mv) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargeVoltageLimit(mv));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerChargerConfiguration(IDevice *device, ChargerConfiguration cfg) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ bq24193::ChargerConfiguration bq_cfg;
+ switch (cfg) {
+ case ChargerConfiguration_ChargeDisable: bq_cfg = bq24193::ChargerConfiguration_ChargeDisable; break;
+ case ChargerConfiguration_ChargeBattery: bq_cfg = bq24193::ChargerConfiguration_ChargeBattery; break;
+ case ChargerConfiguration_Otg: bq_cfg = bq24193::ChargerConfiguration_Otg; break;
+ AMS_UNREACHABLE_DEFAULT_CASE();
+ }
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargerConfiguration(bq_cfg));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::IsChargerHiZEnabled(bool *out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().IsHiZEnabled(out));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerHiZEnabled(IDevice *device, bool en) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetHiZEnabled(en));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerInputCurrentLimit(int *out_ma, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_ma != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetInputCurrentLimit(out_ma));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerInputCurrentLimit(IDevice *device, int ma) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputCurrentLimit(ma));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerInputVoltageLimit(int *out_mv, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_mv != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetInputVoltageLimit(out_mv));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerInputVoltageLimit(IDevice *device, int mv) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputVoltageLimit(mv));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerChargerStatus(ChargerStatus *out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ bq24193::ChargerStatus bq_status;
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargerStatus(std::addressof(bq_status)));
+
+ switch (bq_status) {
+ case bq24193::ChargerStatus_NotCharging:
+ *out = ChargerStatus_NotCharging;
+ break;
+ case bq24193::ChargerStatus_PreCharge:
+ case bq24193::ChargerStatus_FastCharging:
+ *out = ChargerStatus_Charging;
+ break;
+ case bq24193::ChargerStatus_ChargeTerminationDone:
+ *out = ChargerStatus_ChargeTerminationDone;
+ break;
+ AMS_UNREACHABLE_DEFAULT_CASE();
+ }
+
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::IsChargerWatchdogTimerEnabled(bool *out, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ *out = device->SafeCastTo().IsWatchdogTimerEnabled();
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerWatchdogTimerEnabled(IDevice *device, bool en) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ auto &charger_device = device->SafeCastTo();
+
+ if (en) {
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().ResetWatchdogTimer());
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetWatchdogTimerSetting(charger_device.GetWatchdogTimerTimeout().GetSeconds()));
+ } else {
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetWatchdogTimerSetting(0));
+ }
+
+ charger_device.SetWatchdogTimerEnabled(en);
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerWatchdogTimerTimeout(IDevice *device, TimeSpan timeout) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ device->SafeCastTo().SetWatchdogTimerTimeout(timeout);
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::ResetChargerWatchdogTimer(IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().ResetWatchdogTimer());
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerBatteryCompensation(int *out_mo, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_mo != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetBatteryCompensation(out_mo));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerBatteryCompensation(IDevice *device, int mo) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetBatteryCompensation(mo));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::GetChargerVoltageClamp(int *out_mv, IDevice *device) {
+ /* Validate arguments. */
+ R_UNLESS(out_mv != nullptr, powctl::ResultInvalidArgument());
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetVoltageClamp(out_mv));
+ return ResultSuccess();
+ }
+
+ Result ChargerDriver::SetChargerVoltageClamp(IDevice *device, int mv) {
+ /* Validate arguments. */
+ R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
+
+ AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetVoltageClamp(mv));
+ return ResultSuccess();
+ }
+
+}
\ No newline at end of file
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.hpp
new file mode 100644
index 000000000..69a4814f0
--- /dev/null
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_charger_driver.hpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+#include
+#include "../../powctl_i_power_control_driver.hpp"
+#include "powctl_interrupt_event_handler.hpp"
+
+namespace ams::powctl::impl::board::nintendo_nx {
+
+ class ChargerDevice : public powctl::impl::IDevice {
+ NON_COPYABLE(ChargerDevice);
+ NON_MOVEABLE(ChargerDevice);
+ AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo_nx::ChargerDevice, ::ams::powctl::impl::IDevice);
+ private:
+ gpio::GpioPadSession gpio_pad_session;
+ bool watchdog_timer_enabled;
+ TimeSpan watchdog_timer_timeout;
+ bool use_event_handler;
+ std::optional event_handler;
+ os::SystemEventType system_event;
+ public:
+ ChargerDevice(bool ev);
+
+ bool IsWatchdogTimerEnabled() const { return this->watchdog_timer_enabled; }
+ void SetWatchdogTimerEnabled(bool en) { this->watchdog_timer_enabled = en; }
+
+ TimeSpan GetWatchdogTimerTimeout() const { return this->watchdog_timer_timeout; }
+ void SetWatchdogTimerTimeout(TimeSpan ts) { this->watchdog_timer_timeout = ts; }
+
+ gpio::GpioPadSession *GetPadSession() { return std::addressof(this->gpio_pad_session); }
+
+ os::SystemEventType *GetSystemEvent() { return std::addressof(this->system_event); }
+
+ void SetInterruptEnabled(bool en) {
+ if (this->use_event_handler) {
+ this->event_handler->SetInterruptEnabled(en);
+ }
+ }
+ };
+
+ class ChargerDriver : public IPowerControlDriver {
+ NON_COPYABLE(ChargerDriver);
+ NON_MOVEABLE(ChargerDriver);
+ AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::board::nintendo_nx::ChargerDriver, ::ams::powctl::impl::IPowerControlDriver);
+ public:
+ ChargerDriver(bool ev) : IPowerControlDriver(ev) { /* ... */ }
+
+ /* Generic API. */
+ virtual void InitializeDriver() override;
+ virtual void FinalizeDriver() override;
+
+ virtual Result GetDeviceSystemEvent(os::SystemEventType **out, IDevice *device) override;
+ virtual Result SetDeviceInterruptEnabled(IDevice *device, bool enable) override;
+
+ virtual Result GetDeviceErrorStatus(u32 *out, IDevice *device) override;
+ virtual Result SetDeviceErrorStatus(IDevice *device, u32 status) override;
+
+ /* Charger API. */
+ virtual Result GetChargerChargeCurrentState(ChargeCurrentState *out, IDevice *device) override;
+ virtual Result SetChargerChargeCurrentState(IDevice *device, ChargeCurrentState state) override;
+
+ virtual Result GetChargerFastChargeCurrentLimit(int *out_ma, IDevice *device) override;
+ virtual Result SetChargerFastChargeCurrentLimit(IDevice *device, int ma) override;
+
+ virtual Result GetChargerChargeVoltageLimit(int *out_mv, IDevice *device) override;
+ virtual Result SetChargerChargeVoltageLimit(IDevice *device, int mv) override;
+
+ virtual Result SetChargerChargerConfiguration(IDevice *device, ChargerConfiguration cfg) override;
+
+ virtual Result IsChargerHiZEnabled(bool *out, IDevice *device) override;
+ virtual Result SetChargerHiZEnabled(IDevice *device, bool en) override;
+
+ virtual Result GetChargerInputCurrentLimit(int *out_ma, IDevice *device) override;
+ virtual Result SetChargerInputCurrentLimit(IDevice *device, int ma) override;
+
+ virtual Result GetChargerInputVoltageLimit(int *out_mv, IDevice *device) override;
+ virtual Result SetChargerInputVoltageLimit(IDevice *device, int mv) override;
+
+ virtual Result GetChargerChargerStatus(ChargerStatus *out, IDevice *device) override;
+
+ virtual Result IsChargerWatchdogTimerEnabled(bool *out, IDevice *device) override;
+ virtual Result SetChargerWatchdogTimerEnabled(IDevice *device, bool en) override;
+
+ virtual Result SetChargerWatchdogTimerTimeout(IDevice *device, TimeSpan timeout) override;
+ virtual Result ResetChargerWatchdogTimer(IDevice *device) override;
+
+ virtual Result GetChargerBatteryCompensation(int *out_mo, IDevice *device) override;
+ virtual Result SetChargerBatteryCompensation(IDevice *device, int mo) override;
+
+ virtual Result GetChargerVoltageClamp(int *out_mv, IDevice *device) override;
+ virtual Result SetChargerVoltageClamp(IDevice *device, int mv) override;
+
+ /* Unsupported Battery API. */
+ virtual Result GetBatterySocRep(float *out_percent, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatterySocVf(float *out_percent, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryFullCapacity(int *out_mah, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result GetBatteryRemainingCapacity(int *out_mah, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryPercentageFullThreshold(IDevice *device, float percentage) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryAverageCurrent(int *out_ma, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result GetBatteryCurrent(int *out_ma, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryInternalState(void *dst, size_t *out_size, IDevice *device, size_t dst_size) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryInternalState(IDevice *device, const void *src, size_t src_size) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryNeedToRestoreParameters(bool *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryNeedToRestoreParameters(IDevice *device, bool en) override { return powctl::ResultNotSupported(); }
+
+ virtual Result IsBatteryI2cShutdownEnabled(bool *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryI2cShutdownEnabled(IDevice *device, bool en) override { return powctl::ResultNotSupported(); }
+
+ virtual Result IsBatteryPresent(bool *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryCycles(int *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryCycles(IDevice *device, int cycles) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryAge(float *out_percent, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryTemperature(float *out_c, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result GetBatteryMaximumTemperature(float *out_c, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetBatteryTemperatureMinimumAlertThreshold(IDevice *device, float c) override { return powctl::ResultNotSupported(); }
+ virtual Result SetBatteryTemperatureMaximumAlertThreshold(IDevice *device, float c) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryVCell(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+ virtual Result GetBatteryAverageVCell(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryAverageVCellTime(TimeSpan *out, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetBatteryVoltageMinimumAlertThreshold(IDevice *device, int mv) override { return powctl::ResultNotSupported(); }
+
+ virtual Result GetBatteryOpenCircuitVoltage(int *out_mv, IDevice *device) override { return powctl::ResultNotSupported(); }
+
+ virtual Result SetBatteryVoltageMaximumAlertThreshold(IDevice *device, int mv) override { return powctl::ResultNotSupported(); }
+ };
+
+}
diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp
index 331c6465e..17c83bb9a 100644
--- a/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp
+++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo_nx/powctl_interrupt_event_handler.hpp
@@ -39,6 +39,12 @@ namespace ams::powctl::impl::board::nintendo_nx {
return std::addressof(this->gpio_system_event);
}
+ void SetInterruptEnabled(bool en) {
+ std::scoped_lock lk(this->mutex);
+
+ gpio::SetInterruptEnable(std::addressof(this->gpio_session), en);
+ }
+
virtual void HandleEvent() override final {
/* Acquire exclusive access to ourselves. */
std::scoped_lock lk(this->mutex);
@@ -50,7 +56,7 @@ namespace ams::powctl::impl::board::nintendo_nx {
os::ClearSystemEvent(std::addressof(this->gpio_system_event));
/* Signal the event. */
- Derived::SignalEvent(this->device);
+ static_cast(this)->SignalEvent(this->device);
}
};
diff --git a/libraries/libstratosphere/source/powctl/impl/powctl_i_power_control_driver.hpp b/libraries/libstratosphere/source/powctl/impl/powctl_i_power_control_driver.hpp
index fc4e1ee55..030443e44 100644
--- a/libraries/libstratosphere/source/powctl/impl/powctl_i_power_control_driver.hpp
+++ b/libraries/libstratosphere/source/powctl/impl/powctl_i_power_control_driver.hpp
@@ -44,7 +44,7 @@ namespace ams::powctl::impl {
virtual void InitializeDriver() = 0;
virtual void FinalizeDriver() = 0;
- virtual Result GetDeviceSystemEvent(IDevice *device) = 0;
+ virtual Result GetDeviceSystemEvent(os::SystemEventType **out, IDevice *device) = 0;
virtual Result SetDeviceInterruptEnabled(IDevice *device, bool enable) = 0;
/* TODO: Eventually implement proper error status enum? */