Documentation/driver-api/soundwire/stream.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

Audio Stream in SoundWire

SoundWire audio topology, channel·slot 규칙, stream state machine과 ASoC 연계 API를 다루는 전문 번역입니다.

Source pathDocumentation/driver-api/soundwire/stream.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

stream.rst:1-527

SoundWire stream은 memory·FIFO·Codec 사이의 logical audio connection이며 다양한 Master·Slave·port topology에서 channel을 운반합니다. Bus는 ALLOCATED, CONFIGURED, PREPARED, ENABLED, DISABLED, DEPREPARED, RELEASED state를 관리하고 alternate bank, PrepareCtrl, ChannelEn을 사용해 active stream을 중단하지 않고 설정을 전환합니다. 각 state는 ASoC DPCM의 startup, hw_params, prepare, trigger, hw_free, shutdown과 대응하는 core API를 가집니다.

문서 구성
원문 줄내용
1-194Audio stream 정의와 8가지 topology
195-263Slot·bitSlot 규칙과 state machine
264-335ALLOCATED·CONFIGURED
336-444PREPARED·ENABLED·DISABLED
445-520DEPREPARED·RELEASED
521-527지원하지 않는 multichannel port 공유

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 =========================
2 Audio Stream in SoundWire
3 =========================
4
5 An audio stream is a logical or virtual connection created between
6
7 (1) System memory buffer(s) and Codec(s)
8
9 (2) DSP memory buffer(s) and Codec(s)
10
11 (3) FIFO(s) and Codec(s)
12
13 (4) Codec(s) and Codec(s)
14
15 which is typically driven by a DMA(s) channel through the data link. An
16 audio stream contains one or more channels of data. All channels within
17 stream must have same sample rate and same sample size.
18
19 Assume a stream with two channels (Left & Right) is opened using SoundWire
20 interface. Below are some ways a stream can be represented in SoundWire.
21
22 Stream Sample in memory (System memory, DSP memory or FIFOs) ::
23
24 -------------------------
25 | L | R | L | R | L | R |
26 -------------------------
27
28 Example 1: Stereo Stream with L and R channels is rendered from Master to
29 Slave. Both Master and Slave is using single port. ::
30
31 +---------------+ Clock Signal +---------------+
32 | Master +----------------------------------+ Slave |
33 | Interface | | Interface |
34 | | | 1 |
35 | | Data Signal | |
36 | L + R +----------------------------------+ L + R |
37 | (Data) | Data Direction | (Data) |
38 +---------------+ +-----------------------> +---------------+
39
40
41 Example 2: Stereo Stream with L and R channels is captured from Slave to
42 Master. Both Master and Slave is using single port. ::
43
44
45 +---------------+ Clock Signal +---------------+
46 | Master +----------------------------------+ Slave |
47 | Interface | | Interface |
48 | | | 1 |
49 | | Data Signal | |
50 | L + R +----------------------------------+ L + R |
51 | (Data) | Data Direction | (Data) |
52 +---------------+ <-----------------------+ +---------------+
53
54
55 Example 3: Stereo Stream with L and R channels is rendered by Master. Each
56 of the L and R channel is received by two different Slaves. Master and both
57 Slaves are using single port. ::
58
59 +---------------+ Clock Signal +---------------+
60 | Master +---------+------------------------+ Slave |
61 | Interface | | | Interface |
62 | | | | 1 |
63 | | | Data Signal | |
64 | L + R +---+------------------------------+ L |
65 | (Data) | | | Data Direction | (Data) |
66 +---------------+ | | +-------------> +---------------+
67 | |
68 | |
69 | | +---------------+
70 | +----------------------> | Slave |
71 | | Interface |
72 | | 2 |
73 | | |
74 +----------------------------> | R |
75 | (Data) |
76 +---------------+
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. ::
84
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
105 Ports of the Master and is received by only single Port of the Slave
106 interface. ::
107
108 +--------------------+
109 | |
110 | +--------------+ +----------------+
111 | | || | |
112 | | Data Port || L Channel | |
113 | | 1 |------------+ | |
114 | | L Channel || | +-----+----+ |
115 | | (Data) || | L + R Channel || Data | |
116 | Master +----------+ | +---+---------> || Port | |
117 | Interface | | || 1 | |
118 | +--------------+ | || | |
119 | | || | +----------+ |
120 | | Data Port |------------+ | |
121 | | 2 || R Channel | Slave |
122 | | R Channel || | Interface |
123 | | (Data) || | 1 |
124 | +--------------+ Clock Signal | L + R |
125 | +---------------------------> | (Data) |
126 +--------------------+ | |
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.
214
215 SoundWire Stream Management flow
216 ================================
217
218 Stream definitions
219 ------------------
220
221 (1) Current stream: This is classified as the stream on which operation has
222 to be performed like prepare, enable, disable, de-prepare etc.
223
224 (2) Active stream: This is classified as the stream which is already active
225 on Bus other than current stream. There can be multiple active streams
226 on the Bus.
227
228 SoundWire Bus manages stream operations for each stream getting
229 rendered/captured on the SoundWire Bus. This section explains Bus operations
230 done for each of the stream allocated/released on Bus. Following are the
231 stream states maintained by the Bus for each of the audio stream.
232
233
234 SoundWire stream states
235 -----------------------
236
237 Below shows the SoundWire stream states and state transition diagram. ::
238
239 +-----------+ +------------+ +----------+ +----------+
240 | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED |
241 | STATE | | STATE | | STATE | | STATE |
242 +-----------+ +------------+ +---+--+---+ +----+-----+
243 ^ ^ ^
244 | | |
245 __| |___________ |
246 | | |
247 v | v
248 +----------+ +-----+------+ +-+--+-----+
249 | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED |
250 | STATE | | STATE | | STATE |
251 +----------+ +------------+ +----------+
252
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.
258
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.
263
264 Stream State Operations
265 -----------------------
266
267 Below section explains the operations done by the Bus on Master(s) and
268 Slave(s) as part of stream state transitions.
269
270 SDW_STREAM_ALLOCATED
271 ~~~~~~~~~~~~~~~~~~~~
272
273 Allocation state for stream. This is the entry state
274 of the stream. Operations performed before entering in this state:
275
276 (1) A stream runtime is allocated for the stream. This stream
277 runtime is used as a reference for all the operations performed
278 on the stream.
279
280 (2) The resources required for holding stream runtime information are
281 allocated and initialized. This holds all stream related information
282 such as stream type (PCM/PDM) and parameters, Master and Slave
283 interface associated with the stream, stream state etc.
284
285 After all above operations are successful, stream state is set to
286 ``SDW_STREAM_ALLOCATED``.
287
288 Bus implements below API for allocate a stream which needs to be called once
289 per stream. From ASoC DPCM framework, this stream state maybe linked to
290 .startup() operation.
291
292 .. code-block:: c
293
294 int sdw_alloc_stream(char * stream_name, enum sdw_stream_type type);
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.
300
301 SDW_STREAM_CONFIGURED
302 ~~~~~~~~~~~~~~~~~~~~~
303
304 Configuration state of stream. Operations performed before entering in
305 this state:
306
307 (1) The resources allocated for stream information in SDW_STREAM_ALLOCATED
308 state are updated here. This includes stream parameters, Master(s)
309 and Slave(s) runtime information associated with current stream.
310
311 (2) All the Master(s) and Slave(s) associated with current stream provide
312 the port information to Bus which includes port numbers allocated by
313 Master(s) and Slave(s) for current stream and their channel mask.
314
315 After all above operations are successful, stream state is set to
316 ``SDW_STREAM_CONFIGURED``.
317
318 Bus implements below APIs for CONFIG state which needs to be called by
319 the respective Master(s) and Slave(s) associated with stream. These APIs can
320 only be invoked once by respective Master(s) and Slave(s). From ASoC DPCM
321 framework, this stream state is linked to .hw_params() operation.
322
323 .. code-block:: c
324
325 int sdw_stream_add_master(struct sdw_bus * bus,
326 struct sdw_stream_config * stream_config,
327 const struct sdw_ports_config * ports_config,
328 struct sdw_stream_runtime * stream);
329
330 int sdw_stream_add_slave(struct sdw_slave * slave,
331 struct sdw_stream_config * stream_config,
332 const struct sdw_ports_config * ports_config,
333 struct sdw_stream_runtime * stream);
334
335
336 SDW_STREAM_PREPARED
337 ~~~~~~~~~~~~~~~~~~~
338
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.
343
344 (1) Bus parameters such as bandwidth, frame shape, clock frequency,
345 are computed based on current stream as well as already active
346 stream(s) on Bus. Re-computation is required to accommodate current
347 stream on the Bus.
348
349 (2) Transport and port parameters of all Master(s) and Slave(s) port(s) are
350 computed for the current as well as already active stream based on frame
351 shape and clock frequency computed in step 1.
352
353 (3) Computed Bus and transport parameters are programmed in Master(s) and
354 Slave(s) registers. The banked registers programming is done on the
355 alternate bank (bank currently unused). Port(s) are enabled for the
356 already active stream(s) on the alternate bank (bank currently unused).
357 This is done in order to not disrupt already active stream(s).
358
359 (4) Once all the values are programmed, Bus initiates switch to alternate
360 bank where all new values programmed gets into effect.
361
362 (5) Ports of Master(s) and Slave(s) for current stream are prepared by
363 programming PrepareCtrl register.
364
365 After all above operations are successful, stream state is set to
366 ``SDW_STREAM_PREPARED``.
367
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.
373
374 .. code-block:: c
375
376 int sdw_prepare_stream(struct sdw_stream_runtime * stream);
377
378
379 SDW_STREAM_ENABLED
380 ~~~~~~~~~~~~~~~~~~
381
382 Enable state of stream. The data port(s) are enabled upon entering this state.
383 Operations performed before entering in this state:
384
385 (1) All the values computed in SDW_STREAM_PREPARED state are programmed
386 in alternate bank (bank currently unused). It includes programming of
387 already active stream(s) as well.
388
389 (2) All the Master(s) and Slave(s) port(s) for the current stream are
390 enabled on alternate bank (bank currently unused) by programming
391 ChannelEn register.
392
393 (3) Once all the values are programmed, Bus initiates switch to alternate
394 bank where all new values programmed gets into effect and port(s)
395 associated with current stream are enabled.
396
397 After all above operations are successful, stream state is set to
398 ``SDW_STREAM_ENABLED``.
399
400 Bus implements below API for ENABLE state which needs to be called once per
401 stream. From ASoC DPCM framework, this stream state is linked to
402 .trigger() start operation.
403
404 .. code-block:: c
405
406 int sdw_enable_stream(struct sdw_stream_runtime * stream);
407
408 SDW_STREAM_DISABLED
409 ~~~~~~~~~~~~~~~~~~~
410
411 Disable state of stream. The data port(s) are disabled upon exiting this state.
412 Operations performed before entering in this state:
413
414 (1) All the Master(s) and Slave(s) port(s) for the current stream are
415 disabled on alternate bank (bank currently unused) by programming
416 ChannelEn register.
417
418 (2) All the current configuration of Bus and active stream(s) are programmed
419 into alternate bank (bank currently unused).
420
421 (3) Once all the values are programmed, Bus initiates switch to alternate
422 bank where all new values programmed gets into effect and port(s) associated
423 with current stream are disabled.
424
425 After all above operations are successful, stream state is set to
426 ``SDW_STREAM_DISABLED``.
427
428 Bus implements below API for DISABLED state which needs to be called once
429 per stream. From ASoC DPCM framework, this stream state is linked to
430 .trigger() stop operation.
431
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
442 int sdw_disable_stream(struct sdw_stream_runtime * stream);
443
444
445 SDW_STREAM_DEPREPARED
446 ~~~~~~~~~~~~~~~~~~~~~
447
448 De-prepare state of stream. Operations performed before entering in this
449 state:
450
451 (1) All the port(s) of Master(s) and Slave(s) for current stream are
452 de-prepared by programming PrepareCtrl register.
453
454 (2) The payload bandwidth of current stream is reduced from the total
455 bandwidth requirement of bus and new parameters calculated and
456 applied by performing bank switch etc.
457
458 After all above operations are successful, stream state is set to
459 ``SDW_STREAM_DEPREPARED``.
460
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.
465
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
476 int sdw_deprepare_stream(struct sdw_stream_runtime * stream);
477
478
479 SDW_STREAM_RELEASED
480 ~~~~~~~~~~~~~~~~~~~
481
482 Release state of stream. Operations performed before entering in this state:
483
484 (1) Release port resources for all Master(s) and Slave(s) port(s)
485 associated with current stream.
486
487 (2) Release Master(s) and Slave(s) runtime resources associated with
488 current stream.
489
490 (3) Release stream runtime resources associated with current stream.
491
492 After all above operations are successful, stream state is set to
493 ``SDW_STREAM_RELEASED``.
494
495 Bus implements below APIs for RELEASE state which needs to be called by
496 all the Master(s) and Slave(s) associated with stream. From ASoC DPCM
497 framework, this stream state is linked to .hw_free() operation.
498
499 .. code-block:: c
500
501 int sdw_stream_remove_master(struct sdw_bus * bus,
502 struct sdw_stream_runtime * stream);
503 int sdw_stream_remove_slave(struct sdw_slave * slave,
504 struct sdw_stream_runtime * stream);
505
506
507 The .shutdown() ASoC DPCM operation calls below Bus API to release
508 stream assigned as part of ALLOCATED state.
509
510 In .shutdown() the data structure maintaining stream state are freed up.
511
512 .. code-block:: c
513
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.
520
521 Not Supported
522 =============
523
524 1. A single port with multiple channels supported cannot be used between two
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.
528

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

Audio stream과 memory sample

1-27

Audio stream은 system memory buffer와 Codec, DSP memory buffer와 Codec, FIFO와 Codec 또는 Codec과 Codec 사이에 만드는 logical 또는 virtual connection입니다.

일반적으로 DMA channel이 data link를 통해 stream을 구동합니다. 하나의 audio stream에는 한 개 이상의 data channel이 들어가며, 같은 stream의 모든 channel은 sample rate와 sample size가 같아야 합니다.

SoundWire interface로 Left와 Right 두 channel의 stream을 열었다고 가정하면 system memory, DSP memory 또는 FIFO의 sample은 `L | R | L | R | L | R` 순서로 interleave될 수 있습니다.

Audio stream endpoint와 channel 규칙
연결 형태구동공통 조건
System memory buffer(s) -> Codec(s)DMA / data link동일 sample rate·size
DSP memory buffer(s) -> Codec(s)DMA / data link동일 sample rate·size
FIFO(s) -> Codec(s)DMA / data link동일 sample rate·size
Codec(s) -> Codec(s)Data link동일 sample rate·size
Stereo memory sample`L R L R L R`Interleaved channels

=========================
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-2: 단일 port render와 capture

28-54

Example 1은 Master에서 Slave로 stereo stream을 render합니다. Master와 Slave가 각각 하나의 port를 사용하고, clock은 Master interface에서 Slave interface로 전달되며 L+R data도 같은 방향으로 흐릅니다.

Example 2는 Slave에서 Master로 stereo stream을 capture합니다. 두 endpoint 모두 single port를 사용하지만 data direction은 Slave에서 Master 쪽으로 반대가 됩니다. Clock signal 방향은 그대로 Master에서 Slave입니다.

Single-port stereo 방향
예제동작ClockData
1RenderMaster -> SlaveMaster L+R -> Slave L+R
2CaptureMaster -> SlaveSlave L+R -> Master L+R

원문의 두 ASCII interface diagram을 clock과 data direction 기준으로 구조화했습니다.

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-4: 여러 Slave의 channel 선택

55-103

Example 3에서는 Master가 L+R stereo를 render하고 서로 다른 두 Slave가 각각 한 channel만 받습니다. Master와 두 Slave는 모두 single port를 사용하며 Slave Interface 1은 L, Slave Interface 2는 R을 수신합니다.

Example 4에서도 Master가 L+R을 render하지만 두 Slave 모두 L+R 전체를 받습니다. 각 Slave는 static configuration 또는 dynamic orientation에 따라 L+R data를 local에서 처리하고 하나 이상의 speaker를 구동할 수 있습니다.

한 link에서 두 Slave로 배포
예제Master 송신Slave 1Slave 2Local 처리
3L+RLRChannel subset
4L+RL+RL+RStatic config 또는 dynamic orientation

동일한 bus data에서 Slave가 전체 channel 또는 subset을 선택하는 차이를 나타냅니다.

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

        +---------------+                    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-6: 여러 port와 여러 Master

104-150

Example 5에서는 한 Master의 서로 다른 두 port가 L과 R을 각각 render하고, 한 Slave interface의 single port가 L+R을 함께 수신합니다. Master Data Port 1은 L, Data Port 2는 R을 제공합니다.

Example 6에서는 두 Master가 각각 한 channel을 render하고 두 Slave가 각각 한 channel을 받습니다. Master Interface 1과 Slave Interface 1은 L을, Master Interface 2와 Slave Interface 2는 R을 담당하며 모든 endpoint는 single port를 사용합니다.

Port와 Master 분할
예제Source 구성Sink 구성Channel mapping
5Master 1개, port 2개Slave 1개, port 1개L port + R port -> L+R port
6Master 2개, 각 port 1개Slave 2개, 각 port 1개Master1 L -> Slave1 L, Master2 R -> Slave2 R

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

        +--------------------+
        |                    |
        |     +--------------+                             +----------------+
        |     |             ||                             |                |
        |     |  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)    |
        +--------------------+                             |                |
                                                           +----------------+

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

        +---------------+                    Clock Signal  +---------------+
        |    Master     +----------------------------------+     Slave     |
        |   Interface   |                                  |   Interface   |
        |       1       |                                  |       1       |
        |               |                     Data Signal  |               |
        |       L       +----------------------------------+       L       |
        |     (Data)    |     Data Direction               |     (Data)    |
        +---------------+  +----------------------->       +---------------+

        +---------------+                    Clock Signal  +---------------+
        |    Master     +----------------------------------+     Slave     |
        |   Interface   |                                  |   Interface   |
        |       2       |                                  |       2       |
        |               |                     Data Signal  |               |
        |       R       +----------------------------------+       R       |
        |     (Data)    |     Data Direction               |     (Data)    |
        +---------------+  +----------------------->       +---------------+

Example 7-8: Multi-link stream

151-194

Example 7에서는 두 Master가 각각 L+R을 render하고 각 Slave도 L+R을 받습니다. Application은 Example 4와 같지만 Slave가 별도 link에 배치됩니다.

Example 8은 4-channel stream을 두 Master가 각각 2 channel씩 render하는 구성입니다. Master Interface 1은 L1+R1을 Slave Interface 1로, Master Interface 2는 L2+R2를 Slave Interface 2로 전달합니다.

Multi-link channel 구성
예제Link 1Link 2전체 stream
7Master1 L+R -> Slave1 L+RMaster2 L+R -> Slave2 L+RStereo 복제
8Master1 L1+R1 -> Slave1Master2 L2+R2 -> Slave24 channels

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)    |
        +---------------+  +----------------------->       +---------------+

Multi-link lock, TDM slot과 bitSlot 제약

195-215

Note 1: 일반적인 multi-link locking이라면 global lock을 acquire한 다음 각 bus instance를 lock합니다. 그러나 caller framework인 ASoC DPCM이 한 card의 stream operation을 항상 serialize하므로 race condition이 없고 global lock이 필요하지 않습니다.

Note 2: Slave는 주어진 Stream에서 link로 전송되는 모든 channel을 받거나 일부만 받을 수 있습니다. 이 Slave configuration은 SoundWire subsystem API가 아니라 `snd_soc_dai_set_tdm_slot()` API로 처리하며 platform 또는 machine driver가 사용할 slot을 정합니다.

Example 4에서는 모든 Device가 같은 slot을 사용합니다. Example 3에서는 예를 들어 Slave Device1이 Slot 0을, Slave device2가 Slot 1을 사용합니다.

Note 3: 여러 Sink port는 SoundWire frame의 같은 bitSlot에서 같은 정보를 추출할 수 있지만 여러 Source port는 서로 다른 bitSlot configuration을 사용해야 합니다. 이는 I2S/PCM TDM과 같은 제약입니다.

Stream topology 보조 규칙
항목규칙
Multi-link lockASoC DPCM serialization으로 global lock 불필요
Slave channel selection`snd_soc_dai_set_tdm_slot()`에서 slot 구성
Multiple Sink ports같은 bitSlots 사용 가능
Multiple Source ports서로 다른 bitSlot configuration 필요
동일 제약I2S/PCM TDM

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

Current stream과 Active stream

216-233

Current stream은 Prepare, Enable, Disable, De-prepare 같은 operation을 지금 수행해야 하는 stream입니다.

Active stream은 current stream 이외에 Bus에서 이미 active인 stream입니다. 하나의 Bus에는 active stream이 여러 개 존재할 수 있습니다.

SoundWire Bus는 Bus에서 render 또는 capture되는 각 stream의 operation을 관리하고, allocation과 release 사이의 상태를 stream별로 유지합니다.

Stream 분류
분류정의개수
Current stream현재 operation 대상해당 operation마다 1개
Active streamBus에서 이미 active인 다른 stream0개 이상

================================

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.

Stream state와 transition

234-263

기본 lifecycle은 `SDW_STREAM_ALLOCATED`에서 `SDW_STREAM_CONFIGURED`, `SDW_STREAM_PREPARED`, `SDW_STREAM_ENABLED`로 진행하고, 정지 시 `SDW_STREAM_DISABLED`, `SDW_STREAM_DEPREPARED`, `SDW_STREAM_RELEASED`로 이동합니다.

ALSA/ASoC가 `INFO_PAUSE`를 지원할 때만 `SDW_STREAM_ENABLED`와 `SDW_STREAM_DISABLED` 사이 transition이 의미가 있습니다. `SDW_DISABLED_STATE`에서 `SDW_PREPARED_STATE`로 돌아가는 transition도 `INFO_RESUME` 지원에 의존합니다.

Framework는 기본 state transition을 검사하지만 특정 platform에서 DISABLED에서 ENABLED로의 transition이 유효한지는 검사하지 않습니다. 이런 검사는 ALSA/ASoC level에 추가해야 합니다.

SoundWire stream state machine
ALLOCATEDCONFIGUREDPREPAREDENABLED
ENABLEDDISABLEDDEPREPAREDRELEASED
DISABLEDENABLEDINFO_PAUSE
DISABLEDPREPAREDINFO_RESUME
PREPAREDDEPREPAREDTrigger가 뒤따르지 않는 경우

원문의 ASCII state transition diagram을 lifecycle과 pause/resume 분기로 다시 구성했습니다.

SoundWire stream states
-----------------------

Below shows the SoundWire stream states and state transition diagram. ::

        +-----------+     +------------+     +----------+     +----------+
        | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED  |
        |   STATE   |     |    STATE   |     |  STATE   |     |  STATE   |
        +-----------+     +------------+     +---+--+---+     +----+-----+
                                                 ^  ^              ^
                                                 |  |              |
                                               __|  |___________   |
                                              |                 |  |
                                              v                 |  v
                 +----------+           +-----+------+        +-+--+-----+
                 | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED |
                 |  STATE   |           |   STATE    |        |  STATE   |
                 +----------+           +------------+        +----------+

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

SDW_STREAM_ALLOCATED

264-300

`SDW_STREAM_ALLOCATED`는 stream의 entry state입니다. 먼저 이후 모든 stream operation의 reference가 되는 stream runtime을 allocate합니다.

그다음 stream runtime information을 보관할 resource를 allocate하고 initialize합니다. 여기에는 stream type인 PCM/PDM과 parameter, 연결된 Master·Slave interface, stream state 등 모든 stream 관련 정보가 포함됩니다.

모든 operation이 성공하면 state를 `SDW_STREAM_ALLOCATED`로 설정합니다.

Bus API `sdw_alloc_stream(char * stream_name, enum sdw_stream_type type)`은 stream마다 한 번 호출하며 ASoC DPCM의 `.startup()` operation과 연결할 수 있습니다.

SoundWire core의 `sdw_startup_stream()` helper는 일반적으로 dailink `.startup()` callback에서 호출합니다. 이 helper는 stream을 allocate하고 해당 stream에 연결된 모든 DAI의 stream pointer를 설정합니다.

ALLOCATED 진입
순서Operation
1Stream runtime allocate
2PCM/PDM, parameter, Master·Slave, state resource initialize
3State = `SDW_STREAM_ALLOCATED`
ASoC`.startup()` / `sdw_startup_stream()`

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, enum sdw_stream_type type);

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

301-335

`SDW_STREAM_CONFIGURED`에 들어가기 전에 ALLOCATED state에서 만든 resource를 stream parameter와 current stream의 Master·Slave runtime information으로 update합니다.

Current stream에 연결된 모든 Master와 Slave는 할당한 port number와 channel mask를 포함한 port information을 Bus에 제공합니다.

모든 operation이 성공하면 state를 `SDW_STREAM_CONFIGURED`로 설정합니다.

각 Master와 Slave는 CONFIG state API를 각각 한 번만 호출할 수 있습니다. Master는 `sdw_stream_add_master()`, Slave는 `sdw_stream_add_slave()`를 사용하며 ASoC DPCM의 `.hw_params()` operation과 연결됩니다.

CONFIGURED 진입
제공자정보 / API
CommonStream parameter와 runtime update
MasterPort number·channel mask, `sdw_stream_add_master()`
SlavePort number·channel mask, `sdw_stream_add_slave()`
ASoC`.hw_params()`

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,
                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,
                const struct sdw_ports_config * ports_config,
                struct sdw_stream_runtime * stream);

SDW_STREAM_PREPARED

336-378

Resume operation에서는 bus bandwidth를 이미 알고 있으므로 아래 1단계와 2단계를 생략합니다.

1단계에서는 current stream과 기존 active stream을 함께 고려해 bandwidth, frame shape, clock frequency 같은 Bus parameter를 다시 계산합니다. Current stream을 Bus에 수용하기 위해 re-computation이 필요합니다.

2단계에서는 1단계의 frame shape와 clock frequency를 바탕으로 current stream과 active stream의 모든 Master·Slave port에 대한 transport parameter와 port parameter를 계산합니다.

3단계에서는 계산한 Bus·transport parameter를 Master와 Slave register의 alternate bank에 program하고, 이미 active인 stream의 port도 alternate bank에서 enable합니다. 기존 active stream을 중단하지 않기 위한 절차입니다.

4단계에서는 Bus가 alternate bank로 switch해 새 값을 적용합니다. 5단계에서는 `PrepareCtrl` register를 program해 current stream의 Master·Slave port를 prepare합니다.

성공하면 state를 `SDW_STREAM_PREPARED`로 설정합니다. `sdw_prepare_stream()`은 stream마다 한 번 호출하며 ASoC DPCM `.prepare()`와 연결됩니다. `.trigger()`가 `.prepare()` 뒤에 오지 않을 수 있으므로 PREPARED에서 DEPREPARED로 직접 전이할 수 있습니다.

PREPARED 진입 sequence
Bus parameter 계산Bandwidth·frame shape·clock
Transport / port parameter 계산Current + active streams
Alternate bank programmingActive ports 포함
Bank switch새 값 적용
PrepareCtrlCurrent ports prepare
State`SDW_STREAM_PREPARED`

Resume에서는 bandwidth가 알려져 있어 첫 두 계산 단계를 생략합니다.

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

  int sdw_prepare_stream(struct sdw_stream_runtime * stream);

SDW_STREAM_ENABLED

379-407

`SDW_STREAM_ENABLED`에 들어가면 data port가 enable됩니다.

먼저 PREPARED state에서 계산한 모든 값과 기존 active stream의 설정을 alternate bank에 program합니다. 그다음 `ChannelEn` register를 program해 current stream의 모든 Master·Slave port를 alternate bank에서 enable합니다.

값을 모두 program한 뒤 Bus가 alternate bank로 switch하면 새 값이 적용되고 current stream port가 활성화됩니다. 성공하면 state를 `SDW_STREAM_ENABLED`로 설정합니다.

`sdw_enable_stream()`은 stream마다 한 번 호출하며 ASoC DPCM의 `.trigger()` start operation과 연결됩니다.

ENABLED 진입 sequence
PREPARED valuesAlternate bank program
ChannelEnCurrent Master·Slave ports enable
Bank switchNew values effective
State`SDW_STREAM_ENABLED`
ASoC`.trigger()` start

Alternate bank를 사용해 기존 active stream을 유지하면서 current 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

408-444

DISABLED state로 들어갈 때 current stream의 data port를 disable합니다. 모든 Master·Slave port의 `ChannelEn` register를 alternate bank에서 program해 disable합니다.

현재 Bus configuration과 active stream configuration도 alternate bank에 program한 뒤 bank switch를 수행합니다. 새 값이 적용되면 current stream port가 disable되고 state를 `SDW_STREAM_DISABLED`로 설정합니다.

`sdw_disable_stream()`은 stream마다 한 번 호출하며 ASoC DPCM의 `.trigger()` stop operation과 연결됩니다.

`INFO_PAUSE`를 지원하면 DISABLED에서 ENABLED로 직접 전이할 수 있습니다. ASoC가 `.prepare()` callback을 쓰는 resume에서는 DISABLED에서 PREPARED로 전이해 필요한 설정을 복원하지만 bandwidth와 bit allocation은 update하지 않습니다.

DISABLED 진입과 재개
ChannelEnAlternate bank에서 current ports disable
Bus + active configAlternate bank program
Bank switchState = `SDW_STREAM_DISABLED`
INFO_PAUSEDirect -> ENABLED
Resume via `.prepare()`-> PREPAREDBandwidth·bit allocation 유지

정지 후 pause 또는 resume capability에 따라 복귀 경로가 달라집니다.

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.

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);

SDW_STREAM_DEPREPARED

445-478

DEPREPARED state에 들어가기 전에 `PrepareCtrl` register를 program해 current stream의 모든 Master·Slave port를 de-prepare합니다.

Current stream의 payload bandwidth를 Bus의 total bandwidth requirement에서 빼고 새 parameter를 계산한 뒤 bank switch 등으로 적용합니다. 성공하면 state를 `SDW_STREAM_DEPREPARED`로 설정합니다.

`sdw_deprepare_stream()`은 stream마다 한 번 호출합니다. ALSA/ASoC에는 deprepare concept가 없으므로 이 state와 ALSA/ASoC operation의 mapping은 implementation-specific일 수 있습니다.

`INFO_PAUSE`를 지원하면 이 state는 `.hw_free()` operation과 연결되고 `TRIGGER_STOP`에서는 stream을 de-prepare하지 않습니다. 다른 구현은 PREPARED를 거치는 transition이 필요할 때 `TRIGGER_STOP`에서 DEPREPARED로 이동할 수 있습니다.

DEPREPARED 처리
항목동작
Ports`PrepareCtrl`로 de-prepare
BandwidthCurrent payload를 total requirement에서 차감
BusParameter 재계산 후 bank switch
INFO_PAUSE`.hw_free()`에서 de-prepare
Alternative`TRIGGER_STOP`에서 DEPREPARED 전이

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

  int sdw_deprepare_stream(struct sdw_stream_runtime * stream);

SDW_STREAM_RELEASED

479-520

RELEASED state에 들어가기 전에 current stream과 연결된 모든 Master·Slave port resource, Master·Slave runtime resource, stream runtime resource를 차례로 release합니다.

모든 operation이 성공하면 state를 `SDW_STREAM_RELEASED`로 설정합니다.

모든 연결된 Master와 Slave가 `sdw_stream_remove_master()` 또는 `sdw_stream_remove_slave()`를 호출해야 하며, ASoC DPCM의 `.hw_free()` operation과 연결됩니다.

`.shutdown()`은 ALLOCATED state에서 할당한 stream을 release하기 위해 `sdw_release_stream()`을 호출하고 stream state를 유지하던 data structure를 해제합니다.

SoundWire core의 `sdw_shutdown_stream()` helper는 일반적으로 dailink `.shutdown()` callback에서 호출합니다. 연결된 모든 DAI의 stream pointer를 clear하고 stream에 할당한 memory를 release합니다.

RELEASED resource 해제
순서Resource / API
1Master·Slave port resources
2Master·Slave runtime resources
3Stream runtime resources
Per endpoint`sdw_stream_remove_master/slave()`
Shutdown`sdw_release_stream()` / `sdw_shutdown_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);

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.

지원하지 않는 port 공유

521-527

여러 channel을 지원하는 single port 하나를 두 stream 사이 또는 여러 stream에 걸쳐 사용할 수 없습니다.

예를 들어 이론적으로 SoundWire에서 가능하더라도 4-channel port 하나로 서로 독립적인 stereo stream 두 개를 처리할 수 없습니다.

Unsupported port usage
Port capability요청지원
Single 4-channel port독립 stereo stream 2개지원하지 않음
Single multichannel portStream 간 공유지원하지 않음

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.