This document describes the codec interface between controllers and codecs in Fuchsia. It is meant to serve as a reference for driver-authors, and to define the interface contract which codec drivers must implement and that controllers can use. The codec interface is a Banjo protocol exposed by codec drivers.
In this document:
<x0,x1,...,xn-1>
, for example a vector with two elements 5 and 6 as <5,6>
.<<5,6>,<7,8>>
represents a vector with 2 vectors in it.Term | Definition |
---|---|
Codec | A real or virtual device that encodes/decodes a signal from |
: : digital/analog to/from analog/digital including all : | |
: : combinations, e.g. digital to digital. Example codecs include : | |
: : DAC-Amplifiers combos and ADC converters. : | |
Controller | The part of a system that manages the audio signals, for |
: : example an SOC's audio subsystem or an independent sound card. : | |
DAI | Digital Audio Interface. Interface between controllers and |
: : Codecs. For example an I2S or HDA link. : | |
Frame Sync | A DAI signal that marks frame boundaries, a.k.a. LRCLK, SYNC. |
Sclk | A DAI signal used to mark the data line(s) bits transferring, : |
: : a.k.a. SCK, BCLK. : | |
Mclk | Master clock, a DAI signal sometimes needed to provide a clock |
: : to codecs. Sometimes Sclk is used as the Mclk (or Mclk is : | |
: : derived from the Sclk within the codec). : | |
Frame | The representation of a single moment in time across data, : |
: : frame sync and sclk in the DAI. : | |
Frame format | A frame's data, frame sync and sclk arrangement, e.g. location |
: : of the frame sync w.r.t. samples in the data line(s). : | |
Slot | Within a frame, the bits reserved for a sample. A slot may be |
: : bigger than needed to hold the samples, e.g. 32 bits slot : | |
: : holding 24 or 16 bits samples. : | |
Channel | A single source or destination of audio samples, usually |
: : to be rendered by a single speaker or captured by a single : | |
: : microphone. Within a DAI every frame will contain samples in : | |
: : a fixed number of slots for the same fixed number of channels. : | |
Sample | A digital representation of sound taken at a particular time. |
The functionality provided by the codecs is divided into:
The controller is responsible for configuring and controlling the codecs. Codecs advertize capabilities and a controller determines how they are used as described below. The controller can control the codec's state, such as through the reset function. A reset is required to get codecs to an initialized state. Note that the codec drivers are expected to perform their own shutdown, just like any other driver.
Codecs are composite devices that provide the codec protocol to controllers. It is expected that only one controller uses a codec's protocol, and one controller may use multiple codecs at once.
The simple-codec library facilitates writing and using simple codec drivers implementing the codec protocol.
The codec protocol is defined in Banjo at ddk.protocol.codec.
Many codec protocol operations are “fire-and-forget”, i.e. they do not expect a reply. Codec protocol operations with a reply are not considered completed until the reply of the function is received, and not considered completed successfully unless the reply contains a status ZX_OK
.
A codec can be reset by a controller at any time by issuing the Reset
function.
The GetInfo
function retrieves information from the codec including:
The codec operation can be started and stopped at any time with the Start
and Stop
functions. By default the codec state is stopped, so ‘Start’ must be issued at least once for the codec to be fully operational. Stopping the codec operation can be used for example to change the DAI configuration safely avoiding glitches or errors in the codec operation.
Before specifying the DAI format the controller must query the codec for its bridging capabilites. If the codec is bridgeable, then the controller must enable or disable bridging based on its knowledge of the system configuration. Note that this is a singular property of a codec, i.e. a codec either supports bridging or not, and it can be set in bridged mode or not. This protocol allows configuring as bridged only 2 channel stereo codecs, with the 2 outputs of the codec electrically bridged.
The DAI Format related protocol functions allow the codec to list its supported formats for the DAI. The supported formats may include multiple sample formats, rates, etc. Each codec advertises what it can support and the controller mandates what DAI Format is to be used for each codec.
To find out what formats are supported by a given codec, the controller uses the GetDaiFormats
function. The codec replies with a vector of DaiSupportedFormats
, where each DaiSupportedFormats
includes:
<2,4,6,8>
. A stereo codec reports a vector with one element <2>
. Note that a codec that takes one channel and outputs its contents in all its outputs (e.g. 2 for a stereo amplifier) would report a vector with one element <1>
, if it supports either one or two input channels, it would report a vector with two elements <1,2>
.PCM_SIGNED
.STEREO_LEFT
and STEREO_RIGHT
.When not all combinations supported by the codec can be described with one DaiSupportedFormats
, the codec returns more than one DaiSupportedFormats
in the returned vector.
For example, if one DaiSupportedFormats
allows for 32 bits samples at 48KHz, and 16 bits samples at 96KHz, but not 32 bits samples at 96KHz, then the codec will reply with 2 DaiSupportedFormats
: <<32bits>,<48KHz>>
and <<16bits>,<96KHz>>
. For simplicity, this example ignores parameters other than rate and bits per sample. In the case where the codec supports either 16 or 32 bits samples at either 48 or 96KHz, the codec would reply with 1 DaiSupportedFormats
: <<16bits,32bits>,<48KHz,96KHz>>
.
Additionally, it is assumed that bits per sample is always smaller or equal to bits per slot. Hence, a codec can report <<16bits_per_slot,32bits_per_slot>,<16bits_per_sample,32bits_per_sample>>
and this does not imply that it is reporting that 32 bits per sample on 16 bits samples is valid, it specifies only the 3 valid combinations:
Using the information provided by the codec in IsBridgeable
and GetDaiFormat
, what is supported by the controller, and any other requirements, the controller specifies the format to use in the DAI with the SetDaiFormat
function. This functions takes a parameter that specifies:
<0,1>
, i.e. both left and right channels are used. In bridged mode this will list only the one channel to be used by the codec, for example a codec’s stereo amplifier output bridged into one electrical mono output from the right channel of an I2S DAI would list only channel <1>
. If not bridged, a codec with multiple electrical outputs that is configured with one channel in SetDaiFormat
is expected to replicate the samples in this mono input on all its outputs.Once SetDaiFormat
is successful, the DAI format configuration is considered completed and samples can be sent across the DAI.
TODO(andresoportus): Add DAI format loss notification support once asynchronous notifications are added to Banjo.
Gain related support by any given codec is returned by the codec in response to a GetGainFormat
function in the GainFormat
structure. The controller can control gain, mute and AGC states in a codec using the SetGainState
function and the corresponding GetGainState
function allows retrieving the current state for the same.
The controller can query the plug detect state with the GetPlugState
function. The plug state includes hardwired and plugged states.
TODO(andresoportus): Add can_notify
bool to PlugState
once asynchronous notifications are added to Banjo.
TODO(andresoportus).
TODO(andresoportus).
TODO(andresoportus).
TODO(andresoportus).