From 53b321c945d7e6782a6011b7ee55035da8f54dbc Mon Sep 17 00:00:00 2001
From: Narr the Reg <juangerman-13@hotmail.com>
Date: Mon, 22 Jan 2024 23:30:34 -0600
Subject: [PATCH] service: set: Implement more settings functions for Qlaunch

---
 src/core/hle/service/btm/btm.cpp              |   9 +-
 src/core/hle/service/hid/hid.cpp              |   2 +-
 src/core/hle/service/hid/hid_server.cpp       |   4 +-
 .../hle/service/hid/hid_system_server.cpp     |  54 +++++-
 src/core/hle/service/hid/hid_system_server.h  |   9 +-
 .../set/setting_formats/system_settings.cpp   |   1 +
 src/core/hle/service/set/settings_types.h     |   9 +
 .../service/set/system_settings_server.cpp    | 175 +++++++++++++-----
 .../hle/service/set/system_settings_server.h  |  36 ++--
 src/hid_core/resource_manager.cpp             |   8 +-
 .../resources/hid_firmware_settings.cpp       |  12 ++
 .../resources/hid_firmware_settings.h         |   3 +
 src/hid_core/resources/npad/npad.cpp          |   5 +-
 src/hid_core/resources/npad/npad.h            |   7 +-
 .../resources/npad/npad_vibration.cpp         |  36 ++--
 src/hid_core/resources/npad/npad_vibration.h  |   7 +
 16 files changed, 289 insertions(+), 88 deletions(-)

diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index c65e324898..2dc23e674a 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -283,7 +283,7 @@ public:
             {17, &IBtmSystemCore::GetConnectedAudioDevices, "GetConnectedAudioDevices"},
             {18, nullptr, "DisconnectAudioDevice"},
             {19, nullptr, "AcquirePairedAudioDeviceInfoChangedEvent"},
-            {20, nullptr, "GetPairedAudioDevices"},
+            {20, &IBtmSystemCore::GetPairedAudioDevices, "GetPairedAudioDevices"},
             {21, nullptr, "RemoveAudioDevicePairing"},
             {22, &IBtmSystemCore::RequestAudioDeviceConnectionRejection, "RequestAudioDeviceConnectionRejection"},
             {23, &IBtmSystemCore::CancelAudioDeviceConnectionRejection, "CancelAudioDeviceConnectionRejection"}
@@ -327,6 +327,13 @@ private:
         rb.Push<u32>(0);
     }
 
+    void GetPairedAudioDevices(HLERequestContext& ctx) {
+        LOG_WARNING(Service_BTM, "(STUBBED) called");
+        IPC::ResponseBuilder rb{ctx, 3};
+        rb.Push(ResultSuccess);
+        rb.Push<u32>(0);
+    }
+
     void RequestAudioDeviceConnectionRejection(HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
         IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 595a3372e0..5b28be5777 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -33,7 +33,7 @@ void LoopProcess(Core::System& system) {
     server_manager->RegisterNamedService(
         "hid:dbg", std::make_shared<IHidDebugServer>(system, resource_manager));
     server_manager->RegisterNamedService(
-        "hid:sys", std::make_shared<IHidSystemServer>(system, resource_manager));
+        "hid:sys", std::make_shared<IHidSystemServer>(system, resource_manager, firmware_settings));
 
     server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
 
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index 30afed8122..09c47b5e30 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -1419,8 +1419,8 @@ void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ct
 
     const auto parameters{rp.PopRaw<Parameters>()};
 
-    LOG_INFO(Service_HID, "called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
-             parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
+    LOG_DEBUG(Service_HID, "called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
+              parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
 
     if (!IsNpadIdValid(parameters.npad_id)) {
         IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index bf27ddfbf5..d1ec42edc3 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -3,8 +3,10 @@
 
 #include "core/hle/service/hid/hid_system_server.h"
 #include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/set/settings_types.h"
 #include "hid_core/hid_result.h"
 #include "hid_core/resource_manager.h"
+#include "hid_core/resources/hid_firmware_settings.h"
 #include "hid_core/resources/npad/npad.h"
 #include "hid_core/resources/npad/npad_types.h"
 #include "hid_core/resources/npad/npad_vibration.h"
@@ -13,9 +15,10 @@
 
 namespace Service::HID {
 
-IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
+IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
+                                   std::shared_ptr<HidFirmwareSettings> settings)
     : ServiceFramework{system_, "hid:sys"}, service_context{system_, service_name},
-      resource_manager{resource} {
+      resource_manager{resource}, firmware_settings{settings} {
     // clang-format off
     static const FunctionInfo functions[] = {
         {31, nullptr, "SendKeyboardLockKeyEvent"},
@@ -25,7 +28,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {131, nullptr, "ActivateSleepButton"},
         {141, nullptr, "AcquireCaptureButtonEventHandle"},
         {151, nullptr, "ActivateCaptureButton"},
-        {161, nullptr, "GetPlatformConfig"},
+        {161, &IHidSystemServer::GetPlatformConfig, "GetPlatformConfig"},
         {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
         {211, nullptr, "GetNpadsWithNfc"},
         {212, nullptr, "AcquireNfcActivateEventHandle"},
@@ -80,7 +83,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {520, nullptr, "EnableHandheldHids"},
         {521, nullptr, "DisableHandheldHids"},
         {522, nullptr, "SetJoyConRailEnabled"},
-        {523, nullptr, "IsJoyConRailEnabled"},
+        {523, &IHidSystemServer::IsJoyConRailEnabled, "IsJoyConRailEnabled"},
         {524, nullptr, "IsHandheldHidsEnabled"},
         {525, &IHidSystemServer::IsJoyConAttachedOnAllRail, "IsJoyConAttachedOnAllRail"},
         {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
@@ -123,7 +126,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {831, nullptr, "SetNotificationLedPatternWithTimeout"},
         {832, nullptr, "PrepareHidsForNotificationWake"},
         {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
-        {851, nullptr, "EnableUsbFullKeyController"},
+        {851, &IHidSystemServer::EnableUsbFullKeyController, "EnableUsbFullKeyController"},
         {852, nullptr, "IsUsbConnected"},
         {870, &IHidSystemServer::IsHandheldButtonPressedOnConsoleMode, "IsHandheldButtonPressedOnConsoleMode"},
         {900, nullptr, "ActivateInputDetector"},
@@ -148,7 +151,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
         {1120, &IHidSystemServer::SetFirmwareHotfixUpdateSkipEnabled, "SetFirmwareHotfixUpdateSkipEnabled"},
         {1130, &IHidSystemServer::InitializeUsbFirmwareUpdate, "InitializeUsbFirmwareUpdate"},
         {1131, &IHidSystemServer::FinalizeUsbFirmwareUpdate, "FinalizeUsbFirmwareUpdate"},
-        {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
+        {1132, &IHidSystemServer::CheckUsbFirmwareUpdateRequired, "CheckUsbFirmwareUpdateRequired"},
         {1133, nullptr, "StartUsbFirmwareUpdate"},
         {1134, nullptr, "GetUsbFirmwareUpdateState"},
         {1135, &IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory, "InitializeUsbFirmwareUpdateWithoutMemory"},
@@ -239,6 +242,16 @@ IHidSystemServer::~IHidSystemServer() {
     service_context.CloseEvent(unique_pad_connection_event);
 };
 
+void IHidSystemServer::GetPlatformConfig(HLERequestContext& ctx) {
+    const auto platform_config = firmware_settings->GetPlatformConfig();
+
+    LOG_INFO(Service_HID, "called, platform_config={}", platform_config.raw);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.PushRaw(platform_config);
+}
+
 void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
     const auto applet_resource_user_id{rp.Pop<u64>()};
@@ -674,6 +687,16 @@ void IHidSystemServer::EndPermitVibrationSession(HLERequestContext& ctx) {
     rb.Push(result);
 }
 
+void IHidSystemServer::IsJoyConRailEnabled(HLERequestContext& ctx) {
+    const bool is_attached = true;
+
+    LOG_WARNING(Service_HID, "(STUBBED) called, is_attached={}", is_attached);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(is_attached);
+}
+
 void IHidSystemServer::IsJoyConAttachedOnAllRail(HLERequestContext& ctx) {
     const bool is_attached = true;
 
@@ -727,7 +750,7 @@ void IHidSystemServer::AcquireUniquePadConnectionEventHandle(HLERequestContext&
 }
 
 void IHidSystemServer::GetUniquePadIds(HLERequestContext& ctx) {
-    LOG_WARNING(Service_HID, "(STUBBED) called");
+    LOG_DEBUG(Service_HID, "(STUBBED) called");
 
     IPC::ResponseBuilder rb{ctx, 4};
     rb.Push(ResultSuccess);
@@ -752,6 +775,16 @@ void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
     rb.Push(is_enabled);
 }
 
+void IHidSystemServer::EnableUsbFullKeyController(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto is_enabled{rp.Pop<bool>()};
+
+    LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void IHidSystemServer::IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx) {
     const bool button_pressed = false;
 
@@ -798,6 +831,13 @@ void IHidSystemServer::FinalizeUsbFirmwareUpdate(HLERequestContext& ctx) {
     rb.Push(ResultSuccess);
 }
 
+void IHidSystemServer::CheckUsbFirmwareUpdateRequired(HLERequestContext& ctx) {
+    LOG_WARNING(Service_HID, "(STUBBED) called");
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void IHidSystemServer::InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx) {
     LOG_WARNING(Service_HID, "(STUBBED) called");
 
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
index 90a719f026..4ab4d3931f 100644
--- a/src/core/hle/service/hid/hid_system_server.h
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -16,13 +16,16 @@ class KEvent;
 
 namespace Service::HID {
 class ResourceManager;
+class HidFirmwareSettings;
 
 class IHidSystemServer final : public ServiceFramework<IHidSystemServer> {
 public:
-    explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
+    explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
+                              std::shared_ptr<HidFirmwareSettings> settings);
     ~IHidSystemServer() override;
 
 private:
+    void GetPlatformConfig(HLERequestContext& ctx);
     void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
     void EnableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
     void DisableAssigningSingleOnSlSrPress(HLERequestContext& ctx);
@@ -50,6 +53,7 @@ private:
     void GetVibrationMasterVolume(HLERequestContext& ctx);
     void BeginPermitVibrationSession(HLERequestContext& ctx);
     void EndPermitVibrationSession(HLERequestContext& ctx);
+    void IsJoyConRailEnabled(HLERequestContext& ctx);
     void IsJoyConAttachedOnAllRail(HLERequestContext& ctx);
     void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
     void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
@@ -58,12 +62,14 @@ private:
     void GetUniquePadIds(HLERequestContext& ctx);
     void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
     void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
+    void EnableUsbFullKeyController(HLERequestContext& ctx);
     void IsHandheldButtonPressedOnConsoleMode(HLERequestContext& ctx);
     void InitializeFirmwareUpdate(HLERequestContext& ctx);
     void CheckFirmwareUpdateRequired(HLERequestContext& ctx);
     void SetFirmwareHotfixUpdateSkipEnabled(HLERequestContext& ctx);
     void InitializeUsbFirmwareUpdate(HLERequestContext& ctx);
     void FinalizeUsbFirmwareUpdate(HLERequestContext& ctx);
+    void CheckUsbFirmwareUpdateRequired(HLERequestContext& ctx);
     void InitializeUsbFirmwareUpdateWithoutMemory(HLERequestContext& ctx);
     void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
     void SetForceHandheldStyleVibration(HLERequestContext& ctx);
@@ -77,6 +83,7 @@ private:
     Kernel::KEvent* unique_pad_connection_event;
     KernelHelpers::ServiceContext service_context;
     std::shared_ptr<ResourceManager> resource_manager;
+    std::shared_ptr<HidFirmwareSettings> firmware_settings;
 };
 
 } // namespace Service::HID
diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp
index ec00b90a66..88a305f03d 100644
--- a/src/core/hle/service/set/setting_formats/system_settings.cpp
+++ b/src/core/hle/service/set/setting_formats/system_settings.cpp
@@ -50,6 +50,7 @@ SystemSettings DefaultSystemSettings() {
     settings.primary_album_storage = PrimaryAlbumStorage::SdCard;
     settings.battery_percentage_flag = true;
     settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0;
+    settings.vibration_master_volume = 1.0f;
 
     return settings;
 }
diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h
index f6f227fde2..968425319c 100644
--- a/src/core/hle/service/set/settings_types.h
+++ b/src/core/hle/service/set/settings_types.h
@@ -323,6 +323,15 @@ struct NotificationFlag {
 };
 static_assert(sizeof(NotificationFlag) == 4, "NotificationFlag is an invalid size");
 
+struct PlatformConfig {
+    union {
+        u32 raw{};
+        BitField<0, 1, u32> has_rail_interface;
+        BitField<1, 1, u32> has_sio_mcu;
+    };
+};
+static_assert(sizeof(PlatformConfig) == 0x4, "PlatformConfig is an invalid size");
+
 /// This is nn::settings::system::TvFlag
 struct TvFlag {
     union {
diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp
index f40a1c8f3b..345c7ec32e 100644
--- a/src/core/hle/service/set/system_settings_server.cpp
+++ b/src/core/hle/service/set/system_settings_server.cpp
@@ -123,8 +123,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
         {30, &ISystemSettingsServer::SetNotificationSettings, "SetNotificationSettings"},
         {31, &ISystemSettingsServer::GetAccountNotificationSettings, "GetAccountNotificationSettings"},
         {32, &ISystemSettingsServer::SetAccountNotificationSettings, "SetAccountNotificationSettings"},
-        {35, nullptr, "GetVibrationMasterVolume"},
-        {36, nullptr, "SetVibrationMasterVolume"},
+        {35, &ISystemSettingsServer::GetVibrationMasterVolume, "GetVibrationMasterVolume"},
+        {36, &ISystemSettingsServer::SetVibrationMasterVolume, "SetVibrationMasterVolume"},
         {37, &ISystemSettingsServer::GetSettingsItemValueSize, "GetSettingsItemValueSize"},
         {38, &ISystemSettingsServer::GetSettingsItemValue, "GetSettingsItemValue"},
         {39, &ISystemSettingsServer::GetTvSettings, "GetTvSettings"},
@@ -133,10 +133,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
         {42, nullptr, "SetEdid"},
         {43, nullptr, "GetAudioOutputMode"},
         {44, nullptr, "SetAudioOutputMode"},
-        {45, nullptr, "IsForceMuteOnHeadphoneRemoved"},
-        {46, nullptr, "SetForceMuteOnHeadphoneRemoved"},
+        {45, &ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved, "IsForceMuteOnHeadphoneRemoved"},
+        {46, &ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved, "SetForceMuteOnHeadphoneRemoved"},
         {47, &ISystemSettingsServer::GetQuestFlag, "GetQuestFlag"},
-        {48, nullptr, "SetQuestFlag"},
+        {48, &ISystemSettingsServer::SetQuestFlag, "SetQuestFlag"},
         {49, nullptr, "GetDataDeletionSettings"},
         {50, nullptr, "SetDataDeletionSettings"},
         {51, nullptr, "GetInitialSystemAppletProgramId"},
@@ -152,7 +152,7 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_)
         {61, &ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled, "SetUserSystemClockAutomaticCorrectionEnabled"},
         {62, &ISystemSettingsServer::GetDebugModeFlag, "GetDebugModeFlag"},
         {63, &ISystemSettingsServer::GetPrimaryAlbumStorage, "GetPrimaryAlbumStorage"},
-        {64, nullptr, "SetPrimaryAlbumStorage"},
+        {64, &ISystemSettingsServer::SetPrimaryAlbumStorage, "SetPrimaryAlbumStorage"},
         {65, nullptr, "GetUsb30EnableFlag"},
         {66, nullptr, "SetUsb30EnableFlag"},
         {67, nullptr, "GetBatteryLot"},
@@ -467,7 +467,7 @@ void ISystemSettingsServer::GetExternalSteadyClockSourceId(HLERequestContext& ct
     LOG_INFO(Service_SET, "called");
 
     Common::UUID id{};
-    auto res = GetExternalSteadyClockSourceId(id);
+    const auto res = GetExternalSteadyClockSourceId(id);
 
     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Common::UUID) / sizeof(u32)};
     rb.Push(res);
@@ -478,9 +478,9 @@ void ISystemSettingsServer::SetExternalSteadyClockSourceId(HLERequestContext& ct
     LOG_INFO(Service_SET, "called");
 
     IPC::RequestParser rp{ctx};
-    auto id{rp.PopRaw<Common::UUID>()};
+    const auto id{rp.PopRaw<Common::UUID>()};
 
-    auto res = SetExternalSteadyClockSourceId(id);
+    const auto res = SetExternalSteadyClockSourceId(id);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -490,7 +490,7 @@ void ISystemSettingsServer::GetUserSystemClockContext(HLERequestContext& ctx) {
     LOG_INFO(Service_SET, "called");
 
     Service::PSC::Time::SystemClockContext context{};
-    auto res = GetUserSystemClockContext(context);
+    const auto res = GetUserSystemClockContext(context);
 
     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)};
     rb.Push(res);
@@ -501,9 +501,9 @@ void ISystemSettingsServer::SetUserSystemClockContext(HLERequestContext& ctx) {
     LOG_INFO(Service_SET, "called");
 
     IPC::RequestParser rp{ctx};
-    auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
+    const auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
 
-    auto res = SetUserSystemClockContext(context);
+    const auto res = SetUserSystemClockContext(context);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -652,6 +652,29 @@ void ISystemSettingsServer::SetAccountNotificationSettings(HLERequestContext& ct
     rb.Push(ResultSuccess);
 }
 
+void ISystemSettingsServer::GetVibrationMasterVolume(HLERequestContext& ctx) {
+    f32 vibration_master_volume = {};
+    const auto result = GetVibrationMasterVolume(vibration_master_volume);
+
+    LOG_INFO(Service_SET, "called, master_volume={}", vibration_master_volume);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(result);
+    rb.Push(vibration_master_volume);
+}
+
+void ISystemSettingsServer::SetVibrationMasterVolume(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto vibration_master_volume = rp.PopRaw<f32>();
+
+    LOG_INFO(Service_SET, "called, elements={}", m_system_settings.vibration_master_volume);
+
+    const auto result = SetVibrationMasterVolume(vibration_master_volume);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(result);
+}
+
 // FIXME: implement support for the real system_settings.ini
 
 template <typename T>
@@ -683,6 +706,8 @@ static Settings GetSettings() {
     ret["time"]["standard_user_clock_initial_year"] = ToBytes(s32{2023});
 
     // HID
+    ret["hid"]["has_rail_interface"] = ToBytes(bool{true});
+    ret["hid"]["has_sio_mcu"] = ToBytes(bool{true});
     ret["hid_debug"]["enables_debugpad"] = ToBytes(bool{true});
     ret["hid_debug"]["manages_devices"] = ToBytes(bool{true});
     ret["hid_debug"]["manages_touch_ic_i2c"] = ToBytes(bool{true});
@@ -700,6 +725,9 @@ static Settings GetSettings() {
     // Settings
     ret["settings_debug"]["is_debug_mode_enabled"] = ToBytes(bool{false});
 
+    // Error
+    ret["err"]["applet_auto_close"] = ToBytes(bool{false});
+
     return ret;
 }
 
@@ -786,15 +814,25 @@ void ISystemSettingsServer::SetTvSettings(HLERequestContext& ctx) {
     rb.Push(ResultSuccess);
 }
 
-void ISystemSettingsServer::GetDebugModeFlag(HLERequestContext& ctx) {
-    bool is_debug_mode_enabled = false;
-    GetSettingsItemValue<bool>(is_debug_mode_enabled, "settings_debug", "is_debug_mode_enabled");
-
-    LOG_DEBUG(Service_SET, "called, is_debug_mode_enabled={}", is_debug_mode_enabled);
+void ISystemSettingsServer::IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) {
+    LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}",
+             m_system_settings.force_mute_on_headphone_removed);
 
     IPC::ResponseBuilder rb{ctx, 3};
     rb.Push(ResultSuccess);
-    rb.Push(is_debug_mode_enabled);
+    rb.PushRaw(m_system_settings.force_mute_on_headphone_removed);
+}
+
+void ISystemSettingsServer::SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    m_system_settings.force_mute_on_headphone_removed = rp.PopRaw<bool>();
+    SetSaveNeeded();
+
+    LOG_INFO(Service_SET, "called, force_mute_on_headphone_removed={}",
+             m_system_settings.force_mute_on_headphone_removed);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
 }
 
 void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) {
@@ -805,11 +843,22 @@ void ISystemSettingsServer::GetQuestFlag(HLERequestContext& ctx) {
     rb.PushEnum(m_system_settings.quest_flag);
 }
 
+void ISystemSettingsServer::SetQuestFlag(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    m_system_settings.quest_flag = rp.PopEnum<QuestFlag>();
+    SetSaveNeeded();
+
+    LOG_INFO(Service_SET, "called, quest_flag={}", m_system_settings.quest_flag);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void ISystemSettingsServer::GetDeviceTimeZoneLocationName(HLERequestContext& ctx) {
     LOG_INFO(Service_SET, "called");
 
     Service::PSC::Time::LocationName name{};
-    auto res = GetDeviceTimeZoneLocationName(name);
+    const auto res = GetDeviceTimeZoneLocationName(name);
 
     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::LocationName) / sizeof(u32)};
     rb.Push(res);
@@ -822,7 +871,7 @@ void ISystemSettingsServer::SetDeviceTimeZoneLocationName(HLERequestContext& ctx
     IPC::RequestParser rp{ctx};
     auto name{rp.PopRaw<Service::PSC::Time::LocationName>()};
 
-    auto res = SetDeviceTimeZoneLocationName(name);
+    const auto res = SetDeviceTimeZoneLocationName(name);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -843,7 +892,7 @@ void ISystemSettingsServer::GetNetworkSystemClockContext(HLERequestContext& ctx)
     LOG_INFO(Service_SET, "called");
 
     Service::PSC::Time::SystemClockContext context{};
-    auto res = GetNetworkSystemClockContext(context);
+    const auto res = GetNetworkSystemClockContext(context);
 
     IPC::ResponseBuilder rb{ctx, 2 + sizeof(Service::PSC::Time::SystemClockContext) / sizeof(u32)};
     rb.Push(res);
@@ -854,9 +903,9 @@ void ISystemSettingsServer::SetNetworkSystemClockContext(HLERequestContext& ctx)
     LOG_INFO(Service_SET, "called");
 
     IPC::RequestParser rp{ctx};
-    auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
+    const auto context{rp.PopRaw<Service::PSC::Time::SystemClockContext>()};
 
-    auto res = SetNetworkSystemClockContext(context);
+    const auto res = SetNetworkSystemClockContext(context);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -866,7 +915,7 @@ void ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(HLEReque
     LOG_INFO(Service_SET, "called");
 
     bool enabled{};
-    auto res = IsUserSystemClockAutomaticCorrectionEnabled(enabled);
+    const auto res = IsUserSystemClockAutomaticCorrectionEnabled(enabled);
 
     IPC::ResponseBuilder rb{ctx, 3};
     rb.Push(res);
@@ -879,12 +928,23 @@ void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionEnabled(HLERequ
     IPC::RequestParser rp{ctx};
     auto enabled{rp.Pop<bool>()};
 
-    auto res = SetUserSystemClockAutomaticCorrectionEnabled(enabled);
+    const auto res = SetUserSystemClockAutomaticCorrectionEnabled(enabled);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
 }
 
+void ISystemSettingsServer::GetDebugModeFlag(HLERequestContext& ctx) {
+    bool is_debug_mode_enabled = false;
+    GetSettingsItemValue<bool>(is_debug_mode_enabled, "settings_debug", "is_debug_mode_enabled");
+
+    LOG_DEBUG(Service_SET, "called, is_debug_mode_enabled={}", is_debug_mode_enabled);
+
+    IPC::ResponseBuilder rb{ctx, 3};
+    rb.Push(ResultSuccess);
+    rb.Push(is_debug_mode_enabled);
+}
+
 void ISystemSettingsServer::GetPrimaryAlbumStorage(HLERequestContext& ctx) {
     LOG_INFO(Service_SET, "called, primary_album_storage={}",
              m_system_settings.primary_album_storage);
@@ -894,6 +954,18 @@ void ISystemSettingsServer::GetPrimaryAlbumStorage(HLERequestContext& ctx) {
     rb.PushEnum(m_system_settings.primary_album_storage);
 }
 
+void ISystemSettingsServer::SetPrimaryAlbumStorage(HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    m_system_settings.primary_album_storage = rp.PopEnum<PrimaryAlbumStorage>();
+    SetSaveNeeded();
+
+    LOG_INFO(Service_SET, "called, primary_album_storage={}",
+             m_system_settings.primary_album_storage);
+
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(ResultSuccess);
+}
+
 void ISystemSettingsServer::GetNfcEnableFlag(HLERequestContext& ctx) {
     LOG_INFO(Service_SET, "called, nfc_enable_flag={}", m_system_settings.nfc_enable_flag);
 
@@ -1072,7 +1144,7 @@ void ISystemSettingsServer::SetExternalSteadyClockInternalOffset(HLERequestConte
     IPC::RequestParser rp{ctx};
     auto offset{rp.Pop<s64>()};
 
-    auto res = SetExternalSteadyClockInternalOffset(offset);
+    const auto res = SetExternalSteadyClockInternalOffset(offset);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -1082,7 +1154,7 @@ void ISystemSettingsServer::GetExternalSteadyClockInternalOffset(HLERequestConte
     LOG_DEBUG(Service_SET, "called.");
 
     s64 offset{};
-    auto res = GetExternalSteadyClockInternalOffset(offset);
+    const auto res = GetExternalSteadyClockInternalOffset(offset);
 
     IPC::ResponseBuilder rb{ctx, 4};
     rb.Push(res);
@@ -1140,7 +1212,7 @@ void ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(HLERequestConte
     LOG_INFO(Service_SET, "called");
 
     Service::PSC::Time::SteadyClockTimePoint time_point{};
-    auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point);
+    const auto res = GetDeviceTimeZoneLocationUpdatedTime(time_point);
 
     IPC::ResponseBuilder rb{ctx, 4};
     rb.Push(res);
@@ -1153,7 +1225,7 @@ void ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(HLERequestConte
     IPC::RequestParser rp{ctx};
     auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()};
 
-    auto res = SetDeviceTimeZoneLocationUpdatedTime(time_point);
+    const auto res = SetDeviceTimeZoneLocationUpdatedTime(time_point);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -1164,7 +1236,7 @@ void ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime(
     LOG_INFO(Service_SET, "called");
 
     Service::PSC::Time::SteadyClockTimePoint time_point{};
-    auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
+    const auto res = GetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
 
     IPC::ResponseBuilder rb{ctx, 4};
     rb.Push(res);
@@ -1176,9 +1248,9 @@ void ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime(
     LOG_INFO(Service_SET, "called");
 
     IPC::RequestParser rp{ctx};
-    auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()};
+    const auto time_point{rp.PopRaw<Service::PSC::Time::SteadyClockTimePoint>()};
 
-    auto res = SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
+    const auto res = SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(res);
@@ -1304,57 +1376,68 @@ Result ISystemSettingsServer::GetSettingsItemValue(std::vector<u8>& out_value,
     R_SUCCEED();
 }
 
-Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) {
+Result ISystemSettingsServer::GetVibrationMasterVolume(f32& out_volume) const {
+    out_volume = m_system_settings.vibration_master_volume;
+    R_SUCCEED();
+}
+
+Result ISystemSettingsServer::SetVibrationMasterVolume(f32 volume) {
+    m_system_settings.vibration_master_volume = volume;
+    SetSaveNeeded();
+    R_SUCCEED();
+}
+
+Result ISystemSettingsServer::GetExternalSteadyClockSourceId(Common::UUID& out_id) const {
     out_id = m_private_settings.external_clock_source_id;
     R_SUCCEED();
 }
 
-Result ISystemSettingsServer::SetExternalSteadyClockSourceId(Common::UUID id) {
+Result ISystemSettingsServer::SetExternalSteadyClockSourceId(const Common::UUID& id) {
     m_private_settings.external_clock_source_id = id;
     SetSaveNeeded();
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::GetUserSystemClockContext(
-    Service::PSC::Time::SystemClockContext& out_context) {
+    Service::PSC::Time::SystemClockContext& out_context) const {
     out_context = m_system_settings.user_system_clock_context;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::SetUserSystemClockContext(
-    Service::PSC::Time::SystemClockContext& context) {
+    const Service::PSC::Time::SystemClockContext& context) {
     m_system_settings.user_system_clock_context = context;
     SetSaveNeeded();
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::GetDeviceTimeZoneLocationName(
-    Service::PSC::Time::LocationName& out_name) {
+    Service::PSC::Time::LocationName& out_name) const {
     out_name = m_system_settings.device_time_zone_location_name;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::SetDeviceTimeZoneLocationName(
-    Service::PSC::Time::LocationName& name) {
+    const Service::PSC::Time::LocationName& name) {
     m_system_settings.device_time_zone_location_name = name;
     SetSaveNeeded();
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::GetNetworkSystemClockContext(
-    Service::PSC::Time::SystemClockContext& out_context) {
+    Service::PSC::Time::SystemClockContext& out_context) const {
     out_context = m_system_settings.network_system_clock_context;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::SetNetworkSystemClockContext(
-    Service::PSC::Time::SystemClockContext& context) {
+    const Service::PSC::Time::SystemClockContext& context) {
     m_system_settings.network_system_clock_context = context;
     SetSaveNeeded();
     R_SUCCEED();
 }
 
-Result ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) {
+Result ISystemSettingsServer::IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) const {
     out_enabled = m_system_settings.user_system_clock_automatic_correction_enabled;
     R_SUCCEED();
 }
@@ -1371,32 +1454,32 @@ Result ISystemSettingsServer::SetExternalSteadyClockInternalOffset(s64 offset) {
     R_SUCCEED();
 }
 
-Result ISystemSettingsServer::GetExternalSteadyClockInternalOffset(s64& out_offset) {
+Result ISystemSettingsServer::GetExternalSteadyClockInternalOffset(s64& out_offset) const {
     out_offset = m_private_settings.external_steady_clock_internal_offset;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::GetDeviceTimeZoneLocationUpdatedTime(
-    Service::PSC::Time::SteadyClockTimePoint& out_time_point) {
+    Service::PSC::Time::SteadyClockTimePoint& out_time_point) const {
     out_time_point = m_system_settings.device_time_zone_location_updated_time;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::SetDeviceTimeZoneLocationUpdatedTime(
-    Service::PSC::Time::SteadyClockTimePoint& time_point) {
+    const Service::PSC::Time::SteadyClockTimePoint& time_point) {
     m_system_settings.device_time_zone_location_updated_time = time_point;
     SetSaveNeeded();
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::GetUserSystemClockAutomaticCorrectionUpdatedTime(
-    Service::PSC::Time::SteadyClockTimePoint& out_time_point) {
+    Service::PSC::Time::SteadyClockTimePoint& out_time_point) const {
     out_time_point = m_system_settings.user_system_clock_automatic_correction_updated_time_point;
     R_SUCCEED();
 }
 
 Result ISystemSettingsServer::SetUserSystemClockAutomaticCorrectionUpdatedTime(
-    Service::PSC::Time::SteadyClockTimePoint out_time_point) {
+    const Service::PSC::Time::SteadyClockTimePoint& out_time_point) {
     m_system_settings.user_system_clock_automatic_correction_updated_time_point = out_time_point;
     SetSaveNeeded();
     R_SUCCEED();
diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h
index a2258d16d3..acbda8b8cb 100644
--- a/src/core/hle/service/set/system_settings_server.h
+++ b/src/core/hle/service/set/system_settings_server.h
@@ -48,26 +48,28 @@ public:
         return result;
     }
 
-    Result GetExternalSteadyClockSourceId(Common::UUID& out_id);
-    Result SetExternalSteadyClockSourceId(Common::UUID id);
-    Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context);
-    Result SetUserSystemClockContext(Service::PSC::Time::SystemClockContext& context);
-    Result GetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& out_name);
-    Result SetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& name);
-    Result GetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& out_context);
-    Result SetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& context);
-    Result IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled);
+    Result GetVibrationMasterVolume(f32& out_volume) const;
+    Result SetVibrationMasterVolume(f32 volume);
+    Result GetExternalSteadyClockSourceId(Common::UUID& out_id) const;
+    Result SetExternalSteadyClockSourceId(const Common::UUID& id);
+    Result GetUserSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const;
+    Result SetUserSystemClockContext(const Service::PSC::Time::SystemClockContext& context);
+    Result GetDeviceTimeZoneLocationName(Service::PSC::Time::LocationName& out_name) const;
+    Result SetDeviceTimeZoneLocationName(const Service::PSC::Time::LocationName& name);
+    Result GetNetworkSystemClockContext(Service::PSC::Time::SystemClockContext& out_context) const;
+    Result SetNetworkSystemClockContext(const Service::PSC::Time::SystemClockContext& context);
+    Result IsUserSystemClockAutomaticCorrectionEnabled(bool& out_enabled) const;
     Result SetUserSystemClockAutomaticCorrectionEnabled(bool enabled);
     Result SetExternalSteadyClockInternalOffset(s64 offset);
-    Result GetExternalSteadyClockInternalOffset(s64& out_offset);
+    Result GetExternalSteadyClockInternalOffset(s64& out_offset) const;
     Result GetDeviceTimeZoneLocationUpdatedTime(
-        Service::PSC::Time::SteadyClockTimePoint& out_time_point);
+        Service::PSC::Time::SteadyClockTimePoint& out_time_point) const;
     Result SetDeviceTimeZoneLocationUpdatedTime(
-        Service::PSC::Time::SteadyClockTimePoint& time_point);
+        const Service::PSC::Time::SteadyClockTimePoint& time_point);
     Result GetUserSystemClockAutomaticCorrectionUpdatedTime(
-        Service::PSC::Time::SteadyClockTimePoint& out_time_point);
+        Service::PSC::Time::SteadyClockTimePoint& out_time_point) const;
     Result SetUserSystemClockAutomaticCorrectionUpdatedTime(
-        Service::PSC::Time::SteadyClockTimePoint time_point);
+        const Service::PSC::Time::SteadyClockTimePoint& time_point);
 
 private:
     void SetLanguageCode(HLERequestContext& ctx);
@@ -89,12 +91,17 @@ private:
     void SetNotificationSettings(HLERequestContext& ctx);
     void GetAccountNotificationSettings(HLERequestContext& ctx);
     void SetAccountNotificationSettings(HLERequestContext& ctx);
+    void GetVibrationMasterVolume(HLERequestContext& ctx);
+    void SetVibrationMasterVolume(HLERequestContext& ctx);
     void GetSettingsItemValueSize(HLERequestContext& ctx);
     void GetSettingsItemValue(HLERequestContext& ctx);
     void GetTvSettings(HLERequestContext& ctx);
     void SetTvSettings(HLERequestContext& ctx);
+    void IsForceMuteOnHeadphoneRemoved(HLERequestContext& ctx);
+    void SetForceMuteOnHeadphoneRemoved(HLERequestContext& ctx);
     void GetDebugModeFlag(HLERequestContext& ctx);
     void GetQuestFlag(HLERequestContext& ctx);
+    void SetQuestFlag(HLERequestContext& ctx);
     void GetDeviceTimeZoneLocationName(HLERequestContext& ctx);
     void SetDeviceTimeZoneLocationName(HLERequestContext& ctx);
     void SetRegionCode(HLERequestContext& ctx);
@@ -103,6 +110,7 @@ private:
     void IsUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
     void SetUserSystemClockAutomaticCorrectionEnabled(HLERequestContext& ctx);
     void GetPrimaryAlbumStorage(HLERequestContext& ctx);
+    void SetPrimaryAlbumStorage(HLERequestContext& ctx);
     void GetNfcEnableFlag(HLERequestContext& ctx);
     void SetNfcEnableFlag(HLERequestContext& ctx);
     void GetSleepSettings(HLERequestContext& ctx);
diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp
index ca824b4a32..755f82f29e 100644
--- a/src/hid_core/resource_manager.cpp
+++ b/src/hid_core/resource_manager.cpp
@@ -6,6 +6,8 @@
 #include "core/core_timing.h"
 #include "core/hle/kernel/k_shared_memory.h"
 #include "core/hle/service/ipc_helpers.h"
+#include "core/hle/service/set/system_settings_server.h"
+#include "core/hle/service/sm/sm.h"
 #include "hid_core/hid_core.h"
 #include "hid_core/hid_util.h"
 #include "hid_core/resource_manager.h"
@@ -180,7 +182,11 @@ void ResourceManager::InitializeHidCommonSampler() {
     debug_pad->SetAppletResource(applet_resource, &shared_mutex);
     digitizer->SetAppletResource(applet_resource, &shared_mutex);
     keyboard->SetAppletResource(applet_resource, &shared_mutex);
-    npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config);
+
+    const auto settings =
+        system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys");
+    npad->SetNpadExternals(applet_resource, &shared_mutex, handheld_config, settings);
+
     six_axis->SetAppletResource(applet_resource, &shared_mutex);
     mouse->SetAppletResource(applet_resource, &shared_mutex);
     debug_mouse->SetAppletResource(applet_resource, &shared_mutex);
diff --git a/src/hid_core/resources/hid_firmware_settings.cpp b/src/hid_core/resources/hid_firmware_settings.cpp
index 00ceff7e6f..9c9019e8f4 100644
--- a/src/hid_core/resources/hid_firmware_settings.cpp
+++ b/src/hid_core/resources/hid_firmware_settings.cpp
@@ -40,6 +40,13 @@ void HidFirmwareSettings::LoadSettings(bool reload_config) {
     m_set_sys->GetSettingsItemValue<bool>(is_touch_firmware_auto_update_disabled, "hid_debug",
                                           "touch_firmware_auto_update_disabled");
 
+    bool has_rail_interface{};
+    bool has_sio_mcu{};
+    m_set_sys->GetSettingsItemValue<bool>(has_rail_interface, "hid", "has_rail_interface");
+    m_set_sys->GetSettingsItemValue<bool>(has_sio_mcu, "hid", "has_sio_mcu");
+    platform_config.has_rail_interface.Assign(has_rail_interface);
+    platform_config.has_sio_mcu.Assign(has_sio_mcu);
+
     is_initialized = true;
 }
 
@@ -103,4 +110,9 @@ HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId()
     return features_per_id_disabled;
 }
 
+Set::PlatformConfig HidFirmwareSettings::GetPlatformConfig() {
+    LoadSettings(false);
+    return platform_config;
+}
+
 } // namespace Service::HID
diff --git a/src/hid_core/resources/hid_firmware_settings.h b/src/hid_core/resources/hid_firmware_settings.h
index 3694fa9a3e..7f146f1e65 100644
--- a/src/hid_core/resources/hid_firmware_settings.h
+++ b/src/hid_core/resources/hid_firmware_settings.h
@@ -4,6 +4,7 @@
 #pragma once
 
 #include "common/common_types.h"
+#include "core/hle/service/set/settings_types.h"
 
 namespace Core {
 class System;
@@ -39,6 +40,7 @@ public:
 
     FirmwareSetting GetFirmwareUpdateFailure();
     FeaturesPerId FeaturesDisabledPerId();
+    Set::PlatformConfig GetPlatformConfig();
 
 private:
     bool is_initialized{};
@@ -57,6 +59,7 @@ private:
     bool is_touch_firmware_auto_update_disabled{};
     FirmwareSetting is_firmware_update_failure{};
     FeaturesPerId features_per_id_disabled{};
+    Set::PlatformConfig platform_config{};
 
     std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
 };
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp
index d13a489c95..cde84b1bb2 100644
--- a/src/hid_core/resources/npad/npad.cpp
+++ b/src/hid_core/resources/npad/npad.cpp
@@ -1080,12 +1080,15 @@ void NPad::UnregisterAppletResourceUserId(u64 aruid) {
 
 void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource,
                             std::recursive_mutex* shared_mutex,
-                            std::shared_ptr<HandheldConfig> handheld_config) {
+                            std::shared_ptr<HandheldConfig> handheld_config,
+                            std::shared_ptr<Service::Set::ISystemSettingsServer> settings) {
     applet_resource_holder.applet_resource = resource;
     applet_resource_holder.shared_mutex = shared_mutex;
     applet_resource_holder.shared_npad_resource = &npad_resource;
     applet_resource_holder.handheld_config = handheld_config;
 
+    vibration_handler.SetSettingsService(settings);
+
     for (auto& abstract_pad : abstracted_pads) {
         abstract_pad.SetExternals(&applet_resource_holder, nullptr, nullptr, nullptr, nullptr,
                                   &vibration_handler, &hid_core);
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h
index 88289fa2b0..502cb9b55c 100644
--- a/src/hid_core/resources/npad/npad.h
+++ b/src/hid_core/resources/npad/npad.h
@@ -34,6 +34,10 @@ namespace Service::KernelHelpers {
 class ServiceContext;
 } // namespace Service::KernelHelpers
 
+namespace Service::Set {
+class ISystemSettingsServer;
+}
+
 union Result;
 
 namespace Service::HID {
@@ -128,7 +132,8 @@ public:
     void UnregisterAppletResourceUserId(u64 aruid);
     void SetNpadExternals(std::shared_ptr<AppletResource> resource,
                           std::recursive_mutex* shared_mutex,
-                          std::shared_ptr<HandheldConfig> handheld_config);
+                          std::shared_ptr<HandheldConfig> handheld_config,
+                          std::shared_ptr<Service::Set::ISystemSettingsServer> settings);
 
     AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
 
diff --git a/src/hid_core/resources/npad/npad_vibration.cpp b/src/hid_core/resources/npad/npad_vibration.cpp
index 05aad4c54f..02b1f02903 100644
--- a/src/hid_core/resources/npad/npad_vibration.cpp
+++ b/src/hid_core/resources/npad/npad_vibration.cpp
@@ -1,6 +1,7 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-3.0-or-later
 
+#include "core/hle/service/set/system_settings_server.h"
 #include "hid_core/hid_result.h"
 #include "hid_core/resources/npad/npad_vibration.h"
 
@@ -13,10 +14,11 @@ NpadVibration::~NpadVibration() = default;
 Result NpadVibration::Activate() {
     std::scoped_lock lock{mutex};
 
-    const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
-    // if (master_volume < 0.0f || master_volume > 1.0f) {
-    //     return ResultVibrationStrengthOutOfRange;
-    // }
+    f32 master_volume = 1.0f;
+    m_set_sys->GetVibrationMasterVolume(master_volume);
+    if (master_volume < 0.0f || master_volume > 1.0f) {
+        return ResultVibrationStrengthOutOfRange;
+    }
 
     volume = master_volume;
     return ResultSuccess;
@@ -26,6 +28,12 @@ Result NpadVibration::Deactivate() {
     return ResultSuccess;
 }
 
+Result NpadVibration::SetSettingsService(
+    std::shared_ptr<Service::Set::ISystemSettingsServer> settings) {
+    m_set_sys = settings;
+    return ResultSuccess;
+}
+
 Result NpadVibration::SetVibrationMasterVolume(f32 master_volume) {
     std::scoped_lock lock{mutex};
 
@@ -34,7 +42,7 @@ Result NpadVibration::SetVibrationMasterVolume(f32 master_volume) {
     }
 
     volume = master_volume;
-    // nn::settings::system::SetVibrationMasterVolume(master_volume);
+    m_set_sys->SetVibrationMasterVolume(master_volume);
 
     return ResultSuccess;
 }
@@ -48,10 +56,11 @@ Result NpadVibration::GetVibrationVolume(f32& out_volume) const {
 Result NpadVibration::GetVibrationMasterVolume(f32& out_volume) const {
     std::scoped_lock lock{mutex};
 
-    const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
-    // if (master_volume < 0.0f || master_volume > 1.0f) {
-    //     return ResultVibrationStrengthOutOfRange;
-    // }
+    f32 master_volume = 1.0f;
+    m_set_sys->GetVibrationMasterVolume(master_volume);
+    if (master_volume < 0.0f || master_volume > 1.0f) {
+        return ResultVibrationStrengthOutOfRange;
+    }
 
     out_volume = master_volume;
     return ResultSuccess;
@@ -67,10 +76,11 @@ Result NpadVibration::BeginPermitVibrationSession(u64 aruid) {
 Result NpadVibration::EndPermitVibrationSession() {
     std::scoped_lock lock{mutex};
 
-    const f32 master_volume = 1.0f; // nn::settings::system::GetVibrationMasterVolume();
-    // if (master_volume < 0.0f || master_volume > 1.0f) {
-    //     return ResultVibrationStrengthOutOfRange;
-    // }
+    f32 master_volume = 1.0f;
+    m_set_sys->GetVibrationMasterVolume(master_volume);
+    if (master_volume < 0.0f || master_volume > 1.0f) {
+        return ResultVibrationStrengthOutOfRange;
+    }
 
     volume = master_volume;
     session_aruid = 0;
diff --git a/src/hid_core/resources/npad/npad_vibration.h b/src/hid_core/resources/npad/npad_vibration.h
index d5a95f2a09..6412ca4ab0 100644
--- a/src/hid_core/resources/npad/npad_vibration.h
+++ b/src/hid_core/resources/npad/npad_vibration.h
@@ -8,6 +8,10 @@
 #include "common/common_types.h"
 #include "core/hle/result.h"
 
+namespace Service::Set {
+class ISystemSettingsServer;
+}
+
 namespace Service::HID {
 
 class NpadVibration final {
@@ -18,6 +22,7 @@ public:
     Result Activate();
     Result Deactivate();
 
+    Result SetSettingsService(std::shared_ptr<Service::Set::ISystemSettingsServer> settings);
     Result SetVibrationMasterVolume(f32 master_volume);
     Result GetVibrationVolume(f32& out_volume) const;
     Result GetVibrationMasterVolume(f32& out_volume) const;
@@ -31,6 +36,8 @@ private:
     f32 volume{};
     u64 session_aruid{};
     mutable std::mutex mutex;
+
+    std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys;
 };
 
 } // namespace Service::HID