mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
778 lines
23 KiB
C
778 lines
23 KiB
C
/** @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 <IndustryStandard/HdaVerbs.h>
|
|
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/DevicePathLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcAudioLib.h>
|
|
#include <Library/OcDevicePathLib.h>
|
|
#include <Library/OcFileLib.h>
|
|
#include <Library/OcGuardLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/OcStringLib.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
|
|
#include <Protocol/DevicePathToText.h>
|
|
#include <Protocol/HdaIo.h>
|
|
#include <Protocol/HdaCodecInfo.h>
|
|
#include <Protocol/HdaControllerInfo.h>
|
|
|
|
#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"<NULL>");
|
|
DEBUG ((DEBUG_INFO, "OCAU: Dumping controller at %s\n", DevicePathStr != NULL ? DevicePathStr : L"<NULL>"));
|
|
if (DevicePathStr != NULL) {
|
|
FreePool (DevicePathStr);
|
|
}
|
|
|
|
Status = HdaControllerInfo->GetName (HdaControllerInfo, &Name);
|
|
OcAsciiPrintBuffer (&FileBuffer, &FileBufferSize, "Controller: %s\n", Status == EFI_SUCCESS ? Name : L"<NULL>");
|
|
|
|
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"<NULL>");
|
|
DEBUG ((DEBUG_INFO, "OCAU: Dumping codec at %s\n", DevicePathStr != NULL ? DevicePathStr : L"<NULL>"));
|
|
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"<NULL>");
|
|
|
|
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;
|
|
}
|