diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 8bc69c372..f47a9e61c 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -31,6 +31,10 @@ public:
     virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
                           std::size_t size) = 0;
 
+    // When the controller is requesting a motion update for the shared memory
+    virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
+                                std::size_t size) {}
+
     // Called when input devices should be loaded
     virtual void OnLoadInputDevices() = 0;
 
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 620386cd1..e34ee519e 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -365,44 +365,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
         }
         const u32 npad_index = static_cast<u32>(i);
 
-        const std::array<SixAxisGeneric*, 6> controller_sixaxes{
-            &npad.sixaxis_full,       &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
-            &npad.sixaxis_dual_right, &npad.sixaxis_left,     &npad.sixaxis_right,
-        };
-
-        for (auto* sixaxis_sensor : controller_sixaxes) {
-            sixaxis_sensor->common.entry_count = 16;
-            sixaxis_sensor->common.total_entry_count = 17;
-
-            const auto& last_entry =
-                sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
-
-            sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
-            sixaxis_sensor->common.last_entry_index =
-                (sixaxis_sensor->common.last_entry_index + 1) % 17;
-
-            auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
-
-            cur_entry.timestamp = last_entry.timestamp + 1;
-            cur_entry.timestamp2 = cur_entry.timestamp;
-        }
-
-        // Try to read sixaxis sensor states
-        std::array<MotionDevice, 2> motion_devices;
-
-        if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
-            sixaxis_at_rest = true;
-            for (std::size_t e = 0; e < motion_devices.size(); ++e) {
-                const auto& device = motions[i][e];
-                if (device) {
-                    std::tie(motion_devices[e].accel, motion_devices[e].gyro,
-                             motion_devices[e].rotation, motion_devices[e].orientation) =
-                        device->GetStatus();
-                    sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
-                }
-            }
-        }
-
         RequestPadStateUpdate(npad_index);
         auto& pad_state = npad_pad_states[npad_index];
 
@@ -446,13 +408,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
             main_controller.pad.r_stick = pad_state.r_stick;
 
             libnx_entry.connection_status.IsWired.Assign(1);
-
-            if (sixaxis_sensors_enabled && motions[i][0]) {
-                full_sixaxis_entry.accel = motion_devices[0].accel;
-                full_sixaxis_entry.gyro = motion_devices[0].gyro;
-                full_sixaxis_entry.rotation = motion_devices[0].rotation;
-                full_sixaxis_entry.orientation = motion_devices[0].orientation;
-            }
             break;
         case NPadControllerType::Handheld:
             handheld_entry.connection_status.raw = 0;
@@ -471,13 +426,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
             libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
             libnx_entry.connection_status.IsLeftJoyWired.Assign(1);
             libnx_entry.connection_status.IsRightJoyWired.Assign(1);
-
-            if (sixaxis_sensors_enabled && motions[i][0]) {
-                handheld_sixaxis_entry.accel = motion_devices[0].accel;
-                handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
-                handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
-                handheld_sixaxis_entry.orientation = motion_devices[0].orientation;
-            }
             break;
         case NPadControllerType::JoyDual:
             dual_entry.connection_status.raw = 0;
@@ -490,21 +438,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
 
             libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
             libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
-
-            if (sixaxis_sensors_enabled && motions[i][0]) {
-                // Set motion for the left joycon
-                dual_left_sixaxis_entry.accel = motion_devices[0].accel;
-                dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
-                dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
-                dual_left_sixaxis_entry.orientation = motion_devices[0].orientation;
-            }
-            if (sixaxis_sensors_enabled && motions[i][1]) {
-                // Set motion for the right joycon
-                dual_right_sixaxis_entry.accel = motion_devices[1].accel;
-                dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
-                dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
-                dual_right_sixaxis_entry.orientation = motion_devices[1].orientation;
-            }
             break;
         case NPadControllerType::JoyLeft:
             left_entry.connection_status.raw = 0;
@@ -515,13 +448,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
             left_entry.pad.r_stick = pad_state.r_stick;
 
             libnx_entry.connection_status.IsLeftJoyConnected.Assign(1);
-
-            if (sixaxis_sensors_enabled && motions[i][0]) {
-                left_sixaxis_entry.accel = motion_devices[0].accel;
-                left_sixaxis_entry.gyro = motion_devices[0].gyro;
-                left_sixaxis_entry.rotation = motion_devices[0].rotation;
-                left_sixaxis_entry.orientation = motion_devices[0].orientation;
-            }
             break;
         case NPadControllerType::JoyRight:
             right_entry.connection_status.raw = 0;
@@ -532,13 +458,6 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
             right_entry.pad.r_stick = pad_state.r_stick;
 
             libnx_entry.connection_status.IsRightJoyConnected.Assign(1);
-
-            if (sixaxis_sensors_enabled && motions[i][1]) {
-                right_sixaxis_entry.accel = motion_devices[1].accel;
-                right_sixaxis_entry.gyro = motion_devices[1].gyro;
-                right_sixaxis_entry.rotation = motion_devices[1].rotation;
-                right_sixaxis_entry.orientation = motion_devices[1].orientation;
-            }
             break;
         case NPadControllerType::Pokeball:
             pokeball_entry.connection_status.raw = 0;
@@ -561,6 +480,143 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
                 shared_memory_entries.size() * sizeof(NPadEntry));
 }
 
+void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
+                                     std::size_t data_len) {
+    if (!IsControllerActivated()) {
+        return;
+    }
+    for (std::size_t i = 0; i < shared_memory_entries.size(); i++) {
+        auto& npad = shared_memory_entries[i];
+
+        const auto& controller_type = connected_controllers[i].type;
+
+        if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
+            continue;
+        }
+
+        const std::array<SixAxisGeneric*, 6> controller_sixaxes{
+            &npad.sixaxis_full,       &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
+            &npad.sixaxis_dual_right, &npad.sixaxis_left,     &npad.sixaxis_right,
+        };
+
+        for (auto* sixaxis_sensor : controller_sixaxes) {
+            sixaxis_sensor->common.entry_count = 16;
+            sixaxis_sensor->common.total_entry_count = 17;
+
+            const auto& last_entry =
+                sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
+
+            sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
+            sixaxis_sensor->common.last_entry_index =
+                (sixaxis_sensor->common.last_entry_index + 1) % 17;
+
+            auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
+
+            cur_entry.timestamp = last_entry.timestamp + 1;
+            cur_entry.timestamp2 = cur_entry.timestamp;
+        }
+
+        // Try to read sixaxis sensor states
+        std::array<MotionDevice, 2> motion_devices;
+
+        if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
+            sixaxis_at_rest = true;
+            for (std::size_t e = 0; e < motion_devices.size(); ++e) {
+                const auto& device = motions[i][e];
+                if (device) {
+                    std::tie(motion_devices[e].accel, motion_devices[e].gyro,
+                             motion_devices[e].rotation, motion_devices[e].orientation) =
+                        device->GetStatus();
+                    sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
+                }
+            }
+        }
+
+        auto& main_controller =
+            npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
+        auto& handheld_entry =
+            npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
+        auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index];
+        auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index];
+        auto& right_entry =
+            npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index];
+        auto& pokeball_entry =
+            npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index];
+        auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
+
+        auto& full_sixaxis_entry =
+            npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index];
+        auto& handheld_sixaxis_entry =
+            npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
+        auto& dual_left_sixaxis_entry =
+            npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
+        auto& dual_right_sixaxis_entry =
+            npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
+        auto& left_sixaxis_entry =
+            npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
+        auto& right_sixaxis_entry =
+            npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
+
+        switch (controller_type) {
+        case NPadControllerType::None:
+            UNREACHABLE();
+            break;
+        case NPadControllerType::ProController:
+            if (sixaxis_sensors_enabled && motions[i][0]) {
+                full_sixaxis_entry.accel = motion_devices[0].accel;
+                full_sixaxis_entry.gyro = motion_devices[0].gyro;
+                full_sixaxis_entry.rotation = motion_devices[0].rotation;
+                full_sixaxis_entry.orientation = motion_devices[0].orientation;
+            }
+            break;
+        case NPadControllerType::Handheld:
+            if (sixaxis_sensors_enabled && motions[i][0]) {
+                handheld_sixaxis_entry.accel = motion_devices[0].accel;
+                handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
+                handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
+                handheld_sixaxis_entry.orientation = motion_devices[0].orientation;
+            }
+            break;
+        case NPadControllerType::JoyDual:
+            if (sixaxis_sensors_enabled && motions[i][0]) {
+                // Set motion for the left joycon
+                dual_left_sixaxis_entry.accel = motion_devices[0].accel;
+                dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
+                dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
+                dual_left_sixaxis_entry.orientation = motion_devices[0].orientation;
+            }
+            if (sixaxis_sensors_enabled && motions[i][1]) {
+                // Set motion for the right joycon
+                dual_right_sixaxis_entry.accel = motion_devices[1].accel;
+                dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
+                dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
+                dual_right_sixaxis_entry.orientation = motion_devices[1].orientation;
+            }
+            break;
+        case NPadControllerType::JoyLeft:
+            if (sixaxis_sensors_enabled && motions[i][0]) {
+                left_sixaxis_entry.accel = motion_devices[0].accel;
+                left_sixaxis_entry.gyro = motion_devices[0].gyro;
+                left_sixaxis_entry.rotation = motion_devices[0].rotation;
+                left_sixaxis_entry.orientation = motion_devices[0].orientation;
+            }
+            break;
+        case NPadControllerType::JoyRight:
+            if (sixaxis_sensors_enabled && motions[i][1]) {
+                right_sixaxis_entry.accel = motion_devices[1].accel;
+                right_sixaxis_entry.gyro = motion_devices[1].gyro;
+                right_sixaxis_entry.rotation = motion_devices[1].rotation;
+                right_sixaxis_entry.orientation = motion_devices[1].orientation;
+            }
+            break;
+        case NPadControllerType::Pokeball:
+            break;
+        }
+    }
+    std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
+                shared_memory_entries.size() * sizeof(NPadEntry));
+}
+
 void Controller_NPad::SetSupportedStyleSet(NPadType style_set) {
     style.raw = style_set.raw;
 }
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 654d97c3f..0fa7455ba 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -32,6 +32,10 @@ public:
     // When the controller is requesting an update for the shared memory
     void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override;
 
+    // When the controller is requesting a motion update for the shared memory
+    void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
+                        std::size_t size) override;
+
     // Called when input devices should be loaded
     void OnLoadInputDevices() override;
 
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 395e83b3f..9a7e5e265 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -40,7 +40,8 @@ namespace Service::HID {
 // Updating period for each HID device.
 // HID is polled every 15ms, this value was derived from
 // https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering#joy-con-status-data-packet
-constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000}; // (1ms, 1000Hz)
+constexpr auto pad_update_ns = std::chrono::nanoseconds{1000 * 1000};         // (1ms, 1000Hz)
+constexpr auto motion_update_ns = std::chrono::nanoseconds{15 * 1000 * 1000}; // (15ms, 66.666Hz)
 constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
 
 IAppletResource::IAppletResource(Core::System& system)
@@ -79,10 +80,14 @@ IAppletResource::IAppletResource(Core::System& system)
         [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
             UpdateControllers(user_data, ns_late);
         });
-
-    // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
+    motion_update_event = Core::Timing::CreateEvent(
+        "HID::MotionPadCallback",
+        [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+            UpdateMotion(user_data, ns_late);
+        });
 
     system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
+    system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
 
     ReloadInputDevices();
 }
@@ -122,6 +127,16 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
     core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
 }
 
+void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+    auto& core_timing = system.CoreTiming();
+
+    for (const auto& controller : controllers) {
+        controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
+    }
+
+    core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event);
+}
+
 class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
 public:
     IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index e04aaf1e9..3cfd72a51 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -65,10 +65,12 @@ private:
 
     void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
     void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+    void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 
     std::shared_ptr<Kernel::SharedMemory> shared_mem;
 
     std::shared_ptr<Core::Timing::EventType> pad_update_event;
+    std::shared_ptr<Core::Timing::EventType> motion_update_event;
     Core::System& system;
 
     std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>