/** @file Copyright (C) 2021, Goldfish64. All rights reserved. All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "OcAudioInternal.h" // // Widget names. // STATIC CHAR8 *mWidgetNames[HDA_WIDGET_TYPE_VENDOR + 1] = { "Audio Output", "Audio Input", "Audio Mixer", "Audio Selector", "Pin Complex", "Power Widget", "Volume Knob Widget", "Beep Generator Widget", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Vendor Defined Widget" }; // // Port names. // STATIC CHAR8 *mPortConnectivities[4] = { "Jack", "None", "Fixed", "Int Jack" }; // // Device names. // STATIC CHAR8 *mDefaultDevices[HDA_CONFIG_DEFAULT_DEVICE_OTHER + 1] = { "Line Out", "Speaker", "HP Out", "CD", "SPDIF Out", "Digital Out", "Modem Line", "Modem Handset", "Line In", "Aux", "Mic", "Telephone", "SPDIF In", "Digital In", "Reserved", "Other" }; // // Port surface type names. // STATIC CHAR8 *mSurfaces[4] = { "Ext", "Int", "Ext", "Other" }; // // Port location names. // STATIC CHAR8 *mLocations[0xF + 1] = { "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom", "Special", "Special", "Special", "Reserved", "Reserved", "Reserved", "Reserved" }; // // Connection type names. // STATIC CHAR8 *mConnTypes[HDA_CONFIG_DEFAULT_CONN_OTHER + 1] = { "Unknown", "1/8", "1/4", "ATAPI", "RCA", "Optical", "Digital", "Analog", "Multi", "XLR", "RJ11", "Combo", "Other", "Other", "Other", "Other" }; // // Port color names. STATIC CHAR8 *mColors[HDA_CONFIG_DEFAULT_COLOR_OTHER + 1] = { "Unknown", "Black", "Grey", "Blue", "Green", "Red", "Orange", "Yellow", "Purple", "Pink", "Reserved", "Reserved", "Reserved", "Reserved", "White", "Other" }; STATIC VOID PrintRatesFormats ( IN OUT CHAR8 **AsciiBuffer, IN UINTN *AsciiBufferSize, IN UINT32 Rates, IN UINT32 Formats ) { // // Print sample rates. // OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " rates [0x%X]:", (UINT16)Rates); if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 8000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_11KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 11025"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 16000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_22KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 22050"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 32000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_44KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 44100"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_48KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 48000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_88KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 88200"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_96KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 96000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_176KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 176400"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_192KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 192000"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_384KHZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 384000"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); // // Print sample bits. // OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " bits [0x%X]:", (UINT16)(Rates >> 16)); if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_8BIT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 8"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_16BIT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 16"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_20BIT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 20"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_24BIT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 24"); } if (Rates & HDA_PARAMETER_SUPPORTED_PCM_SIZE_RATES_32BIT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 32"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); // // Print sample formats. // OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " formats [0x%X]:", Formats); if (Formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_PCM) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " PCM"); } if (Formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_FLOAT32) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " FLOAT32"); } if (Formats & HDA_PARAMETER_SUPPORTED_STREAM_FORMATS_AC3) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " AC3"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } STATIC VOID PrintAmpCaps ( IN OUT CHAR8 **AsciiBuffer, IN UINTN *AsciiBufferSize, IN UINT32 AmpCaps ) { if (AmpCaps != 0) { OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, "ofs=0x%2X, nsteps=0x%2X, stepsize=0x%2X, mute=%u\n", HDA_PARAMETER_AMP_CAPS_OFFSET (AmpCaps), HDA_PARAMETER_AMP_CAPS_NUM_STEPS (AmpCaps), HDA_PARAMETER_AMP_CAPS_STEP_SIZE (AmpCaps), (AmpCaps & HDA_PARAMETER_AMP_CAPS_MUTE) != 0 ); } else { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "N/A\n"); } } STATIC VOID PrintWidget ( IN OUT CHAR8 **AsciiBuffer, IN UINTN *AsciiBufferSize, IN HDA_WIDGET *HdaWidget ) { UINT32 Index; UINT8 VrefCaps; UINT8 VrefCtrl; // // Node header and widget capabilities. // OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, "Node 0x%2X (%u) [%a] wcaps 0x%X:", HdaWidget->NodeId, HdaWidget->NodeId, mWidgetNames[HDA_PARAMETER_WIDGET_CAPS_TYPE (HdaWidget->Capabilities)], HdaWidget->Capabilities ); if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Stereo"); } else { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Mono"); } if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_DIGITAL) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Digital"); } if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-In"); } if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_OUT_AMP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-Out"); } if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_L_R_SWAP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " R/L"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); // // Input amp capabilities and defaults. // if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-In caps: "); PrintAmpCaps (AsciiBuffer, AsciiBufferSize, HdaWidget->AmpInCapabilities); OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-In vals:"); for (Index = 0; Index < HdaWidget->ConnectionCount; Index++) { if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) { OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " [0x%2X 0x%2X]", HdaWidget->AmpInLeftDefaultGainMute[Index], HdaWidget->AmpInRightDefaultGainMute[Index] ); } else { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " [0x%2X]", HdaWidget->AmpInLeftDefaultGainMute[Index]); } } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } // // Output amp capabilities and defaults. // if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_OUT_AMP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-Out caps: "); PrintAmpCaps (AsciiBuffer, AsciiBufferSize, HdaWidget->AmpOutCapabilities); OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Amp-Out vals:"); if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_STEREO) { OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " [0x%2X 0x%2X]", HdaWidget->AmpOutLeftDefaultGainMute, HdaWidget->AmpOutRightDefaultGainMute ); } else { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " [0x%2X]", HdaWidget->AmpOutLeftDefaultGainMute); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } // // Input/output capabilities and defaults. // if ( (HDA_PARAMETER_WIDGET_CAPS_TYPE (HdaWidget->Capabilities) == HDA_WIDGET_TYPE_INPUT) || (HDA_PARAMETER_WIDGET_CAPS_TYPE (HdaWidget->Capabilities) == HDA_WIDGET_TYPE_OUTPUT)) { OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " Converter: stream=%u, channel=%u\n", HDA_VERB_GET_CONVERTER_STREAM_STR (HdaWidget->DefaultConvStreamChannel), HDA_VERB_GET_CONVERTER_STREAM_CHAN (HdaWidget->DefaultConvStreamChannel) ); if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_FORMAT_OVERRIDE) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " PCM:\n"); PrintRatesFormats (AsciiBuffer, AsciiBufferSize, HdaWidget->SupportedPcmRates, HdaWidget->SupportedFormats); } } // // Pin complex capabilities and defaults. // if (HDA_PARAMETER_WIDGET_CAPS_TYPE (HdaWidget->Capabilities) == HDA_WIDGET_TYPE_PIN_COMPLEX) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Pincap 0x%8X:", HdaWidget->PinCapabilities); if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_INPUT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " IN"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_OUTPUT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " OUT"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HEADPHONE) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " HP"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_EAPD) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " EAPD"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_TRIGGER) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Trigger"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_PRESENCE) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Detect"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HBR) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " HBR"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_HDMI) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " HDMI"); } if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_DISPLAYPORT) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " DP"); } VrefCaps = HDA_PARAMETER_PIN_CAPS_VREF (HdaWidget->PinCapabilities); if (VrefCaps & HDA_PARAMETER_PIN_CAPS_VREF_HIZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_HIZ"); } if (VrefCaps & HDA_PARAMETER_PIN_CAPS_VREF_GRD) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_GRD"); } if (VrefCaps & HDA_PARAMETER_PIN_CAPS_VREF_50) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_50"); } if (VrefCaps & HDA_PARAMETER_PIN_CAPS_VREF_80) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_80"); } if (VrefCaps & HDA_PARAMETER_PIN_CAPS_VREF_100) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_100"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); if (HdaWidget->PinCapabilities & HDA_PARAMETER_PIN_CAPS_EAPD) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " EAPD 0x%X:", HdaWidget->DefaultEapd); if (HdaWidget->DefaultEapd & HDA_EAPD_BTL_ENABLE_BTL) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " BTL"); } if (HdaWidget->DefaultEapd & HDA_EAPD_BTL_ENABLE_EAPD) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " EAPD"); } if (HdaWidget->DefaultEapd & HDA_EAPD_BTL_ENABLE_L_R_SWAP) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " R/L"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " Pin Default 0x%8X: [%a] %a at %a %a\n", HdaWidget->DefaultConfiguration, mPortConnectivities[HDA_VERB_GET_CONFIGURATION_DEFAULT_PORT_CONN (HdaWidget->DefaultConfiguration)], mDefaultDevices[HDA_VERB_GET_CONFIGURATION_DEFAULT_DEVICE (HdaWidget->DefaultConfiguration)], mSurfaces[HDA_VERB_GET_CONFIGURATION_DEFAULT_SURF (HdaWidget->DefaultConfiguration)], mLocations[HDA_VERB_GET_CONFIGURATION_DEFAULT_LOC (HdaWidget->DefaultConfiguration)] ); OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " Conn = %a, Color = %a\n", mConnTypes[HDA_VERB_GET_CONFIGURATION_DEFAULT_CONN_TYPE (HdaWidget->DefaultConfiguration)], mColors[HDA_VERB_GET_CONFIGURATION_DEFAULT_COLOR (HdaWidget->DefaultConfiguration)] ); OcAsciiPrintBuffer ( AsciiBuffer, AsciiBufferSize, " DefAssociation = 0x%X, Sequence = 0x%X\n", HDA_VERB_GET_CONFIGURATION_DEFAULT_ASSOCIATION (HdaWidget->DefaultConfiguration), HDA_VERB_GET_CONFIGURATION_DEFAULT_SEQUENCE (HdaWidget->DefaultConfiguration) ); OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "Pin-ctls: 0x%2X:", HdaWidget->DefaultPinControl); if (HdaWidget->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_IN_EN) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " IN"); } if (HdaWidget->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_OUT_EN) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " OUT"); } if (HdaWidget->DefaultPinControl & HDA_PIN_WIDGET_CONTROL_HP_EN) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " HP"); } VrefCtrl = HDA_PIN_WIDGET_CONTROL_VREF (HdaWidget->DefaultPinControl); if (VrefCtrl == HDA_PIN_WIDGET_CONTROL_VREF_HIZ) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_HIZ"); } else if (VrefCtrl == HDA_PIN_WIDGET_CONTROL_VREF_GRD) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_GRD"); } else if (VrefCtrl == HDA_PIN_WIDGET_CONTROL_VREF_50) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_50"); } else if (VrefCtrl == HDA_PIN_WIDGET_CONTROL_VREF_80) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_80"); } else if (VrefCtrl == HDA_PIN_WIDGET_CONTROL_VREF_100) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " VREF_100"); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } // // Connections to other widgets. // if (HdaWidget->Capabilities & HDA_PARAMETER_WIDGET_CAPS_CONN_LIST) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " Connection: %u\n ", HdaWidget->ConnectionCount); for (Index = 0; Index < HdaWidget->ConnectionCount; Index++) { OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, " 0x%2X", HdaWidget->Connections[Index]); } OcAsciiPrintBuffer (AsciiBuffer, AsciiBufferSize, "\n"); } } EFI_STATUS OcAudioDump ( IN EFI_FILE_PROTOCOL *Root ) { EFI_STATUS Status; UINTN HandleCount; EFI_HANDLE *HandleBuffer; UINT32 Index; EFI_HDA_CONTROLLER_INFO_PROTOCOL *HdaControllerInfo; EFI_HDA_CODEC_INFO_PROTOCOL *HdaCodecInfo; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR8 *FileBuffer; UINTN FileBufferSize; CHAR16 TmpFileName[32]; CONST CHAR16 *Name; CHAR16 *DevicePathStr; BOOLEAN TmpBool; UINT8 Tmp8; UINT32 Tmp32A; UINT32 Tmp32B; HDA_WIDGET *HdaWidgets; UINTN HdaWidgetCount; UINT32 HdaWidgetIndex; HandleCount = 0; // // Get all HDA controller instances. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiHdaControllerInfoProtocolGuid, NULL, &HandleCount, &HandleBuffer ); DEBUG ((DEBUG_INFO, "OCAU: %u HDA controllers installed - %r\n", (UINT32)HandleCount, Status)); if (!EFI_ERROR (Status)) { for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiHdaControllerInfoProtocolGuid, (VOID **)&HdaControllerInfo); DEBUG ((DEBUG_INFO, "OCAU: HDA controller %u info open result - %r\n", Index, Status)); if (EFI_ERROR (Status)) { continue; } FileBufferSize = SIZE_1KB; FileBuffer = AllocateZeroPool (FileBufferSize); if (FileBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } // // Get device path of controller. // DevicePath = DevicePathFromHandle (HandleBuffer[Index]); DevicePathStr = NULL; if (DevicePath != NULL) { DevicePathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE); } OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Device path: %s\n", DevicePathStr != NULL ? DevicePathStr : L""); DEBUG ((DEBUG_INFO, "OCAU: Dumping controller at %s\n", DevicePathStr != NULL ? DevicePathStr : L"")); if (DevicePathStr != NULL) { FreePool (DevicePathStr); } Status = HdaControllerInfo->GetName (HdaControllerInfo, &Name); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Controller: %s\n", Status == EFI_SUCCESS ? Name : L""); Status = HdaControllerInfo->GetVendorId (HdaControllerInfo, &Tmp32A); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Vendor Id: 0x%X\n", Tmp32A); // // Save dumped controller data to file. // if (FileBuffer != NULL) { UnicodeSPrint (TmpFileName, sizeof (TmpFileName), L"Controller%u.txt", Index); Status = OcSetFileData (Root, TmpFileName, FileBuffer, (UINT32)AsciiStrLen (FileBuffer)); DEBUG ((DEBUG_INFO, "OCAU: Dumped HDA controller %u info result - %r\n", Index, Status)); FreePool (FileBuffer); } } FreePool (HandleBuffer); } HandleCount = 0; // // Get all HDA codec instances. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiHdaCodecInfoProtocolGuid, NULL, &HandleCount, &HandleBuffer ); DEBUG ((DEBUG_INFO, "OCAU: %u HDA codecs installed - %r\n", (UINT32)HandleCount, Status)); if (!EFI_ERROR (Status)) { for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiHdaCodecInfoProtocolGuid, (VOID **)&HdaCodecInfo); DEBUG ((DEBUG_INFO, "OCAU: HDA codec %u info open result - %r\n", Index, Status)); if (EFI_ERROR (Status)) { continue; } Status = HdaCodecInfo->GetWidgets (HdaCodecInfo, &HdaWidgets, &HdaWidgetCount); if (EFI_ERROR (Status)) { continue; } if (OcOverflowMulAddUN (SIZE_4KB, HdaWidgetCount, SIZE_4KB, &FileBufferSize)) { HdaCodecInfo->FreeWidgetsBuffer (HdaWidgets, HdaWidgetCount); continue; } FileBuffer = AllocateZeroPool (FileBufferSize); if (FileBuffer == NULL) { HdaCodecInfo->FreeWidgetsBuffer (HdaWidgets, HdaWidgetCount); return EFI_OUT_OF_RESOURCES; } // // Get device path of codec. // DevicePath = DevicePathFromHandle (HandleBuffer[Index]); DevicePathStr = NULL; if (DevicePath != NULL) { DevicePathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE); } OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Device path: %s\n", DevicePathStr != NULL ? DevicePathStr : L""); DEBUG ((DEBUG_INFO, "OCAU: Dumping codec at %s\n", DevicePathStr != NULL ? DevicePathStr : L"")); if (DevicePathStr != NULL) { FreePool (DevicePathStr); } Status = HdaCodecInfo->GetAddress (HdaCodecInfo, &Tmp8); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Address: 0x%X\n\n", Tmp8); Status = HdaCodecInfo->GetName (HdaCodecInfo, &Name); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Codec: %s\n", Status == EFI_SUCCESS ? Name : L""); Status = HdaCodecInfo->GetAudioFuncId (HdaCodecInfo, &Tmp8, &TmpBool); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "AFG Function Id: 0x%X (unsol %u)\n", Tmp8, TmpBool); Status = HdaCodecInfo->GetVendorId (HdaCodecInfo, &Tmp32A); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Vendor Id: 0x%X\n", Tmp32A); Status = HdaCodecInfo->GetRevisionId (HdaCodecInfo, &Tmp32A); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Revision Id: 0x%X\n", Tmp32A); Status = HdaCodecInfo->GetDefaultRatesFormats (HdaCodecInfo, &Tmp32A, &Tmp32B); if (!EFI_ERROR (Status) && ((Tmp32A != 0) || (Tmp32B != 0))) { OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Default PCM:\n"); PrintRatesFormats (&FileBuffer, &FileBufferSize, Tmp32A, Tmp32B); } else { OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Default PCM: N/A\n"); } Status = HdaCodecInfo->GetDefaultAmpCaps (HdaCodecInfo, &Tmp32A, &Tmp32B); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Default Amp-In caps: "); PrintAmpCaps (&FileBuffer, &FileBufferSize, Status == EFI_SUCCESS ? Tmp32A : 0); OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Default Amp-Out caps: "); PrintAmpCaps (&FileBuffer, &FileBufferSize, Status == EFI_SUCCESS ? Tmp32B : 0); // // Print all widgets. // for (HdaWidgetIndex = 0; HdaWidgetIndex < HdaWidgetCount; HdaWidgetIndex++) { PrintWidget (&FileBuffer, &FileBufferSize, &HdaWidgets[HdaWidgetIndex]); } HdaCodecInfo->FreeWidgetsBuffer (HdaWidgets, HdaWidgetCount); // // Save dumped codec data to file. // if (FileBuffer != NULL) { UnicodeSPrint (TmpFileName, sizeof (TmpFileName), L"Codec%u.txt", Index); Status = OcSetFileData (Root, TmpFileName, FileBuffer, (UINT32)AsciiStrLen (FileBuffer)); DEBUG ((DEBUG_INFO, "OCAU: Dumped HDA codec %u info result - %r\n", Index, Status)); FreePool (FileBuffer); } } FreePool (HandleBuffer); } return EFI_SUCCESS; }