/* * 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 /** 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; }