| .. | .. |
|---|
| 75 | 75 | | (Data) | |
|---|
| 76 | 76 | +---------------+ |
|---|
| 77 | 77 | |
|---|
| 78 | +Example 4: Stereo Stream with L and R channels is rendered by |
|---|
| 79 | +Master. Both of the L and R channels are received by two different |
|---|
| 80 | +Slaves. Master and both Slaves are using single port handling |
|---|
| 81 | +L+R. Each Slave device processes the L + R data locally, typically |
|---|
| 82 | +based on static configuration or dynamic orientation, and may drive |
|---|
| 83 | +one or more speakers. :: |
|---|
| 78 | 84 | |
|---|
| 79 | | -Example 4: Stereo Stream with L and R channel is rendered by two different |
|---|
| 85 | + +---------------+ Clock Signal +---------------+ |
|---|
| 86 | + | Master +---------+------------------------+ Slave | |
|---|
| 87 | + | Interface | | | Interface | |
|---|
| 88 | + | | | | 1 | |
|---|
| 89 | + | | | Data Signal | | |
|---|
| 90 | + | L + R +---+------------------------------+ L + R | |
|---|
| 91 | + | (Data) | | | Data Direction | (Data) | |
|---|
| 92 | + +---------------+ | | +-------------> +---------------+ |
|---|
| 93 | + | | |
|---|
| 94 | + | | |
|---|
| 95 | + | | +---------------+ |
|---|
| 96 | + | +----------------------> | Slave | |
|---|
| 97 | + | | Interface | |
|---|
| 98 | + | | 2 | |
|---|
| 99 | + | | | |
|---|
| 100 | + +----------------------------> | L + R | |
|---|
| 101 | + | (Data) | |
|---|
| 102 | + +---------------+ |
|---|
| 103 | + |
|---|
| 104 | +Example 5: Stereo Stream with L and R channel is rendered by two different |
|---|
| 80 | 105 | Ports of the Master and is received by only single Port of the Slave |
|---|
| 81 | 106 | interface. :: |
|---|
| 82 | 107 | |
|---|
| .. | .. |
|---|
| 100 | 125 | | +---------------------------> | (Data) | |
|---|
| 101 | 126 | +--------------------+ | | |
|---|
| 102 | 127 | +----------------+ |
|---|
| 128 | + |
|---|
| 129 | +Example 6: Stereo Stream with L and R channel is rendered by 2 Masters, each |
|---|
| 130 | +rendering one channel, and is received by two different Slaves, each |
|---|
| 131 | +receiving one channel. Both Masters and both Slaves are using single port. :: |
|---|
| 132 | + |
|---|
| 133 | + +---------------+ Clock Signal +---------------+ |
|---|
| 134 | + | Master +----------------------------------+ Slave | |
|---|
| 135 | + | Interface | | Interface | |
|---|
| 136 | + | 1 | | 1 | |
|---|
| 137 | + | | Data Signal | | |
|---|
| 138 | + | L +----------------------------------+ L | |
|---|
| 139 | + | (Data) | Data Direction | (Data) | |
|---|
| 140 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 141 | + |
|---|
| 142 | + +---------------+ Clock Signal +---------------+ |
|---|
| 143 | + | Master +----------------------------------+ Slave | |
|---|
| 144 | + | Interface | | Interface | |
|---|
| 145 | + | 2 | | 2 | |
|---|
| 146 | + | | Data Signal | | |
|---|
| 147 | + | R +----------------------------------+ R | |
|---|
| 148 | + | (Data) | Data Direction | (Data) | |
|---|
| 149 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 150 | + |
|---|
| 151 | +Example 7: Stereo Stream with L and R channel is rendered by 2 |
|---|
| 152 | +Masters, each rendering both channels. Each Slave receives L + R. This |
|---|
| 153 | +is the same application as Example 4 but with Slaves placed on |
|---|
| 154 | +separate links. :: |
|---|
| 155 | + |
|---|
| 156 | + +---------------+ Clock Signal +---------------+ |
|---|
| 157 | + | Master +----------------------------------+ Slave | |
|---|
| 158 | + | Interface | | Interface | |
|---|
| 159 | + | 1 | | 1 | |
|---|
| 160 | + | | Data Signal | | |
|---|
| 161 | + | L + R +----------------------------------+ L + R | |
|---|
| 162 | + | (Data) | Data Direction | (Data) | |
|---|
| 163 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 164 | + |
|---|
| 165 | + +---------------+ Clock Signal +---------------+ |
|---|
| 166 | + | Master +----------------------------------+ Slave | |
|---|
| 167 | + | Interface | | Interface | |
|---|
| 168 | + | 2 | | 2 | |
|---|
| 169 | + | | Data Signal | | |
|---|
| 170 | + | L + R +----------------------------------+ L + R | |
|---|
| 171 | + | (Data) | Data Direction | (Data) | |
|---|
| 172 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 173 | + |
|---|
| 174 | +Example 8: 4-channel Stream is rendered by 2 Masters, each rendering a |
|---|
| 175 | +2 channels. Each Slave receives 2 channels. :: |
|---|
| 176 | + |
|---|
| 177 | + +---------------+ Clock Signal +---------------+ |
|---|
| 178 | + | Master +----------------------------------+ Slave | |
|---|
| 179 | + | Interface | | Interface | |
|---|
| 180 | + | 1 | | 1 | |
|---|
| 181 | + | | Data Signal | | |
|---|
| 182 | + | L1 + R1 +----------------------------------+ L1 + R1 | |
|---|
| 183 | + | (Data) | Data Direction | (Data) | |
|---|
| 184 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 185 | + |
|---|
| 186 | + +---------------+ Clock Signal +---------------+ |
|---|
| 187 | + | Master +----------------------------------+ Slave | |
|---|
| 188 | + | Interface | | Interface | |
|---|
| 189 | + | 2 | | 2 | |
|---|
| 190 | + | | Data Signal | | |
|---|
| 191 | + | L2 + R2 +----------------------------------+ L2 + R2 | |
|---|
| 192 | + | (Data) | Data Direction | (Data) | |
|---|
| 193 | + +---------------+ +-----------------------> +---------------+ |
|---|
| 194 | + |
|---|
| 195 | +Note1: In multi-link cases like above, to lock, one would acquire a global |
|---|
| 196 | +lock and then go on locking bus instances. But, in this case the caller |
|---|
| 197 | +framework(ASoC DPCM) guarantees that stream operations on a card are |
|---|
| 198 | +always serialized. So, there is no race condition and hence no need for |
|---|
| 199 | +global lock. |
|---|
| 200 | + |
|---|
| 201 | +Note2: A Slave device may be configured to receive all channels |
|---|
| 202 | +transmitted on a link for a given Stream (Example 4) or just a subset |
|---|
| 203 | +of the data (Example 3). The configuration of the Slave device is not |
|---|
| 204 | +handled by a SoundWire subsystem API, but instead by the |
|---|
| 205 | +snd_soc_dai_set_tdm_slot() API. The platform or machine driver will |
|---|
| 206 | +typically configure which of the slots are used. For Example 4, the |
|---|
| 207 | +same slots would be used by all Devices, while for Example 3 the Slave |
|---|
| 208 | +Device1 would use e.g. Slot 0 and Slave device2 slot 1. |
|---|
| 209 | + |
|---|
| 210 | +Note3: Multiple Sink ports can extract the same information for the |
|---|
| 211 | +same bitSlots in the SoundWire frame, however multiple Source ports |
|---|
| 212 | +shall be configured with different bitSlot configurations. This is the |
|---|
| 213 | +same limitation as with I2S/PCM TDM usages. |
|---|
| 103 | 214 | |
|---|
| 104 | 215 | SoundWire Stream Management flow |
|---|
| 105 | 216 | ================================ |
|---|
| .. | .. |
|---|
| 128 | 239 | +-----------+ +------------+ +----------+ +----------+ |
|---|
| 129 | 240 | | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED | |
|---|
| 130 | 241 | | STATE | | STATE | | STATE | | STATE | |
|---|
| 131 | | - +-----------+ +------------+ +----------+ +----+-----+ |
|---|
| 132 | | - ^ |
|---|
| 133 | | - | |
|---|
| 134 | | - | |
|---|
| 135 | | - v |
|---|
| 136 | | - +----------+ +------------+ +----+-----+ |
|---|
| 242 | + +-----------+ +------------+ +---+--+---+ +----+-----+ |
|---|
| 243 | + ^ ^ ^ |
|---|
| 244 | + | | | |
|---|
| 245 | + __| |___________ | |
|---|
| 246 | + | | | |
|---|
| 247 | + v | v |
|---|
| 248 | + +----------+ +-----+------+ +-+--+-----+ |
|---|
| 137 | 249 | | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED | |
|---|
| 138 | 250 | | STATE | | STATE | | STATE | |
|---|
| 139 | 251 | +----------+ +------------+ +----------+ |
|---|
| 140 | 252 | |
|---|
| 141 | | -NOTE: State transition between prepare and deprepare is supported in Spec |
|---|
| 142 | | -but not in the software (subsystem) |
|---|
| 253 | +NOTE: State transitions between ``SDW_STREAM_ENABLED`` and |
|---|
| 254 | +``SDW_STREAM_DISABLED`` are only relevant when then INFO_PAUSE flag is |
|---|
| 255 | +supported at the ALSA/ASoC level. Likewise the transition between |
|---|
| 256 | +``SDW_DISABLED_STATE`` and ``SDW_PREPARED_STATE`` depends on the |
|---|
| 257 | +INFO_RESUME flag. |
|---|
| 143 | 258 | |
|---|
| 144 | | -NOTE2: Stream state transition checks need to be handled by caller |
|---|
| 145 | | -framework, for example ALSA/ASoC. No checks for stream transition exist in |
|---|
| 146 | | -SoundWire subsystem. |
|---|
| 259 | +NOTE2: The framework implements basic state transition checks, but |
|---|
| 260 | +does not e.g. check if a transition from DISABLED to ENABLED is valid |
|---|
| 261 | +on a specific platform. Such tests need to be added at the ALSA/ASoC |
|---|
| 262 | +level. |
|---|
| 147 | 263 | |
|---|
| 148 | 264 | Stream State Operations |
|---|
| 149 | 265 | ----------------------- |
|---|
| .. | .. |
|---|
| 173 | 289 | per stream. From ASoC DPCM framework, this stream state maybe linked to |
|---|
| 174 | 290 | .startup() operation. |
|---|
| 175 | 291 | |
|---|
| 176 | | - .. code-block:: c |
|---|
| 292 | +.. code-block:: c |
|---|
| 293 | + |
|---|
| 177 | 294 | int sdw_alloc_stream(char * stream_name); |
|---|
| 178 | 295 | |
|---|
| 296 | +The SoundWire core provides a sdw_startup_stream() helper function, |
|---|
| 297 | +typically called during a dailink .startup() callback, which performs |
|---|
| 298 | +stream allocation and sets the stream pointer for all DAIs |
|---|
| 299 | +connected to a stream. |
|---|
| 179 | 300 | |
|---|
| 180 | 301 | SDW_STREAM_CONFIGURED |
|---|
| 181 | 302 | ~~~~~~~~~~~~~~~~~~~~~ |
|---|
| .. | .. |
|---|
| 199 | 320 | only be invoked once by respective Master(s) and Slave(s). From ASoC DPCM |
|---|
| 200 | 321 | framework, this stream state is linked to .hw_params() operation. |
|---|
| 201 | 322 | |
|---|
| 202 | | - .. code-block:: c |
|---|
| 323 | +.. code-block:: c |
|---|
| 324 | + |
|---|
| 203 | 325 | int sdw_stream_add_master(struct sdw_bus * bus, |
|---|
| 204 | 326 | struct sdw_stream_config * stream_config, |
|---|
| 205 | 327 | struct sdw_ports_config * ports_config, |
|---|
| .. | .. |
|---|
| 215 | 337 | ~~~~~~~~~~~~~~~~~~~ |
|---|
| 216 | 338 | |
|---|
| 217 | 339 | Prepare state of stream. Operations performed before entering in this state: |
|---|
| 340 | + |
|---|
| 341 | + (0) Steps 1 and 2 are omitted in the case of a resume operation, |
|---|
| 342 | + where the bus bandwidth is known. |
|---|
| 218 | 343 | |
|---|
| 219 | 344 | (1) Bus parameters such as bandwidth, frame shape, clock frequency, |
|---|
| 220 | 345 | are computed based on current stream as well as already active |
|---|
| .. | .. |
|---|
| 240 | 365 | After all above operations are successful, stream state is set to |
|---|
| 241 | 366 | ``SDW_STREAM_PREPARED``. |
|---|
| 242 | 367 | |
|---|
| 243 | | -Bus implements below API for PREPARE state which needs to be called once per |
|---|
| 244 | | -stream. From ASoC DPCM framework, this stream state is linked to |
|---|
| 245 | | -.prepare() operation. |
|---|
| 368 | +Bus implements below API for PREPARE state which needs to be called |
|---|
| 369 | +once per stream. From ASoC DPCM framework, this stream state is linked |
|---|
| 370 | +to .prepare() operation. Since the .trigger() operations may not |
|---|
| 371 | +follow the .prepare(), a direct transition from |
|---|
| 372 | +``SDW_STREAM_PREPARED`` to ``SDW_STREAM_DEPREPARED`` is allowed. |
|---|
| 246 | 373 | |
|---|
| 247 | | - .. code-block:: c |
|---|
| 374 | +.. code-block:: c |
|---|
| 375 | + |
|---|
| 248 | 376 | int sdw_prepare_stream(struct sdw_stream_runtime * stream); |
|---|
| 249 | 377 | |
|---|
| 250 | 378 | |
|---|
| .. | .. |
|---|
| 273 | 401 | stream. From ASoC DPCM framework, this stream state is linked to |
|---|
| 274 | 402 | .trigger() start operation. |
|---|
| 275 | 403 | |
|---|
| 276 | | - .. code-block:: c |
|---|
| 404 | +.. code-block:: c |
|---|
| 405 | + |
|---|
| 277 | 406 | int sdw_enable_stream(struct sdw_stream_runtime * stream); |
|---|
| 278 | 407 | |
|---|
| 279 | 408 | SDW_STREAM_DISABLED |
|---|
| .. | .. |
|---|
| 300 | 429 | per stream. From ASoC DPCM framework, this stream state is linked to |
|---|
| 301 | 430 | .trigger() stop operation. |
|---|
| 302 | 431 | |
|---|
| 303 | | - .. code-block:: c |
|---|
| 432 | +When the INFO_PAUSE flag is supported, a direct transition to |
|---|
| 433 | +``SDW_STREAM_ENABLED`` is allowed. |
|---|
| 434 | + |
|---|
| 435 | +For resume operations where ASoC will use the .prepare() callback, the |
|---|
| 436 | +stream can transition from ``SDW_STREAM_DISABLED`` to |
|---|
| 437 | +``SDW_STREAM_PREPARED``, with all required settings restored but |
|---|
| 438 | +without updating the bandwidth and bit allocation. |
|---|
| 439 | + |
|---|
| 440 | +.. code-block:: c |
|---|
| 441 | + |
|---|
| 304 | 442 | int sdw_disable_stream(struct sdw_stream_runtime * stream); |
|---|
| 305 | 443 | |
|---|
| 306 | 444 | |
|---|
| .. | .. |
|---|
| 320 | 458 | After all above operations are successful, stream state is set to |
|---|
| 321 | 459 | ``SDW_STREAM_DEPREPARED``. |
|---|
| 322 | 460 | |
|---|
| 323 | | -Bus implements below API for DEPREPARED state which needs to be called once |
|---|
| 324 | | -per stream. From ASoC DPCM framework, this stream state is linked to |
|---|
| 325 | | -.trigger() stop operation. |
|---|
| 461 | +Bus implements below API for DEPREPARED state which needs to be called |
|---|
| 462 | +once per stream. ALSA/ASoC do not have a concept of 'deprepare', and |
|---|
| 463 | +the mapping from this stream state to ALSA/ASoC operation may be |
|---|
| 464 | +implementation specific. |
|---|
| 326 | 465 | |
|---|
| 327 | | - .. code-block:: c |
|---|
| 466 | +When the INFO_PAUSE flag is supported, the stream state is linked to |
|---|
| 467 | +the .hw_free() operation - the stream is not deprepared on a |
|---|
| 468 | +TRIGGER_STOP. |
|---|
| 469 | + |
|---|
| 470 | +Other implementations may transition to the ``SDW_STREAM_DEPREPARED`` |
|---|
| 471 | +state on TRIGGER_STOP, should they require a transition through the |
|---|
| 472 | +``SDW_STREAM_PREPARED`` state. |
|---|
| 473 | + |
|---|
| 474 | +.. code-block:: c |
|---|
| 475 | + |
|---|
| 328 | 476 | int sdw_deprepare_stream(struct sdw_stream_runtime * stream); |
|---|
| 329 | 477 | |
|---|
| 330 | 478 | |
|---|
| .. | .. |
|---|
| 348 | 496 | all the Master(s) and Slave(s) associated with stream. From ASoC DPCM |
|---|
| 349 | 497 | framework, this stream state is linked to .hw_free() operation. |
|---|
| 350 | 498 | |
|---|
| 351 | | - .. code-block:: c |
|---|
| 499 | +.. code-block:: c |
|---|
| 500 | + |
|---|
| 352 | 501 | int sdw_stream_remove_master(struct sdw_bus * bus, |
|---|
| 353 | 502 | struct sdw_stream_runtime * stream); |
|---|
| 354 | 503 | int sdw_stream_remove_slave(struct sdw_slave * slave, |
|---|
| .. | .. |
|---|
| 360 | 509 | |
|---|
| 361 | 510 | In .shutdown() the data structure maintaining stream state are freed up. |
|---|
| 362 | 511 | |
|---|
| 363 | | - .. code-block:: c |
|---|
| 512 | +.. code-block:: c |
|---|
| 513 | + |
|---|
| 364 | 514 | void sdw_release_stream(struct sdw_stream_runtime * stream); |
|---|
| 515 | + |
|---|
| 516 | +The SoundWire core provides a sdw_shutdown_stream() helper function, |
|---|
| 517 | +typically called during a dailink .shutdown() callback, which clears |
|---|
| 518 | +the stream pointer for all DAIS connected to a stream and releases the |
|---|
| 519 | +memory allocated for the stream. |
|---|
| 365 | 520 | |
|---|
| 366 | 521 | Not Supported |
|---|
| 367 | 522 | ============= |
|---|
| 368 | 523 | |
|---|
| 369 | 524 | 1. A single port with multiple channels supported cannot be used between two |
|---|
| 370 | | -streams or across stream. For example a port with 4 channels cannot be used |
|---|
| 371 | | -to handle 2 independent stereo streams even though it's possible in theory |
|---|
| 372 | | -in SoundWire. |
|---|
| 525 | + streams or across stream. For example a port with 4 channels cannot be used |
|---|
| 526 | + to handle 2 independent stereo streams even though it's possible in theory |
|---|
| 527 | + in SoundWire. |
|---|