diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h
index ccdd391114..575f1b677b 100644
--- a/Marlin/src/HAL/AVR/inc/SanityCheck.h
+++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h
@@ -41,6 +41,8 @@
   #elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
     #error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
   #endif
+#elif defined(SPINDLE_LASER_FREQUENCY)
+  #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_PWM."
 #endif
 
 /**
diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h
index 0ddd092852..71937a897a 100644
--- a/Marlin/src/feature/spindle_laser.h
+++ b/Marlin/src/feature/spindle_laser.h
@@ -109,8 +109,6 @@ public:
   FORCE_INLINE static void refresh() { apply_power(power); }
   FORCE_INLINE static void set_power(const uint8_t upwr) { power = upwr; refresh(); }
 
-  static inline void set_enabled(const bool enable) { set_power(enable ? (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)) : 0); }
-
   #if ENABLED(SPINDLE_LASER_PWM)
 
     static void set_ocr(const uint8_t ocr);
@@ -148,21 +146,21 @@ public:
       cutter_power_t upwr;
       switch (pwrUnit) {
         case 0:                                                 // PWM
-          upwr = (
+          upwr = cutter_power_t(
               (pwr < pct_to_ocr(min_pct)) ? pct_to_ocr(min_pct) // Use minimum if set below
             : (pwr > pct_to_ocr(max_pct)) ? pct_to_ocr(max_pct) // Use maximum if set above
             :  pwr
           );
           break;
         case 1:                                                 // PERCENT
-          upwr = (
+          upwr = cutter_power_t(
               (pwr < min_pct) ? min_pct                         // Use minimum if set below
             : (pwr > max_pct) ? max_pct                         // Use maximum if set above
             :  pwr                                              // PCT
           );
           break;
         case 2:                                                 // RPM
-          upwr = (
+          upwr = cutter_power_t(
               (pwr < SPEED_POWER_MIN) ? SPEED_POWER_MIN         // Use minimum if set below
             : (pwr > SPEED_POWER_MAX) ? SPEED_POWER_MAX         // Use maximum if set above
             : pwr                                               // Calculate OCR value
@@ -175,6 +173,10 @@ public:
 
   #endif // SPINDLE_LASER_PWM
 
+  static inline void set_enabled(const bool enable) {
+    set_power(enable ? TERN(SPINDLE_LASER_PWM, (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)), 255) : 0);
+  }
+
   // Wait for spindle to spin up or spin down
   static inline void power_delay(const bool on) {
     #if DISABLED(LASER_POWER_INLINE)
@@ -194,7 +196,7 @@ public:
 
     static inline void enable_with_dir(const bool reverse) {
       isReady = true;
-      const uint8_t ocr = upower_to_ocr(menuPower);
+      const uint8_t ocr = TERN(SPINDLE_LASER_PWM, upower_to_ocr(menuPower), 255);
       if (menuPower)
         power = ocr;
       else
diff --git a/Marlin/src/gcode/control/M3-M5.cpp b/Marlin/src/gcode/control/M3-M5.cpp
index 0ef385221b..2ddccde0d2 100644
--- a/Marlin/src/gcode/control/M3-M5.cpp
+++ b/Marlin/src/gcode/control/M3-M5.cpp
@@ -67,8 +67,12 @@
  */
 void GcodeSuite::M3_M4(const bool is_M4) {
   auto get_s_power = [] {
-    if (parser.seen('S'))
-      cutter.unitPower = cutter.power_to_range(cutter_power_t(round(parser.value_float())));
+    if (parser.seenval('S')) {
+      const float spwr = parser.value_float();
+      cutter.unitPower = TERN(SPINDLE_LASER_PWM,
+                              cutter.power_to_range(cutter_power_t(round(spwr))),
+                              spwr > 0 ? 255 : 0);
+    }
     else
       cutter.unitPower = cutter.cpwr_to_upwr(SPEED_POWER_STARTUP);
     return cutter.unitPower;
@@ -86,7 +90,7 @@ void GcodeSuite::M3_M4(const bool is_M4) {
         else
           cutter.inline_power(cutter.upower_to_ocr(get_s_power()));
       #else
-        cutter.inline_enabled(true);
+        cutter.set_inline_enabled(true);
       #endif
       return;
     }
diff --git a/Marlin/src/gcode/gcode.cpp b/Marlin/src/gcode/gcode.cpp
index 5dee317ca7..f543342e81 100644
--- a/Marlin/src/gcode/gcode.cpp
+++ b/Marlin/src/gcode/gcode.cpp
@@ -179,8 +179,10 @@ void GcodeSuite::get_destination_from_command() {
 
   #if ENABLED(LASER_MOVE_POWER)
     // Set the laser power in the planner to configure this move
-    if (parser.seen('S'))
-      cutter.inline_power(cutter.power_to_range(cutter_power_t(round(parser.value_float()))));
+    if (parser.seen('S')) {
+      const float spwr = parser.value_float();
+      cutter.inline_power(TERN(SPINDLE_LASER_PWM, cutter.power_to_range(cutter_power_t(round(spwr))), spwr > 0 ? 255 : 0));
+    }
     else if (ENABLED(LASER_MOVE_G0_OFF) && parser.codenum == 0) // G0
       cutter.set_inline_enabled(false);
   #endif