15#include <Library/BaseMemoryLib.h>
16#include <Library/DebugLib.h>
17#include <Library/DevicePathLib.h>
18#include <Library/MemoryAllocationLib.h>
22#include <Library/UefiBootServicesTableLib.h>
32EFI_DEVICE_PATH_PROTOCOL *
34 IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath,
40 CodecDevicePathNode.
Header.Type = MESSAGING_DEVICE_PATH;
41 CodecDevicePathNode.
Header.SubType = MSG_VENDOR_DP;
42 SetDevicePathNodeLength (&CodecDevicePathNode,
sizeof (CodecDevicePathNode));
44 CodecDevicePathNode.
Address = CodecAddress;
46 return AppendDevicePathNode (
48 (EFI_DEVICE_PATH_PROTOCOL *)&CodecDevicePathNode
64 "OCAU: Incorrect audio I/O protocol revision %u != %u\n",
69 return EFI_UNSUPPORTED;
76 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
77 IN EFI_HANDLE *AudioIoHandles,
78 IN UINTN AudioIoHandleCount
83 CHAR16 *DevicePathText;
84 EFI_DEVICE_PATH_PROTOCOL *CodecDevicePath;
86 UINTN OutputPortsCount;
89 DevicePathText = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
92 "OCAU: Matching %s...\n",
93 DevicePathText != NULL ? DevicePathText : L
"<invalid>"
95 if (DevicePathText != NULL) {
96 FreePool (DevicePathText);
101 for (Index = 0; Index < AudioIoHandleCount; ++Index) {
102 Status =
gBS->HandleProtocol (
103 AudioIoHandles[Index],
105 (VOID **)&CodecDevicePath
109 DevicePathText = NULL;
110 if (!EFI_ERROR (Status)) {
111 DevicePathText = ConvertDevicePathToText (CodecDevicePath, FALSE, FALSE);
114 OutputPortsCount = 0;
115 Status =
gBS->HandleProtocol (
116 AudioIoHandles[Index],
118 (VOID **)&Private->AudioIo
120 if (!EFI_ERROR (Status)) {
124 if (!EFI_ERROR (Status)) {
125 Status = Private->AudioIo->GetOutputs (
130 if (!EFI_ERROR (Status)) {
131 FreePool (OutputPorts);
137 "OCAU: %u/%u %s (%u outputs) - %r\n",
139 (UINT32)(AudioIoHandleCount),
140 DevicePathText != NULL ? DevicePathText : L
"<invalid>",
141 (UINT32)OutputPortsCount,
145 if (DevicePathText != NULL) {
146 FreePool (DevicePathText);
152 Status =
gBS->HandleProtocol (
153 AudioIoHandles[Index],
155 (VOID **)&Private->AudioIo
157 if (!EFI_ERROR (Status)) {
165 return EFI_NOT_FOUND;
179 Private->
Gain = Gain;
188 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL,
189 IN UINT8 CodecAddress OPTIONAL,
190 IN UINT64 OutputIndexMask
195 EFI_HANDLE *AudioIoHandles;
196 UINTN AudioIoHandleCount;
197 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
203 if (DevicePath == NULL) {
204 Status =
gBS->LocateProtocol (
209 if (!EFI_ERROR (Status)) {
213 Status =
gBS->LocateHandleBuffer (
221 if (!EFI_ERROR (Status)) {
223 if (DevicePath == NULL) {
224 DEBUG ((DEBUG_INFO,
"OCAU: Cannot get full device path\n"));
225 FreePool (AudioIoHandles);
226 return EFI_INVALID_PARAMETER;
236 if (EFI_ERROR (Status)) {
241 DEBUG ((DEBUG_INFO,
"OCAU: Retrying with fixed device path\n"));
251 FreePool (DevicePath);
252 FreePool (AudioIoHandles);
254 DEBUG ((DEBUG_INFO,
"OCAU: No AudioIo instances - %r\n", Status));
258 if (EFI_ERROR (Status)) {
259 DEBUG ((DEBUG_INFO,
"OCAU: Cannot find specified audio device - %r\n", Status));
278 if (Acquire == NULL) {
279 return EFI_INVALID_PARAMETER;
303 DEBUG ((DEBUG_VERBOSE,
"OCAU: PlayFileDone signaling for completion\n"));
333 if (Private->
AudioIo == NULL) {
334 DEBUG ((DEBUG_INFO,
"OCAU: RawGainToDecibels has no AudioIo\n"));
345 if (EFI_ERROR (Status)) {
346 DEBUG ((DEBUG_INFO,
"OCAU: RawGainToDecibels conversion failure - %r\n", Status));
356 IN CONST CHAR8 *BasePath,
357 IN CONST CHAR8 *BaseType,
358 IN BOOLEAN Localised,
359 IN INT8 Gain OPTIONAL,
367 UINT32 RawBufferSize;
376 DEBUG ((DEBUG_INFO,
"OCAU: PlayFile has no AudioIo or provider is unconfigured\n"));
393 if (EFI_ERROR (Status)) {
394 DEBUG ((DEBUG_INFO,
"OCAU: PlayFile has no file %a for type %a lang %u - %r\n", BasePath, BaseType, Private->
Language, Status));
395 return EFI_NOT_FOUND;
400 "OCAU: File %a for type %a lang %u is %d %d %d (%u) - %r\n",
407 (UINT32)RawBufferSize,
411 if (EFI_ERROR (Status)) {
412 DEBUG ((DEBUG_INFO,
"OCAU: PlayFile has invalid file %a for type %a lang %u - %r\n", BasePath, BaseType, Private->
Language, Status));
417 return EFI_NOT_FOUND;
420 This->StopPlayback (This, Wait);
422 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
428 UseGain ? Gain : Private->
Gain,
434 if (!EFI_ERROR (Status)) {
443 if (EFI_ERROR (Status)) {
444 DEBUG ((DEBUG_INFO,
"OCAU: PlayFile playback failure - %r\n", Status));
447 DEBUG ((DEBUG_INFO,
"OCAU: PlayFile playback setup failure - %r\n", Status));
450 if (EFI_ERROR (Status)) {
458 gBS->RestoreTPL (OldTpl);
482 DEBUG ((DEBUG_VERBOSE,
"OCAU: StopPlayback %d %p\n", Wait, Private->
CurrentBuffer != NULL));
496 DEBUG ((DEBUG_VERBOSE,
"OCAU: StopPlayback wait - %r\n", Status));
501 if (!EFI_ERROR (Status)) {
512 OldTpl =
gBS->RaiseTPL (TPL_NOTIFY);
544 DEBUG ((DEBUG_VERBOSE,
"OCAU: StopPlayback check - %r\n", Status));
547 gBS->RestoreTPL (OldTpl);
567 return PreviousDelay;
#define EFI_AUDIO_IO_PROTOCOL_REVISION
EFI_AUDIO_IO_PROTOCOL_FREQ
EFI_GUID gEfiAudioIoProtocolGuid
EFI_AUDIO_IO_PROTOCOL_BITS
EFI_GUID gEfiHdaIoDevicePathGuid
EFI_STATUS EFIAPI InternalOcAudioStopPlayback(IN OUT OC_AUDIO_PROTOCOL *This, IN BOOLEAN Wait)
EFI_STATUS EFIAPI InternalOcAudioPlayFile(IN OUT OC_AUDIO_PROTOCOL *This, IN CONST CHAR8 *BasePath, IN CONST CHAR8 *BaseType, IN BOOLEAN Localised, IN INT8 Gain OPTIONAL, IN BOOLEAN UseGain, IN BOOLEAN Wait)
STATIC EFI_DEVICE_PATH_PROTOCOL * OcAudioGetCodecDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *ControllerDevicePath, IN UINT8 CodecAddress)
EFI_STATUS EFIAPI InternalOcAudioConnect(IN OUT OC_AUDIO_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN UINT8 CodecAddress OPTIONAL, IN UINT64 OutputIndexMask)
EFI_STATUS EFIAPI InternalOcAudioRawGainToDecibels(IN OUT OC_AUDIO_PROTOCOL *This, IN UINT8 GainParam, OUT INT8 *Gain)
EFI_STATUS EFIAPI InternalOcAudioSetProvider(IN OUT OC_AUDIO_PROTOCOL *This, IN OC_AUDIO_PROVIDER_ACQUIRE Acquire, IN OC_AUDIO_PROVIDER_RELEASE Release OPTIONAL, IN VOID *Context)
UINTN EFIAPI InternalOcAudioSetDelay(IN OUT OC_AUDIO_PROTOCOL *This, IN UINTN Delay)
EFI_STATUS EFIAPI InternalOcAudioSetDefaultGain(IN OUT OC_AUDIO_PROTOCOL *This, IN INT8 Gain)
STATIC EFI_STATUS AudioIoProtocolConfirmRevision(IN CONST EFI_AUDIO_IO_PROTOCOL *AudioIo)
STATIC EFI_STATUS InternalMatchCodecDevicePath(IN OUT OC_AUDIO_PROTOCOL_PRIVATE *Private, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_HANDLE *AudioIoHandles, IN UINTN AudioIoHandleCount)
STATIC VOID EFIAPI InernalOcAudioPlayFileDone(IN EFI_AUDIO_IO_PROTOCOL *AudioIo, IN VOID *Context)
EFI_STATUS(EFIAPI * OC_AUDIO_PROVIDER_RELEASE)(IN VOID *Context, IN UINT8 *Buffer)
EFI_STATUS(EFIAPI * OC_AUDIO_PROVIDER_ACQUIRE)(IN VOID *Context, IN CONST CHAR8 *BasePath, IN CONST CHAR8 *BaseType, IN BOOLEAN Localised, IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode, OUT UINT8 **Buffer, OUT UINT32 *BufferSize, OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency, OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits, OUT UINT8 *Channels)
#define OC_AUDIO_PROTOCOL_PRIVATE_FROM_OC_AUDIO(Proto)
INTN OcFixAppleBootDevicePath(IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **RemainingDevicePath)
BOOLEAN EFIAPI IsDevicePathEqual(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
EFI_GUID gEfiDevicePathProtocolGuid
EFI_AUDIO_IO_STOP_PLAYBACK StopPlayback
EFI_AUDIO_IO_START_PLAYBACK_ASYNC StartPlaybackAsync
EFI_AUDIO_IO_SETUP_PLAYBACK SetupPlayback
EFI_AUDIO_IO_RAW_GAIN_TO_DECIBELS RawGainToDecibels
EFI_DEVICE_PATH_PROTOCOL Header
OC_AUDIO_PROVIDER_RELEASE ProviderRelease
OC_AUDIO_PROVIDER_ACQUIRE ProviderAcquire
EFI_AUDIO_IO_PROTOCOL * AudioIo