mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-03 11:11:14 +00:00
powctl: add ChargerDriver body (needs impl)
This commit is contained in:
parent
d9350d24a9
commit
5bd02f128d
9 changed files with 983 additions and 4 deletions
|
@ -33,6 +33,7 @@ namespace ams::powctl {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ChargeCurrentState {
|
enum ChargeCurrentState {
|
||||||
|
ChargeCurrentState_Unknown = 0x0,
|
||||||
ChargeCurrentState_NotCharging = 0x1,
|
ChargeCurrentState_NotCharging = 0x1,
|
||||||
ChargeCurrentState_ChargingForce20Percent = 0x2,
|
ChargeCurrentState_ChargingForce20Percent = 0x2,
|
||||||
ChargeCurrentState_Charging = 0x3,
|
ChargeCurrentState_Charging = 0x3,
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#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<BatteryDevice>().GetSystemEvent();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result BatteryDriver::SetDeviceInterruptEnabled(IDevice *device, bool enable) {
|
||||||
|
/* Validate arguments. */
|
||||||
|
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||||
|
|
||||||
|
/* Set the interrupt enable. */
|
||||||
|
device->SafeCastTo<BatteryDevice>().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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#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<BatteryInterruptEventHandler> 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(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -14,13 +14,39 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include "../../powctl_device_management.hpp"
|
||||||
#include "powctl_board_impl.hpp"
|
#include "powctl_board_impl.hpp"
|
||||||
|
#include "powctl_battery_driver.hpp"
|
||||||
|
#include "powctl_charger_driver.hpp"
|
||||||
|
|
||||||
namespace ams::powctl::impl::board::nintendo_nx {
|
namespace ams::powctl::impl::board::nintendo_nx {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constinit std::optional<ChargerDriver> g_charger_driver;
|
||||||
|
constinit std::optional<BatteryDriver> 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) {
|
void Initialize(bool use_event_handlers) {
|
||||||
/* TODO */
|
InitializeChargerDriver(use_event_handlers);
|
||||||
AMS_ABORT();
|
InitializeBatteryDriver(use_event_handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finalize() {
|
void Finalize() {
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#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<ChargerDevice> 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<ChargerDevice>().GetSystemEvent();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ChargerDriver::SetDeviceInterruptEnabled(IDevice *device, bool enable) {
|
||||||
|
/* Validate arguments. */
|
||||||
|
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||||
|
|
||||||
|
/* Set the interrupt enable. */
|
||||||
|
device->SafeCastTo<ChargerDevice>().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<ChargerDevice>().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<ChargerDevice>().GetPadSession(), gpio::GpioValue_High);
|
||||||
|
break;
|
||||||
|
case ChargeCurrentState_ChargingForce20Percent:
|
||||||
|
case ChargeCurrentState_Charging:
|
||||||
|
gpio::SetValue(device->SafeCastTo<ChargerDevice>().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<ChargerDevice>().IsWatchdogTimerEnabled();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ChargerDriver::SetChargerWatchdogTimerEnabled(IDevice *device, bool en) {
|
||||||
|
/* Validate arguments. */
|
||||||
|
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||||
|
|
||||||
|
auto &charger_device = device->SafeCastTo<ChargerDevice>();
|
||||||
|
|
||||||
|
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<ChargerDevice>().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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#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<ChargerInterruptEventHandler> 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(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -39,6 +39,12 @@ namespace ams::powctl::impl::board::nintendo_nx {
|
||||||
return std::addressof(this->gpio_system_event);
|
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 {
|
virtual void HandleEvent() override final {
|
||||||
/* Acquire exclusive access to ourselves. */
|
/* Acquire exclusive access to ourselves. */
|
||||||
std::scoped_lock lk(this->mutex);
|
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));
|
os::ClearSystemEvent(std::addressof(this->gpio_system_event));
|
||||||
|
|
||||||
/* Signal the event. */
|
/* Signal the event. */
|
||||||
Derived::SignalEvent(this->device);
|
static_cast<Derived *>(this)->SignalEvent(this->device);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace ams::powctl::impl {
|
||||||
virtual void InitializeDriver() = 0;
|
virtual void InitializeDriver() = 0;
|
||||||
virtual void FinalizeDriver() = 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;
|
virtual Result SetDeviceInterruptEnabled(IDevice *device, bool enable) = 0;
|
||||||
|
|
||||||
/* TODO: Eventually implement proper error status enum? */
|
/* TODO: Eventually implement proper error status enum? */
|
||||||
|
|
Loading…
Reference in a new issue