diff --git a/src/common/input.h b/src/common/input.h
index b533f3844c..cb30b72547 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -100,7 +100,6 @@ enum class CameraError {
 enum class VibrationAmplificationType {
     Linear,
     Exponential,
-    Test,
 };
 
 // Analog properties for calibration
@@ -325,6 +324,10 @@ public:
         return VibrationError::NotSupported;
     }
 
+    virtual bool IsVibrationEnabled() {
+        return false;
+    }
+
     virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
         return PollingError::NotSupported;
     }
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 57eff72fec..b17b00f2cc 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -970,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
            Common::Input::VibrationError::None;
 }
 
-bool EmulatedController::TestVibration(std::size_t device_index) {
-    if (device_index >= output_devices.size()) {
-        return false;
-    }
-    if (!output_devices[device_index]) {
-        return false;
-    }
-
+bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
     const auto player_index = NpadIdTypeToIndex(npad_id_type);
     const auto& player = Settings::values.players.GetValue()[player_index];
 
@@ -985,31 +978,15 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
         return false;
     }
 
-    const Common::Input::VibrationStatus test_vibration = {
-        .low_amplitude = 0.001f,
-        .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
-        .high_amplitude = 0.001f,
-        .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
-        .type = Common::Input::VibrationAmplificationType::Test,
-    };
+    if (device_index >= output_devices.size()) {
+        return false;
+    }
 
-    const Common::Input::VibrationStatus zero_vibration = {
-        .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
-        .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
-        .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
-        .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
-        .type = Common::Input::VibrationAmplificationType::Test,
-    };
+    if (!output_devices[device_index]) {
+        return false;
+    }
 
-    // Send a slight vibration to test for rumble support
-    output_devices[device_index]->SetVibration(test_vibration);
-
-    // Wait for about 15ms to ensure the controller is ready for the stop command
-    std::this_thread::sleep_for(std::chrono::milliseconds(15));
-
-    // Stop any vibration and return the result
-    return output_devices[device_index]->SetVibration(zero_vibration) ==
-           Common::Input::VibrationError::None;
+    return output_devices[device_index]->IsVibrationEnabled();
 }
 
 bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
@@ -1234,12 +1211,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const {
     return is_connected;
 }
 
-bool EmulatedController::IsVibrationEnabled() const {
-    const auto player_index = NpadIdTypeToIndex(npad_id_type);
-    const auto& player = Settings::values.players.GetValue()[player_index];
-    return player.vibration_enabled;
-}
-
 NpadIdType EmulatedController::GetNpadIdType() const {
     std::scoped_lock lock{mutex};
     return npad_id_type;
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index 319226bf82..d004ca56ad 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -206,9 +206,6 @@ public:
      */
     bool IsConnected(bool get_temporary_value = false) const;
 
-    /// Returns true if vibration is enabled
-    bool IsVibrationEnabled() const;
-
     /// Removes all callbacks created from input devices
     void UnloadInput();
 
@@ -339,7 +336,7 @@ public:
      * Sends a small vibration to the output device
      * @return true if SetVibration was successfull
      */
-    bool TestVibration(std::size_t device_index);
+    bool IsVibrationEnabled(std::size_t device_index);
 
     /**
      * Sets the desired data to be polled from a controller
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 3b26e96dea..2f871de310 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -868,7 +868,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
         return false;
     }
 
-    if (!controller.device->IsVibrationEnabled()) {
+    if (!controller.device->IsVibrationEnabled(device_index)) {
         if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
             controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
             // Send an empty vibration to stop any vibrations.
@@ -1001,7 +1001,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
     }
 
     controller.vibration[device_index].device_mounted =
-        controller.device->TestVibration(device_index);
+        controller.device->IsVibrationEnabled(device_index);
 }
 
 void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp
index f4dd24e7df..826fa21097 100644
--- a/src/input_common/drivers/gc_adapter.cpp
+++ b/src/input_common/drivers/gc_adapter.cpp
@@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) {
     return true;
 }
 
-Common::Input::VibrationError GCAdapter::SetRumble(
+Common::Input::VibrationError GCAdapter::SetVibration(
     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
     const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
     const auto processed_amplitude =
@@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble(
     return Common::Input::VibrationError::None;
 }
 
+bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+    return rumble_enabled;
+}
+
 void GCAdapter::UpdateVibrations() {
     // Use 8 states to keep the switching between on/off fast enough for
     // a human to feel different vibration strenght
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h
index 8682da8470..7f81767f77 100644
--- a/src/input_common/drivers/gc_adapter.h
+++ b/src/input_common/drivers/gc_adapter.h
@@ -25,9 +25,11 @@ public:
     explicit GCAdapter(std::string input_engine_);
     ~GCAdapter() override;
 
-    Common::Input::VibrationError SetRumble(
+    Common::Input::VibrationError SetVibration(
         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
 
+    bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
     /// Used for automapping features
     std::vector<Common::ParamPackage> GetInputDevices() const override;
     ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index c175a88538..45ce588f04 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -114,6 +114,20 @@ public:
         }
         return false;
     }
+
+    void EnableVibration(bool is_enabled) {
+        has_vibration = is_enabled;
+        is_vibration_tested = true;
+    }
+
+    bool HasVibration() const {
+        return has_vibration;
+    }
+
+    bool IsVibrationTested() const {
+        return is_vibration_tested;
+    }
+
     /**
      * The Pad identifier of the joystick
      */
@@ -236,6 +250,8 @@ private:
     u64 last_motion_update{};
     bool has_gyro{false};
     bool has_accel{false};
+    bool has_vibration{false};
+    bool is_vibration_tested{false};
     BasicMotion motion;
 };
 
@@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
     return devices;
 }
 
-Common::Input::VibrationError SDLDriver::SetRumble(
+Common::Input::VibrationError SDLDriver::SetVibration(
     const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
     const auto joystick =
         GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
@@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble(
         .type = Common::Input::VibrationAmplificationType::Exponential,
     };
 
-    if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
-        if (!joystick->RumblePlay(new_vibration)) {
-            return Common::Input::VibrationError::Unknown;
-        }
-        return Common::Input::VibrationError::None;
-    }
-
     vibration_queue.Push(VibrationRequest{
         .identifier = identifier,
         .vibration = new_vibration,
@@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble(
     return Common::Input::VibrationError::None;
 }
 
+bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
+    const auto joystick =
+        GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
+
+    constexpr Common::Input::VibrationStatus test_vibration{
+        .low_amplitude = 1,
+        .low_frequency = 160.0f,
+        .high_amplitude = 1,
+        .high_frequency = 320.0f,
+        .type = Common::Input::VibrationAmplificationType::Exponential,
+    };
+
+    constexpr Common::Input::VibrationStatus zero_vibration{
+        .low_amplitude = 0,
+        .low_frequency = 160.0f,
+        .high_amplitude = 0,
+        .high_frequency = 320.0f,
+        .type = Common::Input::VibrationAmplificationType::Exponential,
+    };
+
+    if (joystick->IsVibrationTested()) {
+        return joystick->HasVibration();
+    }
+
+    // First vibration might fail
+    joystick->RumblePlay(test_vibration);
+
+    // Wait for about 15ms to ensure the controller is ready for the stop command
+    std::this_thread::sleep_for(std::chrono::milliseconds(15));
+
+    if (!joystick->RumblePlay(zero_vibration)) {
+        joystick->EnableVibration(false);
+        return false;
+    }
+
+    joystick->EnableVibration(true);
+    return true;
+}
+
 void SDLDriver::SendVibrations() {
     while (!vibration_queue.Empty()) {
         VibrationRequest request;
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h
index fc3a445724..d1b4471cf7 100644
--- a/src/input_common/drivers/sdl_driver.h
+++ b/src/input_common/drivers/sdl_driver.h
@@ -61,9 +61,11 @@ public:
 
     bool IsStickInverted(const Common::ParamPackage& params) override;
 
-    Common::Input::VibrationError SetRumble(
+    Common::Input::VibrationError SetVibration(
         const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
 
+    bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
 private:
     struct VibrationRequest {
         PadIdentifier identifier;
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h
index cfbdb26bd7..d4c264a8eb 100644
--- a/src/input_common/input_engine.h
+++ b/src/input_common/input_engine.h
@@ -108,12 +108,17 @@ public:
                          [[maybe_unused]] const Common::Input::LedStatus& led_status) {}
 
     // Sets rumble to a controller
-    virtual Common::Input::VibrationError SetRumble(
+    virtual Common::Input::VibrationError SetVibration(
         [[maybe_unused]] const PadIdentifier& identifier,
         [[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
         return Common::Input::VibrationError::NotSupported;
     }
 
+    // Returns true if device supports vibrations
+    virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+        return false;
+    }
+
     // Sets polling mode to a controller
     virtual Common::Input::PollingError SetPollingMode(
         [[maybe_unused]] const PadIdentifier& identifier,
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
index ccc3076ca4..4ac1821473 100644
--- a/src/input_common/input_poller.cpp
+++ b/src/input_common/input_poller.cpp
@@ -763,7 +763,11 @@ public:
 
     Common::Input::VibrationError SetVibration(
         const Common::Input::VibrationStatus& vibration_status) override {
-        return input_engine->SetRumble(identifier, vibration_status);
+        return input_engine->SetVibration(identifier, vibration_status);
+    }
+
+    bool IsVibrationEnabled() override {
+        return input_engine->IsVibrationEnabled(identifier);
     }
 
     Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override {