@@ -106,9 +106,9 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run
106106
107107 spcm -> stream [dir ].list = list ;
108108
109- ret = sof_widget_list_setup (sdev , spcm , params , platform_params , dir );
109+ ret = sof_widget_list_prepare (sdev , spcm , params , platform_params , dir );
110110 if (ret < 0 ) {
111- spcm_err (spcm , dir , "Widget list set up failed\n" );
111+ spcm_err (spcm , dir , "widget list prepare failed\n" );
112112 spcm -> stream [dir ].list = NULL ;
113113 snd_soc_dapm_dai_free_widgets (& list );
114114 return ret ;
@@ -118,15 +118,30 @@ sof_pcm_setup_connected_widgets(struct snd_sof_dev *sdev, struct snd_soc_pcm_run
118118 return 0 ;
119119}
120120
121+ static struct snd_sof_widget * snd_sof_find_swidget_by_comp_id (struct snd_sof_dev * sdev ,
122+ int comp_id )
123+ {
124+ struct snd_sof_widget * swidget ;
125+
126+ list_for_each_entry (swidget , & sdev -> widget_list , list ) {
127+ if (comp_id == swidget -> comp_id )
128+ return swidget ;
129+ }
130+
131+ return NULL ;
132+ }
133+
121134static int sof_pcm_hw_params (struct snd_soc_component * component ,
122135 struct snd_pcm_substream * substream ,
123136 struct snd_pcm_hw_params * params )
124137{
125138 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (component );
126139 struct snd_soc_pcm_runtime * rtd = snd_soc_substream_to_rtd (substream );
140+ const struct sof_ipc_tplg_ops * tplg_ops = sof_ipc_get_ops (sdev , tplg );
127141 const struct sof_ipc_pcm_ops * pcm_ops = sof_ipc_get_ops (sdev , pcm );
128- struct snd_sof_platform_stream_params platform_params = { 0 } ;
142+ struct snd_sof_platform_stream_params * platform_params ;
129143 struct snd_pcm_runtime * runtime = substream -> runtime ;
144+ struct snd_sof_widget * host_widget ;
130145 struct snd_sof_pcm * spcm ;
131146 int ret ;
132147
@@ -152,20 +167,36 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
152167 spcm -> prepared [substream -> stream ] = false;
153168 }
154169
155- ret = snd_sof_pcm_platform_hw_params (sdev , substream , params , & platform_params );
170+ platform_params = & spcm -> platform_params [substream -> stream ];
171+ ret = snd_sof_pcm_platform_hw_params (sdev , substream , params , platform_params );
156172 if (ret < 0 ) {
157173 spcm_err (spcm , substream -> stream , "platform hw params failed\n" );
158174 return ret ;
159175 }
160176
161177 /* if this is a repeated hw_params without hw_free, skip setting up widgets */
162178 if (!spcm -> stream [substream -> stream ].list ) {
163- ret = sof_pcm_setup_connected_widgets (sdev , rtd , spcm , params , & platform_params ,
179+ ret = sof_pcm_setup_connected_widgets (sdev , rtd , spcm , params , platform_params ,
164180 substream -> stream );
165181 if (ret < 0 )
166182 return ret ;
167183 }
168184
185+ if (!sdev -> dspless_mode_selected ) {
186+ int host_comp_id = spcm -> stream [substream -> stream ].comp_id ;
187+
188+ host_widget = snd_sof_find_swidget_by_comp_id (sdev , host_comp_id );
189+ if (!host_widget ) {
190+ spcm_err (spcm , substream -> stream ,
191+ "failed to find host widget with comp_id %d\n" , host_comp_id );
192+ return - EINVAL ;
193+ }
194+
195+ /* set the host DMA ID */
196+ if (tplg_ops && tplg_ops -> host_config )
197+ tplg_ops -> host_config (sdev , host_widget , platform_params );
198+ }
199+
169200 /* create compressed page table for audio firmware */
170201 if (runtime -> buffer_changed ) {
171202 ret = create_page_table (component , substream , runtime -> dma_area ,
@@ -175,14 +206,6 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
175206 return ret ;
176207 }
177208
178- if (pcm_ops && pcm_ops -> hw_params ) {
179- ret = pcm_ops -> hw_params (component , substream , params , & platform_params );
180- if (ret < 0 )
181- return ret ;
182- }
183-
184- spcm -> prepared [substream -> stream ] = true;
185-
186209 /* save pcm hw_params */
187210 memcpy (& spcm -> params [substream -> stream ], params , sizeof (* params ));
188211
@@ -287,6 +310,9 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
287310
288311 ret = sof_pcm_stream_free (sdev , substream , spcm , substream -> stream , true);
289312
313+ /* unprepare and free the list of DAPM widgets */
314+ sof_widget_list_unprepare (sdev , spcm , substream -> stream );
315+
290316 cancel_work_sync (& spcm -> stream [substream -> stream ].period_elapsed_work );
291317
292318 return ret ;
@@ -297,7 +323,12 @@ static int sof_pcm_prepare(struct snd_soc_component *component,
297323{
298324 struct snd_soc_pcm_runtime * rtd = snd_soc_substream_to_rtd (substream );
299325 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (component );
326+ const struct sof_ipc_pcm_ops * pcm_ops = sof_ipc_get_ops (sdev , pcm );
327+ struct snd_sof_platform_stream_params * platform_params ;
328+ struct snd_soc_dapm_widget_list * list ;
329+ struct snd_pcm_hw_params * params ;
300330 struct snd_sof_pcm * spcm ;
331+ int dir = substream -> stream ;
301332 int ret ;
302333
303334 /* nothing to do for BE */
@@ -323,15 +354,33 @@ static int sof_pcm_prepare(struct snd_soc_component *component,
323354 return ret ;
324355 }
325356
326- /* set hw_params */
327- ret = sof_pcm_hw_params (component ,
328- substream , & spcm -> params [substream -> stream ]);
357+ ret = sof_pcm_hw_params (component , substream , & spcm -> params [substream -> stream ]);
329358 if (ret < 0 ) {
330359 spcm_err (spcm , substream -> stream ,
331360 "failed to set hw_params after resume\n" );
332361 return ret ;
333362 }
334363
364+ list = spcm -> stream [dir ].list ;
365+ params = & spcm -> params [substream -> stream ];
366+ platform_params = & spcm -> platform_params [substream -> stream ];
367+ ret = sof_widget_list_setup (sdev , spcm , params , platform_params , dir );
368+ if (ret < 0 ) {
369+ dev_err (sdev -> dev , "failed widget list set up for pcm %d dir %d\n" ,
370+ spcm -> pcm .pcm_id , dir );
371+ spcm -> stream [dir ].list = NULL ;
372+ snd_soc_dapm_dai_free_widgets (& list );
373+ return ret ;
374+ }
375+
376+ if (pcm_ops && pcm_ops -> hw_params ) {
377+ ret = pcm_ops -> hw_params (component , substream , params , platform_params );
378+ if (ret < 0 )
379+ return ret ;
380+ }
381+
382+ spcm -> prepared [substream -> stream ] = true;
383+
335384 return 0 ;
336385}
337386
0 commit comments