.. | .. |
---|
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. |
---|