CloverBootloader/Drivers/AudioDxe/HdaCodec/HdaCodecInfo.c

356 lines
13 KiB
C
Raw Normal View History

/*
* File: HdaCodecInfo.c
*
* Copyright (c) 2018 John Davis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
//#include "HdaCodec.h"
#include "../AudioDxe.h"
//#include <IndustryStandard/HdaCodec.h>
/**
Gets the codec's name.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] CodecName A pointer to the buffer to return the codec name.
@retval EFI_SUCCESS The codec name was retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetCodecName(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT CHAR16 **CodecName) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetCodecName(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (CodecName == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill codec name parameter.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*CodecName = HdaPrivateData->HdaCodecDev->Name;
return EFI_SUCCESS;
}
/**
Gets the codec's vendor and device ID.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] VendorId The vendor and device ID of the codec.
@retval EFI_SUCCESS The vendor and device ID was retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetVendorId(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT UINT32 *VendorId) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetVendorId(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (VendorId == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill vendor ID parameter.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*VendorId = HdaPrivateData->HdaCodecDev->VendorId;
return EFI_SUCCESS;
}
/**
Gets the codec's revision ID.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] RevisionId The revision ID of the codec.
@retval EFI_SUCCESS The revision ID was retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetRevisionId(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT UINT32 *RevisionId) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetRevisionId(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (RevisionId == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill revision ID parameter.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*RevisionId = HdaPrivateData->HdaCodecDev->RevisionId;
return EFI_SUCCESS;
}
/**
Gets the node ID of the codec's audio function.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] AudioFuncId The node ID of the codec's audio function.
@retval EFI_SUCCESS The node ID was retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetAudioFuncId(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT UINT8 *AudioFuncId,
OUT BOOLEAN *UnsolCapable) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetAudioFuncId(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (AudioFuncId == NULL) || (UnsolCapable == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill node ID parameter.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*AudioFuncId = HdaPrivateData->HdaCodecDev->AudioFuncGroup->NodeId;
*UnsolCapable = HdaPrivateData->HdaCodecDev->AudioFuncGroup->UnsolCapable;
return EFI_SUCCESS;
}
/**
Gets the codec's default supported stream rates and formats.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] Rates The default supported rates.
@param[out] Formats The default supported formats.
@retval EFI_SUCCESS The stream rates and formats were retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetDefaultRatesFormats(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT UINT32 *Rates,
OUT UINT32 *Formats) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetDefaultRatesFormats(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (Rates == NULL) || (Formats == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill rates and formats parameters.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*Rates = HdaPrivateData->HdaCodecDev->AudioFuncGroup->SupportedPcmRates;
*Formats = HdaPrivateData->HdaCodecDev->AudioFuncGroup->SupportedFormats;
return EFI_SUCCESS;
}
/**
Gets the codec's default amp capabilities.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] AmpInCaps The default input amp capabilities.
@param[out] AmpOutCaps The default output amp capabilities.
@retval EFI_SUCCESS The default amp capabilities were retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetDefaultAmpCaps(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT UINT32 *AmpInCaps,
OUT UINT32 *AmpOutCaps) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetDefaultAmpCaps(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
// If parameters are null, fail.
if ((This == NULL) || (AmpInCaps == NULL) || (AmpOutCaps == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and fill amp caps parameters.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
*AmpInCaps = HdaPrivateData->HdaCodecDev->AudioFuncGroup->AmpInCapabilities;
*AmpOutCaps = HdaPrivateData->HdaCodecDev->AudioFuncGroup->AmpOutCapabilities;
return EFI_SUCCESS;
}
/**
Gets the codec's widgets.
@param[in] This A pointer to the EFI_HDA_CODEC_INFO_PROTOCOL instance.
@param[out] Widgets A pointer to the buffer to return the requested array of widgets.
@param[out] WidgetCount The number of widgets returned in Widgets.
@retval EFI_SUCCESS The widgets were retrieved.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
@retval EFI_OUT_OF_RESOURCES A buffer couldn't be allocated.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoGetWidgets(
IN EFI_HDA_CODEC_INFO_PROTOCOL *This,
OUT HDA_WIDGET **Widgets,
OUT UINTN *WidgetCount) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoGetWidgets(): start\n"));
// Create variables.
HDA_CODEC_INFO_PRIVATE_DATA *HdaPrivateData;
HDA_WIDGET_DEV *HdaWidgetDev;
UINT8 AmpInCount;
HDA_WIDGET *HdaWidgets;
UINTN HdaWidgetsCount;
// If parameters are null, fail.
if ((This == NULL) || (Widgets == NULL) || (WidgetCount == NULL))
return EFI_INVALID_PARAMETER;
// Get private data and allocate widgets array.
HdaPrivateData = HDA_CODEC_INFO_PRIVATE_DATA_FROM_THIS(This);
HdaWidgetsCount = HdaPrivateData->HdaCodecDev->AudioFuncGroup->WidgetsCount;
HdaWidgets = AllocateZeroPool(sizeof(HDA_WIDGET) * HdaWidgetsCount);
if (HdaWidgets == NULL)
return EFI_OUT_OF_RESOURCES;
// Populate widgets array.
for (UINTN w = 0; w < HdaWidgetsCount; w++) {
// Get widget.
HdaWidgetDev = HdaPrivateData->HdaCodecDev->AudioFuncGroup->Widgets + w;
// Get basic data.
HdaWidgets[w].NodeId = HdaWidgetDev->NodeId;
HdaWidgets[w].Capabilities = HdaWidgetDev->Capabilities;
HdaWidgets[w].DefaultUnSol = HdaWidgetDev->DefaultUnSol;
HdaWidgets[w].DefaultEapd = HdaWidgetDev->DefaultEapd;
// Get connections.
HdaWidgets[w].ConnectionListLength = HdaWidgetDev->ConnectionListLength;
HdaWidgets[w].Connections = AllocateZeroPool(sizeof(UINT16) * HdaWidgetDev->ConnectionCount);
if (HdaWidgets[w].Connections == NULL)
goto FREE_WIDGETS;
CopyMem(HdaWidgets[w].Connections, HdaWidgetDev->Connections, sizeof(UINT16) * HdaWidgetDev->ConnectionCount);
// Get power info.
HdaWidgets[w].SupportedPowerStates = HdaWidgetDev->SupportedPowerStates;
HdaWidgets[w].DefaultPowerState = HdaWidgetDev->DefaultPowerState;
// Get input amps.
HdaWidgets[w].AmpInCapabilities = HdaWidgetDev->AmpInCapabilities;
if (HdaWidgetDev->Capabilities & HDA_PARAMETER_WIDGET_CAPS_IN_AMP) {
// Determine number of input amps.
AmpInCount = HdaWidgetDev->ConnectionCount;
if (AmpInCount < 1)
AmpInCount = 1;
// Allocate arrays.
HdaWidgets[w].AmpInLeftDefaultGainMute = AllocateZeroPool(sizeof(UINT8) * AmpInCount);
HdaWidgets[w].AmpInRightDefaultGainMute = AllocateZeroPool(sizeof(UINT8) * AmpInCount);
if ((HdaWidgets[w].AmpInLeftDefaultGainMute == NULL) ||
(HdaWidgets[w].AmpInRightDefaultGainMute == NULL))
goto FREE_WIDGETS;
// Copy arrays.
CopyMem(HdaWidgets[w].AmpInLeftDefaultGainMute, HdaWidgetDev->AmpInLeftDefaultGainMute,
sizeof(UINT8) * AmpInCount);
CopyMem(HdaWidgets[w].AmpInRightDefaultGainMute, HdaWidgetDev->AmpInRightDefaultGainMute,
sizeof(UINT8) * AmpInCount);
}
// Get output amp.
HdaWidgets[w].AmpOutCapabilities = HdaWidgetDev->AmpOutCapabilities;
HdaWidgets[w].AmpOutLeftDefaultGainMute = HdaWidgetDev->AmpOutLeftDefaultGainMute;
HdaWidgets[w].AmpOutRightDefaultGainMute = HdaWidgetDev->AmpOutRightDefaultGainMute;
// Get input/output data.
HdaWidgets[w].SupportedPcmRates = HdaWidgetDev->SupportedPcmRates;
HdaWidgets[w].SupportedFormats = HdaWidgetDev->SupportedFormats;
HdaWidgets[w].DefaultConvFormat = HdaWidgetDev->DefaultConvFormat;
HdaWidgets[w].DefaultConvStreamChannel = HdaWidgetDev->DefaultConvStreamChannel;
HdaWidgets[w].DefaultConvChannelCount = HdaWidgetDev->DefaultConvChannelCount;
// Get pin complex data.
HdaWidgets[w].PinCapabilities = HdaWidgetDev->PinCapabilities;
HdaWidgets[w].DefaultPinControl = HdaWidgetDev->DefaultPinControl;
HdaWidgets[w].DefaultConfiguration = HdaWidgetDev->DefaultConfiguration;
// Get volume knob data.
HdaWidgets[w].VolumeCapabilities = HdaWidgetDev->VolumeCapabilities;
HdaWidgets[w].DefaultVolume = HdaWidgetDev->DefaultVolume;
}
// Fill parameters.
*WidgetCount = HdaWidgetsCount;
*Widgets = HdaWidgets;
return EFI_SUCCESS;
FREE_WIDGETS:
HdaCodecInfoFreeWidgetsBuffer(HdaWidgets, HdaWidgetsCount);
return EFI_OUT_OF_RESOURCES;
}
/**
Frees an array of HDA_WIDGET.
@param[in] Widgets A pointer to the buffer array of widgets that is to be freed.
@param[in] WidgetCount The number of widgets in Widgets.
@retval EFI_SUCCESS The buffer was freed.
@retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
EFI_STATUS
EFIAPI
HdaCodecInfoFreeWidgetsBuffer(
IN HDA_WIDGET *Widgets,
IN UINTN WidgetCount) {
//DEBUG((DEBUG_INFO, "HdaCodecInfoFreeWidgetsBuffer(): start\n"));
// If parameter is null, fail.
if (Widgets == NULL)
return EFI_INVALID_PARAMETER;
// Free pool buffers.
for (UINTN w = 0; w < WidgetCount; w++) {
if (Widgets[w].Connections != NULL)
FreePool(Widgets[w].Connections);
if (Widgets[w].AmpInLeftDefaultGainMute != NULL)
FreePool(Widgets[w].AmpInLeftDefaultGainMute);
if (Widgets[w].AmpInRightDefaultGainMute != NULL)
FreePool(Widgets[w].AmpInRightDefaultGainMute);
}
FreePool(Widgets);
return EFI_SUCCESS;
}