diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 9fa9e18814..f9618709c9 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -882,14 +882,14 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
     SRC += outputselect.c
 
     ifeq ($(strip $(BLUETOOTH_DRIVER)), BluefruitLE)
-        OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE
-        SRC += analog.c
+        OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE -DHAL_USE_SPI=TRUE
         SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
+        QUANTUM_LIB_SRC += analog.c
         QUANTUM_LIB_SRC += spi_master.c
     endif
 
     ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
-        OPT_DEFS += -DBLUETOOTH_RN42
+        OPT_DEFS += -DBLUETOOTH_RN42 -DHAL_USE_SERIAL=TRUE
         SRC += $(DRIVER_PATH)/bluetooth/rn42.c
         QUANTUM_LIB_SRC += uart.c
     endif
diff --git a/drivers/bluetooth/bluefruit_le.cpp b/drivers/bluetooth/bluefruit_le.cpp
index 19310767cf..50170b83fe 100644
--- a/drivers/bluetooth/bluefruit_le.cpp
+++ b/drivers/bluetooth/bluefruit_le.cpp
@@ -79,9 +79,7 @@ struct sdep_msg {
 enum queue_type {
     QTKeyReport, // 1-byte modifier + 6-byte key report
     QTConsumer,  // 16-bit key code
-#ifdef MOUSE_ENABLE
     QTMouseMove, // 4-byte mouse report
-#endif
 };
 
 struct queue_item {
@@ -442,7 +440,7 @@ bool bluefruit_le_enable_keyboard(void) {
     // Disable command echo
     static const char kEcho[] PROGMEM = "ATE=0";
     // Make the advertised name match the keyboard
-    static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" STR(PRODUCT);
+    static const char kGapDevName[] PROGMEM = "AT+GAPDEVNAME=" PRODUCT;
     // Turn on keyboard support
     static const char kHidEnOn[] PROGMEM = "AT+BLEHIDEN=1";
 
@@ -581,10 +579,12 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) {
             snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->key.modifier, item->key.keys[0], item->key.keys[1], item->key.keys[2], item->key.keys[3], item->key.keys[4], item->key.keys[5]);
             return at_command(cmdbuf, NULL, 0, true, timeout);
 
+#ifdef EXTRAKEY_ENABLE
         case QTConsumer:
             strcpy_P(fmtbuf, PSTR("AT+BLEHIDCONTROLKEY=0x%04x"));
             snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, item->consumer);
             return at_command(cmdbuf, NULL, 0, true, timeout);
+#endif
 
 #ifdef MOUSE_ENABLE
         case QTMouseMove:
@@ -658,7 +658,6 @@ void bluefruit_le_send_consumer_key(uint16_t usage) {
     }
 }
 
-#ifdef MOUSE_ENABLE
 void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) {
     struct queue_item item;
 
@@ -673,7 +672,6 @@ void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan,
         send_buf_send_one();
     }
 }
-#endif
 
 uint32_t bluefruit_le_read_battery_voltage(void) {
     return state.vbat;
diff --git a/drivers/bluetooth/bluefruit_le.h b/drivers/bluetooth/bluefruit_le.h
index de301c6167..731ba2e370 100644
--- a/drivers/bluetooth/bluefruit_le.h
+++ b/drivers/bluetooth/bluefruit_le.h
@@ -40,12 +40,10 @@ extern void bluefruit_le_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uin
  * (milliseconds) */
 extern void bluefruit_le_send_consumer_key(uint16_t usage);
 
-#ifdef MOUSE_ENABLE
 /* Send a mouse/wheel movement report.
  * The parameters are signed and indicate positive or negative direction
  * change. */
 extern void bluefruit_le_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons);
-#endif
 
 /* Compute battery voltage by reading an analog pin.
  * Returns the integer number of millivolts */
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 1c62a43d9d..3b5e9b0200 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -107,6 +107,11 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 #ifdef BLUETOOTH_ENABLE
 #    include "outputselect.h"
+#    ifdef BLUETOOTH_BLUEFRUIT_LE
+#        include "bluefruit_le.h"
+#    elif BLUETOOTH_RN42
+#        include "rn42.h"
+#    endif
 #endif
 #ifdef CAPS_WORD_ENABLE
 #    include "caps_word.h"
@@ -346,9 +351,6 @@ void quantum_init(void) {
 #ifdef HAPTIC_ENABLE
     haptic_init();
 #endif
-#if defined(BLUETOOTH_ENABLE) && defined(OUTPUT_AUTO_ENABLE)
-    set_output(OUTPUT_AUTO);
-#endif
 }
 
 /** \brief keyboard_init
@@ -410,6 +412,9 @@ void keyboard_init(void) {
     // init after split init
     pointing_device_init();
 #endif
+#if defined(BLUETOOTH_RN42)
+    rn42_init();
+#endif
 
 #if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE)
     debug_enable = true;
@@ -670,5 +675,9 @@ void keyboard_task(void) {
     programmable_button_send();
 #endif
 
+#ifdef BLUETOOTH_BLUEFRUIT_LE
+    bluefruit_le_task();
+#endif
+
     led_task();
 }
diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
index 2ebd176ea4..53854b94fb 100644
--- a/tmk_core/protocol/host.c
+++ b/tmk_core/protocol/host.c
@@ -24,6 +24,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "debug.h"
 #include "digitizer.h"
 
+#ifdef BLUETOOTH_ENABLE
+#    include "outputselect.h"
+#    ifdef BLUETOOTH_BLUEFRUIT_LE
+#        include "bluefruit_le.h"
+#    elif BLUETOOTH_RN42
+#        include "rn42.h"
+#    endif
+#endif
+
 #ifdef NKRO_ENABLE
 #    include "keycode_config.h"
 extern keymap_config_t keymap_config;
@@ -63,6 +72,17 @@ led_t host_keyboard_led_state(void) {
 
 /* send report */
 void host_keyboard_send(report_keyboard_t *report) {
+#ifdef BLUETOOTH_ENABLE
+    if (where_to_send() == OUTPUT_BLUETOOTH) {
+#    ifdef BLUETOOTH_BLUEFRUIT_LE
+        bluefruit_le_send_keys(report->mods, report->keys, sizeof(report->keys));
+#    elif BLUETOOTH_RN42
+        rn42_send_keyboard(report);
+#    endif
+        return;
+    }
+#endif
+
     if (!driver) return;
 #if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
     if (keyboard_protocol && keymap_config.nkro) {
@@ -90,6 +110,18 @@ void host_keyboard_send(report_keyboard_t *report) {
 }
 
 void host_mouse_send(report_mouse_t *report) {
+#ifdef BLUETOOTH_ENABLE
+    if (where_to_send() == OUTPUT_BLUETOOTH) {
+#    ifdef BLUETOOTH_BLUEFRUIT_LE
+        // FIXME: mouse buttons
+        bluefruit_le_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
+#    elif BLUETOOTH_RN42
+        rn42_send_mouse(report);
+#    endif
+        return;
+    }
+#endif
+
     if (!driver) return;
 #ifdef MOUSE_SHARED_EP
     report->report_id = REPORT_ID_MOUSE;
@@ -114,6 +146,17 @@ void host_consumer_send(uint16_t report) {
     if (report == last_consumer_report) return;
     last_consumer_report = report;
 
+#ifdef BLUETOOTH_ENABLE
+    if (where_to_send() == OUTPUT_BLUETOOTH) {
+#    ifdef BLUETOOTH_BLUEFRUIT_LE
+        bluefruit_le_send_consumer_key(report);
+#    elif BLUETOOTH_RN42
+        rn42_send_consumer(report);
+#    endif
+        return;
+    }
+#endif
+
     if (!driver) return;
     (*driver->send_extra)(REPORT_ID_CONSUMER, report);
 }
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 03e19745f8..2a3f5fd883 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -65,15 +65,6 @@ extern keymap_config_t keymap_config;
 #    include "audio.h"
 #endif
 
-#ifdef BLUETOOTH_ENABLE
-#    include "outputselect.h"
-#    ifdef BLUETOOTH_BLUEFRUIT_LE
-#        include "bluefruit_le.h"
-#    elif BLUETOOTH_RN42
-#        include "rn42.h"
-#    endif
-#endif
-
 #ifdef VIRTSER_ENABLE
 #    include "virtser.h"
 #endif
@@ -648,17 +639,6 @@ static uint8_t keyboard_leds(void) {
 static void send_keyboard(report_keyboard_t *report) {
     uint8_t timeout = 255;
 
-#ifdef BLUETOOTH_ENABLE
-    if (where_to_send() == OUTPUT_BLUETOOTH) {
-#    ifdef BLUETOOTH_BLUEFRUIT_LE
-        bluefruit_le_send_keys(report->mods, report->keys, sizeof(report->keys));
-#    elif BLUETOOTH_RN42
-        rn42_send_keyboard(report);
-#    endif
-        return;
-    }
-#endif
-
     /* Select the Keyboard Report Endpoint */
     uint8_t ep   = KEYBOARD_IN_EPNUM;
     uint8_t size = KEYBOARD_REPORT_SIZE;
@@ -695,18 +675,6 @@ static void send_mouse(report_mouse_t *report) {
 #ifdef MOUSE_ENABLE
     uint8_t timeout = 255;
 
-#    ifdef BLUETOOTH_ENABLE
-    if (where_to_send() == OUTPUT_BLUETOOTH) {
-#        ifdef BLUETOOTH_BLUEFRUIT_LE
-        // FIXME: mouse buttons
-        bluefruit_le_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons);
-#        elif BLUETOOTH_RN42
-        rn42_send_mouse(report);
-#        endif
-        return;
-    }
-#    endif
-
     /* Select the Mouse Report Endpoint */
     Endpoint_SelectEndpoint(MOUSE_IN_EPNUM);
 
@@ -747,17 +715,6 @@ static void send_report(void *report, size_t size) {
  */
 static void send_extra(uint8_t report_id, uint16_t data) {
 #ifdef EXTRAKEY_ENABLE
-#    ifdef BLUETOOTH_ENABLE
-    if (report_id == REPORT_ID_CONSUMER && where_to_send() == OUTPUT_BLUETOOTH) {
-#        ifdef BLUETOOTH_BLUEFRUIT_LE
-        bluefruit_le_send_consumer_key(data);
-#        elif BLUETOOTH_RN42
-        rn42_send_consumer(data);
-#        endif
-        return;
-    }
-#    endif
-
     static report_extra_t r;
     r = (report_extra_t){.report_id = report_id, .usage = data};
     send_report(&r, sizeof(r));
@@ -1007,10 +964,6 @@ void protocol_pre_init(void) {
     setup_usb();
     sei();
 
-#if defined(BLUETOOTH_RN42)
-    rn42_init();
-#endif
-
     /* wait for USB startup & debug output */
 
 #ifdef WAIT_FOR_USB
@@ -1062,10 +1015,6 @@ void protocol_post_task(void) {
     MIDI_Device_USBTask(&USB_MIDI_Interface);
 #endif
 
-#ifdef BLUETOOTH_BLUEFRUIT_LE
-    bluefruit_le_task();
-#endif
-
 #ifdef VIRTSER_ENABLE
     virtser_task();
     CDC_Device_USBTask(&cdc_device);