diff --git a/reform2-keyboard-fw/README.md b/reform2-keyboard-fw/README.md
index 5fec0ed6ea5e868a061449073dce662c40696955..a9a9698a237a7191a17c6ab432c3a3f97065450e 100644
--- a/reform2-keyboard-fw/README.md
+++ b/reform2-keyboard-fw/README.md
@@ -4,8 +4,8 @@
 
 - `constants.h`: Define which keyboard variant you want to build for
 - `keyboard.c`: Main entrypoint that includes the chosen matrix file (keyboard layout)
-- `matrix.c`: Keyboard layout definition (default)
-- `matrix_*.c`: Alternative layouts
+- `matrix.h`: Keyboard layout definition (default)
+- `matrix_*.h`: Alternative layouts
 - `backlight.c`: Keyboard backlight control
 - `menu.c`: OLED Menu handling
 - `oled.c`: OLED graphics control
@@ -47,5 +47,3 @@ To build, type:
 
 To flash, put your keyboard into [flashing mode](https://mntre.com/reform2/handbook/parts.html#keyboard-firmware) and run:
 `sudo ./flash.sh`
-
-
diff --git a/reform2-keyboard-fw/constants.h b/reform2-keyboard-fw/constants.h
index d47489a40d263908d8edafb138c57f4d5f6bc50d..9fdbe6f36069faedc31cec081c9ae95f20d810a4 100644
--- a/reform2-keyboard-fw/constants.h
+++ b/reform2-keyboard-fw/constants.h
@@ -7,8 +7,8 @@
 #ifndef _CONSTANTS_H_
 #define _CONSTANTS_H_
 
-#define KBD_FW_REV "R1 20210927"
-//#define KBD_VARIANT_STANDALONE
+#define KBD_FW_REV "R1 20211213"
+#define KBD_VARIANT_STANDALONE
 #define KBD_VARIANT_QWERTY_US
 //#define KBD_VARIANT_NEO2
 //#define KBD_VARIANT_ELLEN
diff --git a/reform2-keyboard-fw/descriptors.c b/reform2-keyboard-fw/descriptors.c
index f4663570cbe2a5c5d64b56b49ba7c6c7b415635f..d82476b19b4163a01c031980e514cd3a9f22fd35 100644
--- a/reform2-keyboard-fw/descriptors.c
+++ b/reform2-keyboard-fw/descriptors.c
@@ -23,10 +23,42 @@
  */
 const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
 {
-	/* Use the HID class driver's standard Keyboard report.
-	 *   Max simultaneous keys: 6
-	 */
-	HID_DESCRIPTOR_KEYBOARD(6)
+  /* Use the HID class driver's standard Keyboard report.
+   *   Max simultaneous keys: 6
+   */
+  HID_DESCRIPTOR_KEYBOARD(6)
+};
+
+/** HID class report descriptor. This is a special descriptor constructed with values from the
+ *  USBIF HID class specification to describe the reports and capabilities of the HID device. This
+ *  descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
+ *  the device will send, and what it may be sent back from the host. Refer to the HID specification for
+ *  more details on HID report descriptors.
+ */
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MediaControlReport[] =
+{
+	HID_RI_USAGE_PAGE(8, 0x0C), /* Consumer Page */
+	HID_RI_USAGE(8, 0x01), /* Consumer Controls */
+	HID_RI_COLLECTION(8, 0x01), /* Application */
+		HID_RI_USAGE(8, 0xB0), /* Play */
+		HID_RI_USAGE(8, 0xB1), /* Pause */
+		HID_RI_USAGE(8, 0xB3), /* Fast Forward */
+		HID_RI_USAGE(8, 0xB4), /* Rewind */
+		HID_RI_USAGE(8, 0xB5), /* Next Track */
+		HID_RI_USAGE(8, 0xB6), /* Previous Track */
+		HID_RI_USAGE(8, 0xB7), /* Stop */
+		HID_RI_USAGE(8, 0xCD), /* Play/Pause (toggle) */
+		HID_RI_USAGE(8, 0xE2), /* Mute */
+		HID_RI_USAGE(8, 0xE9), /* Volume Up */
+		HID_RI_USAGE(8, 0xEA), /* Volume Down */
+		HID_RI_REPORT_SIZE(8, 0x01),
+		HID_RI_REPORT_COUNT(8, 0x0B),
+		HID_RI_LOGICAL_MINIMUM(8, 0),
+		HID_RI_LOGICAL_MAXIMUM(8, 1),
+		HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
+		HID_RI_REPORT_COUNT(8, 0x05),
+		HID_RI_INPUT(8, HID_IOF_CONSTANT),
+	HID_RI_END_COLLECTION(0),
 };
 
 /** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
@@ -36,24 +68,24 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
  */
 const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
 {
-	.Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+  .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
 
-	.USBSpecification       = VERSION_BCD(1,1,0),
-	.Class                  = USB_CSCP_NoDeviceClass,
-	.SubClass               = USB_CSCP_NoDeviceSubclass,
-	.Protocol               = USB_CSCP_NoDeviceProtocol,
+  .USBSpecification       = VERSION_BCD(1,1,0),
+  .Class                  = USB_CSCP_NoDeviceClass,
+  .SubClass               = USB_CSCP_NoDeviceSubclass,
+  .Protocol               = USB_CSCP_NoDeviceProtocol,
 
-	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
+  .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
-	.VendorID               = 0x03EB,
-	.ProductID              = 0x2042,
-	.ReleaseNumber          = VERSION_BCD(0,0,1),
+  .VendorID               = 0x03EB,
+  .ProductID              = 0x2042,
+  .ReleaseNumber          = VERSION_BCD(0,0,1),
 
-	.ManufacturerStrIndex   = STRING_ID_Manufacturer,
-	.ProductStrIndex        = STRING_ID_Product,
-	.SerialNumStrIndex      = NO_DESCRIPTOR,
+  .ManufacturerStrIndex   = STRING_ID_Manufacturer,
+  .ProductStrIndex        = STRING_ID_Product,
+  .SerialNumStrIndex      = NO_DESCRIPTOR,
 
-	.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+  .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
 };
 
 /** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
@@ -63,57 +95,94 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
  */
 const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 {
-	.Config =
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+  .Config =
+    {
+      .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+      .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+      .TotalInterfaces        = 2,
 
-			.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
-			.TotalInterfaces        = 1,
+      .ConfigurationNumber    = 1,
+      .ConfigurationStrIndex  = NO_DESCRIPTOR,
 
-			.ConfigurationNumber    = 1,
-			.ConfigurationStrIndex  = NO_DESCRIPTOR,
+      .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
 
-			.ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+      .MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
+    },
 
-			.MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
-		},
+  .HID1_KeyboardInterface =
+    {
+      .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 
-	.HID_Interface =
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+      .InterfaceNumber        = INTERFACE_ID_Keyboard,
+      .AlternateSetting       = 0x00,
 
-			.InterfaceNumber        = INTERFACE_ID_Keyboard,
-			.AlternateSetting       = 0x00,
+      .TotalEndpoints         = 1,
 
-			.TotalEndpoints         = 1,
+      .Class                  = HID_CSCP_HIDClass,
+      .SubClass               = HID_CSCP_BootSubclass,
+      .Protocol               = HID_CSCP_KeyboardBootProtocol,
 
-			.Class                  = HID_CSCP_HIDClass,
-			.SubClass               = HID_CSCP_BootSubclass,
-			.Protocol               = HID_CSCP_KeyboardBootProtocol,
+      .InterfaceStrIndex      = NO_DESCRIPTOR
+    },
 
-			.InterfaceStrIndex      = NO_DESCRIPTOR
-		},
+  .HID1_KeyboardHID =
+    {
+      .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
 
-	.HID_KeyboardHID =
-		{
-			.Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+      .HIDSpec                = VERSION_BCD(1,1,1),
+      .CountryCode            = 0x00,
+      .TotalReportDescriptors = 1,
+      .HIDReportType          = HID_DTYPE_Report,
+      .HIDReportLength        = sizeof(KeyboardReport)
+    },
 
-			.HIDSpec                = VERSION_BCD(1,1,1),
-			.CountryCode            = 0x00,
-			.TotalReportDescriptors = 1,
-			.HIDReportType          = HID_DTYPE_Report,
-			.HIDReportLength        = sizeof(KeyboardReport)
-		},
+  .HID1_ReportINEndpoint =
+    {
+      .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 
-	.HID_ReportINEndpoint =
-		{
-			.Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+      .EndpointAddress        = KEYBOARD_EPADDR,
+      .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+      .EndpointSize           = HID_EPSIZE,
+      .PollingIntervalMS      = 10
+    },
 
-			.EndpointAddress        = KEYBOARD_EPADDR,
-			.Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
-			.EndpointSize           = KEYBOARD_EPSIZE,
-			.PollingIntervalMS      = 0x05
-		},
+  .HID2_MediaControlInterface =
+    {
+      .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+      .InterfaceNumber        = INTERFACE_ID_MediaControl,
+      .AlternateSetting       = 0x00,
+
+      .TotalEndpoints         = 1,
+
+      .Class                  = HID_CSCP_HIDClass,
+      .SubClass               = HID_CSCP_NonBootSubclass,
+      .Protocol               = HID_CSCP_NonBootProtocol,
+
+      .InterfaceStrIndex      = NO_DESCRIPTOR
+    },
+
+  .HID2_MediaControlHID =
+    {
+      .Header                 = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
+
+      .HIDSpec                = VERSION_BCD(1,1,1),
+      .CountryCode            = 0x00,
+      .TotalReportDescriptors = 1,
+      .HIDReportType          = HID_DTYPE_Report,
+      .HIDReportLength        = sizeof(MediaControlReport)
+    },
+
+  .HID2_ReportINEndpoint =
+    {
+      .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+      .EndpointAddress        = MEDIACONTROL_EPADDR,
+      .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+      .EndpointSize           = HID_EPSIZE,
+      .PollingIntervalMS      = 100
+    },
 };
 
 /** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
@@ -144,51 +213,67 @@ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
                                     const uint16_t wIndex,
                                     const void** const DescriptorAddress)
 {
-	const uint8_t  DescriptorType   = (wValue >> 8);
-	const uint8_t  DescriptorNumber = (wValue & 0xFF);
-
-	const void* Address = NULL;
-	uint16_t    Size    = NO_DESCRIPTOR;
-
-	switch (DescriptorType)
-	{
-		case DTYPE_Device:
-			Address = &DeviceDescriptor;
-			Size    = sizeof(USB_Descriptor_Device_t);
-			break;
-		case DTYPE_Configuration:
-			Address = &ConfigurationDescriptor;
-			Size    = sizeof(USB_Descriptor_Configuration_t);
-			break;
-		case DTYPE_String:
-			switch (DescriptorNumber)
-			{
-				case STRING_ID_Language:
-					Address = &LanguageString;
-					Size    = pgm_read_byte(&LanguageString.Header.Size);
-					break;
-				case STRING_ID_Manufacturer:
-					Address = &ManufacturerString;
-					Size    = pgm_read_byte(&ManufacturerString.Header.Size);
-					break;
-				case STRING_ID_Product:
-					Address = &ProductString;
-					Size    = pgm_read_byte(&ProductString.Header.Size);
-					break;
-			}
-
-			break;
-		case HID_DTYPE_HID:
-			Address = &ConfigurationDescriptor.HID_KeyboardHID;
-			Size    = sizeof(USB_HID_Descriptor_HID_t);
-			break;
-		case HID_DTYPE_Report:
-			Address = &KeyboardReport;
-			Size    = sizeof(KeyboardReport);
-			break;
-	}
-
-	*DescriptorAddress = Address;
-	return Size;
+  const uint8_t  DescriptorType   = (wValue >> 8);
+  const uint8_t  DescriptorNumber = (wValue & 0xFF);
+
+  const void* Address = NULL;
+  uint16_t    Size    = NO_DESCRIPTOR;
+
+  switch (DescriptorType)
+  {
+    case DTYPE_Device:
+      Address = &DeviceDescriptor;
+      Size    = sizeof(USB_Descriptor_Device_t);
+      break;
+    case DTYPE_Configuration:
+      Address = &ConfigurationDescriptor;
+      Size    = sizeof(USB_Descriptor_Configuration_t);
+      break;
+    case DTYPE_String:
+      switch (DescriptorNumber)
+      {
+        case STRING_ID_Language:
+          Address = &LanguageString;
+          Size    = pgm_read_byte(&LanguageString.Header.Size);
+          break;
+        case STRING_ID_Manufacturer:
+          Address = &ManufacturerString;
+          Size    = pgm_read_byte(&ManufacturerString.Header.Size);
+          break;
+        case STRING_ID_Product:
+          Address = &ProductString;
+          Size    = pgm_read_byte(&ProductString.Header.Size);
+          break;
+      }
+      break;
+    case HID_DTYPE_HID:
+      switch (wIndex)
+      {
+        case INTERFACE_ID_Keyboard:
+          Address = &ConfigurationDescriptor.HID1_KeyboardHID;
+          Size    = sizeof(USB_HID_Descriptor_HID_t);
+          break;
+        case INTERFACE_ID_MediaControl:
+          Address = &ConfigurationDescriptor.HID2_MediaControlHID;
+          Size    = sizeof(USB_HID_Descriptor_HID_t);
+          break;
+      }
+      break;
+    case HID_DTYPE_Report:
+      switch (wIndex)
+      {
+        case INTERFACE_ID_Keyboard:
+          Address = &KeyboardReport;
+          Size    = sizeof(KeyboardReport);
+          break;
+        case INTERFACE_ID_MediaControl:
+          Address = &MediaControlReport;
+          Size    = sizeof(MediaControlReport);
+          break;
+      }
+      break;
+  }
+
+  *DescriptorAddress = Address;
+  return Size;
 }
-
diff --git a/reform2-keyboard-fw/descriptors.h b/reform2-keyboard-fw/descriptors.h
index 1ec1ee7d7e648c61ef21ae0c2a57836b753cd4a4..101eb89d9c7232ea67d9801c758313e19d6ac27a 100644
--- a/reform2-keyboard-fw/descriptors.h
+++ b/reform2-keyboard-fw/descriptors.h
@@ -27,9 +27,13 @@
 			USB_Descriptor_Configuration_Header_t Config;
 
 			// Keyboard HID Interface
-			USB_Descriptor_Interface_t            HID_Interface;
-			USB_HID_Descriptor_HID_t              HID_KeyboardHID;
-			USB_Descriptor_Endpoint_t             HID_ReportINEndpoint;
+			USB_Descriptor_Interface_t            HID1_KeyboardInterface;
+			USB_HID_Descriptor_HID_t              HID1_KeyboardHID;
+			USB_Descriptor_Endpoint_t             HID1_ReportINEndpoint;
+      // Media Control HID Interface
+			USB_Descriptor_Interface_t            HID2_MediaControlInterface;
+			USB_HID_Descriptor_HID_t              HID2_MediaControlHID;
+			USB_Descriptor_Endpoint_t             HID2_ReportINEndpoint;
 		} USB_Descriptor_Configuration_t;
 
 		/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
@@ -39,6 +43,7 @@
 		enum InterfaceDescriptors_t
 		{
 			INTERFACE_ID_Keyboard = 0, /**< Keyboard interface descriptor ID */
+			INTERFACE_ID_MediaControl = 1, /**< Media Control interface descriptor ID */
 		};
 
 		/** Enum for the device string descriptor IDs within the device. Each string descriptor should
@@ -56,8 +61,11 @@
 		/** Endpoint address of the Keyboard HID reporting IN endpoint. */
 		#define KEYBOARD_EPADDR              (ENDPOINT_DIR_IN | 1)
 
-		/** Size in bytes of the Keyboard HID reporting IN endpoint. */
-		#define KEYBOARD_EPSIZE              8
+		/** Endpoint address of the Media Control HID reporting IN endpoint. */
+		#define MEDIACONTROL_EPADDR          (ENDPOINT_DIR_IN | 3)
+
+		/** Size in bytes of HID reporting IN endpoints. */
+		#define HID_EPSIZE          8
 
 	/* Function Prototypes: */
 //uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
@@ -66,4 +74,3 @@
 //	                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
 
 #endif
-
diff --git a/reform2-keyboard-fw/keyboard.c b/reform2-keyboard-fw/keyboard.c
index 399ee1e36f78bdaa8cfc4a2c64490270e5df7194..e08441fa963a812cdd6e362d64085bc7e39dd335 100644
--- a/reform2-keyboard-fw/keyboard.c
+++ b/reform2-keyboard-fw/keyboard.c
@@ -26,13 +26,14 @@
 #include "scancodes.h"
 
 #ifdef KBD_VARIANT_ELLEN
-#include "matrix_ellen.c"
+#include "matrix_ellen.h"
 #else
-#include "matrix.c"
+#include "matrix.h"
 #endif
 
 /** Buffer to hold the previously generated Keyboard HID report, for comparison purposes inside the HID class driver. */
 static uint8_t PrevKeyboardHIDReportBuffer[sizeof(USB_KeyboardReport_Data_t)];
+static uint8_t PrevMediaControlHIDReportBuffer[sizeof(USB_MediaReport_Data_t)];
 
 /** LUFA HID Class driver interface configuration and state information. This structure is
  *  passed to all HID Class driver functions, so that multiple instances of the same class
@@ -46,7 +47,7 @@ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
         .ReportINEndpoint             =
           {
             .Address              = KEYBOARD_EPADDR,
-            .Size                 = KEYBOARD_EPSIZE,
+            .Size                 = HID_EPSIZE,
             .Banks                = 1,
           },
         .PrevReportINBuffer           = PrevKeyboardHIDReportBuffer,
@@ -54,6 +55,23 @@ USB_ClassInfo_HID_Device_t Keyboard_HID_Interface =
       },
   };
 
+/** LUFA HID Class driver interface configuration and state information for the Media Controller */
+USB_ClassInfo_HID_Device_t MediaControl_HID_Interface =
+  {
+    .Config =
+      {
+        .InterfaceNumber              = INTERFACE_ID_MediaControl,
+        .ReportINEndpoint             =
+          {
+            .Address              = MEDIACONTROL_EPADDR,
+            .Size                 = HID_EPSIZE,
+            .Banks                = 1,
+          },
+        .PrevReportINBuffer           = PrevMediaControlHIDReportBuffer,
+        .PrevReportINBufferSize       = sizeof(PrevMediaControlHIDReportBuffer),
+      },
+  };
+
 uint8_t matrix_debounce[KBD_COLS*KBD_ROWS];
 uint8_t matrix_state[KBD_COLS*KBD_ROWS];
 
@@ -79,8 +97,39 @@ void reset_keyboard_state(void) {
   last_meta_key = 0;
 }
 
+inline bool is_media_key(uint8_t keycode) {
+  return (keycode>=HID_KEYBOARD_SC_MEDIA_PLAY);
+}
+
+bool get_media_keys(uint8_t keycode, USB_MediaReport_Data_t* mcr) {
+  bool media_key = false;
+  if (keycode == HID_KEYBOARD_SC_MEDIA_MUTE) {
+    if (mcr) mcr->Mute = 1;
+    media_key = true;
+  } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_UP) {
+    if (mcr) mcr->VolumeUp = 1;
+    media_key = true;
+  } else if (keycode == HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN) {
+    if (mcr) mcr->VolumeDown = 1;
+    media_key = true;
+  } else if (keycode == HID_KEYBOARD_SC_MEDIA_BACKWARD) {
+    if (mcr) mcr->PreviousTrack = 1;
+    media_key = true;
+  } else if (keycode == HID_KEYBOARD_SC_MEDIA_FORWARD) {
+    if (mcr) mcr->NextTrack = 1;
+    media_key = true;
+  } else if (keycode == HID_KEYBOARD_SC_MEDIA_PLAY) {
+    if (mcr) mcr->PlayPause = 1;
+    media_key = true;
+  }
+  return media_key;
+}
+
+#define MAX_SCANCODES 6
+static uint8_t pressed_scancodes[MAX_SCANCODES] = {0,0,0,0,0,0};
+
 // usb_report_mode: if you pass 0, you can leave KeyboardReport NULL
-void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardReport) {
+int process_keyboard(uint8_t* resulting_scancodes) {
   // how many keys are pressed this round
   uint8_t total_pressed = 0;
   uint8_t used_key_codes = 0;
@@ -98,7 +147,7 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
 
     // wait for signal to stabilize
     // TODO maybe not necessary
-    _delay_us(10);
+    //_delay_us(10);
 
     // check input COLs
     for (int x=0; x<14; x++) {
@@ -170,14 +219,14 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
               if (stay_meta == 2) {
                 reset_keyboard_state();
                 enter_meta_mode();
-                return;
+                return 0;
               }
             }
           } else if (!last_meta_key) {
             // not meta mode, regular key: report keypress via USB
-            // 6 keys is a hard limit in the HID descriptor :/
-            if (usb_report_mode && KeyboardReport && used_key_codes<6) {
-              KeyboardReport->KeyCode[used_key_codes++] = keycode;
+            // 6 keys is the limit in the HID descriptor
+            if (used_key_codes < MAX_SCANCODES && resulting_scancodes) {
+              resulting_scancodes[used_key_codes++] = keycode;
             }
           }
         }
@@ -195,13 +244,13 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
             if (!media_toggle) {
               media_toggle = 1;
               active_matrix = matrix_fn_toggled;
-            } else { 
+            } else {
               media_toggle = 0;
-              active_matrix = matrix_fn; 
+              active_matrix = matrix_fn;
             }
           }
           circle = 0;
-        } 
+        }
       }
     }
 
@@ -217,6 +266,8 @@ void process_keyboard(char usb_report_mode, USB_KeyboardReport_Data_t* KeyboardR
 
   // if no more keys are held down, allow a new meta command
   if (total_pressed<1) last_meta_key = 0;
+
+  return used_key_codes;
 }
 
 int main(void)
@@ -238,8 +289,9 @@ int main(void)
 
   for (;;)
   {
-    process_keyboard(0, NULL);
+    process_keyboard(NULL);
     HID_Device_USBTask(&Keyboard_HID_Interface);
+    HID_Device_USBTask(&MediaControl_HID_Interface);
     USB_USBTask();
     counter++;
 #ifndef KBD_VARIANT_STANDALONE
@@ -309,6 +361,7 @@ void EVENT_USB_Device_ConfigurationChanged(void)
   bool ConfigSuccess = true;
 
   ConfigSuccess &= HID_Device_ConfigureEndpoints(&Keyboard_HID_Interface);
+	ConfigSuccess &= HID_Device_ConfigureEndpoints(&MediaControl_HID_Interface);
 
   USB_Device_EnableSOFEvents();
 }
@@ -317,12 +370,14 @@ void EVENT_USB_Device_ConfigurationChanged(void)
 void EVENT_USB_Device_ControlRequest(void)
 {
   HID_Device_ProcessControlRequest(&Keyboard_HID_Interface);
+  HID_Device_ProcessControlRequest(&MediaControl_HID_Interface);
 }
 
 /** Event handler for the USB device Start Of Frame event. */
 void EVENT_USB_Device_StartOfFrame(void)
 {
   HID_Device_MillisecondElapsed(&Keyboard_HID_Interface);
+  HID_Device_MillisecondElapsed(&MediaControl_HID_Interface);
 }
 
 /** HID class driver callback function for the creation of HID reports to the host.
@@ -342,11 +397,30 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn
                                          void* ReportData,
                                          uint16_t* const ReportSize)
 {
-  USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
-
-  process_keyboard(1, KeyboardReport);
-
-  *ReportSize = sizeof(USB_KeyboardReport_Data_t);
+  int num_keys = process_keyboard(pressed_scancodes);
+  if (num_keys > MAX_SCANCODES) num_keys = MAX_SCANCODES;
+
+  if (HIDInterfaceInfo == &Keyboard_HID_Interface) {
+    // host asks for a keyboard report
+    USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
+    *ReportSize = sizeof(USB_KeyboardReport_Data_t);
+    for (int i=0; i<num_keys; i++) {
+      uint8_t sc = pressed_scancodes[i];
+      if (!is_media_key(sc)) {
+        KeyboardReport->KeyCode[i] = sc;
+      }
+    }
+  } else if (HIDInterfaceInfo == &MediaControl_HID_Interface) {
+    // host asks for a media control report
+    USB_MediaReport_Data_t* MediaControlReport = (USB_MediaReport_Data_t*)ReportData;
+    *ReportSize = sizeof(USB_MediaReport_Data_t);
+    for (int i=0; i<num_keys; i++) {
+      uint8_t sc = pressed_scancodes[i];
+      if (is_media_key(sc)) {
+        get_media_keys(sc, MediaControlReport);
+      }
+    }
+  }
   return false;
 }
 
diff --git a/reform2-keyboard-fw/keyboard.h b/reform2-keyboard-fw/keyboard.h
index b934fbe68b68cffa8e3eadbadc6e948e077f7904..46ed00c483acc35e5706bdd036fe4f19b871e045 100644
--- a/reform2-keyboard-fw/keyboard.h
+++ b/reform2-keyboard-fw/keyboard.h
@@ -125,6 +125,23 @@
   HID_KEYBOARD_SC_DOWN_ARROW,\
   HID_KEYBOARD_SC_RIGHT_ARROW
 
+// MediaController USB Report
+typedef struct
+{
+  unsigned Play           : 1;
+  unsigned Pause          : 1;
+  unsigned FForward       : 1;
+  unsigned Rewind         : 1;
+  unsigned NextTrack      : 1;
+  unsigned PreviousTrack  : 1;
+  unsigned Stop           : 1;
+  unsigned PlayPause      : 1;
+  unsigned Mute           : 1;
+  unsigned VolumeUp       : 1;
+  unsigned VolumeDown     : 1;
+  unsigned RESERVED       : 5;
+} ATTR_PACKED USB_MediaReport_Data_t;
+
 void setup_hardware(void);
 void reset_keyboard_state(void);
 
diff --git a/reform2-keyboard-fw/matrix.c b/reform2-keyboard-fw/matrix.h
similarity index 86%
rename from reform2-keyboard-fw/matrix.c
rename to reform2-keyboard-fw/matrix.h
index 329710023e7939780ea35a56590aee6944a794bf..e66d87006a5ce17ddce848443c2c290936fd6c12 100644
--- a/reform2-keyboard-fw/matrix.c
+++ b/reform2-keyboard-fw/matrix.h
@@ -33,9 +33,9 @@ uint8_t matrix_fn[KBD_MATRIX_SZ] = {
   HID_KEYBOARD_SC_MEDIA_BACKWARD,
   HID_KEYBOARD_SC_MEDIA_PLAY,
   HID_KEYBOARD_SC_MEDIA_FORWARD,
-  173, // mute
-  174, // volume down
-  175, // volume up
+  HID_KEYBOARD_SC_MEDIA_MUTE,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
   KEY_CIRCLE,
 
   MATRIX_DEFAULT_ROW_2,
@@ -58,9 +58,9 @@ uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
   HID_KEYBOARD_SC_MEDIA_BACKWARD,
   HID_KEYBOARD_SC_MEDIA_PLAY,
   HID_KEYBOARD_SC_MEDIA_FORWARD,
-  173,
-  174,
-  175,
+  HID_KEYBOARD_SC_MEDIA_MUTE,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
   KEY_CIRCLE,
 
   MATRIX_DEFAULT_ROW_2,
diff --git a/reform2-keyboard-fw/matrix_ellen.c b/reform2-keyboard-fw/matrix_ellen.h
similarity index 89%
rename from reform2-keyboard-fw/matrix_ellen.c
rename to reform2-keyboard-fw/matrix_ellen.h
index fbb444a3cddf0b9926dec6087b69ca4837d6f647..297dd903749eb9fc869cf5c8d349f6bcf266f0a2 100644
--- a/reform2-keyboard-fw/matrix_ellen.c
+++ b/reform2-keyboard-fw/matrix_ellen.h
@@ -18,7 +18,7 @@ uint8_t matrix[KBD_MATRIX_SZ] = {
   // Custom row six
   HID_KEYBOARD_SC_LEFT_CONTROL,
   HID_KEYBOARD_SC_LEFT_ALT,
-  HID_KEYBOARD_SC_LEFT_GUI, 
+  HID_KEYBOARD_SC_LEFT_GUI,
   KEY_SPACE,
   KEY_SPACE,
   KEY_SPACE,
@@ -28,7 +28,7 @@ uint8_t matrix[KBD_MATRIX_SZ] = {
   HID_KEYBOARD_SC_LEFT_ARROW,
   HID_KEYBOARD_SC_DOWN_ARROW,
   HID_KEYBOARD_SC_RIGHT_ARROW,
-  
+
   // Marker for layout editor (FIXME)
   KBD_EDITOR_MARKER
 };
@@ -46,9 +46,9 @@ uint8_t matrix_fn[KBD_MATRIX_SZ] = {
   HID_KEYBOARD_SC_MEDIA_BACKWARD,
   HID_KEYBOARD_SC_MEDIA_PLAY,
   HID_KEYBOARD_SC_MEDIA_FORWARD,
-  173, // mute
-  174, // volume down
-  175, // volume up
+  HID_KEYBOARD_SC_MEDIA_MUTE,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
   KEY_CIRCLE,
 
   MATRIX_DEFAULT_ROW_2,
@@ -74,7 +74,7 @@ uint8_t matrix_fn[KBD_MATRIX_SZ] = {
   // Custom row 6
   HID_KEYBOARD_SC_LEFT_CONTROL,
   HID_KEYBOARD_SC_LEFT_ALT,
-  HID_KEYBOARD_SC_LEFT_GUI, 
+  HID_KEYBOARD_SC_LEFT_GUI,
   KEY_SPACE,
   KEY_SPACE,
   KEY_SPACE,
@@ -99,9 +99,9 @@ uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
   HID_KEYBOARD_SC_MEDIA_BACKWARD,
   HID_KEYBOARD_SC_MEDIA_PLAY,
   HID_KEYBOARD_SC_MEDIA_FORWARD,
-  173,
-  174,
-  175,
+  HID_KEYBOARD_SC_MEDIA_MUTE,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_DOWN,
+  HID_KEYBOARD_SC_MEDIA_VOLUME_UP,
   KEY_CIRCLE,
 
   MATRIX_DEFAULT_ROW_2,
@@ -112,7 +112,7 @@ uint8_t matrix_fn_toggled[KBD_MATRIX_SZ] = {
   // Custom row six
   HID_KEYBOARD_SC_LEFT_CONTROL,
   HID_KEYBOARD_SC_LEFT_ALT,
-  HID_KEYBOARD_SC_LEFT_GUI, 
+  HID_KEYBOARD_SC_LEFT_GUI,
   KEY_SPACE,
   KEY_SPACE,
   KEY_SPACE,