powctl: integrate 13.0.0 changes (aula params not done yet)

This commit is contained in:
Michael Scire 2021-10-15 16:30:27 -07:00
parent c04a262d49
commit 990daec3a2
16 changed files with 241 additions and 154 deletions

View file

@ -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);

View file

@ -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) { /* ... */ }
};

View file

@ -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();
}

View file

@ -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;

View file

@ -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);

View file

@ -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() {
/* ... */
}

View file

@ -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();
}

View file

@ -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(); }

View file

@ -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

View file

@ -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);

View file

@ -21,11 +21,11 @@ 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) { \
const Result __powctl_retry_result = (__EXPR__); \
const Result __powctl_retry_result = ( __EXPR__ ); \
if (R_SUCCEEDED(__powctl_retry_result)) { \
break; \
} \
@ -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__ ); }) )
}

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}
};

View file

@ -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;
}

View file

@ -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;
}
}