mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
powctl: integrate 13.0.0 changes (aula params not done yet)
This commit is contained in:
parent
c04a262d49
commit
990daec3a2
16 changed files with 241 additions and 154 deletions
|
@ -21,16 +21,20 @@
|
|||
namespace ams::powctl {
|
||||
|
||||
/* Battery API. */
|
||||
Result GetBatterySocRep(float *out_percent, Session &session);
|
||||
Result GetBatteryChargePercentage(float *out_percent, Session &session);
|
||||
|
||||
Result GetBatterySocVf(float *out_percent, Session &session);
|
||||
Result GetBatteryVoltageFuelGaugePercentage(float *out_percent, Session &session);
|
||||
|
||||
Result GetBatteryFullCapacity(int *out_mah, Session &session);
|
||||
Result GetBatteryRemainingCapacity(int *out_mah, Session &session);
|
||||
|
||||
Result SetBatteryPercentageMinimumAlertThreshold(Session &session, float percentage);
|
||||
Result SetBatteryPercentageMaximumAlertThreshold(Session &session, float percentage);
|
||||
Result SetBatteryPercentageFullThreshold(Session &session, float percentage);
|
||||
Result SetBatteryChargePercentageMinimumAlertThreshold(Session &session, float percentage);
|
||||
Result SetBatteryChargePercentageMaximumAlertThreshold(Session &session, float percentage);
|
||||
|
||||
Result SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(Session &session, float percentage);
|
||||
Result SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(Session &session, float percentage);
|
||||
|
||||
Result SetBatteryFullChargeThreshold(Session &session, float percentage);
|
||||
|
||||
Result GetBatteryAverageCurrent(int *out_ma, Session &session);
|
||||
Result GetBatteryCurrent(int *out_ma, Session &session);
|
||||
|
|
|
@ -37,6 +37,10 @@ namespace ams::powctl {
|
|||
bool has_session;
|
||||
util::TypedStorage<impl::SessionImpl> impl_storage;
|
||||
|
||||
struct ConstantInitializeTag{};
|
||||
|
||||
constexpr Session(ConstantInitializeTag) : has_session(false), impl_storage() { /* ... */ }
|
||||
|
||||
Session() : has_session(false) { /* ... */ }
|
||||
};
|
||||
|
||||
|
|
|
@ -25,21 +25,10 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
constinit util::optional<BatteryDevice> g_battery_device;
|
||||
|
||||
constinit util::TypedStorage<Max17050Driver> g_max17050_driver;
|
||||
constinit bool g_constructed_max17050_driver;
|
||||
constinit os::SdkMutex g_max17050_driver_mutex;
|
||||
constinit Max17050Driver g_max17050_driver;
|
||||
|
||||
Max17050Driver &GetMax17050Driver() {
|
||||
if (AMS_UNLIKELY(!g_constructed_max17050_driver)) {
|
||||
std::scoped_lock lk(g_max17050_driver_mutex);
|
||||
|
||||
if (AMS_LIKELY(!g_constructed_max17050_driver)) {
|
||||
util::ConstructAt(g_max17050_driver);
|
||||
g_constructed_max17050_driver = true;
|
||||
}
|
||||
}
|
||||
|
||||
return util::GetReference(g_max17050_driver);
|
||||
ALWAYS_INLINE Max17050Driver &GetMax17050Driver() {
|
||||
return g_max17050_driver;
|
||||
}
|
||||
|
||||
constexpr inline const double SenseResistorValue = 0.005;
|
||||
|
@ -143,28 +132,28 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
AMS_ABORT();
|
||||
}
|
||||
|
||||
Result BatteryDriver::GetBatterySocRep(float *out_percent, IDevice *device) {
|
||||
Result BatteryDriver::GetBatteryChargePercentage(float *out_percent, IDevice *device) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(out_percent != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
double percent;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetSocRep(std::addressof(percent)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetChargePercentage(std::addressof(percent)));
|
||||
|
||||
/* Set output. */
|
||||
*out_percent = percent;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::GetBatterySocVf(float *out_percent, IDevice *device) {
|
||||
Result BatteryDriver::GetBatteryVoltageFuelGaugePercentage(float *out_percent, IDevice *device) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(out_percent != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
double percent;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetSocVf(std::addressof(percent)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetVoltageFuelGaugePercentage(std::addressof(percent)));
|
||||
|
||||
/* Set output. */
|
||||
*out_percent = percent;
|
||||
|
@ -178,7 +167,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double mah;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetFullCapacity(std::addressof(mah), SenseResistorValue));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetFullCapacity(std::addressof(mah), SenseResistorValue));
|
||||
|
||||
/* Set output. */
|
||||
*out_mah = mah;
|
||||
|
@ -192,36 +181,54 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double mah;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetRemainingCapacity(std::addressof(mah), SenseResistorValue));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetRemainingCapacity(std::addressof(mah), SenseResistorValue));
|
||||
|
||||
/* Set output. */
|
||||
*out_mah = mah;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) {
|
||||
Result BatteryDriver::SetBatteryChargePercentageMinimumAlertThreshold(IDevice *device, float percentage) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetPercentageMinimumAlertThreshold(percentage));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetChargePercentageMinimumAlertThreshold(percentage));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) {
|
||||
Result BatteryDriver::SetBatteryChargePercentageMaximumAlertThreshold(IDevice *device, float percentage) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetPercentageMaximumAlertThreshold(percentage));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetChargePercentageMaximumAlertThreshold(percentage));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::SetBatteryPercentageFullThreshold(IDevice *device, float percentage) {
|
||||
Result BatteryDriver::SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(IDevice *device, float percentage) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetPercentageFullThreshold(percentage));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageFuelGaugePercentageMinimumAlertThreshold(percentage));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(IDevice *device, float percentage) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageFuelGaugePercentageMaximumAlertThreshold(percentage));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result BatteryDriver::SetBatteryFullChargeThreshold(IDevice *device, float percentage) {
|
||||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetFullChargeThreshold(percentage));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -233,7 +240,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double ma;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageCurrent(std::addressof(ma), SenseResistorValue));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageCurrent(std::addressof(ma), SenseResistorValue));
|
||||
|
||||
/* Set output. */
|
||||
*out_ma = ma;
|
||||
|
@ -247,7 +254,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double ma;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetCurrent(std::addressof(ma), SenseResistorValue));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetCurrent(std::addressof(ma), SenseResistorValue));
|
||||
|
||||
/* Set output. */
|
||||
*out_ma = ma;
|
||||
|
@ -262,7 +269,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(dst_size == sizeof(max17050::InternalState), powctl::ResultInvalidArgument());
|
||||
R_UNLESS(util::IsAligned(reinterpret_cast<uintptr_t>(dst), alignof(max17050::InternalState)), powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().ReadInternalState());
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().ReadInternalState());
|
||||
GetMax17050Driver().GetInternalState(static_cast<max17050::InternalState *>(dst));
|
||||
|
||||
return ResultSuccess();
|
||||
|
@ -276,7 +283,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(util::IsAligned(reinterpret_cast<uintptr_t>(src), alignof(max17050::InternalState)), powctl::ResultInvalidArgument());
|
||||
|
||||
GetMax17050Driver().SetInternalState(*static_cast<const max17050::InternalState *>(src));
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().WriteInternalState());
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().WriteInternalState());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -287,7 +294,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetNeedToRestoreParameters(out));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetNeedToRestoreParameters(out));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -297,7 +304,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Set the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetNeedToRestoreParameters(en));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetNeedToRestoreParameters(en));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -308,7 +315,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().IsI2cShutdownEnabled(out));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().IsI2cShutdownEnabled(out));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -318,7 +325,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Set the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetI2cShutdownEnabled(en));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetI2cShutdownEnabled(en));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -330,7 +337,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the battery status. */
|
||||
u16 status;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetStatus(std::addressof(status)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetStatus(std::addressof(status)));
|
||||
|
||||
/* Set output. */
|
||||
*out = (status & 0x0008) == 0;
|
||||
|
@ -344,7 +351,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the battery cycles. */
|
||||
u16 cycles;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetCycles(std::addressof(cycles)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetCycles(std::addressof(cycles)));
|
||||
|
||||
/* Set output. */
|
||||
*out = cycles;
|
||||
|
@ -355,7 +362,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(cycles == 0, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().ResetCycles());
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().ResetCycles());
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -367,7 +374,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double percent;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetAge(std::addressof(percent)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetAge(std::addressof(percent)));
|
||||
|
||||
/* Set output. */
|
||||
*out_percent = percent;
|
||||
|
@ -381,7 +388,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double temp;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetTemperature(std::addressof(temp)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetTemperature(std::addressof(temp)));
|
||||
|
||||
/* Set output. */
|
||||
*out_c = temp;
|
||||
|
@ -395,7 +402,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
u8 max_temp;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetMaximumTemperature(std::addressof(max_temp)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetMaximumTemperature(std::addressof(max_temp)));
|
||||
|
||||
/* Set output. */
|
||||
*out_c = static_cast<float>(max_temp);
|
||||
|
@ -406,7 +413,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetTemperatureMinimumAlertThreshold(c));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetTemperatureMinimumAlertThreshold(c));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -415,7 +422,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetTemperatureMaximumAlertThreshold(c));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetTemperatureMaximumAlertThreshold(c));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -426,7 +433,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetVCell(out_mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetVCell(out_mv));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -437,7 +444,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageVCell(out_mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageVCell(out_mv));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -449,7 +456,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
/* Get the value. */
|
||||
double ms;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageVCellTime(std::addressof(ms)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetAverageVCellTime(std::addressof(ms)));
|
||||
|
||||
/* Set output. */
|
||||
*out = TimeSpan::FromMicroSeconds(static_cast<s64>(ms * 1000.0));
|
||||
|
@ -460,7 +467,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageMinimumAlertThreshold(mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageMinimumAlertThreshold(mv));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -471,7 +478,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* Get the value. */
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().GetOpenCircuitVoltage(out_mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().GetOpenCircuitVoltage(out_mv));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -480,7 +487,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageMaximumAlertThreshold(mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetMax17050Driver().SetVoltageMaximumAlertThreshold(mv));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
|
|
@ -58,16 +58,19 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
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 GetBatteryChargePercentage(float *out_percent, IDevice *device) override;
|
||||
virtual Result GetBatteryVoltageFuelGaugePercentage(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 SetBatteryChargePercentageMinimumAlertThreshold(IDevice *device, float percentage) override;
|
||||
virtual Result SetBatteryChargePercentageMaximumAlertThreshold(IDevice *device, float percentage) override;
|
||||
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(IDevice *device, float percentage) override;
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(IDevice *device, float percentage) override;
|
||||
|
||||
virtual Result SetBatteryFullChargeThreshold(IDevice *device, float percentage) override;
|
||||
|
||||
virtual Result GetBatteryAverageCurrent(int *out_ma, IDevice *device) override;
|
||||
virtual Result GetBatteryCurrent(int *out_ma, IDevice *device) override;
|
||||
|
|
|
@ -84,8 +84,9 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
constexpr int DecodeChargeVoltageLimit(u8 reg) {
|
||||
constexpr int Minimum = 3504;
|
||||
constexpr int Maximum = 4400;
|
||||
|
||||
return Minimum + (static_cast<u32>(reg & 0xFC) << 2);
|
||||
return std::min<int>(Maximum, Minimum + (static_cast<u32>(reg & 0xFC) << 2));
|
||||
}
|
||||
|
||||
static_assert(DecodeChargeVoltageLimit(EncodeChargeVoltageLimit(3504)) == 3504);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
private:
|
||||
Result InitializeSession();
|
||||
public:
|
||||
Bq24193Driver() : m_mutex(), m_init_count(0), m_i2c_session() {
|
||||
constexpr Bq24193Driver() : m_mutex(), m_init_count(0), m_i2c_session() {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
|
|
|
@ -25,21 +25,10 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
|
||||
constinit util::optional<ChargerDevice> g_charger_device;
|
||||
|
||||
constinit util::TypedStorage<Bq24193Driver> g_bq24193_driver;
|
||||
constinit bool g_constructed_bq24193_driver;
|
||||
constinit os::SdkMutex g_bq24193_driver_mutex;
|
||||
constinit Bq24193Driver g_bq24193_driver;
|
||||
|
||||
Bq24193Driver &GetBq24193Driver() {
|
||||
if (AMS_UNLIKELY(!g_constructed_bq24193_driver)) {
|
||||
std::scoped_lock lk(g_bq24193_driver_mutex);
|
||||
|
||||
if (AMS_LIKELY(!g_constructed_bq24193_driver)) {
|
||||
util::ConstructAt(g_bq24193_driver);
|
||||
g_constructed_bq24193_driver = true;
|
||||
}
|
||||
}
|
||||
|
||||
return util::GetReference(g_bq24193_driver);
|
||||
ALWAYS_INLINE Bq24193Driver &GetBq24193Driver() {
|
||||
return g_bq24193_driver;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -141,13 +130,15 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
/* NOTE: Nintendo doesn't hold the mutex while doing the gpio:: call here, for some reason. */
|
||||
|
||||
/* 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)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetForce20PercentChargeCurrent(std::addressof(force_20_percent)));
|
||||
|
||||
/* Set output appropriately. */
|
||||
if (force_20_percent) {
|
||||
|
@ -164,6 +155,8 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
std::scoped_lock lk(this->GetMutex());
|
||||
|
||||
switch (state) {
|
||||
case ChargeCurrentState_NotCharging:
|
||||
gpio::SetValue(device->SafeCastTo<ChargerDevice>().GetPadSession(), gpio::GpioValue_High);
|
||||
|
@ -171,7 +164,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
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));
|
||||
AMS_POWCTL_DRIVER_R_TRY_WITH_RETRY(GetBq24193Driver().SetForce20PercentChargeCurrent(state == ChargeCurrentState_ChargingForce20Percent));
|
||||
break;
|
||||
case ChargeCurrentState_Unknown:
|
||||
return powctl::ResultInvalidArgument();
|
||||
|
@ -185,7 +178,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out_ma != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetFastChargeCurrentLimit(out_ma));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetFastChargeCurrentLimit(out_ma));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -193,7 +186,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetFastChargeCurrentLimit(ma));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetFastChargeCurrentLimit(ma));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -202,7 +195,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out_mv != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargeVoltageLimit(out_mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargeVoltageLimit(out_mv));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -210,7 +203,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargeVoltageLimit(mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargeVoltageLimit(mv));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -226,7 +219,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargerConfiguration(bq_cfg));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetChargerConfiguration(bq_cfg));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -235,7 +228,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().IsHiZEnabled(out));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().IsHiZEnabled(out));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -243,7 +236,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetHiZEnabled(en));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetHiZEnabled(en));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -252,7 +245,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out_ma != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetInputCurrentLimit(out_ma));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetInputCurrentLimit(out_ma));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -260,7 +253,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputCurrentLimit(ma));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputCurrentLimit(ma));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -268,7 +261,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputVoltageLimit(mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetInputVoltageLimit(mv));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -276,7 +269,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetBoostModeCurrentLimit(ma));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetBoostModeCurrentLimit(ma));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -285,7 +278,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
bq24193::ChargerStatus bq_status;
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargerStatus(std::addressof(bq_status)));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetChargerStatus(std::addressof(bq_status)));
|
||||
|
||||
switch (bq_status) {
|
||||
case bq24193::ChargerStatus_NotCharging:
|
||||
|
@ -320,10 +313,11 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
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()));
|
||||
std::scoped_lock lk(this->GetMutex());
|
||||
AMS_POWCTL_DRIVER_R_TRY_WITH_RETRY(GetBq24193Driver().ResetWatchdogTimer());
|
||||
AMS_POWCTL_DRIVER_R_TRY_WITH_RETRY(GetBq24193Driver().SetWatchdogTimerSetting(charger_device.GetWatchdogTimerTimeout().GetSeconds()));
|
||||
} else {
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetWatchdogTimerSetting(0));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetWatchdogTimerSetting(0));
|
||||
}
|
||||
|
||||
charger_device.SetWatchdogTimerEnabled(en);
|
||||
|
@ -342,7 +336,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().ResetWatchdogTimer());
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().ResetWatchdogTimer());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -351,7 +345,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out_mo != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetBatteryCompensation(out_mo));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetBatteryCompensation(out_mo));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -359,7 +353,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetBatteryCompensation(mo));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetBatteryCompensation(mo));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -368,7 +362,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
R_UNLESS(out_mv != nullptr, powctl::ResultInvalidArgument());
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().GetVoltageClamp(out_mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().GetVoltageClamp(out_mv));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -376,7 +370,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
/* Validate arguments. */
|
||||
R_UNLESS(device != nullptr, powctl::ResultInvalidArgument());
|
||||
|
||||
AMS_POWCTL_R_TRY_WITH_RETRY(GetBq24193Driver().SetVoltageClamp(mv));
|
||||
AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(GetBq24193Driver().SetVoltageClamp(mv));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
|
|
@ -105,16 +105,20 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
virtual Result SetChargerVoltageClamp(IDevice *device, int mv) override;
|
||||
|
||||
/* Unsupported Battery API. */
|
||||
virtual Result GetBatterySocRep(float *out_percent, IDevice *device) override { AMS_UNUSED(out_percent, device); return powctl::ResultNotSupported(); }
|
||||
virtual Result GetBatteryChargePercentage(float *out_percent, IDevice *device) override { AMS_UNUSED(out_percent, device); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result GetBatterySocVf(float *out_percent, IDevice *device) override { AMS_UNUSED(out_percent, device); return powctl::ResultNotSupported(); }
|
||||
virtual Result GetBatteryVoltageFuelGaugePercentage(float *out_percent, IDevice *device) override { AMS_UNUSED(out_percent, device); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result GetBatteryFullCapacity(int *out_mah, IDevice *device) override { AMS_UNUSED(out_mah, device); return powctl::ResultNotSupported(); }
|
||||
virtual Result GetBatteryRemainingCapacity(int *out_mah, IDevice *device) override { AMS_UNUSED(out_mah, device); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
virtual Result SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
virtual Result SetBatteryPercentageFullThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
virtual Result SetBatteryChargePercentageMinimumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
virtual Result SetBatteryChargePercentageMaximumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result SetBatteryFullChargeThreshold(IDevice *device, float percentage) override { AMS_UNUSED(device, percentage); return powctl::ResultNotSupported(); }
|
||||
|
||||
virtual Result GetBatteryAverageCurrent(int *out_ma, IDevice *device) override { AMS_UNUSED(out_ma, device); return powctl::ResultNotSupported(); }
|
||||
virtual Result GetBatteryCurrent(int *out_ma, IDevice *device) override { AMS_UNUSED(out_ma, device); return powctl::ResultNotSupported(); }
|
||||
|
|
|
@ -330,11 +330,11 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
u16 vfsoc, qh;
|
||||
{
|
||||
R_TRY(ReadRegister(m_i2c_session, max17050::SocVf, std::addressof(vfsoc)));
|
||||
R_TRY(this->UnlockVfSoc());
|
||||
R_TRY(this->UnlockVoltageFuelGauge());
|
||||
while (!WriteValidateRegister(m_i2c_session, max17050::SocVf0, vfsoc)) { /* ... */ }
|
||||
R_TRY(ReadRegister(m_i2c_session, max17050::Qh, std::addressof(qh)));
|
||||
R_TRY(WriteRegister(m_i2c_session, max17050::Qh0, qh));
|
||||
R_TRY(this->LockVfSoc());
|
||||
R_TRY(this->LockVoltageFuelGauge());
|
||||
}
|
||||
|
||||
/* Reset cycles. */
|
||||
|
@ -371,6 +371,14 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
return WriteRegister(m_i2c_session, max17050::ShdnTimer, 0xE000);
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetAlertByChargePercentage() {
|
||||
return ReadWriteRegister(m_i2c_session, max17050::MiscCfg, 0x0003, 0x0000);
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetAlertByVoltageFuelGaugePercentage() {
|
||||
return ReadWriteRegister(m_i2c_session, max17050::MiscCfg, 0x0003, 0x0003);
|
||||
}
|
||||
|
||||
bool Max17050Driver::IsPowerOnReset() {
|
||||
/* Get the register. */
|
||||
u16 val;
|
||||
|
@ -380,11 +388,11 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
return (val & 0x0002) != 0;
|
||||
}
|
||||
|
||||
Result Max17050Driver::LockVfSoc() {
|
||||
Result Max17050Driver::LockVoltageFuelGauge() {
|
||||
return WriteRegister(m_i2c_session, max17050::SocVfAccess, 0x0000);
|
||||
}
|
||||
|
||||
Result Max17050Driver::UnlockVfSoc() {
|
||||
Result Max17050Driver::UnlockVoltageFuelGauge() {
|
||||
return WriteRegister(m_i2c_session, max17050::SocVfAccess, 0x0080);
|
||||
}
|
||||
|
||||
|
@ -479,7 +487,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Max17050Driver::GetSocRep(double *out) {
|
||||
Result Max17050Driver::GetChargePercentage(double *out) {
|
||||
/* Validate parameters. */
|
||||
AMS_ABORT_UNLESS(out != nullptr);
|
||||
|
||||
|
@ -492,7 +500,7 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Max17050Driver::GetSocVf(double *out) {
|
||||
Result Max17050Driver::GetVoltageFuelGaugePercentage(double *out) {
|
||||
/* Validate parameters. */
|
||||
AMS_ABORT_UNLESS(out != nullptr);
|
||||
|
||||
|
@ -535,15 +543,27 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetPercentageMinimumAlertThreshold(int percentage) {
|
||||
Result Max17050Driver::SetChargePercentageMinimumAlertThreshold(int percentage) {
|
||||
R_TRY(this->SetAlertByChargePercentage());
|
||||
return ReadWriteRegister(m_i2c_session, max17050::SocAlrtThreshold, 0x00FF, static_cast<u8>(percentage));
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetPercentageMaximumAlertThreshold(int percentage) {
|
||||
Result Max17050Driver::SetChargePercentageMaximumAlertThreshold(int percentage) {
|
||||
R_TRY(this->SetAlertByChargePercentage());
|
||||
return ReadWriteRegister(m_i2c_session, max17050::SocAlrtThreshold, 0xFF00, static_cast<u16>(static_cast<u8>(percentage)) << 8);
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetPercentageFullThreshold(double percentage) {
|
||||
Result Max17050Driver::SetVoltageFuelGaugePercentageMinimumAlertThreshold(int percentage) {
|
||||
R_TRY(this->SetAlertByVoltageFuelGaugePercentage());
|
||||
return ReadWriteRegister(m_i2c_session, max17050::SocAlrtThreshold, 0x00FF, static_cast<u8>(percentage));
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetVoltageFuelGaugePercentageMaximumAlertThreshold(int percentage) {
|
||||
R_TRY(this->SetAlertByVoltageFuelGaugePercentage());
|
||||
return ReadWriteRegister(m_i2c_session, max17050::SocAlrtThreshold, 0xFF00, static_cast<u16>(static_cast<u8>(percentage)) << 8);
|
||||
}
|
||||
|
||||
Result Max17050Driver::SetFullChargeThreshold(double percentage) {
|
||||
#if defined(ATMOSPHERE_ARCH_ARM64)
|
||||
const u16 val = vcvtd_n_s64_f64(percentage, BITSIZEOF(u8));
|
||||
#else
|
||||
|
|
|
@ -45,16 +45,19 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
Result InitializeSession(const char *battery_vendor, u8 battery_version);
|
||||
Result SetMaximumShutdownTimerThreshold();
|
||||
|
||||
Result SetAlertByChargePercentage();
|
||||
Result SetAlertByVoltageFuelGaugePercentage();
|
||||
|
||||
bool IsPowerOnReset();
|
||||
Result LockVfSoc();
|
||||
Result UnlockVfSoc();
|
||||
Result LockVoltageFuelGauge();
|
||||
Result UnlockVoltageFuelGauge();
|
||||
Result LockModelTable();
|
||||
Result UnlockModelTable();
|
||||
bool IsModelTableLocked();
|
||||
Result SetModelTable(const u16 *model_table);
|
||||
bool IsModelTableSet(const u16 *model_table);
|
||||
public:
|
||||
Max17050Driver() : m_mutex(), m_init_count(0), m_i2c_session(), m_internal_state() {
|
||||
constexpr Max17050Driver() : m_mutex(), m_init_count(0), m_i2c_session(), m_internal_state() {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
|
@ -97,16 +100,19 @@ namespace ams::powctl::impl::board::nintendo::nx {
|
|||
m_internal_state = src;
|
||||
}
|
||||
|
||||
Result GetSocRep(double *out);
|
||||
Result GetSocVf(double *out);
|
||||
Result GetChargePercentage(double *out);
|
||||
Result GetVoltageFuelGaugePercentage(double *out);
|
||||
|
||||
Result GetFullCapacity(double *out, double sense_resistor);
|
||||
Result GetRemainingCapacity(double *out, double sense_resistor);
|
||||
|
||||
Result SetPercentageMinimumAlertThreshold(int percentage);
|
||||
Result SetPercentageMaximumAlertThreshold(int percentage);
|
||||
Result SetChargePercentageMinimumAlertThreshold(int percentage);
|
||||
Result SetChargePercentageMaximumAlertThreshold(int percentage);
|
||||
|
||||
Result SetPercentageFullThreshold(double percentage);
|
||||
Result SetVoltageFuelGaugePercentageMinimumAlertThreshold(int percentage);
|
||||
Result SetVoltageFuelGaugePercentageMaximumAlertThreshold(int percentage);
|
||||
|
||||
Result SetFullChargeThreshold(double percentage);
|
||||
|
||||
Result GetAverageCurrent(double *out, double sense_resistor);
|
||||
Result GetCurrent(double *out, double sense_resistor);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ams::powctl::impl {
|
|||
constexpr inline const TimeSpan PowerControlRetryTimeout = TimeSpan::FromSeconds(10);
|
||||
constexpr inline const TimeSpan PowerControlRetryInterval = TimeSpan::FromMilliSeconds(20);
|
||||
|
||||
#define AMS_POWCTL_R_TRY_WITH_RETRY(__EXPR__) \
|
||||
#define AMS_POWCTL_DRIVER_R_TRY_WITH_RETRY(__EXPR__) \
|
||||
({ \
|
||||
TimeSpan __powctl_retry_current_time = 0; \
|
||||
while (true) { \
|
||||
|
@ -37,5 +37,6 @@ namespace ams::powctl::impl {
|
|||
} \
|
||||
})
|
||||
|
||||
#define AMS_POWCTL_DRIVER_LOCKED_R_TRY_WITH_RETRY(__EXPR__) AMS_POWCTL_DRIVER_R_TRY_WITH_RETRY( ({ std::scoped_lock lk(this->GetMutex()); ( __EXPR__ ); }) )
|
||||
|
||||
}
|
||||
|
|
|
@ -33,12 +33,17 @@ namespace ams::powctl::impl {
|
|||
AMS_DDSF_CASTABLE_TRAITS(ams::powctl::impl::IPowerControlDriver, ::ams::ddsf::IDriver);
|
||||
private:
|
||||
bool m_event_handler_enabled;
|
||||
os::SdkMutex m_mutex;
|
||||
protected:
|
||||
constexpr bool IsEventHandlerEnabled() const {
|
||||
return m_event_handler_enabled;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE os::SdkMutex &GetMutex() {
|
||||
return m_mutex;
|
||||
}
|
||||
public:
|
||||
IPowerControlDriver(bool ev) : IDriver(), m_event_handler_enabled(ev) { /* ... */ }
|
||||
IPowerControlDriver(bool ev) : IDriver(), m_event_handler_enabled(ev), m_mutex() { /* ... */ }
|
||||
virtual ~IPowerControlDriver() { /* ... */ }
|
||||
|
||||
virtual void InitializeDriver() = 0;
|
||||
|
@ -51,16 +56,19 @@ namespace ams::powctl::impl {
|
|||
virtual Result GetDeviceErrorStatus(u32 *out, IDevice *device) = 0;
|
||||
virtual Result SetDeviceErrorStatus(IDevice *device, u32 status) = 0;
|
||||
|
||||
virtual Result GetBatterySocRep(float *out_percent, IDevice *device) = 0;
|
||||
virtual Result GetBatteryChargePercentage(float *out_percent, IDevice *device) = 0;
|
||||
|
||||
virtual Result GetBatterySocVf(float *out_percent, IDevice *device) = 0;
|
||||
virtual Result GetBatteryVoltageFuelGaugePercentage(float *out_percent, IDevice *device) = 0;
|
||||
|
||||
virtual Result GetBatteryFullCapacity(int *out_mah, IDevice *device) = 0;
|
||||
virtual Result GetBatteryRemainingCapacity(int *out_mah, IDevice *device) = 0;
|
||||
|
||||
virtual Result SetBatteryPercentageMinimumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryPercentageMaximumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryPercentageFullThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryChargePercentageMinimumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryChargePercentageMaximumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
virtual Result SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(IDevice *device, float percentage) = 0;
|
||||
|
||||
virtual Result SetBatteryFullChargeThreshold(IDevice *device, float percentage) = 0;
|
||||
|
||||
virtual Result GetChargerChargeCurrentState(ChargeCurrentState *out, IDevice *device) = 0;
|
||||
virtual Result SetChargerChargeCurrentState(IDevice *device, ChargeCurrentState state) = 0;
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ams::powctl {
|
|||
|
||||
}
|
||||
|
||||
Result GetBatterySocRep(float *out_percent, Session &session) {
|
||||
Result GetBatteryChargePercentage(float *out_percent, Session &session) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
|
@ -41,10 +41,10 @@ namespace ams::powctl {
|
|||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().GetBatterySocRep(out_percent, std::addressof(device));
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().GetBatteryChargePercentage(out_percent, std::addressof(device));
|
||||
}
|
||||
|
||||
Result GetBatterySocVf(float *out_percent, Session &session) {
|
||||
Result GetBatteryVoltageFuelGaugePercentage(float *out_percent, Session &session) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
|
@ -55,7 +55,7 @@ namespace ams::powctl {
|
|||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().GetBatterySocVf(out_percent, std::addressof(device));
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().GetBatteryVoltageFuelGaugePercentage(out_percent, std::addressof(device));
|
||||
}
|
||||
|
||||
Result GetBatteryFullCapacity(int *out_mah, Session &session) {
|
||||
|
@ -86,7 +86,7 @@ namespace ams::powctl {
|
|||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().GetBatteryRemainingCapacity(out_mah, std::addressof(device));
|
||||
}
|
||||
|
||||
Result SetBatteryPercentageMinimumAlertThreshold(Session &session, float percentage) {
|
||||
Result SetBatteryChargePercentageMinimumAlertThreshold(Session &session, float percentage) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
|
@ -97,10 +97,10 @@ namespace ams::powctl {
|
|||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryPercentageMinimumAlertThreshold(std::addressof(device), percentage);
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryChargePercentageMinimumAlertThreshold(std::addressof(device), percentage);
|
||||
}
|
||||
|
||||
Result SetBatteryPercentageMaximumAlertThreshold(Session &session, float percentage) {
|
||||
Result SetBatteryChargePercentageMaximumAlertThreshold(Session &session, float percentage) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
|
@ -111,10 +111,10 @@ namespace ams::powctl {
|
|||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryPercentageMaximumAlertThreshold(std::addressof(device), percentage);
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryChargePercentageMaximumAlertThreshold(std::addressof(device), percentage);
|
||||
}
|
||||
|
||||
Result SetBatteryPercentageFullThreshold(Session &session, float percentage) {
|
||||
Result SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(Session &session, float percentage) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
|
@ -125,7 +125,35 @@ namespace ams::powctl {
|
|||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryPercentageFullThreshold(std::addressof(device), percentage);
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryVoltageFuelGaugePercentageMinimumAlertThreshold(std::addressof(device), percentage);
|
||||
}
|
||||
|
||||
Result SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(Session &session, float percentage) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
/* Check the access mode. */
|
||||
R_UNLESS(impl.CheckAccess(ddsf::AccessMode_Write), ddsf::ResultPermissionDenied());
|
||||
|
||||
/* Get the device. */
|
||||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryVoltageFuelGaugePercentageMaximumAlertThreshold(std::addressof(device), percentage);
|
||||
}
|
||||
|
||||
Result SetBatteryFullChargeThreshold(Session &session, float percentage) {
|
||||
/* Get the session impl. */
|
||||
auto &impl = GetOpenSessionImpl(session);
|
||||
|
||||
/* Check the access mode. */
|
||||
R_UNLESS(impl.CheckAccess(ddsf::AccessMode_Write), ddsf::ResultPermissionDenied());
|
||||
|
||||
/* Get the device. */
|
||||
auto &device = impl.GetDevice().SafeCastTo<impl::IDevice>();
|
||||
|
||||
/* Call into the driver. */
|
||||
return device.GetDriver().SafeCastTo<impl::IPowerControlDriver>().SetBatteryFullChargeThreshold(std::addressof(device), percentage);
|
||||
}
|
||||
|
||||
Result GetBatteryAverageCurrent(int *out_ma, Session &session) {
|
||||
|
|
|
@ -19,55 +19,62 @@
|
|||
namespace ams::boot {
|
||||
|
||||
class BatteryDriver {
|
||||
NON_COPYABLE(BatteryDriver);
|
||||
NON_MOVEABLE(BatteryDriver);
|
||||
private:
|
||||
powctl::Session m_battery_session;
|
||||
static constinit inline powctl::Session s_battery_session{powctl::Session::ConstantInitializeTag{}};
|
||||
static constinit inline int s_reference_count{0};
|
||||
public:
|
||||
BatteryDriver() : m_battery_session() {
|
||||
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(m_battery_session), powctl::DeviceCode_Max17050, ddsf::AccessMode_ReadWrite));
|
||||
BatteryDriver() {
|
||||
if ((s_reference_count++) == 0) {
|
||||
R_ABORT_UNLESS(powctl::OpenSession(std::addressof(s_battery_session), powctl::DeviceCode_Max17050, ddsf::AccessMode_ReadWrite));
|
||||
}
|
||||
}
|
||||
|
||||
~BatteryDriver() {
|
||||
powctl::CloseSession(m_battery_session);
|
||||
if ((--s_reference_count) == 0) {
|
||||
powctl::CloseSession(s_battery_session);
|
||||
}
|
||||
}
|
||||
public:
|
||||
Result IsBatteryRemoved(bool *out) {
|
||||
bool present;
|
||||
R_TRY(powctl::IsBatteryPresent(std::addressof(present), m_battery_session));
|
||||
R_TRY(powctl::IsBatteryPresent(std::addressof(present), s_battery_session));
|
||||
|
||||
*out = !present;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result GetSocRep(float *out) {
|
||||
return powctl::GetBatterySocRep(out, m_battery_session);
|
||||
Result GetChargePercentage(float *out) {
|
||||
return powctl::GetBatteryChargePercentage(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result GetAverageVCell(int *out) {
|
||||
return powctl::GetBatteryAverageVCell(out, m_battery_session);
|
||||
return powctl::GetBatteryAverageVCell(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result GetOpenCircuitVoltage(int *out) {
|
||||
return powctl::GetBatteryOpenCircuitVoltage(out, m_battery_session);
|
||||
return powctl::GetBatteryOpenCircuitVoltage(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result GetAverageCurrent(int *out) {
|
||||
return powctl::GetBatteryAverageCurrent(out, m_battery_session);
|
||||
return powctl::GetBatteryAverageCurrent(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result GetCurrent(int *out) {
|
||||
return powctl::GetBatteryCurrent(out, m_battery_session);
|
||||
return powctl::GetBatteryCurrent(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result GetTemperature(float *out) {
|
||||
return powctl::GetBatteryTemperature(out, m_battery_session);
|
||||
return powctl::GetBatteryTemperature(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result IsI2cShutdownEnabled(bool *out) {
|
||||
return powctl::IsBatteryI2cShutdownEnabled(out, m_battery_session);
|
||||
return powctl::IsBatteryI2cShutdownEnabled(out, s_battery_session);
|
||||
}
|
||||
|
||||
Result SetI2cShutdownEnabled(bool en) {
|
||||
return powctl::SetBatteryI2cShutdownEnabled(m_battery_session, en);
|
||||
return powctl::SetBatteryI2cShutdownEnabled(s_battery_session, en);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ namespace ams::boot {
|
|||
if (show_charging_display) {
|
||||
/* Get the raw battery charge. */
|
||||
float raw_battery_charge;
|
||||
if (R_FAILED(m_battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
|
||||
if (R_FAILED(m_battery_driver.GetChargePercentage(std::addressof(raw_battery_charge)))) {
|
||||
return CheckBatteryResult::Shutdown;
|
||||
}
|
||||
|
||||
|
@ -372,7 +372,7 @@ namespace ams::boot {
|
|||
while (true) {
|
||||
/* Get the raw battery charge. */
|
||||
float raw_battery_charge;
|
||||
if (R_FAILED(m_battery_driver.GetSocRep(std::addressof(raw_battery_charge)))) {
|
||||
if (R_FAILED(m_battery_driver.GetChargePercentage(std::addressof(raw_battery_charge)))) {
|
||||
return CheckBatteryResult::Shutdown;
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ namespace ams::boot {
|
|||
bool use_desired_shutdown = true;
|
||||
if (spl::GetHardwareType() == spl::HardwareType::Hoag) {
|
||||
float battery_charge_raw;
|
||||
if (R_FAILED(battery_driver.GetSocRep(std::addressof(battery_charge_raw))) || battery_charge_raw >= 80.0) {
|
||||
if (R_FAILED(battery_driver.GetChargePercentage(std::addressof(battery_charge_raw))) || battery_charge_raw >= 80.0) {
|
||||
use_desired_shutdown = false;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue