|
|
||
|---|---|---|
| .. | ||
| Include | ||
| IncludePrivate | ||
| LibraryPrivate | ||
| SndwBeepAlc1308 | ||
| SndwBeepExample | ||
| SndwInitDxe | ||
| Package.dsc | ||
| Readme.md | ||
| SndwFeaturePkg.dec | ||
| SndwFeaturePkg.dsc | ||
Readme.md
Overview
- Feature Name: SndwFeaturePkg - The SoundWire (Sndw) Manager IP is a soft controller IP with configurable parameters that can be tailored to support audio streaming applications over the SoundWire interface on Intel platforms.
- PI Phase(s) Supported: DXE
- SMM Required: No
Purpose
This feature allows to initialize built-in SoundWire controllers on Intel platforms and enumerate/control connected codecs to each SoundWire controller over the SoundWire interface. For more information about SoundWire interface, see SoundWire specification.
Currently supported use cases:
- Driver strength selection
- Multiple codecs support, up to 11 codecs on each SoundWire link (single Manager interface handles up to 11 codecs according to SoundWire specification)
- Installing SndwAccess protocol which allows communication with all connected codecs
- Installing SndwBeep protocol which allows short tones generation by supported codecs
Currently supported codecs:
- Realtek ALC1308
High-Level Theory of Operation
Feature package contains:
-
Protocols
- SndwAccess
- This protocol contains all functions needed to operate on attached SoundWire codecs. Enable/disable functions allow to enable and disable access to SoundWire codecs. User before any operation on codecs should use Enable function. In other cases access will not be ready. After the user is done using codecs, Disable function should be called. In other cases SoundWire OS driver may work incorrectly.
- SndwBeep
- This protocol contains functions which allow to generate short tones e.g. for diagnostic purpose. This protocol for correct working require SndwAccess protocol.
- SndwAccess
-
Drivers
-
SndwInitDxe (DxeSndwInit.inf)
- This driver is responsible for installing the SndwAccess protocol on SndwInitDxe entry point. SndwAccess protocol allows to prepare SoundWire controllers for codecs enumeration process. During enumeration SndwInitDxe driver checks and initializes all of the connected codecs and reads all identification information from them. Based on this data SndwInitDxe driver creates codecs list. The SndwInitDxe.inf entry point has to be executed before drivers start binding to the hardware. It is board responsibility to place them in flash in a way that meets this requirement.
-
SndwBeepRltkAlc1308 (SndwBeepRltkAlc1308.inf)
- This driver is responsible for installing the SndwBeep protocol. It implements all of the SndwBeep protocol functions for Realtek ALC1308 codec. This driver requires SndwAccess protocol to work.
-
SoundWire Access Protocol
| EFI Guid Name | Guid Value |
|---|---|
| gSndwAccessProtocolGuid | 0x0DA23D05-425B-4A21-83EE-D3546E2CD4C3 |
| Function Name | Parameters | Comments |
|---|---|---|
Send |
CONST SNDW_ACCESS *ThisSNDW_CODEC_INFO SndwCodecInfoSNDW_COMMAND *TxCommandUINTN TxSize |
Function operating on Sndw Fifo buffer for sending messages to codecs. |
SendWithAck |
CONST SNDW_ACCESS *ThisSNDW_CODEC_INFO SndwCodecInfoSNDW_COMMAND TxCommandSNDW_COMMAND RxCommand (OPTIONAL) |
Function sends one message through the Sndw interface and waits for the corresponding ACK message. |
Receive |
CONST SNDW_ACCESS *ThisSNDW_CODEC_INFO SndwCodecInfoSNDW_COMMAND **RxCommandUINTN RxSize |
Function operating on Sndw Fifo for receiving messages from codecs. |
GetFirstCodec |
CONST SNDW_ACCESS *ThisSNDW_CODEC_INFO **SndwCodecInfo |
Function return first codec saved in codecs list. If it does not exist, function sets *CodecInfo to NULL. |
GetNextCodec |
CONST SNDW_ACCESS *ThisSNDW_CODEC_INFO *SndwCodecInfoSNDW_CODEC_INFO **NextCodecInfo |
Function retrieves the next codec saved in codecs list that follows the given one. If it does not exist, function sets *NextCodecInfo to NULL. |
Enable |
CONST SNDW_ACCESS *This |
Function enables Soundwire interface and enumerates attached codecs. |
Disable |
CONST SNDW_ACCESS *This |
Function disables Soundwire interface. |
SoundWire CodecInfo structure (SNDW_CODEC_INFO)
| Field Name | Comments |
|---|---|
SndwLinkIndex |
Number of SoundWire link from 1 to max SoundWire link number (Defined by silicon). Check board design. |
CodecId |
Structure specifying the address of SoundWire codec. This address should be unique on link, where codec is connected. |
SoundWire CodecId structure
| Register Address | Field Name | Comments |
|---|---|---|
0x50 |
Version | Indicates compliance with a specific SoundWire specification version. b 0011 => SoundWire v1.2b 0010 => SoundWire v1.1b 0001 => SoundWire v1.0 |
0x51, 0x52 |
ManufacturerID | MIPI standard manufacturer code, see http://mid.mipi.org. |
0x53, 0x54 |
PartID | Fields implemented and defined by manufacturer. |
0x55 |
Class | Field reserved for MIPI-defined class encoding. |
SoundWire MIPI Tx/Rx Commands structure
| Bits | Field Name | Read | Write | Comments |
|---|---|---|---|---|
31 |
SspTag | SSPOINT_TAG | SSPOINT_TAG | This bit is used to inform hardware that this command should be delayed until the next SSP occurs. |
30:28 |
Opcode | SndwCmdRead | SndwCmdWrite | Type of the command. |
27:24 |
DeviceAddress | Device Address (0-11) | DeviceAddress (0-11) | Do not edit this field. It is overriden by driver based on enumeration process. |
23:8 |
RegAddress | Register Address | Register Address | It is an address of the register in codec memory. Check codec specification. |
7:0 |
RegData | Reserved | Register Data | New value of register |
SoundWire MIPI Rx Responses structure
| Bits | Field Name | Read | Write | Comments |
|---|---|---|---|---|
31:16 |
Reserved2 | Reserved | Reserved | Reserved. |
15:8 |
Data | RegData | Response Data | Response from Read Tx Command. |
7 |
Reserved1 | Reserved | Reserved | Reserved. |
6:4 |
Opcode | SndwCmdRead | SndwCmdWrite | Type of command. |
3:2 |
Reserved0 | Reserved | Reserved | Reserved. |
1 |
Nak | NAK | NAK | If this value is equal to b1, command is aborted. |
0 |
Ack | ACK | ACK | Informs whether command has been accepted. If this value is equal to b1 then command has been accepted. |
Opcode
| Value in Opcode field | Command Name |
|---|---|
b000 |
Ping |
b010 |
Read |
b011 |
Write |
SoundWire Beep Protocol
| EFI Guid Name | Guid Value |
|---|---|
| gSndwBeepProtocolGuid | 0x5D2A7CCF-33BE-444D-BAA6-D6B597F5668B |
| Function Name | Parameters | Comments |
|---|---|---|
BeepOff |
CONST SNDW_BEEP *This |
Function send command which disables sine tone generator. |
BeepOn |
CONST SNDW_BEEP *ThisUINTN FrequencyINTN Amplitude |
Function sends command which enables sine tone generator. |
Beep |
CONST SNDW_BEEP *ThisUINTN FrequencyINTN AmplitudeUINTN NumOfBeepsUINTN BeepDurationUINTN PauseDuration |
Function send command which enables sine tone generator. It allows to customize parameters like duration, number of beeps and pause between beeps. |
Enable |
CONST SNDW_BEEP *This |
Function calls Enable function from SoundWire Access protocol. |
Disable |
CONST SNDW_BEEP *This |
Function calls Disable function from SoundWire Access protocol. |
Modules
- DxeSndwInit.inf
- SndwBeepRltkAlc1308.inf
- SndwBeepExample.inf
Configuration
Set gSndwFeatureModuleTokenSpaceGuid.PcdSndwFeatureEnable to TRUE to enable SoundWire feature.
SndwBeepDriver is configured by PCDs: PcdSndwBeepLinkNumber and PcdSndwBeepCodecId. PcdSndwBeepLinkNumber is used to select the number of SoundWire link. SoundWire links are numbered from 1. PcdSndwBeepCodecId contains information about codec IDs.
Settings example
gSndwFeatureModuleTokenSpaceGuid.PcdSndwBeepLinkNumber|0x01
gSndwFeatureModuleTokenSpaceGuid.PcdSndwBeepCodecId|{0x20, 0x02, 0x5D, 0x13, 0x08, 0x00}
Data flows
SoundWire Access Protocol
SndwAccess Protocol can be used in all DXE phases after protocol installation. Before calling any function for communication with codecs user should use Enable function. After that user can call any function provided by SndwAccess Protocol. After all operations user should use Disable function. This step is important for further SoundWire components like OS drivers.
Example:
Status = gBS->LocateProtocol (
&gSndwAccessProtocolGuid,
NULL,
(VOID **) &SndwAccess
);
ASSERT_EFI_ERROR (Status);
Status = SndwAccess->Enable (SndwAccess);
...
Status = SndwAccess->Disable (SndwAccess);
After SndwAccess->Enable call user can send and receive MCP messages from codecs. Function Send is able to send multiple messages. Parameters for Send function are pointer to SndwAccess Protocol, codec informations (SNDW_CODEC_INFO), pointer to array of MCP messages (SNDW_COMMAND) and number of messages. Refer to SoundWire CodecId structure, SoundWire MIPI Tx/Rx Commands structure and Opcode.
Example:
SNDW_CODEC_INFO CodecInfo;
SNDW_COMMAND Command[1];
CodecInfo.SndwLinkIndex = 1; // Sndw Link index
CodecInfo.CodecId.Encoding.Version = 0x20;
CodecInfo.CodecId.Encoding.ManufacturerID[0] = 0x02;
CodecInfo.CodecId.Encoding.ManufacturerID[1] = 0x5D;
CodecInfo.CodecId.Encoding.PartId[0] = 0x13;
CodecInfo.CodecId.Encoding.PartId[1] = 0x08;
CodecInfo.CodecId.Encoding.Class = 0x00;
Command[0].TxWrite.OpCode = SndwCmdWrite; // write data to codec
Command[0].TxWrite.RegAddr = 0x42; // address of register in codec memory
Command[0].TxWrite.RegData = 0x21; // new register value
Status = SndwAccess->Send (SndwAccess, CodecInfo, &Command, 1);
All messages sent to codecs have responses. Response contains data from codec if OpCode of command was SndwRead, Ack and Nak. Refer to SoundWire MIPI Rx Responses structure. Function for getting responses is Receive. Parameters for Receive function are pointer to SndwAccess protocol, codec information structure (SNDW_CODEC_INFO), pointer to received MCP messages (SNDW_COMMAND) and number of received messages. Receive function allocates memory and user should free up this memory with FreePool;
Example:
SNDW_CODEC_INFO CodecInfo;
SNDW_COMMAND *CommandResponse;
UINTN ResponseSize;
CodecInfo.SndwLinkIndex = 1; // Sndw Link index
CodecInfo.CodecId.Encoding.Version = 0x20;
CodecInfo.CodecId.Encoding.ManufacturerID[0] = 0x02;
CodecInfo.CodecId.Encoding.ManufacturerID[1] = 0x5D;
CodecInfo.CodecId.Encoding.PartId[0] = 0x13;
CodecInfo.CodecId.Encoding.PartId[1] = 0x08;
CodecInfo.CodecId.Encoding.Class = 0x00;
Status = SndwAccess->Receive (SndwAccess, CodecInfo, &CommandResponse, &ResponseSize);
if (!EFI_ERROR (Status) && CommandResponse[0].Rx.Ack == 1) {
// command success
}
FreePool (CommandResponse);
SndwAccess Protocol allows to send and receive one MCP message at a time by SendWithAck function. Parameters are pointer to SndwAccess protocol, codec information structure (SNDW_CODEC_INFO), MCP messages to send (SNDW_COMMAND) and pointer to received MCP message.
Example:
SNDW_CODEC_INFO CodecInfo;
SNDW_COMMAND Command;
SNDW_COMMAND *CommandRespons;
CodecInfo.SndwLinkIndex = 1; // Sndw Link index
CodecInfo.CodecId.Encoding.Version = 0x20;
CodecInfo.CodecId.Encoding.ManufacturerID[0] = 0x02;
CodecInfo.CodecId.Encoding.ManufacturerID[1] = 0x5D;
CodecInfo.CodecId.Encoding.PartId[0] = 0x13;
CodecInfo.CodecId.Encoding.PartId[1] = 0x08;
CodecInfo.CodecId.Encoding.Class = 0x00;
Command.TxWrite.OpCode = SndwCmdWrite; // write data to codec
Command.TxWrite.RegAddr = 0x42; // address of regioster in codec
Command.TxWrite.RegData = 0x21; // new register value
SndwAccess->SendWithAck (SndwAccess, CodecInfo, Command, CommandRespons);
if (!EFI_ERROR (Status) && CommandRespons->Rx.Ack == 1) {
// command success
}
During the codecs enumeration process codecs list is created. From this list user can retrieve information about any found codec. GetFirstCodec function allows to get information about first codec discovered during codecs enumeration. Parameters for this function are pointer to SndwAccess protocol and pointer to pointer to codec information structure (SNDW_CODEC_INFO **CodecInfo). GetFirstCodec allocates memory for codec information structure and user should free up this memory with FreePool.
GetNextCodec retrieves codec information about codec that follows the given one. Parameters for this function are are pointer to SndwAccess protocol, pointer to codec information structure (SNDW_CODEC_INFO *CodecInfo) preceding the one that user wants to get and pointer to pointer to codec information structure (SNDW_CODEC_INFO **NextCodecInfo). GetNextCodec allocates memory for codec information structure and user should free up this memory with FreePool. If there is no codec in codecs list following the given one, value pointed out by NextCodecInfo will be set to NULL.
Example:
SNDW_CODEC_INFO *CodecInfo;
SNDW_CODEC_INFO *NextCodecInfo;
SndwAccess->GetFirstCodec (SndwAccess, &NextCodecInfo);
while (NextCodecInfo != NULL) {
DEBUG ((DEBUG_INFO, "------- SNDW CODEC -------\n"));
DEBUG ((DEBUG_INFO, "SndwLinkIndex: %d\n", NextCodecInfo->SndwLinkIndex));
DEBUG ((DEBUG_INFO, "Codec ID:\n"));
DEBUG ((DEBUG_INFO, " Version: 0x%02x\n", NextCodecInfo->CodecId.Encoding.Version));
DEBUG ((DEBUG_INFO, " ManufacturerID[0]: 0x%02x\n", NextCodecInfo->CodecId.Encoding.ManufacturerID[0]));
DEBUG ((DEBUG_INFO, " ManufacturerID[1]: 0x%02x\n", NextCodecInfo->CodecId.Encoding.ManufacturerID[1]));
DEBUG ((DEBUG_INFO, " PartId[0]: 0x%02x\n", NextCodecInfo->CodecId.Encoding.PartId[0]));
DEBUG ((DEBUG_INFO, " PartId[1]: 0x%02x\n", NextCodecInfo->CodecId.Encoding.PartId[1]));
DEBUG ((DEBUG_INFO, " Class: 0x%02x\n", NextCodecInfo->CodecId.Encoding.Class));
DEBUG ((DEBUG_INFO, "----------------------\n"));
CodecInfo = NextCodecInfo;
NextCodecInfo = NULL;
SndwAccess->GetNextCodec (SndwAccess, CodecInfo, &NextCodecInfo);
FreePool (CodecInfo);
}
SoundWire Beep Protocol
SndwBeep Protocol can be used in all DXE phases after protocol installation. Before using functions for generating beep sound user should use Enable function, after that user can use Beep function. Parameters for Beep are pointer to SndwBeep Protocol, frequency in Hz, amplitude in dB, number of beep sound, duration of beep in milliseconds and pause between beeps in milliseconds. Beep function is blocking function. It means that user cannot do anything before end of this function. SndwBeep Protocol contains also function for non blocking beep sounds. BeepOn function alows to turn on tone generator. Parameters for BeepOn are pointer to SndwBeep Protocol, frequency in Hz, amplitude in dB. BeepOff allow to turn off tone generator. Parameter for BeepOff is pointer to SndwBeep Protocol. After all operations user should use Disable function. This step is important for further SoundWire components like OS drivers.
Example of generating beep:
Status = gBS->LocateProtocol (
&gSndwBeepProtocolGuid,
NULL,
(VOID **) &SndwBeep
);
ASSERT_EFI_ERROR (Status);
Status = SndwBeep->Enable (SndwBeep);
Status = SndwBeep->Beep (SndwBeep, 250, 0, 2, 1000, 500);
Status = SndwBeep->Disable (SndwBeep);
Build flows
No special tools are required to build this feature.
Feature Enabling Checklist
- Add SndwFeaturePkg.dsc entry, check if all required packages and libraries are available.
- Add SndwFeaturePostMemory.fdf to flash map file.
- SndwBeepExample.c shows an example of use.