@@ -119,15 +119,12 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
119119 struct snd_pcm_substream * substream ,
120120 struct snd_pcm_hw_params * params )
121121{
122- struct snd_soc_pcm_runtime * rtd = asoc_substream_to_rtd (substream );
123- struct snd_pcm_runtime * runtime = substream -> runtime ;
124122 struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (component );
125- const struct sof_ipc_pcm_ops * pcm_ops = sdev -> ipc -> ops -> pcm ;
123+ struct snd_soc_pcm_runtime * rtd = asoc_substream_to_rtd ( substream ) ;
126124 struct snd_sof_platform_stream_params platform_params = { 0 };
127- struct sof_ipc_fw_version * v = & sdev -> fw_ready .version ;
125+ const struct sof_ipc_pcm_ops * pcm_ops = sdev -> ipc -> ops -> pcm ;
126+ struct snd_pcm_runtime * runtime = substream -> runtime ;
128127 struct snd_sof_pcm * spcm ;
129- struct sof_ipc_pcm_params pcm ;
130- struct sof_ipc_pcm_params_reply ipc_params_reply ;
131128 int ret ;
132129
133130 /* nothing to do for BE */
@@ -153,117 +150,40 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
153150 dev_dbg (component -> dev , "pcm: hw params stream %d dir %d\n" ,
154151 spcm -> pcm .pcm_id , substream -> stream );
155152
156- memset (& pcm , 0 , sizeof (pcm ));
153+ /* if this is a repeated hw_params without hw_free, skip setting up widgets */
154+ if (!spcm -> stream [substream -> stream ].list ) {
155+ ret = sof_pcm_setup_connected_widgets (sdev , rtd , spcm , substream -> stream );
156+ if (ret < 0 )
157+ return ret ;
158+ }
157159
158160 /* create compressed page table for audio firmware */
159161 if (runtime -> buffer_changed ) {
160162 ret = create_page_table (component , substream , runtime -> dma_area ,
161163 runtime -> dma_bytes );
164+
162165 if (ret < 0 )
163166 return ret ;
164167 }
165168
166- /* number of pages should be rounded up */
167- pcm .params .buffer .pages = PFN_UP (runtime -> dma_bytes );
168-
169- /* set IPC PCM parameters */
170- pcm .hdr .size = sizeof (pcm );
171- pcm .hdr .cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_PARAMS ;
172- pcm .comp_id = spcm -> stream [substream -> stream ].comp_id ;
173- pcm .params .hdr .size = sizeof (pcm .params );
174- pcm .params .buffer .phy_addr =
175- spcm -> stream [substream -> stream ].page_table .addr ;
176- pcm .params .buffer .size = runtime -> dma_bytes ;
177- pcm .params .direction = substream -> stream ;
178- pcm .params .sample_valid_bytes = params_width (params ) >> 3 ;
179- pcm .params .buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED ;
180- pcm .params .rate = params_rate (params );
181- pcm .params .channels = params_channels (params );
182- pcm .params .host_period_bytes = params_period_bytes (params );
183-
184- /* container size */
185- ret = snd_pcm_format_physical_width (params_format (params ));
186- if (ret < 0 )
187- return ret ;
188- pcm .params .sample_container_bytes = ret >> 3 ;
189-
190- /* format */
191- switch (params_format (params )) {
192- case SNDRV_PCM_FORMAT_S16 :
193- pcm .params .frame_fmt = SOF_IPC_FRAME_S16_LE ;
194- break ;
195- case SNDRV_PCM_FORMAT_S24 :
196- pcm .params .frame_fmt = SOF_IPC_FRAME_S24_4LE ;
197- break ;
198- case SNDRV_PCM_FORMAT_S32 :
199- pcm .params .frame_fmt = SOF_IPC_FRAME_S32_LE ;
200- break ;
201- case SNDRV_PCM_FORMAT_FLOAT :
202- pcm .params .frame_fmt = SOF_IPC_FRAME_FLOAT ;
203- break ;
204- default :
205- return - EINVAL ;
206- }
207-
208- /* firmware already configured host stream */
209- ret = snd_sof_pcm_platform_hw_params (sdev ,
210- substream ,
211- params ,
212- & platform_params );
169+ ret = snd_sof_pcm_platform_hw_params (sdev , substream , params , & platform_params );
213170 if (ret < 0 ) {
214- dev_err (component -> dev , "error: platform hw params failed\n" );
171+ dev_err (component -> dev , "platform hw params failed\n" );
215172 return ret ;
216173 }
217174
218- /* Update the IPC message with information from the platform */
219- pcm .params .stream_tag = platform_params .stream_tag ;
220-
221- if (platform_params .use_phy_address )
222- pcm .params .buffer .phy_addr = platform_params .phy_addr ;
223-
224- if (platform_params .no_ipc_position ) {
225- /* For older ABIs set host_period_bytes to zero to inform
226- * FW we don't want position updates. Newer versions use
227- * no_stream_position for this purpose.
228- */
229- if (v -> abi_version < SOF_ABI_VER (3 , 10 , 0 ))
230- pcm .params .host_period_bytes = 0 ;
231- else
232- pcm .params .no_stream_position = 1 ;
233- }
234-
235- dev_dbg (component -> dev , "stream_tag %d" , pcm .params .stream_tag );
236-
237- /* if this is a repeated hw_params without hw_free, skip setting up widgets */
238- if (!spcm -> stream [substream -> stream ].list ) {
239- ret = sof_pcm_setup_connected_widgets (sdev , rtd , spcm , substream -> stream );
175+ if (pcm_ops -> hw_params ) {
176+ ret = pcm_ops -> hw_params (component , substream , params , & platform_params );
240177 if (ret < 0 )
241178 return ret ;
242179 }
243180
244- /* send hw_params IPC to the DSP */
245- ret = sof_ipc_tx_message (sdev -> ipc , pcm .hdr .cmd , & pcm , sizeof (pcm ),
246- & ipc_params_reply , sizeof (ipc_params_reply ));
247- if (ret < 0 ) {
248- dev_err (component -> dev , "error: hw params ipc failed for stream %d\n" ,
249- pcm .params .stream_tag );
250- return ret ;
251- }
252-
253- ret = snd_sof_set_stream_data_offset (sdev , substream ,
254- ipc_params_reply .posn_offset );
255- if (ret < 0 ) {
256- dev_err (component -> dev , "%s: invalid stream data offset for PCM %d\n" ,
257- __func__ , spcm -> pcm .pcm_id );
258- return ret ;
259- }
260-
261181 spcm -> prepared [substream -> stream ] = true;
262182
263183 /* save pcm hw_params */
264184 memcpy (& spcm -> params [substream -> stream ], params , sizeof (* params ));
265185
266- return ret ;
186+ return 0 ;
267187}
268188
269189static int sof_pcm_hw_free (struct snd_soc_component * component ,
0 commit comments