123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- =========================
- Audio Stream in SoundWire
- =========================
- An audio stream is a logical or virtual connection created between
- (1) System memory buffer(s) and Codec(s)
- (2) DSP memory buffer(s) and Codec(s)
- (3) FIFO(s) and Codec(s)
- (4) Codec(s) and Codec(s)
- which is typically driven by a DMA(s) channel through the data link. An
- audio stream contains one or more channels of data. All channels within
- stream must have same sample rate and same sample size.
- Assume a stream with two channels (Left & Right) is opened using SoundWire
- interface. Below are some ways a stream can be represented in SoundWire.
- Stream Sample in memory (System memory, DSP memory or FIFOs) ::
- -------------------------
- | L | R | L | R | L | R |
- -------------------------
- Example 1: Stereo Stream with L and R channels is rendered from Master to
- Slave. Both Master and Slave is using single port. ::
- +---------------+ Clock Signal +---------------+
- | Master +----------------------------------+ Slave |
- | Interface | | Interface |
- | | | 1 |
- | | Data Signal | |
- | L + R +----------------------------------+ L + R |
- | (Data) | Data Direction | (Data) |
- +---------------+ +-----------------------> +---------------+
- Example 2: Stereo Stream with L and R channels is captured from Slave to
- Master. Both Master and Slave is using single port. ::
- +---------------+ Clock Signal +---------------+
- | Master +----------------------------------+ Slave |
- | Interface | | Interface |
- | | | 1 |
- | | Data Signal | |
- | L + R +----------------------------------+ L + R |
- | (Data) | Data Direction | (Data) |
- +---------------+ <-----------------------+ +---------------+
- Example 3: Stereo Stream with L and R channels is rendered by Master. Each
- of the L and R channel is received by two different Slaves. Master and both
- Slaves are using single port. ::
- +---------------+ Clock Signal +---------------+
- | Master +---------+------------------------+ Slave |
- | Interface | | | Interface |
- | | | | 1 |
- | | | Data Signal | |
- | L + R +---+------------------------------+ L |
- | (Data) | | | Data Direction | (Data) |
- +---------------+ | | +-------------> +---------------+
- | |
- | |
- | | +---------------+
- | +----------------------> | Slave |
- | | Interface |
- | | 2 |
- | | |
- +----------------------------> | R |
- | (Data) |
- +---------------+
- Example 4: Stereo Stream with L and R channel is rendered by two different
- Ports of the Master and is received by only single Port of the Slave
- interface. ::
- +--------------------+
- | |
- | +--------------+ +----------------+
- | | || | |
- | | Data Port || L Channel | |
- | | 1 |------------+ | |
- | | L Channel || | +-----+----+ |
- | | (Data) || | L + R Channel || Data | |
- | Master +----------+ | +---+---------> || Port | |
- | Interface | | || 1 | |
- | +--------------+ | || | |
- | | || | +----------+ |
- | | Data Port |------------+ | |
- | | 2 || R Channel | Slave |
- | | R Channel || | Interface |
- | | (Data) || | 1 |
- | +--------------+ Clock Signal | L + R |
- | +---------------------------> | (Data) |
- +--------------------+ | |
- +----------------+
- SoundWire Stream Management flow
- ================================
- Stream definitions
- ------------------
- (1) Current stream: This is classified as the stream on which operation has
- to be performed like prepare, enable, disable, de-prepare etc.
- (2) Active stream: This is classified as the stream which is already active
- on Bus other than current stream. There can be multiple active streams
- on the Bus.
- SoundWire Bus manages stream operations for each stream getting
- rendered/captured on the SoundWire Bus. This section explains Bus operations
- done for each of the stream allocated/released on Bus. Following are the
- stream states maintained by the Bus for each of the audio stream.
- SoundWire stream states
- -----------------------
- Below shows the SoundWire stream states and state transition diagram. ::
- +-----------+ +------------+ +----------+ +----------+
- | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED |
- | STATE | | STATE | | STATE | | STATE |
- +-----------+ +------------+ +----------+ +----+-----+
- ^
- |
- |
- v
- +----------+ +------------+ +----+-----+
- | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED |
- | STATE | | STATE | | STATE |
- +----------+ +------------+ +----------+
- NOTE: State transition between prepare and deprepare is supported in Spec
- but not in the software (subsystem)
- NOTE2: Stream state transition checks need to be handled by caller
- framework, for example ALSA/ASoC. No checks for stream transition exist in
- SoundWire subsystem.
- Stream State Operations
- -----------------------
- Below section explains the operations done by the Bus on Master(s) and
- Slave(s) as part of stream state transitions.
- SDW_STREAM_ALLOCATED
- ~~~~~~~~~~~~~~~~~~~~
- Allocation state for stream. This is the entry state
- of the stream. Operations performed before entering in this state:
- (1) A stream runtime is allocated for the stream. This stream
- runtime is used as a reference for all the operations performed
- on the stream.
- (2) The resources required for holding stream runtime information are
- allocated and initialized. This holds all stream related information
- such as stream type (PCM/PDM) and parameters, Master and Slave
- interface associated with the stream, stream state etc.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_ALLOCATED``.
- Bus implements below API for allocate a stream which needs to be called once
- per stream. From ASoC DPCM framework, this stream state maybe linked to
- .startup() operation.
- .. code-block:: c
- int sdw_alloc_stream(char * stream_name);
- SDW_STREAM_CONFIGURED
- ~~~~~~~~~~~~~~~~~~~~~
- Configuration state of stream. Operations performed before entering in
- this state:
- (1) The resources allocated for stream information in SDW_STREAM_ALLOCATED
- state are updated here. This includes stream parameters, Master(s)
- and Slave(s) runtime information associated with current stream.
- (2) All the Master(s) and Slave(s) associated with current stream provide
- the port information to Bus which includes port numbers allocated by
- Master(s) and Slave(s) for current stream and their channel mask.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_CONFIGURED``.
- Bus implements below APIs for CONFIG state which needs to be called by
- the respective Master(s) and Slave(s) associated with stream. These APIs can
- only be invoked once by respective Master(s) and Slave(s). From ASoC DPCM
- framework, this stream state is linked to .hw_params() operation.
- .. code-block:: c
- int sdw_stream_add_master(struct sdw_bus * bus,
- struct sdw_stream_config * stream_config,
- struct sdw_ports_config * ports_config,
- struct sdw_stream_runtime * stream);
- int sdw_stream_add_slave(struct sdw_slave * slave,
- struct sdw_stream_config * stream_config,
- struct sdw_ports_config * ports_config,
- struct sdw_stream_runtime * stream);
- SDW_STREAM_PREPARED
- ~~~~~~~~~~~~~~~~~~~
- Prepare state of stream. Operations performed before entering in this state:
- (1) Bus parameters such as bandwidth, frame shape, clock frequency,
- are computed based on current stream as well as already active
- stream(s) on Bus. Re-computation is required to accommodate current
- stream on the Bus.
- (2) Transport and port parameters of all Master(s) and Slave(s) port(s) are
- computed for the current as well as already active stream based on frame
- shape and clock frequency computed in step 1.
- (3) Computed Bus and transport parameters are programmed in Master(s) and
- Slave(s) registers. The banked registers programming is done on the
- alternate bank (bank currently unused). Port(s) are enabled for the
- already active stream(s) on the alternate bank (bank currently unused).
- This is done in order to not disrupt already active stream(s).
- (4) Once all the values are programmed, Bus initiates switch to alternate
- bank where all new values programmed gets into effect.
- (5) Ports of Master(s) and Slave(s) for current stream are prepared by
- programming PrepareCtrl register.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_PREPARED``.
- Bus implements below API for PREPARE state which needs to be called once per
- stream. From ASoC DPCM framework, this stream state is linked to
- .prepare() operation.
- .. code-block:: c
- int sdw_prepare_stream(struct sdw_stream_runtime * stream);
- SDW_STREAM_ENABLED
- ~~~~~~~~~~~~~~~~~~
- Enable state of stream. The data port(s) are enabled upon entering this state.
- Operations performed before entering in this state:
- (1) All the values computed in SDW_STREAM_PREPARED state are programmed
- in alternate bank (bank currently unused). It includes programming of
- already active stream(s) as well.
- (2) All the Master(s) and Slave(s) port(s) for the current stream are
- enabled on alternate bank (bank currently unused) by programming
- ChannelEn register.
- (3) Once all the values are programmed, Bus initiates switch to alternate
- bank where all new values programmed gets into effect and port(s)
- associated with current stream are enabled.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_ENABLED``.
- Bus implements below API for ENABLE state which needs to be called once per
- stream. From ASoC DPCM framework, this stream state is linked to
- .trigger() start operation.
- .. code-block:: c
- int sdw_enable_stream(struct sdw_stream_runtime * stream);
- SDW_STREAM_DISABLED
- ~~~~~~~~~~~~~~~~~~~
- Disable state of stream. The data port(s) are disabled upon exiting this state.
- Operations performed before entering in this state:
- (1) All the Master(s) and Slave(s) port(s) for the current stream are
- disabled on alternate bank (bank currently unused) by programming
- ChannelEn register.
- (2) All the current configuration of Bus and active stream(s) are programmed
- into alternate bank (bank currently unused).
- (3) Once all the values are programmed, Bus initiates switch to alternate
- bank where all new values programmed gets into effect and port(s) associated
- with current stream are disabled.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_DISABLED``.
- Bus implements below API for DISABLED state which needs to be called once
- per stream. From ASoC DPCM framework, this stream state is linked to
- .trigger() stop operation.
- .. code-block:: c
- int sdw_disable_stream(struct sdw_stream_runtime * stream);
- SDW_STREAM_DEPREPARED
- ~~~~~~~~~~~~~~~~~~~~~
- De-prepare state of stream. Operations performed before entering in this
- state:
- (1) All the port(s) of Master(s) and Slave(s) for current stream are
- de-prepared by programming PrepareCtrl register.
- (2) The payload bandwidth of current stream is reduced from the total
- bandwidth requirement of bus and new parameters calculated and
- applied by performing bank switch etc.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_DEPREPARED``.
- Bus implements below API for DEPREPARED state which needs to be called once
- per stream. From ASoC DPCM framework, this stream state is linked to
- .trigger() stop operation.
- .. code-block:: c
- int sdw_deprepare_stream(struct sdw_stream_runtime * stream);
- SDW_STREAM_RELEASED
- ~~~~~~~~~~~~~~~~~~~
- Release state of stream. Operations performed before entering in this state:
- (1) Release port resources for all Master(s) and Slave(s) port(s)
- associated with current stream.
- (2) Release Master(s) and Slave(s) runtime resources associated with
- current stream.
- (3) Release stream runtime resources associated with current stream.
- After all above operations are successful, stream state is set to
- ``SDW_STREAM_RELEASED``.
- Bus implements below APIs for RELEASE state which needs to be called by
- all the Master(s) and Slave(s) associated with stream. From ASoC DPCM
- framework, this stream state is linked to .hw_free() operation.
- .. code-block:: c
- int sdw_stream_remove_master(struct sdw_bus * bus,
- struct sdw_stream_runtime * stream);
- int sdw_stream_remove_slave(struct sdw_slave * slave,
- struct sdw_stream_runtime * stream);
- The .shutdown() ASoC DPCM operation calls below Bus API to release
- stream assigned as part of ALLOCATED state.
- In .shutdown() the data structure maintaining stream state are freed up.
- .. code-block:: c
- void sdw_release_stream(struct sdw_stream_runtime * stream);
- Not Supported
- =============
- 1. A single port with multiple channels supported cannot be used between two
- streams or across stream. For example a port with 4 channels cannot be used
- to handle 2 independent stereo streams even though it's possible in theory
- in SoundWire.
|