alder_lake_bios/Intel/AlderLake/Features/Audio/SndwFeaturePkg/SndwBeepAlc1308/SndwBeepRltkAlc1308.c

584 lines
19 KiB
C

/** @file
This DXE driver configures and supports "PC Beep" by SoundWire interface.
@copyright
INTEL CONFIDENTIAL
Copyright 2020 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <Base.h>
#include <Uefi.h>
#include <Uefi/UefiBaseType.h>
#include <Pi/PiFirmwareFile.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/PciSegmentLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <IndustryStandard/Pci22.h>
#include <Protocol/SndwBeepProtocol.h>
#include <Protocol/SndwAccessProtocol.h>
#include <SndwMipiCmd.h>
#define MAP_RANGE(X, IN_MIN, IN_MAX, OUT_MIN, OUT_MAX) (X - IN_MIN) * (OUT_MAX - OUT_MIN) / (IN_MAX - IN_MIN) + OUT_MIN
#define RLTK_ALC1308_DEFAULT_FREQUENCY 0x22
#define RLTK_ALC1308_MAX_FREQUENCY_REG 0x3F
#define RLTK_ALC1308_MIN_FREQUENCY_REG 0x0
#define RLTK_ALC1308_MAX_FREQUENCY_HZ 345
#define RLTK_ALC1308_MIN_FREQUENCY_HZ 5
#define RLTK_ALC1308_FREQUENCY_MAP(X) MAP_RANGE (X, RLTK_ALC1308_MIN_FREQUENCY_HZ, RLTK_ALC1308_MAX_FREQUENCY_HZ, RLTK_ALC1308_MIN_FREQUENCY_REG, RLTK_ALC1308_MAX_FREQUENCY_REG)
#define RLTK_ALC1308_DEFAULT_AMPLITUDE 0x2F
#define RLTK_ALC1308_MAX_AMPLITUDE_REG 0x3F
#define RLTK_ALC1308_MIN_AMPLITUDE_REG 0x0
#define RLTK_ALC1308_MAX_AMPLITUDE_dB 20
#define RLTK_ALC1308_MIN_AMPLITUDE_dB -65
#define RLTK_ALC1308_AMPLITUDE_MAP(X) MAP_RANGE (X, RLTK_ALC1308_MIN_AMPLITUDE_dB, RLTK_ALC1308_MAX_AMPLITUDE_dB, RLTK_ALC1308_MIN_AMPLITUDE_REG, RLTK_ALC1308_MAX_AMPLITUDE_REG)
#define SNDW_BEEP_SIGNATURE SIGNATURE_32 ('s', 'd', 'w', 'b')
typedef struct {
UINT32 Signature;
SNDW_BEEP_PROTOCOL SndwBeepApi;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
SNDW_CODEC_INFO SndwCodecInfo;
} SNDW_BEEP_CONTEXT;
#define SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL(a) CR (a, SNDW_BEEP_CONTEXT, SndwBeepApi, SNDW_BEEP_SIGNATURE)
GLOBAL_REMOVE_IF_UNREFERENCED SNDW_COMMAND RltkAlc1308SndwBeepInitCmds[] = {
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC320,
.RegData = 0xFF,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC321,
.RegData = 0x37,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC322,
.RegData = 0x16,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC080,
.RegData = 0x04,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC310,
.RegData = 0x22,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC311,
.RegData = 0x7F,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC090,
.RegData = 0x61,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC360,
.RegData = 0x0B,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC361,
.RegData = 0x80,
}
},
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC501,
.RegData = 0x22,
}
}
};
GLOBAL_REMOVE_IF_UNREFERENCED SNDW_COMMAND RltkAlc1308SndwBeepFrequencyControlCmds =
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC501,
.RegData = RLTK_ALC1308_DEFAULT_FREQUENCY,
}
};
GLOBAL_REMOVE_IF_UNREFERENCED SNDW_COMMAND RltkAlc1308SndwBeepAmplitudeControlCmds =
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC502,
.RegData = RLTK_ALC1308_DEFAULT_AMPLITUDE,
}
};
GLOBAL_REMOVE_IF_UNREFERENCED SNDW_COMMAND RltkAlc1308SndwBeepOnCmds =
{
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC500,
.RegData = 0x50,
}
};
GLOBAL_REMOVE_IF_UNREFERENCED SNDW_COMMAND RltkAlc1308SndwBeepOffCmds = {
.TxWrite = {
.OpCode = SndwCmdWrite,
.RegAddr = 0xC500,
.RegData = 0x10,
}
};
/**
This function returns register value corresponding to given frequency
@param[in] Frequency Frequency for which register value should be returned
**/
UINT8
Alc1308GetRegValueFromFrequency (
IN UINTN Frequency
)
{
///
/// Override frequency value if given value is out of range
///
Frequency = MAX (Frequency, RLTK_ALC1308_MIN_FREQUENCY_HZ);
Frequency = MIN (Frequency, RLTK_ALC1308_MAX_FREQUENCY_HZ);
DEBUG ((DEBUG_INFO, "Selected frequency: %d Hz.\n", Frequency));
return (UINT8) (RLTK_ALC1308_FREQUENCY_MAP (Frequency));
}
/**
This function returns register value corresponding to given amplitude
@param[in] Amplitude Amplitude for which register value should be returned
**/
UINT8
Alc1308GetRegValueFromAmplitude (
IN INTN Amplitude
)
{
///
/// Override amplitude value if given value is out of range
///
Amplitude = MAX (Amplitude, RLTK_ALC1308_MIN_AMPLITUDE_dB);
Amplitude = MIN (Amplitude, RLTK_ALC1308_MAX_AMPLITUDE_dB);
DEBUG ((DEBUG_INFO, "Selected amplitude: %d dB.\n", Amplitude));
return (UINT8) (RLTK_ALC1308_AMPLITUDE_MAP (Amplitude));
}
/**
This function turns on tone generator located in Sndw codec
@param[in] This Pointer to Sndw beep protocol.
@param[in] Frequency Frequency value for tone generator. Refer to codec specyfication.
@param[in] Amplitude Amplitude value for tone generator. Refer to codec specyfication.
@param[in] NumOfBeeps Number of beeps.
@param[in] BeepDuration Length of beep sound in miliseconds.
@param[in] PauseDuration Duration of pause between beeps.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
**/
EFI_STATUS
EFIAPI
DxeSndwBeep (
IN CONST SNDW_BEEP_PROTOCOL *This,
IN UINTN Frequency,
IN INTN Amplitude,
IN UINTN NumOfBeeps,
IN UINTN BeepDuration,
IN UINTN PauseDuration
)
{
SNDW_BEEP_CONTEXT *SndwBeepContext;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
UINTN Index;
EFI_STATUS Status;
SNDW_COMMAND CommandResponse;
DEBUG ((DEBUG_INFO, "%a () - Start.\n", __FUNCTION__));
SndwBeepContext = SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL (This);
SndwAccessApi = SndwBeepContext->SndwAccessApi;
for (Index = 0; Index < (sizeof (RltkAlc1308SndwBeepInitCmds) / sizeof (SNDW_COMMAND)); Index++) {
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepInitCmds[Index], &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Tone generator initialization failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return EFI_DEVICE_ERROR;
}
}
RltkAlc1308SndwBeepFrequencyControlCmds.TxWrite.RegData = Alc1308GetRegValueFromFrequency (Frequency);
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepFrequencyControlCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Frequency initialization in tone generator has failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return EFI_DEVICE_ERROR;
}
RltkAlc1308SndwBeepAmplitudeControlCmds.TxWrite.RegData = Alc1308GetRegValueFromAmplitude (Amplitude);
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepAmplitudeControlCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Amplitude initialization in tone generator has failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return EFI_DEVICE_ERROR;
}
for (Index = 0; Index < NumOfBeeps; Index++) {
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepOnCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Turn on tone generator failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return EFI_DEVICE_ERROR;
}
MicroSecondDelay (BeepDuration * 1000);
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepOffCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Turn off tone generator failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return EFI_DEVICE_ERROR;
}
MicroSecondDelay (PauseDuration * 1000);
}
DEBUG ((DEBUG_INFO, "%a () - End.\n", __FUNCTION__));
return EFI_SUCCESS;
}
/**
This function turns on tone generator located in Sndw codec
@param[in] *This Pointer to Sndw beep protocol
@param[in] Frequency Frequency value for tone generator. Refer to codec specyfication.
@param[in] Amplitude Amplitude value for tone generator. Refer to codec specyfication.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
**/
EFI_STATUS
EFIAPI
DxeSndwBeepOn (
IN CONST SNDW_BEEP_PROTOCOL *This,
IN UINTN Frequency,
IN INTN Amplitude
)
{
SNDW_BEEP_CONTEXT *SndwBeepContext;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
UINTN Index;
EFI_STATUS Status;
SNDW_COMMAND CommandResponse;
DEBUG ((DEBUG_INFO, "%a () - Start.\n", __FUNCTION__));
SndwBeepContext = SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL (This);
SndwAccessApi = SndwBeepContext->SndwAccessApi;
for (Index = 0; Index < (sizeof (RltkAlc1308SndwBeepInitCmds) / sizeof (SNDW_COMMAND)); Index++) {
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepInitCmds[Index], &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Tone generator initialization failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
}
RltkAlc1308SndwBeepFrequencyControlCmds.TxWrite.RegData = Alc1308GetRegValueFromFrequency (Frequency);
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepFrequencyControlCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Frequency initialization in tone generator has failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
RltkAlc1308SndwBeepAmplitudeControlCmds.TxWrite.RegData = Alc1308GetRegValueFromAmplitude (Amplitude);
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepAmplitudeControlCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Amplitude initialization in tone generator has failed.\n"));
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepOnCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Turn on tone generator failed.\n"));
}
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
/**
This function turns off tone generator located in Sndw codec
@param[in] *This Pointer to Sndw beep protocol.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
**/
EFI_STATUS
EFIAPI
DxeSndwBeepOff (
IN CONST SNDW_BEEP_PROTOCOL *This
)
{
SNDW_BEEP_CONTEXT *SndwBeepContext;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
EFI_STATUS Status;
SNDW_COMMAND CommandResponse;
DEBUG ((DEBUG_INFO, "%a () - Start.\n", __FUNCTION__));
SndwBeepContext = SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL (This);
SndwAccessApi = SndwBeepContext->SndwAccessApi;
Status = SndwAccessApi->SendWithAck (SndwAccessApi, SndwBeepContext->SndwCodecInfo, RltkAlc1308SndwBeepOffCmds, &CommandResponse);
if (EFI_ERROR (Status) || (CommandResponse.Rx.Ack == 0)) {
DEBUG ((DEBUG_ERROR, "Turn off tone generator failed.\n"));
}
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
/**
This function enables Sndw interface.
@param[in] *This Pointer to Sndw beep protocol.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
**/
EFI_STATUS
EFIAPI
DxeSndwEnable (
IN CONST SNDW_BEEP_PROTOCOL *This
)
{
SNDW_BEEP_CONTEXT *SndwBeepContext;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "%a () - Start.\n", __FUNCTION__));
SndwBeepContext = SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL (This);
SndwAccessApi = SndwBeepContext->SndwAccessApi;
Status = SndwAccessApi->Enable (SndwAccessApi);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Sndw initialization failed.\n"));
}
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
/**
This function disables Sndw interface.
@param[in] *This Pointer to Sndw beep protocol.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
**/
EFI_STATUS
EFIAPI
DxeSndwDisable (
IN CONST SNDW_BEEP_PROTOCOL *This
)
{
SNDW_BEEP_CONTEXT *SndwBeepContext;
SNDW_ACCESS_PROTOCOL *SndwAccessApi;
EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "%a () - Start.\n", __FUNCTION__));
SndwBeepContext = SNDW_BEEP_CONTEXT_FROM_SNDW_BEEP_PROTOCOL (This);
SndwAccessApi = SndwBeepContext->SndwAccessApi;
Status = SndwAccessApi->Disable (SndwAccessApi);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Sndw disbale failed.\n"));
}
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return Status;
}
/**
This function performs basic structures initialization and installs Sndw Beep protocol.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
SndwBeepRltkAlc1308Init (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_HANDLE SndwBeepHandle;
EFI_STATUS Status;
SNDW_BEEP_CONTEXT *SndwBeepContext;
DEBUG ((DEBUG_INFO, "%a () Start.\n", __FUNCTION__));
gBS->CloseEvent (Event);
SndwBeepHandle = NULL;
SndwBeepContext = AllocateZeroPool (sizeof (SNDW_BEEP_CONTEXT));
if (NULL == SndwBeepContext) {
DEBUG ((DEBUG_INFO, "%a () - End. Memory pool allocation error.\n", __FUNCTION__));
return;
}
SndwBeepContext->Signature = SNDW_BEEP_SIGNATURE;
SndwBeepContext->SndwBeepApi.BeepOn = DxeSndwBeepOn;
SndwBeepContext->SndwBeepApi.BeepOff = DxeSndwBeepOff;
SndwBeepContext->SndwBeepApi.Beep = DxeSndwBeep;
SndwBeepContext->SndwBeepApi.Enable = DxeSndwEnable;
SndwBeepContext->SndwBeepApi.Disable = DxeSndwDisable;
SndwBeepContext->SndwCodecInfo.SndwLinkIndex = PcdGet8 (PcdSndwBeepLinkNumber);
CopyMem (SndwBeepContext->SndwCodecInfo.CodecId.Data, PcdGetPtr (PcdSndwBeepCodecId), sizeof (SNDW_CODEC_ID));
DEBUG ((DEBUG_INFO, "Codec ID:\n"));
DEBUG ((DEBUG_INFO, " Version [0x50]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.Version));
DEBUG ((DEBUG_INFO, " ManufacturerID[0] [0x51]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.ManufacturerID[0]));
DEBUG ((DEBUG_INFO, " ManufacturerID[1] [0x52]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.ManufacturerID[1]));
DEBUG ((DEBUG_INFO, " PartId[0] [0x53]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.PartId[0]));
DEBUG ((DEBUG_INFO, " PartId[1] [0x54]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.PartId[1]));
DEBUG ((DEBUG_INFO, " Class [0x55]: %02x\n", SndwBeepContext->SndwCodecInfo.CodecId.Encoding.Class));
///
/// Locate the Sndw Access Protocol.
///
Status = gBS->LocateProtocol (
&gSndwAccessProtocolGuid,
NULL,
(VOID **) &SndwBeepContext->SndwAccessApi
);
ASSERT_EFI_ERROR (Status);
///
/// Install on a new handle
///
Status = gBS->InstallProtocolInterface (
&SndwBeepHandle,
&gSndwBeepProtocolGuid,
EFI_NATIVE_INTERFACE,
&SndwBeepContext->SndwBeepApi
);
DEBUG ((DEBUG_INFO, "Sndw Beep Protocol Installattion Status = %r\n", Status));
if (EFI_ERROR (Status)) {
FreePool (SndwBeepContext);
}
DEBUG ((DEBUG_INFO, "%a () - End. Status = %r.\n", __FUNCTION__, Status));
return;
}
/**
@param ImageHandle The firmware allocated handle for the EFI image.
@param SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_DEVICE_ERROR Not able to enable DSP memory space.
@retval EFI_UNSUPPORTED Requested Sndw link not exists.
**/
EFI_STATUS
EFIAPI
DxeSndwBeepRltkAlc1308EntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
VOID *Registration;
EFI_EVENT Event;
Event = NULL;
Event = EfiCreateProtocolNotifyEvent (
&gSndwAccessProtocolGuid,
TPL_CALLBACK,
SndwBeepRltkAlc1308Init,
NULL,
&Registration
);
if (Event == NULL) {
return EFI_ABORTED;
}
return EFI_SUCCESS;
}