diff --git a/Source/sys-clk-OC/common/include/sysclk/client/ipc.h b/Source/sys-clk-OC/common/include/sysclk/client/ipc.h index 51282653..5056a078 100644 --- a/Source/sys-clk-OC/common/include/sysclk/client/ipc.h +++ b/Source/sys-clk-OC/common/include/sysclk/client/ipc.h @@ -33,6 +33,8 @@ Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues); Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode); Result sysclkIpcGetFrequencyTable(SysClkModule module, SysClkProfile profile, SysClkFrequencyTable* out_table); Result sysclkIpcGetIsMariko(bool* out_is_mariko); +Result sysclkIpcGetBatteryChargingDisabledOverride(bool* out_is_true); +Result sysclkIpcSetBatteryChargingDisabledOverride(bool toggle_true); static inline Result sysclkIpcRemoveOverride(SysClkModule module) { diff --git a/Source/sys-clk-OC/common/include/sysclk/clocks.h b/Source/sys-clk-OC/common/include/sysclk/clocks.h index c658bf18..80b28200 100644 --- a/Source/sys-clk-OC/common/include/sysclk/clocks.h +++ b/Source/sys-clk-OC/common/include/sysclk/clocks.h @@ -62,7 +62,7 @@ typedef enum typedef struct { bool systemCoreBoostCPU; - bool allowUnsafeFreq; + bool batteryChargingDisabledOverride; bool governor; SysClkProfile realProfile; } SysClkOcExtra; diff --git a/Source/sys-clk-OC/common/include/sysclk/ipc.h b/Source/sys-clk-OC/common/include/sysclk/ipc.h index 1020e7da..c8e3268b 100644 --- a/Source/sys-clk-OC/common/include/sysclk/ipc.h +++ b/Source/sys-clk-OC/common/include/sysclk/ipc.h @@ -32,6 +32,8 @@ enum SysClkIpcCmd SysClkIpcCmd_SetReverseNXRTMode = 11, SysClkIpcCmd_GetFrequencyTable = 12, SysClkIpcCmd_GetIsMariko = 13, + SysClkIpcCmd_GetBatteryChargingDisabledOverride = 14, + SysClkIpcCmd_SetBatteryChargingDisabledOverride = 15, }; typedef struct diff --git a/Source/sys-clk-OC/common/src/client/ipc.c b/Source/sys-clk-OC/common/src/client/ipc.c index ce23ca2e..9dacffcc 100644 --- a/Source/sys-clk-OC/common/src/client/ipc.c +++ b/Source/sys-clk-OC/common/src/client/ipc.c @@ -133,3 +133,13 @@ Result sysclkIpcGetIsMariko(bool* out_is_mariko) { return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetIsMariko, *out_is_mariko); } + +Result sysclkIpcGetBatteryChargingDisabledOverride(bool* out_is_true) +{ + return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetBatteryChargingDisabledOverride, *out_is_true); +} + +Result sysclkIpcSetBatteryChargingDisabledOverride(bool toggle_true) +{ + return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetBatteryChargingDisabledOverride, toggle_true); +} diff --git a/Source/sys-clk-OC/overlay/src/ui/gui/freq_choice_gui.cpp b/Source/sys-clk-OC/overlay/src/ui/gui/freq_choice_gui.cpp index f6b149e3..82269642 100644 --- a/Source/sys-clk-OC/overlay/src/ui/gui/freq_choice_gui.cpp +++ b/Source/sys-clk-OC/overlay/src/ui/gui/freq_choice_gui.cpp @@ -56,7 +56,7 @@ void FreqChoiceGui::listUI() size_t idx = 0; uint32_t freq; - while(idx < 20 && (freq = this->hzTable->values[idx])) + while(idx < MAX_ENTRIES && (freq = this->hzTable->values[idx])) { uint32_t mhz = freq / 1000'000; this->listElement->addItem(this->createFreqListItem(mhz, mhz == this->selectedMHz)); diff --git a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp index 45a71352..3c71a5db 100644 --- a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.cpp @@ -57,6 +57,7 @@ void MiscGui::updateConfigToggles() { void MiscGui::listUI() { + // Config list sysclkIpcGetConfigValues(this->configList); this->listElement->addItem(new tsl::elm::CategoryHeader("Config")); @@ -68,6 +69,7 @@ void MiscGui::listUI() addConfigToggle(SysClkConfigValue_SyncReverseNXMode); addConfigToggle(SysClkConfigValue_GovernorExperimental); + // Charging Current this->chargingCurrentHeader = new tsl::elm::CategoryHeader(""); this->listElement->addItem(this->chargingCurrentHeader); this->chargingCurrentBar = new StepTrackBarIcon("", 2000 / 100 + 1); @@ -95,6 +97,7 @@ void MiscGui::listUI() }); this->listElement->addItem(this->chargingCurrentBar); + // Charging Limit this->chargingLimitHeader = new tsl::elm::CategoryHeader(""); this->listElement->addItem(this->chargingLimitHeader); this->chargingLimitBar = new StepTrackBarIcon("", 100 + 1); @@ -121,13 +124,26 @@ void MiscGui::listUI() renderer->drawString("\uE016 Long-term use may render the battery gauge \ninaccurate!", false, x, y + 20, SMALL_TEXT_SIZE, DESC_COLOR); }), SMALL_TEXT_SIZE * 2 + 20); + // Temporary toggles this->listElement->addItem(new tsl::elm::CategoryHeader("Temporary toggles")); + + this->chargingDisabledOverrideToggle = new tsl::elm::ToggleListItem("Force Disable Charging", false); + chargingDisabledOverrideToggle->setStateChangedListener([this](bool state) { + Result rc = sysclkIpcSetBatteryChargingDisabledOverride(state); + if (R_FAILED(rc)) + FatalGui::openWithResultCode("sysclkIpcSetBatteryChargingDisabledOverride", rc); + + this->lastContextUpdate = armGetSystemTick(); + }); + this->listElement->addItem(this->chargingDisabledOverrideToggle); + this->backlightToggle = new tsl::elm::ToggleListItem("Screen Backlight", false); backlightToggle->setStateChangedListener([this](bool state) { LblUpdate(true); }); this->listElement->addItem(this->backlightToggle); + // Info if (this->isMariko) { this->listElement->addItem(new tsl::elm::CategoryHeader("Info")); this->listElement->addItem(new tsl::elm::CustomDrawer([this](tsl::gfx::Renderer *renderer, s32 x, s32 y, s32 w, s32 h) { @@ -149,6 +165,12 @@ void MiscGui::refresh() { PsmUpdate(); this->chargingLimitBar->setIcon(PsmGetBatteryStateIcon(this->chargeInfo)); + bool chargingDisabledOverride; + Result rc = sysclkIpcGetBatteryChargingDisabledOverride(&chargingDisabledOverride); + if (R_FAILED(rc)) + FatalGui::openWithResultCode("sysclkIpcGetBatteryChargingDisabledOverride", rc); + this->chargingDisabledOverrideToggle->setState(chargingDisabledOverride); + LblUpdate(); this->backlightToggle->setState(lblstatus); diff --git a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h index 446df99a..c10a5346 100644 --- a/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h +++ b/Source/sys-clk-OC/overlay/src/ui/gui/misc_gui.h @@ -146,7 +146,7 @@ class MiscGui : public BaseMenuGui void addConfigToggle(SysClkConfigValue); void updateConfigToggles(); - tsl::elm::ToggleListItem* backlightToggle; + tsl::elm::ToggleListItem *chargingDisabledOverrideToggle, *backlightToggle; tsl::elm::CategoryHeader *chargingCurrentHeader, *chargingLimitHeader; StepTrackBarIcon *chargingCurrentBar, *chargingLimitBar; diff --git a/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp b/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp index a146e779..46ef5ce4 100644 --- a/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk-OC/sysmodule/src/clock_manager.cpp @@ -58,6 +58,7 @@ ClockManager::ClockManager() this->oc = new SysClkOcExtra; this->oc->systemCoreBoostCPU = false; + this->oc->batteryChargingDisabledOverride = false; this->oc->governor = false; this->oc->realProfile = SysClkProfile_Handheld; @@ -209,9 +210,7 @@ void ClockManager::WaitForNextTick() bool ClockManager::RefreshContext() { - uint32_t chargingCurrent = this->GetConfig()->GetConfigValue(SysClkConfigValue_ChargingCurrentLimit); - uint32_t chargingLimit = this->GetConfig()->GetConfigValue(SysClkConfigValue_ChargingLimitPercentage); - PsmExt::ChargingHandler(chargingCurrent, chargingLimit); + PsmExt::ChargingHandler(this->GetInstance()); bool hasChanged = this->config->Refresh(); if (hasChanged) { @@ -259,11 +258,13 @@ bool ClockManager::RefreshContext() this->governor->Stop(); } - SysClkProfile profile = Clocks::GetCurrentProfile(); - if (profile != this->oc->realProfile) + SysClkProfile realProfile = Clocks::GetCurrentProfile(); + if (realProfile != this->oc->realProfile) { - FileUtils::LogLine("[mgr] Profile change: %s", Clocks::GetProfileName(profile, true)); - this->oc->realProfile = profile; + FileUtils::LogLine("[mgr] Profile change: %s", Clocks::GetProfileName(realProfile, true)); + this->oc->realProfile = realProfile; + // Signal that power state has been changed, reset the override + this->SetBatteryChargingDisabledOverride(false); hasChanged = true; } @@ -371,3 +372,12 @@ Config* ClockManager::GetConfig() { return this->config; } + +bool ClockManager::GetBatteryChargingDisabledOverride() { + return this->oc->batteryChargingDisabledOverride; +} + +Result ClockManager::SetBatteryChargingDisabledOverride(bool toggle_true) { + this->oc->batteryChargingDisabledOverride = toggle_true; + return 0; +} diff --git a/Source/sys-clk-OC/sysmodule/src/clock_manager.h b/Source/sys-clk-OC/sysmodule/src/clock_manager.h index 57594788..14e3eb9a 100644 --- a/Source/sys-clk-OC/sysmodule/src/clock_manager.h +++ b/Source/sys-clk-OC/sysmodule/src/clock_manager.h @@ -19,6 +19,10 @@ #include "oc_extra.h" +// Forward declaration +class ReverseNXSync; +class Governor; + class ClockManager { public: @@ -33,6 +37,8 @@ class ClockManager void SetRNXRTMode(ReverseNXMode mode); SysClkContext GetCurrentContext(); Config* GetConfig(); + bool GetBatteryChargingDisabledOverride(); + Result SetBatteryChargingDisabledOverride(bool toggle_true); protected: ClockManager(); diff --git a/Source/sys-clk-OC/sysmodule/src/ipc_service.cpp b/Source/sys-clk-OC/sysmodule/src/ipc_service.cpp index 407c44fe..26557f2d 100644 --- a/Source/sys-clk-OC/sysmodule/src/ipc_service.cpp +++ b/Source/sys-clk-OC/sysmodule/src/ipc_service.cpp @@ -171,6 +171,15 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8* case SysClkIpcCmd_GetIsMariko: *out_dataSize = sizeof(bool); return ipcSrv->GetIsMariko((bool*)out_data); + case SysClkIpcCmd_GetBatteryChargingDisabledOverride: + *out_dataSize = sizeof(bool); + return ipcSrv->GetBatteryChargingDisabledOverride((bool*)out_data); + case SysClkIpcCmd_SetBatteryChargingDisabledOverride: + if (r->data.size >= sizeof(bool)) { + bool toggle_true = *((bool*)(r->data.ptr)); + return ipcSrv->SetBatteryChargingDisabledOverride(toggle_true); + } + break; } return SYSCLK_ERROR(Generic); @@ -321,3 +330,14 @@ Result IpcService::GetIsMariko(bool* out_is_mariko) { *out_is_mariko = Clocks::GetIsMariko(); return 0; } + +Result IpcService::GetBatteryChargingDisabledOverride(bool* out_is_true) { + *out_is_true = ClockManager::GetInstance()->GetBatteryChargingDisabledOverride(); + return 0; +} + + +Result IpcService::SetBatteryChargingDisabledOverride(bool toggle_true) { + return ClockManager::GetInstance()->SetBatteryChargingDisabledOverride(toggle_true); +} + diff --git a/Source/sys-clk-OC/sysmodule/src/ipc_service.h b/Source/sys-clk-OC/sysmodule/src/ipc_service.h index 11cf3f4b..fb975c69 100644 --- a/Source/sys-clk-OC/sysmodule/src/ipc_service.h +++ b/Source/sys-clk-OC/sysmodule/src/ipc_service.h @@ -39,6 +39,8 @@ class IpcService Result SetReverseNXRTMode(ReverseNXMode mode); Result GetFrequencyTable(SysClkIpc_GetFrequencyTable_Args* args, SysClkFrequencyTable* out_table); Result GetIsMariko(bool* out_is_mariko); + Result GetBatteryChargingDisabledOverride(bool* out_is_true); + Result SetBatteryChargingDisabledOverride(bool toggle_true); bool running; Thread thread; diff --git a/Source/sys-clk-OC/sysmodule/src/oc_extra.cpp b/Source/sys-clk-OC/sysmodule/src/oc_extra.cpp index 707c3f62..f433369e 100644 --- a/Source/sys-clk-OC/sysmodule/src/oc_extra.cpp +++ b/Source/sys-clk-OC/sysmodule/src/oc_extra.cpp @@ -105,11 +105,12 @@ ReverseNXMode ReverseNXSync::RecheckToolMode() { } -void PsmExt::ChargingHandler(uint32_t chargingCurrent, uint32_t chargingLimit) { +void PsmExt::ChargingHandler(ClockManager* instance) { u32 current; Result res = I2c_Bq24193_GetFastChargeCurrentLimit(¤t); if (R_SUCCEEDED(res)) { current -= current % 100; + u32 chargingCurrent = instance->GetConfig()->GetConfigValue(SysClkConfigValue_ChargingCurrentLimit); if (current != chargingCurrent) I2c_Bq24193_SetFastChargeCurrentLimit(chargingCurrent); } @@ -122,7 +123,9 @@ void PsmExt::ChargingHandler(uint32_t chargingCurrent, uint32_t chargingLimit) { u32 chargeNow = 0; if (R_SUCCEEDED(psmGetBatteryChargePercentage(&chargeNow))) { bool isCharging = PsmIsCharging(info); - if (isCharging && chargingLimit < chargeNow) + u32 chargingLimit = instance->GetConfig()->GetConfigValue(SysClkConfigValue_ChargingLimitPercentage); + bool forceDisabled = instance->GetBatteryChargingDisabledOverride(); + if (isCharging && (forceDisabled || chargingLimit <= chargeNow)) serviceDispatch(session, Psm_DisableBatteryCharging); if (!isCharging && chargingLimit > chargeNow) serviceDispatch(session, Psm_EnableBatteryCharging); diff --git a/Source/sys-clk-OC/sysmodule/src/oc_extra.h b/Source/sys-clk-OC/sysmodule/src/oc_extra.h index 92018507..a9f4310c 100644 --- a/Source/sys-clk-OC/sysmodule/src/oc_extra.h +++ b/Source/sys-clk-OC/sysmodule/src/oc_extra.h @@ -10,6 +10,10 @@ #include "file_utils.h" #include "clocks.h" +// Forward declaration +class ClockManager; +#include "clock_manager.h" + class CpuCoreUtil { public: CpuCoreUtil (int coreid, uint64_t ns); @@ -58,8 +62,8 @@ protected: }; namespace PsmExt { - void ChargingHandler(uint32_t chargingCurrent, uint32_t chargingLimit); -}; + void ChargingHandler(ClockManager* instance); +} class Governor { public: