diff options
Diffstat (limited to 'Documentation/driver-api/soundwire/stream.rst')
-rw-r--r-- | Documentation/driver-api/soundwire/stream.rst | 169 |
1 files changed, 144 insertions, 25 deletions
diff --git a/Documentation/driver-api/soundwire/stream.rst b/Documentation/driver-api/soundwire/stream.rst index 5351bd2f34a8..2a794484f62c 100644 --- a/Documentation/driver-api/soundwire/stream.rst +++ b/Documentation/driver-api/soundwire/stream.rst @@ -75,8 +75,33 @@ Slaves are using single port. :: | (Data) | +---------------+ +Example 4: Stereo Stream with L and R channels is rendered by +Master. Both of the L and R channels are received by two different +Slaves. Master and both Slaves are using single port handling +L+R. Each Slave device processes the L + R data locally, typically +based on static configuration or dynamic orientation, and may drive +one or more speakers. :: -Example 4: Stereo Stream with L and R channel is rendered by two different + +---------------+ Clock Signal +---------------+ + | Master +---------+------------------------+ Slave | + | Interface | | | Interface | + | | | | 1 | + | | | Data Signal | | + | L + R +---+------------------------------+ L + R | + | (Data) | | | Data Direction | (Data) | + +---------------+ | | +-------------> +---------------+ + | | + | | + | | +---------------+ + | +----------------------> | Slave | + | | Interface | + | | 2 | + | | | + +----------------------------> | L + R | + | (Data) | + +---------------+ + +Example 5: 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. :: @@ -101,7 +126,7 @@ interface. :: +--------------------+ | | +----------------+ -Example 5: Stereo Stream with L and R channel is rendered by 2 Masters, each +Example 6: Stereo Stream with L and R channel is rendered by 2 Masters, each rendering one channel, and is received by two different Slaves, each receiving one channel. Both Masters and both Slaves are using single port. :: @@ -123,12 +148,70 @@ receiving one channel. Both Masters and both Slaves are using single port. :: | (Data) | Data Direction | (Data) | +---------------+ +-----------------------> +---------------+ -Note: In multi-link cases like above, to lock, one would acquire a global +Example 7: Stereo Stream with L and R channel is rendered by 2 +Masters, each rendering both channels. Each Slave receives L + R. This +is the same application as Example 4 but with Slaves placed on +separate links. :: + + +---------------+ Clock Signal +---------------+ + | Master +----------------------------------+ Slave | + | Interface | | Interface | + | 1 | | 1 | + | | Data Signal | | + | L + R +----------------------------------+ L + R | + | (Data) | Data Direction | (Data) | + +---------------+ +-----------------------> +---------------+ + + +---------------+ Clock Signal +---------------+ + | Master +----------------------------------+ Slave | + | Interface | | Interface | + | 2 | | 2 | + | | Data Signal | | + | L + R +----------------------------------+ L + R | + | (Data) | Data Direction | (Data) | + +---------------+ +-----------------------> +---------------+ + +Example 8: 4-channel Stream is rendered by 2 Masters, each rendering a +2 channels. Each Slave receives 2 channels. :: + + +---------------+ Clock Signal +---------------+ + | Master +----------------------------------+ Slave | + | Interface | | Interface | + | 1 | | 1 | + | | Data Signal | | + | L1 + R1 +----------------------------------+ L1 + R1 | + | (Data) | Data Direction | (Data) | + +---------------+ +-----------------------> +---------------+ + + +---------------+ Clock Signal +---------------+ + | Master +----------------------------------+ Slave | + | Interface | | Interface | + | 2 | | 2 | + | | Data Signal | | + | L2 + R2 +----------------------------------+ L2 + R2 | + | (Data) | Data Direction | (Data) | + +---------------+ +-----------------------> +---------------+ + +Note1: In multi-link cases like above, to lock, one would acquire a global lock and then go on locking bus instances. But, in this case the caller framework(ASoC DPCM) guarantees that stream operations on a card are always serialized. So, there is no race condition and hence no need for global lock. +Note2: A Slave device may be configured to receive all channels +transmitted on a link for a given Stream (Example 4) or just a subset +of the data (Example 3). The configuration of the Slave device is not +handled by a SoundWire subsystem API, but instead by the +snd_soc_dai_set_tdm_slot() API. The platform or machine driver will +typically configure which of the slots are used. For Example 4, the +same slots would be used by all Devices, while for Example 3 the Slave +Device1 would use e.g. Slot 0 and Slave device2 slot 1. + +Note3: Multiple Sink ports can extract the same information for the +same bitSlots in the SoundWire frame, however multiple Source ports +shall be configured with different bitSlot configurations. This is the +same limitation as with I2S/PCM TDM usages. + SoundWire Stream Management flow ================================ @@ -156,22 +239,27 @@ Below shows the SoundWire stream states and state transition diagram. :: +-----------+ +------------+ +----------+ +----------+ | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED | | STATE | | STATE | | STATE | | STATE | - +-----------+ +------------+ +----------+ +----+-----+ - ^ - | - | - v - +----------+ +------------+ +----+-----+ + +-----------+ +------------+ +---+--+---+ +----+-----+ + ^ ^ ^ + | | | + __| |___________ | + | | | + v | v + +----------+ +-----+------+ +-+--+-----+ | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED | | STATE | | STATE | | STATE | +----------+ +------------+ +----------+ -NOTE: State transition between prepare and deprepare is supported in Spec -but not in the software (subsystem) +NOTE: State transitions between ``SDW_STREAM_ENABLED`` and +``SDW_STREAM_DISABLED`` are only relevant when then INFO_PAUSE flag is +supported at the ALSA/ASoC level. Likewise the transition between +``SDW_DISABLED_STATE`` and ``SDW_PREPARED_STATE`` depends on the +INFO_RESUME flag. -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. +NOTE2: The framework implements basic state transition checks, but +does not e.g. check if a transition from DISABLED to ENABLED is valid +on a specific platform. Such tests need to be added at the ALSA/ASoC +level. Stream State Operations ----------------------- @@ -205,6 +293,10 @@ per stream. From ASoC DPCM framework, this stream state maybe linked to int sdw_alloc_stream(char * stream_name); +The SoundWire core provides a sdw_startup_stream() helper function, +typically called during a dailink .startup() callback, which performs +stream allocation and sets the stream pointer for all DAIs +connected to a stream. SDW_STREAM_CONFIGURED ~~~~~~~~~~~~~~~~~~~~~ @@ -232,12 +324,12 @@ framework, this stream state is linked to .hw_params() operation. int sdw_stream_add_master(struct sdw_bus * bus, struct sdw_stream_config * stream_config, - struct sdw_ports_config * ports_config, + const 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, + const struct sdw_ports_config * ports_config, struct sdw_stream_runtime * stream); @@ -246,6 +338,9 @@ SDW_STREAM_PREPARED Prepare state of stream. Operations performed before entering in this state: + (0) Steps 1 and 2 are omitted in the case of a resume operation, + where the bus bandwidth is known. + (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 @@ -270,9 +365,11 @@ Prepare state of stream. Operations performed before entering in this state: 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. +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. Since the .trigger() operations may not +follow the .prepare(), a direct transition from +``SDW_STREAM_PREPARED`` to ``SDW_STREAM_DEPREPARED`` is allowed. .. code-block:: c @@ -332,6 +429,14 @@ 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. +When the INFO_PAUSE flag is supported, a direct transition to +``SDW_STREAM_ENABLED`` is allowed. + +For resume operations where ASoC will use the .prepare() callback, the +stream can transition from ``SDW_STREAM_DISABLED`` to +``SDW_STREAM_PREPARED``, with all required settings restored but +without updating the bandwidth and bit allocation. + .. code-block:: c int sdw_disable_stream(struct sdw_stream_runtime * stream); @@ -353,9 +458,18 @@ state: 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. +Bus implements below API for DEPREPARED state which needs to be called +once per stream. ALSA/ASoC do not have a concept of 'deprepare', and +the mapping from this stream state to ALSA/ASoC operation may be +implementation specific. + +When the INFO_PAUSE flag is supported, the stream state is linked to +the .hw_free() operation - the stream is not deprepared on a +TRIGGER_STOP. + +Other implementations may transition to the ``SDW_STREAM_DEPREPARED`` +state on TRIGGER_STOP, should they require a transition through the +``SDW_STREAM_PREPARED`` state. .. code-block:: c @@ -399,10 +513,15 @@ In .shutdown() the data structure maintaining stream state are freed up. void sdw_release_stream(struct sdw_stream_runtime * stream); +The SoundWire core provides a sdw_shutdown_stream() helper function, +typically called during a dailink .shutdown() callback, which clears +the stream pointer for all DAIS connected to a stream and releases the +memory allocated for the 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. + 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. |