psm.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <memory>
  4. #include "common/logging/log.h"
  5. #include "core/core.h"
  6. #include "core/hle/ipc_helpers.h"
  7. #include "core/hle/kernel/k_event.h"
  8. #include "core/hle/service/kernel_helpers.h"
  9. #include "core/hle/service/ptm/psm.h"
  10. namespace Service::PTM {
  11. class IPsmSession final : public ServiceFramework<IPsmSession> {
  12. public:
  13. explicit IPsmSession(Core::System& system_)
  14. : ServiceFramework{system_, "IPsmSession"}, service_context{system_, "IPsmSession"} {
  15. // clang-format off
  16. static const FunctionInfo functions[] = {
  17. {0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"},
  18. {1, &IPsmSession::UnbindStateChangeEvent, "UnbindStateChangeEvent"},
  19. {2, &IPsmSession::SetChargerTypeChangeEventEnabled, "SetChargerTypeChangeEventEnabled"},
  20. {3, &IPsmSession::SetPowerSupplyChangeEventEnabled, "SetPowerSupplyChangeEventEnabled"},
  21. {4, &IPsmSession::SetBatteryVoltageStateChangeEventEnabled, "SetBatteryVoltageStateChangeEventEnabled"},
  22. };
  23. // clang-format on
  24. RegisterHandlers(functions);
  25. state_change_event = service_context.CreateEvent("IPsmSession::state_change_event");
  26. }
  27. ~IPsmSession() override {
  28. service_context.CloseEvent(state_change_event);
  29. }
  30. void SignalChargerTypeChanged() {
  31. if (should_signal && should_signal_charger_type) {
  32. state_change_event->Signal();
  33. }
  34. }
  35. void SignalPowerSupplyChanged() {
  36. if (should_signal && should_signal_power_supply) {
  37. state_change_event->Signal();
  38. }
  39. }
  40. void SignalBatteryVoltageStateChanged() {
  41. if (should_signal && should_signal_battery_voltage) {
  42. state_change_event->Signal();
  43. }
  44. }
  45. private:
  46. void BindStateChangeEvent(Kernel::HLERequestContext& ctx) {
  47. LOG_DEBUG(Service_PTM, "called");
  48. should_signal = true;
  49. IPC::ResponseBuilder rb{ctx, 2, 1};
  50. rb.Push(ResultSuccess);
  51. rb.PushCopyObjects(state_change_event->GetReadableEvent());
  52. }
  53. void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
  54. LOG_DEBUG(Service_PTM, "called");
  55. should_signal = false;
  56. IPC::ResponseBuilder rb{ctx, 2};
  57. rb.Push(ResultSuccess);
  58. }
  59. void SetChargerTypeChangeEventEnabled(Kernel::HLERequestContext& ctx) {
  60. IPC::RequestParser rp{ctx};
  61. const auto state = rp.Pop<bool>();
  62. LOG_DEBUG(Service_PTM, "called, state={}", state);
  63. should_signal_charger_type = state;
  64. IPC::ResponseBuilder rb{ctx, 2};
  65. rb.Push(ResultSuccess);
  66. }
  67. void SetPowerSupplyChangeEventEnabled(Kernel::HLERequestContext& ctx) {
  68. IPC::RequestParser rp{ctx};
  69. const auto state = rp.Pop<bool>();
  70. LOG_DEBUG(Service_PTM, "called, state={}", state);
  71. should_signal_power_supply = state;
  72. IPC::ResponseBuilder rb{ctx, 2};
  73. rb.Push(ResultSuccess);
  74. }
  75. void SetBatteryVoltageStateChangeEventEnabled(Kernel::HLERequestContext& ctx) {
  76. IPC::RequestParser rp{ctx};
  77. const auto state = rp.Pop<bool>();
  78. LOG_DEBUG(Service_PTM, "called, state={}", state);
  79. should_signal_battery_voltage = state;
  80. IPC::ResponseBuilder rb{ctx, 2};
  81. rb.Push(ResultSuccess);
  82. }
  83. KernelHelpers::ServiceContext service_context;
  84. bool should_signal_charger_type{};
  85. bool should_signal_power_supply{};
  86. bool should_signal_battery_voltage{};
  87. bool should_signal{};
  88. Kernel::KEvent* state_change_event;
  89. };
  90. PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} {
  91. // clang-format off
  92. static const FunctionInfo functions[] = {
  93. {0, &PSM::GetBatteryChargePercentage, "GetBatteryChargePercentage"},
  94. {1, &PSM::GetChargerType, "GetChargerType"},
  95. {2, nullptr, "EnableBatteryCharging"},
  96. {3, nullptr, "DisableBatteryCharging"},
  97. {4, nullptr, "IsBatteryChargingEnabled"},
  98. {5, nullptr, "AcquireControllerPowerSupply"},
  99. {6, nullptr, "ReleaseControllerPowerSupply"},
  100. {7, &PSM::OpenSession, "OpenSession"},
  101. {8, nullptr, "EnableEnoughPowerChargeEmulation"},
  102. {9, nullptr, "DisableEnoughPowerChargeEmulation"},
  103. {10, nullptr, "EnableFastBatteryCharging"},
  104. {11, nullptr, "DisableFastBatteryCharging"},
  105. {12, nullptr, "GetBatteryVoltageState"},
  106. {13, nullptr, "GetRawBatteryChargePercentage"},
  107. {14, nullptr, "IsEnoughPowerSupplied"},
  108. {15, nullptr, "GetBatteryAgePercentage"},
  109. {16, nullptr, "GetBatteryChargeInfoEvent"},
  110. {17, nullptr, "GetBatteryChargeInfoFields"},
  111. {18, nullptr, "GetBatteryChargeCalibratedEvent"},
  112. };
  113. // clang-format on
  114. RegisterHandlers(functions);
  115. }
  116. PSM::~PSM() = default;
  117. void PSM::GetBatteryChargePercentage(Kernel::HLERequestContext& ctx) {
  118. LOG_DEBUG(Service_PTM, "called");
  119. IPC::ResponseBuilder rb{ctx, 3};
  120. rb.Push(ResultSuccess);
  121. rb.Push<u32>(battery_charge_percentage);
  122. }
  123. void PSM::GetChargerType(Kernel::HLERequestContext& ctx) {
  124. LOG_DEBUG(Service_PTM, "called");
  125. IPC::ResponseBuilder rb{ctx, 3};
  126. rb.Push(ResultSuccess);
  127. rb.PushEnum(charger_type);
  128. }
  129. void PSM::OpenSession(Kernel::HLERequestContext& ctx) {
  130. LOG_DEBUG(Service_PTM, "called");
  131. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  132. rb.Push(ResultSuccess);
  133. rb.PushIpcInterface<IPsmSession>(system);
  134. }
  135. } // namespace Service::PTM