162306a36Sopenharmony_ci========================= 262306a36Sopenharmony_ciAudio Stream in SoundWire 362306a36Sopenharmony_ci========================= 462306a36Sopenharmony_ci 562306a36Sopenharmony_ciAn audio stream is a logical or virtual connection created between 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci (1) System memory buffer(s) and Codec(s) 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci (2) DSP memory buffer(s) and Codec(s) 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci (3) FIFO(s) and Codec(s) 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci (4) Codec(s) and Codec(s) 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciwhich is typically driven by a DMA(s) channel through the data link. An 1662306a36Sopenharmony_ciaudio stream contains one or more channels of data. All channels within 1762306a36Sopenharmony_cistream must have same sample rate and same sample size. 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ciAssume a stream with two channels (Left & Right) is opened using SoundWire 2062306a36Sopenharmony_ciinterface. Below are some ways a stream can be represented in SoundWire. 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ciStream Sample in memory (System memory, DSP memory or FIFOs) :: 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci ------------------------- 2562306a36Sopenharmony_ci | L | R | L | R | L | R | 2662306a36Sopenharmony_ci ------------------------- 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ciExample 1: Stereo Stream with L and R channels is rendered from Master to 2962306a36Sopenharmony_ciSlave. Both Master and Slave is using single port. :: 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 3262306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 3362306a36Sopenharmony_ci | Interface | | Interface | 3462306a36Sopenharmony_ci | | | 1 | 3562306a36Sopenharmony_ci | | Data Signal | | 3662306a36Sopenharmony_ci | L + R +----------------------------------+ L + R | 3762306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 3862306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciExample 2: Stereo Stream with L and R channels is captured from Slave to 4262306a36Sopenharmony_ciMaster. Both Master and Slave is using single port. :: 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 4662306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 4762306a36Sopenharmony_ci | Interface | | Interface | 4862306a36Sopenharmony_ci | | | 1 | 4962306a36Sopenharmony_ci | | Data Signal | | 5062306a36Sopenharmony_ci | L + R +----------------------------------+ L + R | 5162306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 5262306a36Sopenharmony_ci +---------------+ <-----------------------+ +---------------+ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ciExample 3: Stereo Stream with L and R channels is rendered by Master. Each 5662306a36Sopenharmony_ciof the L and R channel is received by two different Slaves. Master and both 5762306a36Sopenharmony_ciSlaves are using single port. :: 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 6062306a36Sopenharmony_ci | Master +---------+------------------------+ Slave | 6162306a36Sopenharmony_ci | Interface | | | Interface | 6262306a36Sopenharmony_ci | | | | 1 | 6362306a36Sopenharmony_ci | | | Data Signal | | 6462306a36Sopenharmony_ci | L + R +---+------------------------------+ L | 6562306a36Sopenharmony_ci | (Data) | | | Data Direction | (Data) | 6662306a36Sopenharmony_ci +---------------+ | | +-------------> +---------------+ 6762306a36Sopenharmony_ci | | 6862306a36Sopenharmony_ci | | 6962306a36Sopenharmony_ci | | +---------------+ 7062306a36Sopenharmony_ci | +----------------------> | Slave | 7162306a36Sopenharmony_ci | | Interface | 7262306a36Sopenharmony_ci | | 2 | 7362306a36Sopenharmony_ci | | | 7462306a36Sopenharmony_ci +----------------------------> | R | 7562306a36Sopenharmony_ci | (Data) | 7662306a36Sopenharmony_ci +---------------+ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciExample 4: Stereo Stream with L and R channels is rendered by 7962306a36Sopenharmony_ciMaster. Both of the L and R channels are received by two different 8062306a36Sopenharmony_ciSlaves. Master and both Slaves are using single port handling 8162306a36Sopenharmony_ciL+R. Each Slave device processes the L + R data locally, typically 8262306a36Sopenharmony_cibased on static configuration or dynamic orientation, and may drive 8362306a36Sopenharmony_cione or more speakers. :: 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 8662306a36Sopenharmony_ci | Master +---------+------------------------+ Slave | 8762306a36Sopenharmony_ci | Interface | | | Interface | 8862306a36Sopenharmony_ci | | | | 1 | 8962306a36Sopenharmony_ci | | | Data Signal | | 9062306a36Sopenharmony_ci | L + R +---+------------------------------+ L + R | 9162306a36Sopenharmony_ci | (Data) | | | Data Direction | (Data) | 9262306a36Sopenharmony_ci +---------------+ | | +-------------> +---------------+ 9362306a36Sopenharmony_ci | | 9462306a36Sopenharmony_ci | | 9562306a36Sopenharmony_ci | | +---------------+ 9662306a36Sopenharmony_ci | +----------------------> | Slave | 9762306a36Sopenharmony_ci | | Interface | 9862306a36Sopenharmony_ci | | 2 | 9962306a36Sopenharmony_ci | | | 10062306a36Sopenharmony_ci +----------------------------> | L + R | 10162306a36Sopenharmony_ci | (Data) | 10262306a36Sopenharmony_ci +---------------+ 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciExample 5: Stereo Stream with L and R channel is rendered by two different 10562306a36Sopenharmony_ciPorts of the Master and is received by only single Port of the Slave 10662306a36Sopenharmony_ciinterface. :: 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci +--------------------+ 10962306a36Sopenharmony_ci | | 11062306a36Sopenharmony_ci | +--------------+ +----------------+ 11162306a36Sopenharmony_ci | | || | | 11262306a36Sopenharmony_ci | | Data Port || L Channel | | 11362306a36Sopenharmony_ci | | 1 |------------+ | | 11462306a36Sopenharmony_ci | | L Channel || | +-----+----+ | 11562306a36Sopenharmony_ci | | (Data) || | L + R Channel || Data | | 11662306a36Sopenharmony_ci | Master +----------+ | +---+---------> || Port | | 11762306a36Sopenharmony_ci | Interface | | || 1 | | 11862306a36Sopenharmony_ci | +--------------+ | || | | 11962306a36Sopenharmony_ci | | || | +----------+ | 12062306a36Sopenharmony_ci | | Data Port |------------+ | | 12162306a36Sopenharmony_ci | | 2 || R Channel | Slave | 12262306a36Sopenharmony_ci | | R Channel || | Interface | 12362306a36Sopenharmony_ci | | (Data) || | 1 | 12462306a36Sopenharmony_ci | +--------------+ Clock Signal | L + R | 12562306a36Sopenharmony_ci | +---------------------------> | (Data) | 12662306a36Sopenharmony_ci +--------------------+ | | 12762306a36Sopenharmony_ci +----------------+ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ciExample 6: Stereo Stream with L and R channel is rendered by 2 Masters, each 13062306a36Sopenharmony_cirendering one channel, and is received by two different Slaves, each 13162306a36Sopenharmony_cireceiving one channel. Both Masters and both Slaves are using single port. :: 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 13462306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 13562306a36Sopenharmony_ci | Interface | | Interface | 13662306a36Sopenharmony_ci | 1 | | 1 | 13762306a36Sopenharmony_ci | | Data Signal | | 13862306a36Sopenharmony_ci | L +----------------------------------+ L | 13962306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 14062306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 14362306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 14462306a36Sopenharmony_ci | Interface | | Interface | 14562306a36Sopenharmony_ci | 2 | | 2 | 14662306a36Sopenharmony_ci | | Data Signal | | 14762306a36Sopenharmony_ci | R +----------------------------------+ R | 14862306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 14962306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ciExample 7: Stereo Stream with L and R channel is rendered by 2 15262306a36Sopenharmony_ciMasters, each rendering both channels. Each Slave receives L + R. This 15362306a36Sopenharmony_ciis the same application as Example 4 but with Slaves placed on 15462306a36Sopenharmony_ciseparate links. :: 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 15762306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 15862306a36Sopenharmony_ci | Interface | | Interface | 15962306a36Sopenharmony_ci | 1 | | 1 | 16062306a36Sopenharmony_ci | | Data Signal | | 16162306a36Sopenharmony_ci | L + R +----------------------------------+ L + R | 16262306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 16362306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 16662306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 16762306a36Sopenharmony_ci | Interface | | Interface | 16862306a36Sopenharmony_ci | 2 | | 2 | 16962306a36Sopenharmony_ci | | Data Signal | | 17062306a36Sopenharmony_ci | L + R +----------------------------------+ L + R | 17162306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 17262306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ciExample 8: 4-channel Stream is rendered by 2 Masters, each rendering a 17562306a36Sopenharmony_ci2 channels. Each Slave receives 2 channels. :: 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 17862306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 17962306a36Sopenharmony_ci | Interface | | Interface | 18062306a36Sopenharmony_ci | 1 | | 1 | 18162306a36Sopenharmony_ci | | Data Signal | | 18262306a36Sopenharmony_ci | L1 + R1 +----------------------------------+ L1 + R1 | 18362306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 18462306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci +---------------+ Clock Signal +---------------+ 18762306a36Sopenharmony_ci | Master +----------------------------------+ Slave | 18862306a36Sopenharmony_ci | Interface | | Interface | 18962306a36Sopenharmony_ci | 2 | | 2 | 19062306a36Sopenharmony_ci | | Data Signal | | 19162306a36Sopenharmony_ci | L2 + R2 +----------------------------------+ L2 + R2 | 19262306a36Sopenharmony_ci | (Data) | Data Direction | (Data) | 19362306a36Sopenharmony_ci +---------------+ +-----------------------> +---------------+ 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ciNote1: In multi-link cases like above, to lock, one would acquire a global 19662306a36Sopenharmony_cilock and then go on locking bus instances. But, in this case the caller 19762306a36Sopenharmony_ciframework(ASoC DPCM) guarantees that stream operations on a card are 19862306a36Sopenharmony_cialways serialized. So, there is no race condition and hence no need for 19962306a36Sopenharmony_ciglobal lock. 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ciNote2: A Slave device may be configured to receive all channels 20262306a36Sopenharmony_citransmitted on a link for a given Stream (Example 4) or just a subset 20362306a36Sopenharmony_ciof the data (Example 3). The configuration of the Slave device is not 20462306a36Sopenharmony_cihandled by a SoundWire subsystem API, but instead by the 20562306a36Sopenharmony_cisnd_soc_dai_set_tdm_slot() API. The platform or machine driver will 20662306a36Sopenharmony_citypically configure which of the slots are used. For Example 4, the 20762306a36Sopenharmony_cisame slots would be used by all Devices, while for Example 3 the Slave 20862306a36Sopenharmony_ciDevice1 would use e.g. Slot 0 and Slave device2 slot 1. 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciNote3: Multiple Sink ports can extract the same information for the 21162306a36Sopenharmony_cisame bitSlots in the SoundWire frame, however multiple Source ports 21262306a36Sopenharmony_cishall be configured with different bitSlot configurations. This is the 21362306a36Sopenharmony_cisame limitation as with I2S/PCM TDM usages. 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ciSoundWire Stream Management flow 21662306a36Sopenharmony_ci================================ 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ciStream definitions 21962306a36Sopenharmony_ci------------------ 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci (1) Current stream: This is classified as the stream on which operation has 22262306a36Sopenharmony_ci to be performed like prepare, enable, disable, de-prepare etc. 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci (2) Active stream: This is classified as the stream which is already active 22562306a36Sopenharmony_ci on Bus other than current stream. There can be multiple active streams 22662306a36Sopenharmony_ci on the Bus. 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ciSoundWire Bus manages stream operations for each stream getting 22962306a36Sopenharmony_cirendered/captured on the SoundWire Bus. This section explains Bus operations 23062306a36Sopenharmony_cidone for each of the stream allocated/released on Bus. Following are the 23162306a36Sopenharmony_cistream states maintained by the Bus for each of the audio stream. 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ciSoundWire stream states 23562306a36Sopenharmony_ci----------------------- 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ciBelow shows the SoundWire stream states and state transition diagram. :: 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci +-----------+ +------------+ +----------+ +----------+ 24062306a36Sopenharmony_ci | ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED | 24162306a36Sopenharmony_ci | STATE | | STATE | | STATE | | STATE | 24262306a36Sopenharmony_ci +-----------+ +------------+ +---+--+---+ +----+-----+ 24362306a36Sopenharmony_ci ^ ^ ^ 24462306a36Sopenharmony_ci | | | 24562306a36Sopenharmony_ci __| |___________ | 24662306a36Sopenharmony_ci | | | 24762306a36Sopenharmony_ci v | v 24862306a36Sopenharmony_ci +----------+ +-----+------+ +-+--+-----+ 24962306a36Sopenharmony_ci | RELEASED |<----------+ DEPREPARED |<-------+ DISABLED | 25062306a36Sopenharmony_ci | STATE | | STATE | | STATE | 25162306a36Sopenharmony_ci +----------+ +------------+ +----------+ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ciNOTE: State transitions between ``SDW_STREAM_ENABLED`` and 25462306a36Sopenharmony_ci``SDW_STREAM_DISABLED`` are only relevant when then INFO_PAUSE flag is 25562306a36Sopenharmony_cisupported at the ALSA/ASoC level. Likewise the transition between 25662306a36Sopenharmony_ci``SDW_DISABLED_STATE`` and ``SDW_PREPARED_STATE`` depends on the 25762306a36Sopenharmony_ciINFO_RESUME flag. 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_ciNOTE2: The framework implements basic state transition checks, but 26062306a36Sopenharmony_cidoes not e.g. check if a transition from DISABLED to ENABLED is valid 26162306a36Sopenharmony_cion a specific platform. Such tests need to be added at the ALSA/ASoC 26262306a36Sopenharmony_cilevel. 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ciStream State Operations 26562306a36Sopenharmony_ci----------------------- 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ciBelow section explains the operations done by the Bus on Master(s) and 26862306a36Sopenharmony_ciSlave(s) as part of stream state transitions. 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ciSDW_STREAM_ALLOCATED 27162306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~ 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ciAllocation state for stream. This is the entry state 27462306a36Sopenharmony_ciof the stream. Operations performed before entering in this state: 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci (1) A stream runtime is allocated for the stream. This stream 27762306a36Sopenharmony_ci runtime is used as a reference for all the operations performed 27862306a36Sopenharmony_ci on the stream. 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci (2) The resources required for holding stream runtime information are 28162306a36Sopenharmony_ci allocated and initialized. This holds all stream related information 28262306a36Sopenharmony_ci such as stream type (PCM/PDM) and parameters, Master and Slave 28362306a36Sopenharmony_ci interface associated with the stream, stream state etc. 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 28662306a36Sopenharmony_ci``SDW_STREAM_ALLOCATED``. 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ciBus implements below API for allocate a stream which needs to be called once 28962306a36Sopenharmony_ciper stream. From ASoC DPCM framework, this stream state maybe linked to 29062306a36Sopenharmony_ci.startup() operation. 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci.. code-block:: c 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci int sdw_alloc_stream(char * stream_name); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ciThe SoundWire core provides a sdw_startup_stream() helper function, 29762306a36Sopenharmony_citypically called during a dailink .startup() callback, which performs 29862306a36Sopenharmony_cistream allocation and sets the stream pointer for all DAIs 29962306a36Sopenharmony_ciconnected to a stream. 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciSDW_STREAM_CONFIGURED 30262306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~ 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ciConfiguration state of stream. Operations performed before entering in 30562306a36Sopenharmony_cithis state: 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci (1) The resources allocated for stream information in SDW_STREAM_ALLOCATED 30862306a36Sopenharmony_ci state are updated here. This includes stream parameters, Master(s) 30962306a36Sopenharmony_ci and Slave(s) runtime information associated with current stream. 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci (2) All the Master(s) and Slave(s) associated with current stream provide 31262306a36Sopenharmony_ci the port information to Bus which includes port numbers allocated by 31362306a36Sopenharmony_ci Master(s) and Slave(s) for current stream and their channel mask. 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 31662306a36Sopenharmony_ci``SDW_STREAM_CONFIGURED``. 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ciBus implements below APIs for CONFIG state which needs to be called by 31962306a36Sopenharmony_cithe respective Master(s) and Slave(s) associated with stream. These APIs can 32062306a36Sopenharmony_cionly be invoked once by respective Master(s) and Slave(s). From ASoC DPCM 32162306a36Sopenharmony_ciframework, this stream state is linked to .hw_params() operation. 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci.. code-block:: c 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci int sdw_stream_add_master(struct sdw_bus * bus, 32662306a36Sopenharmony_ci struct sdw_stream_config * stream_config, 32762306a36Sopenharmony_ci struct sdw_ports_config * ports_config, 32862306a36Sopenharmony_ci struct sdw_stream_runtime * stream); 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci int sdw_stream_add_slave(struct sdw_slave * slave, 33162306a36Sopenharmony_ci struct sdw_stream_config * stream_config, 33262306a36Sopenharmony_ci struct sdw_ports_config * ports_config, 33362306a36Sopenharmony_ci struct sdw_stream_runtime * stream); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ciSDW_STREAM_PREPARED 33762306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~ 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ciPrepare state of stream. Operations performed before entering in this state: 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci (0) Steps 1 and 2 are omitted in the case of a resume operation, 34262306a36Sopenharmony_ci where the bus bandwidth is known. 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci (1) Bus parameters such as bandwidth, frame shape, clock frequency, 34562306a36Sopenharmony_ci are computed based on current stream as well as already active 34662306a36Sopenharmony_ci stream(s) on Bus. Re-computation is required to accommodate current 34762306a36Sopenharmony_ci stream on the Bus. 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci (2) Transport and port parameters of all Master(s) and Slave(s) port(s) are 35062306a36Sopenharmony_ci computed for the current as well as already active stream based on frame 35162306a36Sopenharmony_ci shape and clock frequency computed in step 1. 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci (3) Computed Bus and transport parameters are programmed in Master(s) and 35462306a36Sopenharmony_ci Slave(s) registers. The banked registers programming is done on the 35562306a36Sopenharmony_ci alternate bank (bank currently unused). Port(s) are enabled for the 35662306a36Sopenharmony_ci already active stream(s) on the alternate bank (bank currently unused). 35762306a36Sopenharmony_ci This is done in order to not disrupt already active stream(s). 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci (4) Once all the values are programmed, Bus initiates switch to alternate 36062306a36Sopenharmony_ci bank where all new values programmed gets into effect. 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci (5) Ports of Master(s) and Slave(s) for current stream are prepared by 36362306a36Sopenharmony_ci programming PrepareCtrl register. 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 36662306a36Sopenharmony_ci``SDW_STREAM_PREPARED``. 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ciBus implements below API for PREPARE state which needs to be called 36962306a36Sopenharmony_cionce per stream. From ASoC DPCM framework, this stream state is linked 37062306a36Sopenharmony_cito .prepare() operation. Since the .trigger() operations may not 37162306a36Sopenharmony_cifollow the .prepare(), a direct transition from 37262306a36Sopenharmony_ci``SDW_STREAM_PREPARED`` to ``SDW_STREAM_DEPREPARED`` is allowed. 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci.. code-block:: c 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci int sdw_prepare_stream(struct sdw_stream_runtime * stream); 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ciSDW_STREAM_ENABLED 38062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~ 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ciEnable state of stream. The data port(s) are enabled upon entering this state. 38362306a36Sopenharmony_ciOperations performed before entering in this state: 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci (1) All the values computed in SDW_STREAM_PREPARED state are programmed 38662306a36Sopenharmony_ci in alternate bank (bank currently unused). It includes programming of 38762306a36Sopenharmony_ci already active stream(s) as well. 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci (2) All the Master(s) and Slave(s) port(s) for the current stream are 39062306a36Sopenharmony_ci enabled on alternate bank (bank currently unused) by programming 39162306a36Sopenharmony_ci ChannelEn register. 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci (3) Once all the values are programmed, Bus initiates switch to alternate 39462306a36Sopenharmony_ci bank where all new values programmed gets into effect and port(s) 39562306a36Sopenharmony_ci associated with current stream are enabled. 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 39862306a36Sopenharmony_ci``SDW_STREAM_ENABLED``. 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ciBus implements below API for ENABLE state which needs to be called once per 40162306a36Sopenharmony_cistream. From ASoC DPCM framework, this stream state is linked to 40262306a36Sopenharmony_ci.trigger() start operation. 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci.. code-block:: c 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci int sdw_enable_stream(struct sdw_stream_runtime * stream); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ciSDW_STREAM_DISABLED 40962306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~ 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ciDisable state of stream. The data port(s) are disabled upon exiting this state. 41262306a36Sopenharmony_ciOperations performed before entering in this state: 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci (1) All the Master(s) and Slave(s) port(s) for the current stream are 41562306a36Sopenharmony_ci disabled on alternate bank (bank currently unused) by programming 41662306a36Sopenharmony_ci ChannelEn register. 41762306a36Sopenharmony_ci 41862306a36Sopenharmony_ci (2) All the current configuration of Bus and active stream(s) are programmed 41962306a36Sopenharmony_ci into alternate bank (bank currently unused). 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci (3) Once all the values are programmed, Bus initiates switch to alternate 42262306a36Sopenharmony_ci bank where all new values programmed gets into effect and port(s) associated 42362306a36Sopenharmony_ci with current stream are disabled. 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 42662306a36Sopenharmony_ci``SDW_STREAM_DISABLED``. 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ciBus implements below API for DISABLED state which needs to be called once 42962306a36Sopenharmony_ciper stream. From ASoC DPCM framework, this stream state is linked to 43062306a36Sopenharmony_ci.trigger() stop operation. 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ciWhen the INFO_PAUSE flag is supported, a direct transition to 43362306a36Sopenharmony_ci``SDW_STREAM_ENABLED`` is allowed. 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ciFor resume operations where ASoC will use the .prepare() callback, the 43662306a36Sopenharmony_cistream can transition from ``SDW_STREAM_DISABLED`` to 43762306a36Sopenharmony_ci``SDW_STREAM_PREPARED``, with all required settings restored but 43862306a36Sopenharmony_ciwithout updating the bandwidth and bit allocation. 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci.. code-block:: c 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci int sdw_disable_stream(struct sdw_stream_runtime * stream); 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ciSDW_STREAM_DEPREPARED 44662306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~~~ 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ciDe-prepare state of stream. Operations performed before entering in this 44962306a36Sopenharmony_cistate: 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci (1) All the port(s) of Master(s) and Slave(s) for current stream are 45262306a36Sopenharmony_ci de-prepared by programming PrepareCtrl register. 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci (2) The payload bandwidth of current stream is reduced from the total 45562306a36Sopenharmony_ci bandwidth requirement of bus and new parameters calculated and 45662306a36Sopenharmony_ci applied by performing bank switch etc. 45762306a36Sopenharmony_ci 45862306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 45962306a36Sopenharmony_ci``SDW_STREAM_DEPREPARED``. 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ciBus implements below API for DEPREPARED state which needs to be called 46262306a36Sopenharmony_cionce per stream. ALSA/ASoC do not have a concept of 'deprepare', and 46362306a36Sopenharmony_cithe mapping from this stream state to ALSA/ASoC operation may be 46462306a36Sopenharmony_ciimplementation specific. 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ciWhen the INFO_PAUSE flag is supported, the stream state is linked to 46762306a36Sopenharmony_cithe .hw_free() operation - the stream is not deprepared on a 46862306a36Sopenharmony_ciTRIGGER_STOP. 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ciOther implementations may transition to the ``SDW_STREAM_DEPREPARED`` 47162306a36Sopenharmony_cistate on TRIGGER_STOP, should they require a transition through the 47262306a36Sopenharmony_ci``SDW_STREAM_PREPARED`` state. 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci.. code-block:: c 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci int sdw_deprepare_stream(struct sdw_stream_runtime * stream); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ciSDW_STREAM_RELEASED 48062306a36Sopenharmony_ci~~~~~~~~~~~~~~~~~~~ 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ciRelease state of stream. Operations performed before entering in this state: 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci (1) Release port resources for all Master(s) and Slave(s) port(s) 48562306a36Sopenharmony_ci associated with current stream. 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci (2) Release Master(s) and Slave(s) runtime resources associated with 48862306a36Sopenharmony_ci current stream. 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci (3) Release stream runtime resources associated with current stream. 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ciAfter all above operations are successful, stream state is set to 49362306a36Sopenharmony_ci``SDW_STREAM_RELEASED``. 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ciBus implements below APIs for RELEASE state which needs to be called by 49662306a36Sopenharmony_ciall the Master(s) and Slave(s) associated with stream. From ASoC DPCM 49762306a36Sopenharmony_ciframework, this stream state is linked to .hw_free() operation. 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci.. code-block:: c 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci int sdw_stream_remove_master(struct sdw_bus * bus, 50262306a36Sopenharmony_ci struct sdw_stream_runtime * stream); 50362306a36Sopenharmony_ci int sdw_stream_remove_slave(struct sdw_slave * slave, 50462306a36Sopenharmony_ci struct sdw_stream_runtime * stream); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ciThe .shutdown() ASoC DPCM operation calls below Bus API to release 50862306a36Sopenharmony_cistream assigned as part of ALLOCATED state. 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ciIn .shutdown() the data structure maintaining stream state are freed up. 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci.. code-block:: c 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci void sdw_release_stream(struct sdw_stream_runtime * stream); 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ciThe SoundWire core provides a sdw_shutdown_stream() helper function, 51762306a36Sopenharmony_citypically called during a dailink .shutdown() callback, which clears 51862306a36Sopenharmony_cithe stream pointer for all DAIS connected to a stream and releases the 51962306a36Sopenharmony_cimemory allocated for the stream. 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ciNot Supported 52262306a36Sopenharmony_ci============= 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci1. A single port with multiple channels supported cannot be used between two 52562306a36Sopenharmony_ci streams or across stream. For example a port with 4 channels cannot be used 52662306a36Sopenharmony_ci to handle 2 independent stereo streams even though it's possible in theory 52762306a36Sopenharmony_ci in SoundWire. 528