Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: SOF: ipc4-topology: Rework the module audio

Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>:

When the audio started we print out here and there the Input and Output or only
the Input audio format for the module that is in path of the stream.
This is mostly OK but provides inconsistent an - in my opinion - hard to grasp
information.

The series reworks how the input/output format is selected and tries to improve
the consistency of the prints by applying universal rules:

- Module is not changing the format or it has only input or output and it has
single format on in and out side

Audio format for gain.1.1:

- Module is not changing the format or it has only input or output and it has
multiple formats on either in or out side

Audio format (in/out format index: 2/0) for host-copier.0.playback:

- Module is changing format then we print the input and output ones
- Input if it has single format

Input audio format for host-copier.0.capture:

- Input has multiple formats

Input audio format (format index: 0) for host-copier.0.playback:

Similar versions for the output format prints.

+248 -127
+248 -127
sound/soc/sof/ipc4-topology.c
··· 195 195 for (i = 0; i < num_formats; i++) { 196 196 struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt; 197 197 dev_dbg(dev, 198 - "Pin index #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", 198 + "Pin #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", 199 199 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, 200 200 SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg), 201 201 fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, 202 202 pin_fmt[i].buffer_size); 203 203 } 204 + } 205 + 206 + static void 207 + sof_ipc4_dbg_module_audio_format(struct device *dev, 208 + struct snd_sof_widget *swidget, 209 + struct sof_ipc4_available_audio_format *available_fmt, 210 + int in_fmt_index, int out_fmt_index) 211 + { 212 + struct sof_ipc4_audio_format *in_fmt, *out_fmt; 213 + u32 out_rate, out_channels, out_valid_bits; 214 + u32 in_rate, in_channels, in_valid_bits; 215 + struct sof_ipc4_pin_format *pin_fmt; 216 + 217 + if (!available_fmt->num_input_formats && 218 + !available_fmt->num_output_formats) 219 + return; 220 + 221 + /* Only input or output is supported by the module */ 222 + if (!available_fmt->num_input_formats) { 223 + if (available_fmt->num_output_formats == 1) 224 + dev_dbg(dev, "Output audio format for %s:\n", 225 + swidget->widget->name); 226 + else 227 + dev_dbg(dev, 228 + "Output audio format (format index: %d) for %s:\n", 229 + out_fmt_index, swidget->widget->name); 230 + 231 + pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; 232 + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 233 + 234 + return; 235 + } else if (!available_fmt->num_output_formats) { 236 + if (available_fmt->num_input_formats == 1) 237 + dev_dbg(dev, "Input audio format for %s:\n", 238 + swidget->widget->name); 239 + else 240 + dev_dbg(dev, 241 + "Input audio format (format index: %d) for %s:\n", 242 + out_fmt_index, swidget->widget->name); 243 + 244 + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 245 + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 246 + 247 + return; 248 + } 249 + 250 + in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt; 251 + out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt; 252 + 253 + in_rate = in_fmt->sampling_frequency; 254 + in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 255 + in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 256 + 257 + out_rate = out_fmt->sampling_frequency; 258 + out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); 259 + out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); 260 + 261 + if (!(in_valid_bits != out_valid_bits || in_rate != out_rate || 262 + in_channels != out_channels)) { 263 + /* There is no change in format */ 264 + if (available_fmt->num_input_formats == 1 && 265 + available_fmt->num_output_formats == 1) 266 + dev_dbg(dev, "Audio format for %s:\n", 267 + swidget->widget->name); 268 + else 269 + dev_dbg(dev, 270 + "Audio format (in/out format index: %d/%d) for %s:\n", 271 + in_fmt_index, out_fmt_index, swidget->widget->name); 272 + 273 + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 274 + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 275 + 276 + return; 277 + } 278 + 279 + /* The format is changed by the module */ 280 + if (available_fmt->num_input_formats == 1) 281 + dev_dbg(dev, "Input audio format for %s:\n", 282 + swidget->widget->name); 283 + else 284 + dev_dbg(dev, "Input audio format (format index: %d) for %s:\n", 285 + in_fmt_index, swidget->widget->name); 286 + 287 + pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 288 + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 289 + 290 + if (available_fmt->num_output_formats == 1) 291 + dev_dbg(dev, "Output audio format for %s:\n", 292 + swidget->widget->name); 293 + else 294 + dev_dbg(dev, "Output audio format (format index: %d) for %s:\n", 295 + out_fmt_index, swidget->widget->name); 296 + 297 + pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; 298 + sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 204 299 } 205 300 206 301 static const struct sof_ipc4_audio_format * ··· 1300 1205 } 1301 1206 1302 1207 static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, 1208 + struct snd_sof_widget *swidget, 1303 1209 struct sof_ipc4_base_module_cfg *base_config, 1304 1210 struct sof_ipc4_available_audio_format *available_fmt, 1305 1211 u32 out_ref_rate, u32 out_ref_channels, 1306 1212 u32 out_ref_valid_bits) 1307 1213 { 1308 - struct sof_ipc4_audio_format *out_fmt; 1214 + struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; 1215 + u32 pin_fmts_size = available_fmt->num_output_formats; 1309 1216 bool single_format; 1310 - int i; 1217 + int i = 0; 1311 1218 1312 - if (!available_fmt->num_output_formats) 1219 + if (!pin_fmts_size) { 1220 + dev_err(sdev->dev, "no output formats for %s\n", 1221 + swidget->widget->name); 1313 1222 return -EINVAL; 1223 + } 1314 1224 1315 - single_format = sof_ipc4_is_single_format(sdev, available_fmt->output_pin_fmts, 1316 - available_fmt->num_output_formats); 1225 + single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); 1317 1226 1318 1227 /* pick the first format if there's only one available or if all formats are the same */ 1319 - if (single_format) { 1320 - base_config->obs = available_fmt->output_pin_fmts[0].buffer_size; 1321 - return 0; 1322 - } 1228 + if (single_format) 1229 + goto out_fmt; 1323 1230 1324 1231 /* 1325 1232 * if there are multiple output formats, then choose the output format that matches 1326 1233 * the reference params 1327 1234 */ 1328 - for (i = 0; i < available_fmt->num_output_formats; i++) { 1235 + for (i = 0; i < pin_fmts_size; i++) { 1236 + struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt; 1237 + 1329 1238 u32 _out_rate, _out_channels, _out_valid_bits; 1330 1239 1331 - out_fmt = &available_fmt->output_pin_fmts[i].audio_fmt; 1332 - _out_rate = out_fmt->sampling_frequency; 1333 - _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); 1334 - _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); 1240 + _out_rate = fmt->sampling_frequency; 1241 + _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1242 + _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1335 1243 1336 1244 if (_out_rate == out_ref_rate && _out_channels == out_ref_channels && 1337 - _out_valid_bits == out_ref_valid_bits) { 1338 - base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; 1339 - return i; 1340 - } 1245 + _out_valid_bits == out_ref_valid_bits) 1246 + goto out_fmt; 1341 1247 } 1342 1248 1249 + dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", 1250 + __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels); 1251 + 1343 1252 return -EINVAL; 1253 + 1254 + out_fmt: 1255 + base_config->obs = pin_fmts[i].buffer_size; 1256 + 1257 + return i; 1344 1258 } 1345 1259 1346 1260 static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params) ··· 1382 1278 int sample_valid_bits; 1383 1279 int i = 0; 1384 1280 1385 - if (!available_fmt->num_input_formats) { 1281 + if (!pin_fmts_size) { 1386 1282 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); 1387 1283 return -EINVAL; 1388 1284 } 1389 1285 1390 - single_format = sof_ipc4_is_single_format(sdev, available_fmt->input_pin_fmts, 1391 - available_fmt->num_input_formats); 1286 + single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); 1392 1287 if (single_format) 1393 1288 goto in_fmt; 1394 1289 ··· 1409 1306 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1410 1307 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1411 1308 if (params_rate(params) == rate && params_channels(params) == channels && 1412 - sample_valid_bits == valid_bits) { 1413 - dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", 1414 - rate, valid_bits, channels, i); 1309 + sample_valid_bits == valid_bits) 1415 1310 break; 1416 - } 1417 1311 } 1418 1312 1419 1313 if (i == pin_fmts_size) { ··· 1421 1321 1422 1322 in_fmt: 1423 1323 /* copy input format */ 1424 - if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { 1425 - memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, 1426 - sizeof(struct sof_ipc4_audio_format)); 1324 + memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, 1325 + sizeof(struct sof_ipc4_audio_format)); 1427 1326 1428 - /* set base_cfg ibs/obs */ 1429 - base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; 1430 - 1431 - dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); 1432 - sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); 1433 - } 1327 + /* set base_cfg ibs/obs */ 1328 + base_config->ibs = pin_fmts[i].buffer_size; 1434 1329 1435 1330 return i; 1436 1331 } ··· 1801 1706 struct snd_soc_component *scomp = swidget->scomp; 1802 1707 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1803 1708 struct sof_ipc4_copier_data *copier_data; 1709 + int input_fmt_index, output_fmt_index; 1804 1710 struct snd_pcm_hw_params ref_params; 1805 1711 struct sof_ipc4_copier *ipc4_copier; 1806 1712 struct snd_sof_dai *dai; ··· 1813 1717 int ipc_size, ret, out_ref_valid_bits; 1814 1718 u32 out_ref_rate, out_ref_channels; 1815 1719 u32 deep_buffer_dma_ms = 0; 1816 - int output_fmt_index; 1817 1720 bool single_output_bitdepth; 1818 1721 int i; 1819 1722 ··· 1944 1849 } 1945 1850 1946 1851 /* set input and output audio formats */ 1947 - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &copier_data->base_config, 1948 - &ref_params, available_fmt); 1949 - if (ret < 0) 1950 - return ret; 1852 + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 1853 + &copier_data->base_config, 1854 + &ref_params, available_fmt); 1855 + if (input_fmt_index < 0) 1856 + return input_fmt_index; 1951 1857 1952 1858 /* set the reference params for output format selection */ 1953 1859 single_output_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, ··· 1961 1865 { 1962 1866 struct sof_ipc4_audio_format *in_fmt; 1963 1867 1964 - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; 1868 + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 1965 1869 out_ref_rate = in_fmt->sampling_frequency; 1966 1870 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 1967 1871 ··· 2000 1904 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); 2001 1905 } 2002 1906 2003 - dev_dbg(sdev->dev, "copier %s: reference output rate %d, channels %d valid_bits %d\n", 2004 - swidget->widget->name, out_ref_rate, out_ref_channels, out_ref_valid_bits); 2005 - 2006 - output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &copier_data->base_config, 1907 + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 1908 + &copier_data->base_config, 2007 1909 available_fmt, out_ref_rate, 2008 1910 out_ref_channels, out_ref_valid_bits); 2009 - if (output_fmt_index < 0) { 2010 - dev_err(sdev->dev, "Failed to initialize output format for %s", 2011 - swidget->widget->name); 1911 + if (output_fmt_index < 0) 2012 1912 return output_fmt_index; 2013 - } 2014 1913 2015 1914 /* 2016 1915 * Set the output format. Current topology defines pin 0 input and output formats in pairs. ··· 2017 1926 memcpy(&copier_data->out_format, 2018 1927 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, 2019 1928 sizeof(struct sof_ipc4_audio_format)); 2020 - dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); 2021 - sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[output_fmt_index], 1); 2022 1929 2023 1930 switch (swidget->id) { 2024 1931 case snd_soc_dapm_dai_in: ··· 2193 2104 2194 2105 *ipc_config_size = ipc_size; 2195 2106 2107 + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2108 + input_fmt_index, output_fmt_index); 2109 + 2196 2110 /* update pipeline memory usage */ 2197 2111 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); 2198 2112 ··· 2231 2139 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; 2232 2140 struct sof_ipc4_audio_format *in_fmt; 2233 2141 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2234 - int ret; 2142 + int input_fmt_index, output_fmt_index; 2235 2143 2236 - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &gain->data.base_config, 2237 - pipeline_params, available_fmt); 2238 - if (ret < 0) 2239 - return ret; 2144 + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2145 + &gain->data.base_config, 2146 + pipeline_params, 2147 + available_fmt); 2148 + if (input_fmt_index < 0) 2149 + return input_fmt_index; 2240 2150 2241 - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; 2151 + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2242 2152 out_ref_rate = in_fmt->sampling_frequency; 2243 2153 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2244 2154 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2245 2155 2246 - ret = sof_ipc4_init_output_audio_fmt(sdev, &gain->data.base_config, available_fmt, 2247 - out_ref_rate, out_ref_channels, out_ref_valid_bits); 2248 - if (ret < 0) { 2249 - dev_err(sdev->dev, "Failed to initialize output format for %s", 2250 - swidget->widget->name); 2251 - return ret; 2252 - } 2156 + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2157 + &gain->data.base_config, 2158 + available_fmt, 2159 + out_ref_rate, 2160 + out_ref_channels, 2161 + out_ref_valid_bits); 2162 + if (output_fmt_index < 0) 2163 + return output_fmt_index; 2164 + 2165 + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2166 + input_fmt_index, output_fmt_index); 2253 2167 2254 2168 /* update pipeline memory usage */ 2255 2169 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); ··· 2274 2176 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; 2275 2177 struct sof_ipc4_audio_format *in_fmt; 2276 2178 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2277 - int ret; 2179 + int input_fmt_index, output_fmt_index; 2278 2180 2279 - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &mixer->base_config, 2280 - pipeline_params, available_fmt); 2281 - if (ret < 0) 2282 - return ret; 2181 + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2182 + &mixer->base_config, 2183 + pipeline_params, 2184 + available_fmt); 2185 + if (input_fmt_index < 0) 2186 + return input_fmt_index; 2283 2187 2284 - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; 2188 + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2285 2189 out_ref_rate = in_fmt->sampling_frequency; 2286 2190 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2287 2191 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2288 2192 2289 - ret = sof_ipc4_init_output_audio_fmt(sdev, &mixer->base_config, available_fmt, 2290 - out_ref_rate, out_ref_channels, out_ref_valid_bits); 2291 - if (ret < 0) { 2292 - dev_err(sdev->dev, "Failed to initialize output format for %s", 2293 - swidget->widget->name); 2294 - return ret; 2295 - } 2193 + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2194 + &mixer->base_config, 2195 + available_fmt, 2196 + out_ref_rate, 2197 + out_ref_channels, 2198 + out_ref_valid_bits); 2199 + if (output_fmt_index < 0) 2200 + return output_fmt_index; 2201 + 2202 + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2203 + input_fmt_index, output_fmt_index); 2296 2204 2297 2205 /* update pipeline memory usage */ 2298 2206 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); ··· 2318 2214 struct sof_ipc4_audio_format *out_audio_fmt; 2319 2215 struct sof_ipc4_audio_format *in_audio_fmt; 2320 2216 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2321 - int output_format_index, input_format_index; 2217 + int output_fmt_index, input_fmt_index; 2322 2218 2323 - input_format_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, &src->data.base_config, 2324 - pipeline_params, available_fmt); 2325 - if (input_format_index < 0) 2326 - return input_format_index; 2219 + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2220 + &src->data.base_config, 2221 + pipeline_params, 2222 + available_fmt); 2223 + if (input_fmt_index < 0) 2224 + return input_fmt_index; 2327 2225 2328 2226 /* 2329 2227 * For playback, the SRC sink rate will be configured based on the requested output ··· 2341 2235 * SRC does not perform format conversion, so the output channels and valid bit depth must 2342 2236 * be the same as that of the input. 2343 2237 */ 2344 - in_audio_fmt = &available_fmt->input_pin_fmts[input_format_index].audio_fmt; 2238 + in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2345 2239 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); 2346 2240 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); 2347 2241 ··· 2352 2246 */ 2353 2247 out_ref_rate = params_rate(fe_params); 2354 2248 2355 - output_format_index = sof_ipc4_init_output_audio_fmt(sdev, &src->data.base_config, 2356 - available_fmt, out_ref_rate, 2357 - out_ref_channels, out_ref_valid_bits); 2358 - if (output_format_index < 0) { 2359 - dev_err(sdev->dev, "Failed to initialize output format for %s", 2360 - swidget->widget->name); 2361 - return output_format_index; 2362 - } 2249 + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2250 + &src->data.base_config, 2251 + available_fmt, 2252 + out_ref_rate, 2253 + out_ref_channels, 2254 + out_ref_valid_bits); 2255 + if (output_fmt_index < 0) 2256 + return output_fmt_index; 2257 + 2258 + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2259 + input_fmt_index, output_fmt_index); 2363 2260 2364 2261 /* update pipeline memory usage */ 2365 2262 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); 2366 2263 2367 - out_audio_fmt = &available_fmt->output_pin_fmts[output_format_index].audio_fmt; 2264 + out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt; 2368 2265 src->data.sink_rate = out_audio_fmt->sampling_frequency; 2369 2266 2370 2267 /* update pipeline_params for sink widgets */ ··· 2464 2355 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2465 2356 struct sof_ipc4_process *process = swidget->private; 2466 2357 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; 2467 - struct sof_ipc4_audio_format *in_fmt; 2468 - u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2469 2358 void *cfg = process->ipc_config_data; 2470 - int output_fmt_index; 2359 + int output_fmt_index = 0; 2360 + int input_fmt_index = 0; 2471 2361 int ret; 2472 2362 2473 - ret = sof_ipc4_init_input_audio_fmt(sdev, swidget, &process->base_config, 2474 - pipeline_params, available_fmt); 2475 - if (ret < 0) 2476 - return ret; 2363 + input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2364 + &process->base_config, 2365 + pipeline_params, 2366 + available_fmt); 2367 + if (input_fmt_index < 0) 2368 + return input_fmt_index; 2477 2369 2478 - in_fmt = &available_fmt->input_pin_fmts[ret].audio_fmt; 2479 - out_ref_rate = in_fmt->sampling_frequency; 2480 - out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2481 - out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2370 + /* Configure output audio format only if the module supports output */ 2371 + if (available_fmt->num_output_formats) { 2372 + struct sof_ipc4_audio_format *in_fmt; 2373 + struct sof_ipc4_pin_format *pin_fmt; 2374 + u32 out_ref_rate, out_ref_channels; 2375 + int out_ref_valid_bits; 2482 2376 2483 - output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, &process->base_config, 2484 - available_fmt, out_ref_rate, 2485 - out_ref_channels, out_ref_valid_bits); 2486 - if (output_fmt_index < 0 && available_fmt->num_output_formats) { 2487 - dev_err(sdev->dev, "Failed to initialize output format for %s", 2488 - swidget->widget->name); 2489 - return output_fmt_index; 2377 + in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2378 + 2379 + out_ref_rate = in_fmt->sampling_frequency; 2380 + out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2381 + out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2382 + 2383 + output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2384 + &process->base_config, 2385 + available_fmt, 2386 + out_ref_rate, 2387 + out_ref_channels, 2388 + out_ref_valid_bits); 2389 + if (output_fmt_index < 0) 2390 + return output_fmt_index; 2391 + 2392 + pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index]; 2393 + 2394 + /* copy Pin output format for Pin 0 only */ 2395 + if (pin_fmt->pin_index == 0) { 2396 + memcpy(&process->output_format, &pin_fmt->audio_fmt, 2397 + sizeof(struct sof_ipc4_audio_format)); 2398 + 2399 + /* modify the pipeline params with the output format */ 2400 + ret = sof_ipc4_update_hw_params(sdev, pipeline_params, 2401 + &process->output_format, 2402 + BIT(SNDRV_PCM_HW_PARAM_FORMAT) | 2403 + BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 2404 + BIT(SNDRV_PCM_HW_PARAM_RATE)); 2405 + if (ret) 2406 + return ret; 2407 + } 2490 2408 } 2491 2409 2492 - /* copy Pin 0 output format */ 2493 - if (available_fmt->num_output_formats && 2494 - output_fmt_index < available_fmt->num_output_formats && 2495 - !available_fmt->output_pin_fmts[output_fmt_index].pin_index) { 2496 - memcpy(&process->output_format, 2497 - &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, 2498 - sizeof(struct sof_ipc4_audio_format)); 2499 - 2500 - /* modify the pipeline params with the pin 0 output format */ 2501 - ret = sof_ipc4_update_hw_params(sdev, pipeline_params, 2502 - &process->output_format, 2503 - BIT(SNDRV_PCM_HW_PARAM_FORMAT) | 2504 - BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 2505 - BIT(SNDRV_PCM_HW_PARAM_RATE)); 2506 - if (ret) 2507 - return ret; 2508 - } 2410 + sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2411 + input_fmt_index, output_fmt_index); 2509 2412 2510 2413 /* update pipeline memory usage */ 2511 2414 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config);