@@ -2142,10 +2142,57 @@ static void sof_ipc4_host_config(struct snd_sof_dev *sdev, struct snd_sof_widget
21422142}
21432143
21442144static int
2145- sof_ipc4_prepare_copier_module (struct snd_sof_widget * swidget ,
2146- struct snd_pcm_hw_params * fe_params ,
2147- struct snd_sof_platform_stream_params * platform_params ,
2148- struct snd_pcm_hw_params * pipeline_params , int dir )
2145+ sof_ipc4_copier_module_update_params (struct snd_sof_widget * swidget ,
2146+ struct snd_pcm_hw_params * pipeline_params )
2147+ {
2148+ struct snd_soc_component * scomp = swidget -> scomp ;
2149+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (scomp );
2150+ struct sof_ipc4_copier_data * copier_data ;
2151+ struct sof_ipc4_copier * ipc4_copier ;
2152+
2153+ switch (swidget -> id ) {
2154+ case snd_soc_dapm_aif_in :
2155+ case snd_soc_dapm_aif_out :
2156+ case snd_soc_dapm_buffer :
2157+ ipc4_copier = swidget -> private ;
2158+ copier_data = & ipc4_copier -> data ;
2159+ break ;
2160+ case snd_soc_dapm_dai_in :
2161+ case snd_soc_dapm_dai_out :
2162+ {
2163+ struct snd_sof_widget * pipe_widget = swidget -> spipe -> pipe_widget ;
2164+ struct sof_ipc4_pipeline * pipeline = pipe_widget -> private ;
2165+ struct snd_sof_dai * dai ;
2166+
2167+ if (pipeline -> use_chain_dma )
2168+ return 0 ;
2169+
2170+ dai = swidget -> private ;
2171+
2172+ ipc4_copier = (struct sof_ipc4_copier * )dai -> private ;
2173+ copier_data = & ipc4_copier -> data ;
2174+
2175+ break ;
2176+ }
2177+ default :
2178+ dev_err (sdev -> dev , "unsupported type %d for copier %s" ,
2179+ swidget -> id , swidget -> widget -> name );
2180+ return - EINVAL ;
2181+ }
2182+
2183+ /* modify the input params for the next widget */
2184+ return sof_ipc4_update_hw_params (sdev , pipeline_params ,
2185+ & copier_data -> out_format ,
2186+ BIT (SNDRV_PCM_HW_PARAM_FORMAT ) |
2187+ BIT (SNDRV_PCM_HW_PARAM_CHANNELS ) |
2188+ BIT (SNDRV_PCM_HW_PARAM_RATE ));
2189+ }
2190+
2191+ static int
2192+ _sof_ipc4_prepare_copier_module (struct snd_sof_widget * swidget ,
2193+ struct snd_pcm_hw_params * fe_params ,
2194+ struct snd_sof_platform_stream_params * platform_params ,
2195+ struct snd_pcm_hw_params * pipeline_params , int dir )
21492196{
21502197 struct sof_ipc4_available_audio_format * available_fmt ;
21512198 struct snd_soc_component * scomp = swidget -> scomp ;
@@ -2617,6 +2664,21 @@ sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget,
26172664 return 0 ;
26182665}
26192666
2667+ static int
2668+ sof_ipc4_prepare_copier_module (struct snd_sof_widget * swidget ,
2669+ struct snd_pcm_hw_params * fe_params ,
2670+ struct snd_sof_platform_stream_params * platform_params ,
2671+ struct snd_pcm_hw_params * pipeline_params , int dir )
2672+ {
2673+ if (swidget -> prepared )
2674+ return sof_ipc4_copier_module_update_params (swidget ,
2675+ pipeline_params );
2676+
2677+ return _sof_ipc4_prepare_copier_module (swidget , fe_params ,
2678+ platform_params , pipeline_params ,
2679+ dir );
2680+ }
2681+
26202682static int sof_ipc4_prepare_gain_module (struct snd_sof_widget * swidget ,
26212683 struct snd_pcm_hw_params * fe_params ,
26222684 struct snd_sof_platform_stream_params * platform_params ,
@@ -2630,6 +2692,10 @@ static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget,
26302692 u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
26312693 int input_fmt_index , output_fmt_index ;
26322694
2695+ /* This cannot happen */
2696+ if (unlikely (swidget -> prepared ))
2697+ return 0 ;
2698+
26332699 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
26342700 & gain -> data .base_config ,
26352701 pipeline_params ,
@@ -2675,6 +2741,10 @@ static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget,
26752741 u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
26762742 int input_fmt_index , output_fmt_index ;
26772743
2744+ /* Already prepared, nothing to do */
2745+ if (swidget -> prepared )
2746+ return 0 ;
2747+
26782748 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
26792749 & mixer -> base_config ,
26802750 pipeline_params ,
@@ -2721,6 +2791,10 @@ static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget,
27212791 u32 out_ref_rate , out_ref_channels , out_ref_valid_bits , out_ref_type ;
27222792 int output_fmt_index , input_fmt_index ;
27232793
2794+ /* This cannot happen */
2795+ if (unlikely (swidget -> prepared ))
2796+ return 0 ;
2797+
27242798 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
27252799 & src -> data .base_config ,
27262800 pipeline_params ,
@@ -2887,6 +2961,18 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
28872961 int ret ;
28882962
28892963 if (available_fmt -> num_input_formats ) {
2964+ if (swidget -> prepared ) {
2965+ if (!available_fmt -> num_output_formats )
2966+ return 0 ;
2967+
2968+ /* modify the pipeline params with the output format */
2969+ return sof_ipc4_update_hw_params (sdev , pipeline_params ,
2970+ & process -> output_format ,
2971+ BIT (SNDRV_PCM_HW_PARAM_FORMAT ) |
2972+ BIT (SNDRV_PCM_HW_PARAM_CHANNELS ) |
2973+ BIT (SNDRV_PCM_HW_PARAM_RATE ));
2974+ }
2975+
28902976 input_fmt_index = sof_ipc4_init_input_audio_fmt (sdev , swidget ,
28912977 & process -> base_config ,
28922978 pipeline_params ,
0 commit comments