@@ -987,6 +987,48 @@ static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev,
987987 return 0 ;
988988}
989989
990+ /* update hw_params based on the audio stream format */
991+ static int sof_ipc4_update_hw_params (struct snd_sof_dev * sdev , struct snd_pcm_hw_params * params ,
992+ struct sof_ipc4_audio_format * fmt )
993+ {
994+ snd_pcm_format_t snd_fmt ;
995+ struct snd_interval * i ;
996+ struct snd_mask * m ;
997+ int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH (fmt -> fmt_cfg );
998+ unsigned int channels , rate ;
999+
1000+ switch (valid_bits ) {
1001+ case 16 :
1002+ snd_fmt = SNDRV_PCM_FORMAT_S16_LE ;
1003+ break ;
1004+ case 24 :
1005+ snd_fmt = SNDRV_PCM_FORMAT_S24_LE ;
1006+ break ;
1007+ case 32 :
1008+ snd_fmt = SNDRV_PCM_FORMAT_S32_LE ;
1009+ break ;
1010+ default :
1011+ dev_err (sdev -> dev , "invalid PCM valid_bits %d\n" , valid_bits );
1012+ return - EINVAL ;
1013+ }
1014+
1015+ m = hw_param_mask (params , SNDRV_PCM_HW_PARAM_FORMAT );
1016+ snd_mask_none (m );
1017+ snd_mask_set_format (m , snd_fmt );
1018+
1019+ rate = fmt -> sampling_frequency ;
1020+ i = hw_param_interval (params , SNDRV_PCM_HW_PARAM_RATE );
1021+ i -> min = rate ;
1022+ i -> max = rate ;
1023+
1024+ channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT (fmt -> fmt_cfg );
1025+ i = hw_param_interval (params , SNDRV_PCM_HW_PARAM_CHANNELS );
1026+ i -> min = channels ;
1027+ i -> max = channels ;
1028+
1029+ return 0 ;
1030+ }
1031+
9901032static int sof_ipc4_init_audio_fmt (struct snd_sof_dev * sdev ,
9911033 struct snd_sof_widget * swidget ,
9921034 struct sof_ipc4_base_module_cfg * base_config ,
@@ -1743,10 +1785,16 @@ static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget,
17431785
17441786 /* copy Pin 0 output format */
17451787 if (available_fmt -> num_output_formats && ret < available_fmt -> num_output_formats &&
1746- !available_fmt -> output_pin_fmts [ret ].pin_index )
1788+ !available_fmt -> output_pin_fmts [ret ].pin_index ) {
17471789 memcpy (& process -> output_format , & available_fmt -> output_pin_fmts [ret ].audio_fmt ,
17481790 sizeof (struct sof_ipc4_audio_format ));
17491791
1792+ /* modify the pipeline params with the pin 0 output format */
1793+ ret = sof_ipc4_update_hw_params (sdev , pipeline_params , & process -> output_format );
1794+ if (ret )
1795+ return ret ;
1796+ }
1797+
17501798 /* update pipeline memory usage */
17511799 sof_ipc4_update_pipeline_mem_usage (sdev , swidget , & process -> base_config );
17521800
0 commit comments