diff --git a/lib/vusb b/lib/vusb
index 9a42d205eb..bdb53e4c04 160000
--- a/lib/vusb
+++ b/lib/vusb
@@ -1 +1 @@
-Subproject commit 9a42d205eb60faca494ff4eabce8d59f0ec0fc7f
+Subproject commit bdb53e4c043d089279d9891b68bea77614cb97ee
diff --git a/tmk_core/protocol/vusb/usbconfig.h b/tmk_core/protocol/vusb/usbconfig.h
index dcef7584c4..041f7bd095 100644
--- a/tmk_core/protocol/vusb/usbconfig.h
+++ b/tmk_core/protocol/vusb/usbconfig.h
@@ -85,9 +85,19 @@ section at the end of this file).
 /* If the so-called endpoint 3 is used, it can now be configured to any other
  * endpoint number (except 0) with this macro. Default if undefined is 3.
  */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT4   1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 4 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP4_NUMBER              4
+/* If the so-called endpoint 4 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 4.
+ */
 /* #define USB_INITIAL_DATATOKEN           USBPID_DATA1 */
 /* The above macro defines the startup condition for data toggling on the
- * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * interrupt/bulk endpoints 1, 3 and 4. Defaults to USBPID_DATA1.
  * Since the token is toggled BEFORE sending any data, the first packet is
  * sent with the oposite value of this configuration!
  */
@@ -100,10 +110,10 @@ section at the end of this file).
 #define USB_CFG_SUPPRESS_INTR_CODE      0
 /* Define this to 1 if you want to declare interrupt-in endpoints, but don't
  * want to send any data over them. If this macro is defined to 1, functions
- * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
- * you need the interrupt-in endpoints in order to comply to an interface
- * (e.g. HID), but never want to send any data. This option saves a couple
- * of bytes in flash memory and the transmit buffers in RAM.
+ * usbSetInterrupt(), usbSetInterrupt3() and usbSetInterrupt4() are omitted.
+ * This is useful if you need the interrupt-in endpoints in order to comply
+ * to an interface (e.g. HID), but never want to send any data. This option
+ * saves a couple of bytes in flash memory and the transmit buffers in RAM.
  */
 #define USB_CFG_IS_SELF_POWERED         0
 /* Define this to 1 if the device has its own power supply. Set it to 0 if the
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index 735a1c1d30..77bbbd7bd4 100644
--- a/tmk_core/protocol/vusb/vusb.c
+++ b/tmk_core/protocol/vusb/vusb.c
@@ -62,12 +62,16 @@ enum usb_interfaces {
     TOTAL_INTERFACES = NEXT_INTERFACE
 };
 
-#define MAX_INTERFACES 2
+#define MAX_INTERFACES 3
 
 #if (NEXT_INTERFACE - 1) > MAX_INTERFACES
 #    error There are not enough available interfaces to support all functions. Please disable one or more of the following: Mouse Keys, Extra Keys, Raw HID, Console
 #endif
 
+#if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && CONSOLE_ENABLE
+#    error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
+#endif
+
 static uint8_t keyboard_led_state = 0;
 static uint8_t vusb_idle_rate     = 0;
 
@@ -116,16 +120,16 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
 
     uint8_t *temp = data;
     for (uint8_t i = 0; i < 4; i++) {
-        while (!usbInterruptIsReady3()) {
+        while (!usbInterruptIsReady4()) {
             usbPoll();
         }
-        usbSetInterrupt3(temp, 8);
+        usbSetInterrupt4(temp, 8);
         temp += 8;
     }
-    while (!usbInterruptIsReady3()) {
+    while (!usbInterruptIsReady4()) {
         usbPoll();
     }
-    usbSetInterrupt3(0, 0);
+    usbSetInterrupt4(0, 0);
 }
 
 __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
@@ -683,7 +687,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
             .bLength         = sizeof(usbEndpointDescriptor_t),
             .bDescriptorType = USBDESCR_ENDPOINT
         },
-        .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER),
+        .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP4_NUMBER),
         .bmAttributes        = 0x03,
         .wMaxPacketSize      = RAW_EPSIZE,
         .bInterval           = USB_POLLING_INTERVAL_MS
@@ -693,7 +697,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = {
             .bLength         = sizeof(usbEndpointDescriptor_t),
             .bDescriptorType = USBDESCR_ENDPOINT
         },
-        .bEndpointAddress    = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER),
+        .bEndpointAddress    = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP4_NUMBER),
         .bmAttributes        = 0x03,
         .wMaxPacketSize      = RAW_EPSIZE,
         .bInterval           = USB_POLLING_INTERVAL_MS