1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2022 Intel Corporation 7 // 8 // 9 #include <linux/bitfield.h> 10 #include <linux/cleanup.h> 11 #include <uapi/sound/sof/tokens.h> 12 #include <sound/pcm_params.h> 13 #include <sound/sof/ext_manifest4.h> 14 #include <sound/intel-nhlt.h> 15 #include "sof-priv.h" 16 #include "sof-audio.h" 17 #include "ipc4-priv.h" 18 #include "ipc4-topology.h" 19 #include "ops.h" 20 21 /* 22 * The ignore_cpc flag can be used to ignore the CPC value for all modules by 23 * using 0 instead. 24 * The CPC is sent to the firmware along with the SOF_IPC4_MOD_INIT_INSTANCE 25 * message and it is used for clock scaling. 26 * 0 as CPC value will instruct the firmware to use maximum frequency, thus 27 * deactivating the clock scaling. 28 */ 29 static bool ignore_cpc; 30 module_param_named(ipc4_ignore_cpc, ignore_cpc, bool, 0444); 31 MODULE_PARM_DESC(ipc4_ignore_cpc, 32 "Ignore CPC values. This option will disable clock scaling in firmware."); 33 34 #define SOF_IPC4_GAIN_PARAM_ID 0 35 #define SOF_IPC4_TPLG_ABI_SIZE 6 36 #define SOF_IPC4_CHAIN_DMA_BUF_SIZE_MS 2 37 38 static DEFINE_IDA(alh_group_ida); 39 static DEFINE_IDA(pipeline_ida); 40 41 static const struct sof_topology_token ipc4_sched_tokens[] = { 42 {SOF_TKN_SCHED_LP_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 43 offsetof(struct sof_ipc4_pipeline, lp_mode)}, 44 {SOF_TKN_SCHED_USE_CHAIN_DMA, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, 45 offsetof(struct sof_ipc4_pipeline, use_chain_dma)}, 46 {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 47 offsetof(struct sof_ipc4_pipeline, core_id)}, 48 {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 49 offsetof(struct sof_ipc4_pipeline, priority)}, 50 }; 51 52 static const struct sof_topology_token pipeline_tokens[] = { 53 {SOF_TKN_SCHED_DYNAMIC_PIPELINE, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u16, 54 offsetof(struct snd_sof_widget, dynamic_pipeline_widget)}, 55 }; 56 57 static const struct sof_topology_token ipc4_comp_tokens[] = { 58 {SOF_TKN_COMP_IS_PAGES, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 59 offsetof(struct sof_ipc4_base_module_cfg, is_pages)}, 60 }; 61 62 static const struct sof_topology_token ipc4_in_audio_format_tokens[] = { 63 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 64 offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)}, 65 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 66 offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)}, 67 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 68 offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)}, 69 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 70 offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)}, 71 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 72 get_token_u32, offsetof(struct sof_ipc4_pin_format, 73 audio_fmt.interleaving_style)}, 74 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 75 offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)}, 76 {SOF_TKN_CAVS_AUDIO_FORMAT_INPUT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 77 offsetof(struct sof_ipc4_pin_format, pin_index)}, 78 {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 79 offsetof(struct sof_ipc4_pin_format, buffer_size)}, 80 }; 81 82 static const struct sof_topology_token ipc4_out_audio_format_tokens[] = { 83 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 84 offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)}, 85 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 86 offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)}, 87 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 88 offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)}, 89 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 90 offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)}, 91 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 92 get_token_u32, offsetof(struct sof_ipc4_pin_format, 93 audio_fmt.interleaving_style)}, 94 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 95 offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)}, 96 {SOF_TKN_CAVS_AUDIO_FORMAT_OUTPUT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 97 offsetof(struct sof_ipc4_pin_format, pin_index)}, 98 {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 99 offsetof(struct sof_ipc4_pin_format, buffer_size)}, 100 }; 101 102 static const struct sof_topology_token ipc4_copier_deep_buffer_tokens[] = { 103 {SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, 104 }; 105 106 static const struct sof_topology_token ipc4_copier_tokens[] = { 107 {SOF_TKN_INTEL_COPIER_NODE_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, 108 }; 109 110 static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = { 111 {SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 112 offsetof(struct sof_ipc4_available_audio_format, num_input_formats)}, 113 {SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 114 offsetof(struct sof_ipc4_available_audio_format, num_output_formats)}, 115 }; 116 117 static const struct sof_topology_token dai_tokens[] = { 118 {SOF_TKN_DAI_TYPE, SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_dai_type, 119 offsetof(struct sof_ipc4_copier, dai_type)}, 120 {SOF_TKN_DAI_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 121 offsetof(struct sof_ipc4_copier, dai_index)}, 122 }; 123 124 /* Component extended tokens */ 125 static const struct sof_topology_token comp_ext_tokens[] = { 126 {SOF_TKN_COMP_UUID, SND_SOC_TPLG_TUPLE_TYPE_UUID, get_token_uuid, 127 offsetof(struct snd_sof_widget, uuid)}, 128 {SOF_TKN_COMP_CORE_ID, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 129 offsetof(struct snd_sof_widget, core)}, 130 }; 131 132 static const struct sof_topology_token gain_tokens[] = { 133 {SOF_TKN_GAIN_RAMP_TYPE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 134 get_token_u32, offsetof(struct sof_ipc4_gain_params, curve_type)}, 135 {SOF_TKN_GAIN_RAMP_DURATION, 136 SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 137 offsetof(struct sof_ipc4_gain_params, curve_duration_l)}, 138 {SOF_TKN_GAIN_VAL, SND_SOC_TPLG_TUPLE_TYPE_WORD, 139 get_token_u32, offsetof(struct sof_ipc4_gain_params, init_val)}, 140 }; 141 142 /* SRC */ 143 static const struct sof_topology_token src_tokens[] = { 144 {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 145 offsetof(struct sof_ipc4_src_data, sink_rate)}, 146 }; 147 148 /* ASRC */ 149 static const struct sof_topology_token asrc_tokens[] = { 150 {SOF_TKN_ASRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 151 offsetof(struct sof_ipc4_asrc_data, out_freq)}, 152 {SOF_TKN_ASRC_OPERATION_MODE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 153 offsetof(struct sof_ipc4_asrc_data, asrc_mode)}, 154 }; 155 156 static const struct sof_token_info ipc4_token_list[SOF_TOKEN_COUNT] = { 157 [SOF_DAI_TOKENS] = {"DAI tokens", dai_tokens, ARRAY_SIZE(dai_tokens)}, 158 [SOF_PIPELINE_TOKENS] = {"Pipeline tokens", pipeline_tokens, ARRAY_SIZE(pipeline_tokens)}, 159 [SOF_SCHED_TOKENS] = {"Scheduler tokens", ipc4_sched_tokens, 160 ARRAY_SIZE(ipc4_sched_tokens)}, 161 [SOF_COMP_EXT_TOKENS] = {"Comp extended tokens", comp_ext_tokens, 162 ARRAY_SIZE(comp_ext_tokens)}, 163 [SOF_COMP_TOKENS] = {"IPC4 Component tokens", 164 ipc4_comp_tokens, ARRAY_SIZE(ipc4_comp_tokens)}, 165 [SOF_IN_AUDIO_FORMAT_TOKENS] = {"IPC4 Input Audio format tokens", 166 ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)}, 167 [SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens", 168 ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)}, 169 [SOF_COPIER_DEEP_BUFFER_TOKENS] = {"IPC4 Copier deep buffer tokens", 170 ipc4_copier_deep_buffer_tokens, ARRAY_SIZE(ipc4_copier_deep_buffer_tokens)}, 171 [SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens, 172 ARRAY_SIZE(ipc4_copier_tokens)}, 173 [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens", 174 ipc4_audio_fmt_num_tokens, ARRAY_SIZE(ipc4_audio_fmt_num_tokens)}, 175 [SOF_GAIN_TOKENS] = {"Gain tokens", gain_tokens, ARRAY_SIZE(gain_tokens)}, 176 [SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)}, 177 [SOF_ASRC_TOKENS] = {"ASRC tokens", asrc_tokens, ARRAY_SIZE(asrc_tokens)}, 178 }; 179 180 struct snd_sof_widget *sof_ipc4_find_swidget_by_ids(struct snd_sof_dev *sdev, 181 u32 module_id, int instance_id) 182 { 183 struct snd_sof_widget *swidget; 184 185 list_for_each_entry(swidget, &sdev->widget_list, list) { 186 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 187 188 /* Only active module instances have valid instance_id */ 189 if (!swidget->use_count) 190 continue; 191 192 if (fw_module && fw_module->man4_module_entry.id == module_id && 193 swidget->instance_id == instance_id) 194 return swidget; 195 } 196 197 return NULL; 198 } 199 200 static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_format *pin_fmt, 201 int num_formats) 202 { 203 int i; 204 205 for (i = 0; i < num_formats; i++) { 206 struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt; 207 dev_dbg(dev, 208 "Pin #%d: %uHz, %ubit, %luch (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", 209 pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, 210 SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg), 211 fmt->ch_map, fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, 212 pin_fmt[i].buffer_size); 213 } 214 } 215 216 static void 217 sof_ipc4_dbg_module_audio_format(struct device *dev, 218 struct snd_sof_widget *swidget, 219 struct sof_ipc4_available_audio_format *available_fmt, 220 int in_fmt_index, int out_fmt_index) 221 { 222 struct sof_ipc4_audio_format *in_fmt, *out_fmt; 223 u32 out_rate, out_channels, out_valid_bits; 224 u32 in_rate, in_channels, in_valid_bits; 225 struct sof_ipc4_pin_format *pin_fmt; 226 227 if (!available_fmt->num_input_formats && 228 !available_fmt->num_output_formats) 229 return; 230 231 /* Only input or output is supported by the module */ 232 if (!available_fmt->num_input_formats) { 233 if (available_fmt->num_output_formats == 1) 234 dev_dbg(dev, "Output audio format for %s:\n", 235 swidget->widget->name); 236 else 237 dev_dbg(dev, 238 "Output audio format (format index: %d) for %s:\n", 239 out_fmt_index, swidget->widget->name); 240 241 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; 242 sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 243 244 return; 245 } else if (!available_fmt->num_output_formats) { 246 if (available_fmt->num_input_formats == 1) 247 dev_dbg(dev, "Input audio format for %s:\n", 248 swidget->widget->name); 249 else 250 dev_dbg(dev, 251 "Input audio format (format index: %d) for %s:\n", 252 out_fmt_index, swidget->widget->name); 253 254 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 255 sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 256 257 return; 258 } 259 260 in_fmt = &available_fmt->input_pin_fmts[in_fmt_index].audio_fmt; 261 out_fmt = &available_fmt->output_pin_fmts[out_fmt_index].audio_fmt; 262 263 in_rate = in_fmt->sampling_frequency; 264 in_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 265 in_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 266 267 out_rate = out_fmt->sampling_frequency; 268 out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(out_fmt->fmt_cfg); 269 out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); 270 271 if (!(in_valid_bits != out_valid_bits || in_rate != out_rate || 272 in_channels != out_channels)) { 273 /* There is no change in format */ 274 if (available_fmt->num_input_formats == 1 && 275 available_fmt->num_output_formats == 1) 276 dev_dbg(dev, "Audio format for %s:\n", 277 swidget->widget->name); 278 else 279 dev_dbg(dev, 280 "Audio format (in/out format index: %d/%d) for %s:\n", 281 in_fmt_index, out_fmt_index, swidget->widget->name); 282 283 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 284 sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 285 286 return; 287 } 288 289 /* The format is changed by the module */ 290 if (available_fmt->num_input_formats == 1) 291 dev_dbg(dev, "Input audio format for %s:\n", 292 swidget->widget->name); 293 else 294 dev_dbg(dev, "Input audio format (format index: %d) for %s:\n", 295 in_fmt_index, swidget->widget->name); 296 297 pin_fmt = &available_fmt->input_pin_fmts[in_fmt_index]; 298 sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 299 300 if (available_fmt->num_output_formats == 1) 301 dev_dbg(dev, "Output audio format for %s:\n", 302 swidget->widget->name); 303 else 304 dev_dbg(dev, "Output audio format (format index: %d) for %s:\n", 305 out_fmt_index, swidget->widget->name); 306 307 pin_fmt = &available_fmt->output_pin_fmts[out_fmt_index]; 308 sof_ipc4_dbg_audio_format(dev, pin_fmt, 1); 309 } 310 311 static const struct sof_ipc4_audio_format * 312 sof_ipc4_get_input_pin_audio_fmt(struct snd_sof_widget *swidget, int pin_index) 313 { 314 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext; 315 struct sof_ipc4_process *process; 316 int i; 317 318 if (swidget->id != snd_soc_dapm_effect) { 319 struct sof_ipc4_base_module_cfg *base = swidget->private; 320 321 /* For non-process modules, base module config format is used for all input pins */ 322 return &base->audio_fmt; 323 } 324 325 process = swidget->private; 326 327 /* 328 * For process modules without base config extension, base module config 329 * format is used for all input pins 330 */ 331 if (process->init_config != SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) 332 return &process->base_config.audio_fmt; 333 334 base_cfg_ext = process->base_config_ext; 335 336 /* 337 * If there are multiple input formats available for a pin, the first available format 338 * is chosen. 339 */ 340 for (i = 0; i < base_cfg_ext->num_input_pin_fmts; i++) { 341 struct sof_ipc4_pin_format *pin_format = &base_cfg_ext->pin_formats[i]; 342 343 if (pin_format->pin_index == pin_index) 344 return &pin_format->audio_fmt; 345 } 346 347 return NULL; 348 } 349 350 /** 351 * sof_ipc4_get_audio_fmt - get available audio formats from swidget->tuples 352 * @scomp: pointer to pointer to SOC component 353 * @swidget: pointer to struct snd_sof_widget containing tuples 354 * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in 355 * @module_base_cfg: Pointer to the base_config in the module init IPC payload 356 * 357 * Return: 0 if successful 358 */ 359 static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, 360 struct snd_sof_widget *swidget, 361 struct sof_ipc4_available_audio_format *available_fmt, 362 struct sof_ipc4_base_module_cfg *module_base_cfg) 363 { 364 struct sof_ipc4_pin_format *in_format = NULL; 365 struct sof_ipc4_pin_format *out_format; 366 int ret; 367 368 ret = sof_update_ipc_object(scomp, available_fmt, 369 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, 370 swidget->num_tuples, sizeof(*available_fmt), 1); 371 if (ret) { 372 dev_err(scomp->dev, "Failed to parse audio format token count\n"); 373 return ret; 374 } 375 376 if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { 377 dev_err(scomp->dev, "No input/output pin formats set in topology\n"); 378 return -EINVAL; 379 } 380 381 dev_dbg(scomp->dev, 382 "Number of input audio formats: %d. Number of output audio formats: %d\n", 383 available_fmt->num_input_formats, available_fmt->num_output_formats); 384 385 /* set is_pages in the module's base_config */ 386 ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, 387 swidget->num_tuples, sizeof(*module_base_cfg), 1); 388 if (ret) { 389 dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", 390 swidget->widget->name, ret); 391 return ret; 392 } 393 394 dev_dbg(scomp->dev, "widget %s: is_pages: %d\n", swidget->widget->name, 395 module_base_cfg->is_pages); 396 397 if (available_fmt->num_input_formats) { 398 in_format = kcalloc(available_fmt->num_input_formats, 399 sizeof(*in_format), GFP_KERNEL); 400 if (!in_format) 401 return -ENOMEM; 402 available_fmt->input_pin_fmts = in_format; 403 404 ret = sof_update_ipc_object(scomp, in_format, 405 SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, 406 swidget->num_tuples, sizeof(*in_format), 407 available_fmt->num_input_formats); 408 if (ret) { 409 dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); 410 goto err_in; 411 } 412 413 dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); 414 sof_ipc4_dbg_audio_format(scomp->dev, in_format, 415 available_fmt->num_input_formats); 416 } 417 418 if (available_fmt->num_output_formats) { 419 out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), 420 GFP_KERNEL); 421 if (!out_format) { 422 ret = -ENOMEM; 423 goto err_in; 424 } 425 426 ret = sof_update_ipc_object(scomp, out_format, 427 SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, 428 swidget->num_tuples, sizeof(*out_format), 429 available_fmt->num_output_formats); 430 if (ret) { 431 dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); 432 goto err_out; 433 } 434 435 available_fmt->output_pin_fmts = out_format; 436 dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); 437 sof_ipc4_dbg_audio_format(scomp->dev, out_format, 438 available_fmt->num_output_formats); 439 } 440 441 return 0; 442 443 err_out: 444 kfree(out_format); 445 err_in: 446 kfree(in_format); 447 available_fmt->input_pin_fmts = NULL; 448 return ret; 449 } 450 451 /* release the memory allocated in sof_ipc4_get_audio_fmt */ 452 static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt) 453 454 { 455 kfree(available_fmt->output_pin_fmts); 456 available_fmt->output_pin_fmts = NULL; 457 kfree(available_fmt->input_pin_fmts); 458 available_fmt->input_pin_fmts = NULL; 459 } 460 461 static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget) 462 { 463 kfree(swidget->private); 464 } 465 466 static int sof_ipc4_widget_set_module_info(struct snd_sof_widget *swidget) 467 { 468 struct snd_soc_component *scomp = swidget->scomp; 469 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 470 471 swidget->module_info = sof_ipc4_find_module_by_uuid(sdev, &swidget->uuid); 472 473 if (swidget->module_info) 474 return 0; 475 476 dev_err(sdev->dev, "failed to find module info for widget %s with UUID %pUL\n", 477 swidget->widget->name, &swidget->uuid); 478 return -EINVAL; 479 } 480 481 static int sof_ipc4_widget_setup_msg(struct snd_sof_widget *swidget, struct sof_ipc4_msg *msg) 482 { 483 struct sof_ipc4_fw_module *fw_module; 484 uint32_t type; 485 int ret; 486 487 ret = sof_ipc4_widget_set_module_info(swidget); 488 if (ret) 489 return ret; 490 491 fw_module = swidget->module_info; 492 493 msg->primary = fw_module->man4_module_entry.id; 494 msg->primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_INIT_INSTANCE); 495 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 496 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 497 498 msg->extension = SOF_IPC4_MOD_EXT_CORE_ID(swidget->core); 499 500 type = (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_DP) ? 1 : 0; 501 msg->extension |= SOF_IPC4_MOD_EXT_DOMAIN(type); 502 503 return 0; 504 } 505 506 static void sof_ipc4_widget_update_kcontrol_module_id(struct snd_sof_widget *swidget) 507 { 508 struct snd_soc_component *scomp = swidget->scomp; 509 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 510 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 511 struct snd_sof_control *scontrol; 512 513 /* update module ID for all kcontrols for this widget */ 514 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 515 if (scontrol->comp_id == swidget->comp_id) { 516 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 517 struct sof_ipc4_msg *msg = &cdata->msg; 518 519 msg->primary |= fw_module->man4_module_entry.id; 520 } 521 } 522 } 523 524 static int 525 sof_ipc4_update_card_components_string(struct snd_sof_widget *swidget, 526 struct snd_sof_pcm *spcm, int dir) 527 { 528 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 529 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 530 struct snd_soc_component *scomp = spcm->scomp; 531 struct snd_soc_card *card = scomp->card; 532 const char *pt_marker = "iec61937-pcm"; 533 534 /* 535 * Update the card's components list with iec61937-pcm and a list of PCM 536 * ids where ChainDMA is enabled. 537 * These PCMs can be used for bytestream passthrough. 538 */ 539 if (!pipeline->use_chain_dma) 540 return 0; 541 542 if (card->components) { 543 const char *tmp = card->components; 544 545 if (strstr(card->components, pt_marker)) 546 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 547 "%s,%d", 548 card->components, 549 spcm->pcm.pcm_id); 550 else 551 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 552 "%s %s:%d", 553 card->components, 554 pt_marker, 555 spcm->pcm.pcm_id); 556 557 devm_kfree(card->dev, tmp); 558 } else { 559 card->components = devm_kasprintf(card->dev, GFP_KERNEL, 560 "%s:%d", pt_marker, 561 spcm->pcm.pcm_id); 562 } 563 564 if (!card->components) 565 return -ENOMEM; 566 567 return 0; 568 } 569 570 static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) 571 { 572 struct sof_ipc4_available_audio_format *available_fmt; 573 struct snd_soc_component *scomp = swidget->scomp; 574 struct sof_ipc4_copier *ipc4_copier; 575 struct snd_sof_pcm *spcm; 576 int node_type = 0; 577 int ret, dir; 578 579 ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); 580 if (!ipc4_copier) 581 return -ENOMEM; 582 583 swidget->private = ipc4_copier; 584 available_fmt = &ipc4_copier->available_fmt; 585 586 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 587 588 ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, 589 &ipc4_copier->data.base_config); 590 if (ret) 591 goto free_copier; 592 593 /* 594 * This callback is used by host copier and module-to-module copier, 595 * and only host copier needs to set gtw_cfg. 596 */ 597 if (!WIDGET_IS_AIF(swidget->id)) 598 goto skip_gtw_cfg; 599 600 ret = sof_update_ipc_object(scomp, &node_type, 601 SOF_COPIER_TOKENS, swidget->tuples, 602 swidget->num_tuples, sizeof(node_type), 1); 603 604 if (ret) { 605 dev_err(scomp->dev, "parse host copier node type token failed %d\n", 606 ret); 607 goto free_available_fmt; 608 } 609 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); 610 611 spcm = snd_sof_find_spcm_comp(scomp, swidget->comp_id, &dir); 612 if (!spcm) 613 goto skip_gtw_cfg; 614 615 ret = sof_ipc4_update_card_components_string(swidget, spcm, dir); 616 if (ret) 617 goto free_available_fmt; 618 619 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 620 struct snd_sof_pcm_stream *sps = &spcm->stream[dir]; 621 622 sof_update_ipc_object(scomp, &sps->dsp_max_burst_size_in_ms, 623 SOF_COPIER_DEEP_BUFFER_TOKENS, 624 swidget->tuples, 625 swidget->num_tuples, sizeof(u32), 1); 626 /* Set default DMA buffer size if it is not specified in topology */ 627 if (!sps->dsp_max_burst_size_in_ms) 628 sps->dsp_max_burst_size_in_ms = SOF_IPC4_MIN_DMA_BUFFER_SIZE; 629 } else { 630 /* Capture data is copied from DSP to host in 1ms bursts */ 631 spcm->stream[dir].dsp_max_burst_size_in_ms = 1; 632 } 633 634 skip_gtw_cfg: 635 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); 636 if (!ipc4_copier->gtw_attr) { 637 ret = -ENOMEM; 638 goto free_available_fmt; 639 } 640 641 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; 642 ipc4_copier->data.gtw_cfg.config_length = 643 sizeof(struct sof_ipc4_gtw_attributes) >> 2; 644 645 switch (swidget->id) { 646 case snd_soc_dapm_aif_in: 647 case snd_soc_dapm_aif_out: 648 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); 649 break; 650 case snd_soc_dapm_buffer: 651 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_INVALID_NODE_ID; 652 ipc4_copier->ipc_config_size = 0; 653 break; 654 default: 655 dev_err(scomp->dev, "invalid widget type %d\n", swidget->id); 656 ret = -EINVAL; 657 goto free_gtw_attr; 658 } 659 660 /* set up module info and message header */ 661 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); 662 if (ret) 663 goto free_gtw_attr; 664 665 return 0; 666 667 free_gtw_attr: 668 kfree(ipc4_copier->gtw_attr); 669 free_available_fmt: 670 sof_ipc4_free_audio_fmt(available_fmt); 671 free_copier: 672 kfree(ipc4_copier); 673 swidget->private = NULL; 674 return ret; 675 } 676 677 static void sof_ipc4_widget_free_comp_pcm(struct snd_sof_widget *swidget) 678 { 679 struct sof_ipc4_copier *ipc4_copier = swidget->private; 680 struct sof_ipc4_available_audio_format *available_fmt; 681 682 if (!ipc4_copier) 683 return; 684 685 available_fmt = &ipc4_copier->available_fmt; 686 kfree(available_fmt->output_pin_fmts); 687 kfree(ipc4_copier->gtw_attr); 688 kfree(ipc4_copier); 689 swidget->private = NULL; 690 } 691 692 static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) 693 { 694 struct sof_ipc4_available_audio_format *available_fmt; 695 struct snd_soc_component *scomp = swidget->scomp; 696 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 697 struct snd_sof_dai *dai = swidget->private; 698 struct sof_ipc4_copier *ipc4_copier; 699 struct snd_sof_widget *pipe_widget; 700 struct sof_ipc4_pipeline *pipeline; 701 int node_type = 0; 702 int ret; 703 704 ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); 705 if (!ipc4_copier) 706 return -ENOMEM; 707 708 available_fmt = &ipc4_copier->available_fmt; 709 710 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 711 712 ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, 713 &ipc4_copier->data.base_config); 714 if (ret) 715 goto free_copier; 716 717 ret = sof_update_ipc_object(scomp, &node_type, 718 SOF_COPIER_TOKENS, swidget->tuples, 719 swidget->num_tuples, sizeof(node_type), 1); 720 if (ret) { 721 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); 722 goto free_available_fmt; 723 } 724 725 ret = sof_update_ipc_object(scomp, ipc4_copier, 726 SOF_DAI_TOKENS, swidget->tuples, 727 swidget->num_tuples, sizeof(u32), 1); 728 if (ret) { 729 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); 730 goto free_available_fmt; 731 } 732 733 dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name, 734 node_type, ipc4_copier->dai_type, ipc4_copier->dai_index); 735 736 dai->type = ipc4_copier->dai_type; 737 ipc4_copier->data.gtw_cfg.node_id = SOF_IPC4_NODE_TYPE(node_type); 738 739 pipe_widget = swidget->spipe->pipe_widget; 740 pipeline = pipe_widget->private; 741 742 if (pipeline->use_chain_dma && 743 !snd_sof_is_chain_dma_supported(sdev, ipc4_copier->dai_type)) { 744 dev_err(scomp->dev, "Bad DAI type '%d', Chain DMA is not supported\n", 745 ipc4_copier->dai_type); 746 ret = -ENODEV; 747 goto free_available_fmt; 748 } 749 750 switch (ipc4_copier->dai_type) { 751 case SOF_DAI_INTEL_ALH: 752 { 753 struct sof_ipc4_alh_configuration_blob *blob; 754 struct snd_soc_dapm_path *p; 755 struct snd_sof_widget *w; 756 int src_num = 0; 757 758 snd_soc_dapm_widget_for_each_source_path(swidget->widget, p) 759 src_num++; 760 761 if (swidget->id == snd_soc_dapm_dai_in && src_num == 0) { 762 /* 763 * The blob will not be used if the ALH copier is playback direction 764 * and doesn't connect to any source. 765 * It is fine to call kfree(ipc4_copier->copier_config) since 766 * ipc4_copier->copier_config is null. 767 */ 768 break; 769 } 770 771 blob = kzalloc(sizeof(*blob), GFP_KERNEL); 772 if (!blob) { 773 ret = -ENOMEM; 774 goto free_available_fmt; 775 } 776 777 list_for_each_entry(w, &sdev->widget_list, list) { 778 struct snd_sof_dai *alh_dai; 779 780 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || 781 strcmp(w->widget->sname, swidget->widget->sname)) 782 continue; 783 784 alh_dai = w->private; 785 if (alh_dai->type != SOF_DAI_INTEL_ALH) 786 continue; 787 788 blob->alh_cfg.device_count++; 789 } 790 791 ipc4_copier->copier_config = (uint32_t *)blob; 792 /* set data.gtw_cfg.config_length based on device_count */ 793 ipc4_copier->data.gtw_cfg.config_length = (sizeof(blob->gw_attr) + 794 sizeof(blob->alh_cfg.device_count) + 795 sizeof(*blob->alh_cfg.mapping) * 796 blob->alh_cfg.device_count) >> 2; 797 break; 798 } 799 case SOF_DAI_INTEL_SSP: 800 /* set SSP DAI index as the node_id */ 801 ipc4_copier->data.gtw_cfg.node_id |= 802 SOF_IPC4_NODE_INDEX_INTEL_SSP(ipc4_copier->dai_index); 803 break; 804 case SOF_DAI_INTEL_DMIC: 805 /* set DMIC DAI index as the node_id */ 806 ipc4_copier->data.gtw_cfg.node_id |= 807 SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); 808 break; 809 default: 810 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); 811 if (!ipc4_copier->gtw_attr) { 812 ret = -ENOMEM; 813 goto free_available_fmt; 814 } 815 816 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; 817 ipc4_copier->data.gtw_cfg.config_length = 818 sizeof(struct sof_ipc4_gtw_attributes) >> 2; 819 break; 820 } 821 822 dai->scomp = scomp; 823 dai->private = ipc4_copier; 824 825 /* set up module info and message header */ 826 ret = sof_ipc4_widget_setup_msg(swidget, &ipc4_copier->msg); 827 if (ret) 828 goto free_copier_config; 829 830 return 0; 831 832 free_copier_config: 833 kfree(ipc4_copier->copier_config); 834 free_available_fmt: 835 sof_ipc4_free_audio_fmt(available_fmt); 836 free_copier: 837 kfree(ipc4_copier); 838 dai->private = NULL; 839 dai->scomp = NULL; 840 return ret; 841 } 842 843 static void sof_ipc4_widget_free_comp_dai(struct snd_sof_widget *swidget) 844 { 845 struct sof_ipc4_available_audio_format *available_fmt; 846 struct snd_sof_dai *dai = swidget->private; 847 struct sof_ipc4_copier *ipc4_copier; 848 849 if (!dai) 850 return; 851 852 if (!dai->private) { 853 kfree(dai); 854 swidget->private = NULL; 855 return; 856 } 857 858 ipc4_copier = dai->private; 859 available_fmt = &ipc4_copier->available_fmt; 860 861 kfree(available_fmt->output_pin_fmts); 862 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && 863 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) 864 kfree(ipc4_copier->copier_config); 865 kfree(dai->private); 866 kfree(dai); 867 swidget->private = NULL; 868 } 869 870 static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) 871 { 872 struct snd_soc_component *scomp = swidget->scomp; 873 struct sof_ipc4_pipeline *pipeline; 874 struct snd_sof_pipeline *spipe = swidget->spipe; 875 int ret; 876 877 pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); 878 if (!pipeline) 879 return -ENOMEM; 880 881 ret = sof_update_ipc_object(scomp, pipeline, SOF_SCHED_TOKENS, swidget->tuples, 882 swidget->num_tuples, sizeof(*pipeline), 1); 883 if (ret) { 884 dev_err(scomp->dev, "parsing scheduler tokens failed\n"); 885 goto err; 886 } 887 888 swidget->core = pipeline->core_id; 889 spipe->core_mask |= BIT(pipeline->core_id); 890 891 if (pipeline->use_chain_dma) { 892 dev_dbg(scomp->dev, "Set up chain DMA for %s\n", swidget->widget->name); 893 swidget->private = pipeline; 894 return 0; 895 } 896 897 /* parse one set of pipeline tokens */ 898 ret = sof_update_ipc_object(scomp, swidget, SOF_PIPELINE_TOKENS, swidget->tuples, 899 swidget->num_tuples, sizeof(*swidget), 1); 900 if (ret) { 901 dev_err(scomp->dev, "parsing pipeline tokens failed\n"); 902 goto err; 903 } 904 905 dev_dbg(scomp->dev, "pipeline '%s': id %d, pri %d, core_id %u, lp mode %d\n", 906 swidget->widget->name, swidget->pipeline_id, 907 pipeline->priority, pipeline->core_id, pipeline->lp_mode); 908 909 swidget->private = pipeline; 910 911 pipeline->msg.primary = SOF_IPC4_GLB_PIPE_PRIORITY(pipeline->priority); 912 pipeline->msg.primary |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_CREATE_PIPELINE); 913 pipeline->msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 914 pipeline->msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); 915 916 pipeline->msg.extension = pipeline->lp_mode; 917 pipeline->msg.extension |= SOF_IPC4_GLB_PIPE_EXT_CORE_ID(pipeline->core_id); 918 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; 919 920 return 0; 921 err: 922 kfree(pipeline); 923 return ret; 924 } 925 926 static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) 927 { 928 struct snd_soc_component *scomp = swidget->scomp; 929 struct sof_ipc4_gain *gain; 930 int ret; 931 932 gain = kzalloc(sizeof(*gain), GFP_KERNEL); 933 if (!gain) 934 return -ENOMEM; 935 936 swidget->private = gain; 937 938 gain->data.params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; 939 gain->data.params.init_val = SOF_IPC4_VOL_ZERO_DB; 940 941 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->data.base_config); 942 if (ret) 943 goto err; 944 945 ret = sof_update_ipc_object(scomp, &gain->data.params, SOF_GAIN_TOKENS, 946 swidget->tuples, swidget->num_tuples, sizeof(gain->data), 1); 947 if (ret) { 948 dev_err(scomp->dev, "Parsing gain tokens failed\n"); 949 goto err; 950 } 951 952 dev_dbg(scomp->dev, 953 "pga widget %s: ramp type: %d, ramp duration %d, initial gain value: %#x\n", 954 swidget->widget->name, gain->data.params.curve_type, 955 gain->data.params.curve_duration_l, gain->data.params.init_val); 956 957 ret = sof_ipc4_widget_setup_msg(swidget, &gain->msg); 958 if (ret) 959 goto err; 960 961 sof_ipc4_widget_update_kcontrol_module_id(swidget); 962 963 return 0; 964 err: 965 sof_ipc4_free_audio_fmt(&gain->available_fmt); 966 kfree(gain); 967 swidget->private = NULL; 968 return ret; 969 } 970 971 static void sof_ipc4_widget_free_comp_pga(struct snd_sof_widget *swidget) 972 { 973 struct sof_ipc4_gain *gain = swidget->private; 974 975 if (!gain) 976 return; 977 978 sof_ipc4_free_audio_fmt(&gain->available_fmt); 979 kfree(swidget->private); 980 swidget->private = NULL; 981 } 982 983 static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) 984 { 985 struct snd_soc_component *scomp = swidget->scomp; 986 struct sof_ipc4_mixer *mixer; 987 int ret; 988 989 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 990 991 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); 992 if (!mixer) 993 return -ENOMEM; 994 995 swidget->private = mixer; 996 997 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, 998 &mixer->base_config); 999 if (ret) 1000 goto err; 1001 1002 ret = sof_ipc4_widget_setup_msg(swidget, &mixer->msg); 1003 if (ret) 1004 goto err; 1005 1006 return 0; 1007 err: 1008 sof_ipc4_free_audio_fmt(&mixer->available_fmt); 1009 kfree(mixer); 1010 swidget->private = NULL; 1011 return ret; 1012 } 1013 1014 static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget) 1015 { 1016 struct snd_soc_component *scomp = swidget->scomp; 1017 struct snd_sof_pipeline *spipe = swidget->spipe; 1018 struct sof_ipc4_src *src; 1019 int ret; 1020 1021 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 1022 1023 src = kzalloc(sizeof(*src), GFP_KERNEL); 1024 if (!src) 1025 return -ENOMEM; 1026 1027 swidget->private = src; 1028 1029 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, 1030 &src->data.base_config); 1031 if (ret) 1032 goto err; 1033 1034 ret = sof_update_ipc_object(scomp, &src->data, SOF_SRC_TOKENS, swidget->tuples, 1035 swidget->num_tuples, sizeof(*src), 1); 1036 if (ret) { 1037 dev_err(scomp->dev, "Parsing SRC tokens failed\n"); 1038 goto err; 1039 } 1040 1041 spipe->core_mask |= BIT(swidget->core); 1042 1043 dev_dbg(scomp->dev, "SRC sink rate %d\n", src->data.sink_rate); 1044 1045 ret = sof_ipc4_widget_setup_msg(swidget, &src->msg); 1046 if (ret) 1047 goto err; 1048 1049 return 0; 1050 err: 1051 sof_ipc4_free_audio_fmt(&src->available_fmt); 1052 kfree(src); 1053 swidget->private = NULL; 1054 return ret; 1055 } 1056 1057 static int sof_ipc4_widget_setup_comp_asrc(struct snd_sof_widget *swidget) 1058 { 1059 struct snd_soc_component *scomp = swidget->scomp; 1060 struct snd_sof_pipeline *spipe = swidget->spipe; 1061 struct sof_ipc4_asrc *asrc; 1062 int ret; 1063 1064 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 1065 1066 asrc = kzalloc(sizeof(*asrc), GFP_KERNEL); 1067 if (!asrc) 1068 return -ENOMEM; 1069 1070 swidget->private = asrc; 1071 1072 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &asrc->available_fmt, 1073 &asrc->data.base_config); 1074 if (ret) 1075 goto err; 1076 1077 ret = sof_update_ipc_object(scomp, &asrc->data, SOF_ASRC_TOKENS, swidget->tuples, 1078 swidget->num_tuples, sizeof(*asrc), 1); 1079 if (ret) { 1080 dev_err(scomp->dev, "Parsing ASRC tokens failed\n"); 1081 goto err; 1082 } 1083 1084 spipe->core_mask |= BIT(swidget->core); 1085 1086 dev_dbg(scomp->dev, "ASRC sink rate %d, mode 0x%08x\n", 1087 asrc->data.out_freq, asrc->data.asrc_mode); 1088 1089 ret = sof_ipc4_widget_setup_msg(swidget, &asrc->msg); 1090 if (ret) 1091 goto err; 1092 1093 return 0; 1094 err: 1095 sof_ipc4_free_audio_fmt(&asrc->available_fmt); 1096 kfree(asrc); 1097 swidget->private = NULL; 1098 return ret; 1099 } 1100 1101 static void sof_ipc4_widget_free_comp_src(struct snd_sof_widget *swidget) 1102 { 1103 struct sof_ipc4_src *src = swidget->private; 1104 1105 if (!src) 1106 return; 1107 1108 sof_ipc4_free_audio_fmt(&src->available_fmt); 1109 kfree(swidget->private); 1110 swidget->private = NULL; 1111 } 1112 1113 static void sof_ipc4_widget_free_comp_asrc(struct snd_sof_widget *swidget) 1114 { 1115 struct sof_ipc4_asrc *asrc = swidget->private; 1116 1117 if (!asrc) 1118 return; 1119 1120 sof_ipc4_free_audio_fmt(&asrc->available_fmt); 1121 kfree(swidget->private); 1122 swidget->private = NULL; 1123 } 1124 1125 static void sof_ipc4_widget_free_comp_mixer(struct snd_sof_widget *swidget) 1126 { 1127 struct sof_ipc4_mixer *mixer = swidget->private; 1128 1129 if (!mixer) 1130 return; 1131 1132 sof_ipc4_free_audio_fmt(&mixer->available_fmt); 1133 kfree(swidget->private); 1134 swidget->private = NULL; 1135 } 1136 1137 /* 1138 * Add the process modules support. The process modules are defined as snd_soc_dapm_effect modules. 1139 */ 1140 static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget) 1141 { 1142 struct snd_soc_component *scomp = swidget->scomp; 1143 struct sof_ipc4_fw_module *fw_module; 1144 struct snd_sof_pipeline *spipe = swidget->spipe; 1145 struct sof_ipc4_process *process; 1146 void *cfg; 1147 int ret; 1148 1149 process = kzalloc(sizeof(*process), GFP_KERNEL); 1150 if (!process) 1151 return -ENOMEM; 1152 1153 swidget->private = process; 1154 1155 ret = sof_ipc4_get_audio_fmt(scomp, swidget, &process->available_fmt, 1156 &process->base_config); 1157 if (ret) 1158 goto err; 1159 1160 ret = sof_ipc4_widget_setup_msg(swidget, &process->msg); 1161 if (ret) 1162 goto err; 1163 1164 /* parse process init module payload config type from module info */ 1165 fw_module = swidget->module_info; 1166 process->init_config = FIELD_GET(SOF_IPC4_MODULE_INIT_CONFIG_MASK, 1167 fw_module->man4_module_entry.type); 1168 1169 process->ipc_config_size = sizeof(struct sof_ipc4_base_module_cfg); 1170 1171 /* allocate memory for base config extension if needed */ 1172 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { 1173 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext; 1174 u32 ext_size = struct_size(base_cfg_ext, pin_formats, 1175 size_add(swidget->num_input_pins, 1176 swidget->num_output_pins)); 1177 1178 base_cfg_ext = kzalloc(ext_size, GFP_KERNEL); 1179 if (!base_cfg_ext) { 1180 ret = -ENOMEM; 1181 goto free_available_fmt; 1182 } 1183 1184 base_cfg_ext->num_input_pin_fmts = swidget->num_input_pins; 1185 base_cfg_ext->num_output_pin_fmts = swidget->num_output_pins; 1186 process->base_config_ext = base_cfg_ext; 1187 process->base_config_ext_size = ext_size; 1188 process->ipc_config_size += ext_size; 1189 } 1190 1191 cfg = kzalloc(process->ipc_config_size, GFP_KERNEL); 1192 if (!cfg) { 1193 ret = -ENOMEM; 1194 goto free_base_cfg_ext; 1195 } 1196 1197 process->ipc_config_data = cfg; 1198 1199 sof_ipc4_widget_update_kcontrol_module_id(swidget); 1200 1201 /* set pipeline core mask to keep track of the core the module is scheduled to run on */ 1202 spipe->core_mask |= BIT(swidget->core); 1203 1204 return 0; 1205 free_base_cfg_ext: 1206 kfree(process->base_config_ext); 1207 process->base_config_ext = NULL; 1208 free_available_fmt: 1209 sof_ipc4_free_audio_fmt(&process->available_fmt); 1210 err: 1211 kfree(process); 1212 swidget->private = NULL; 1213 return ret; 1214 } 1215 1216 static void sof_ipc4_widget_free_comp_process(struct snd_sof_widget *swidget) 1217 { 1218 struct sof_ipc4_process *process = swidget->private; 1219 1220 if (!process) 1221 return; 1222 1223 kfree(process->ipc_config_data); 1224 kfree(process->base_config_ext); 1225 sof_ipc4_free_audio_fmt(&process->available_fmt); 1226 kfree(swidget->private); 1227 swidget->private = NULL; 1228 } 1229 1230 static void 1231 sof_ipc4_update_resource_usage(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, 1232 struct sof_ipc4_base_module_cfg *base_config) 1233 { 1234 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 1235 struct snd_sof_widget *pipe_widget; 1236 struct sof_ipc4_pipeline *pipeline; 1237 int task_mem, queue_mem; 1238 int ibs, bss, total; 1239 1240 ibs = base_config->ibs; 1241 bss = base_config->is_pages; 1242 1243 task_mem = SOF_IPC4_PIPELINE_OBJECT_SIZE; 1244 task_mem += SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE + bss; 1245 1246 if (fw_module->man4_module_entry.type & SOF_IPC4_MODULE_LL) { 1247 task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_LL_TASK_OBJECT_SIZE); 1248 task_mem += SOF_IPC4_FW_MAX_QUEUE_COUNT * SOF_IPC4_MODULE_INSTANCE_LIST_ITEM_SIZE; 1249 task_mem += SOF_IPC4_LL_TASK_LIST_ITEM_SIZE; 1250 } else { 1251 task_mem += SOF_IPC4_FW_ROUNDUP(SOF_IPC4_DP_TASK_OBJECT_SIZE); 1252 task_mem += SOF_IPC4_DP_TASK_LIST_SIZE; 1253 } 1254 1255 ibs = SOF_IPC4_FW_ROUNDUP(ibs); 1256 queue_mem = SOF_IPC4_FW_MAX_QUEUE_COUNT * (SOF_IPC4_DATA_QUEUE_OBJECT_SIZE + ibs); 1257 1258 total = SOF_IPC4_FW_PAGE(task_mem + queue_mem); 1259 1260 pipe_widget = swidget->spipe->pipe_widget; 1261 pipeline = pipe_widget->private; 1262 pipeline->mem_usage += total; 1263 1264 /* Update base_config->cpc from the module manifest */ 1265 sof_ipc4_update_cpc_from_manifest(sdev, fw_module, base_config); 1266 1267 if (ignore_cpc) { 1268 dev_dbg(sdev->dev, "%s: ibs / obs: %u / %u, forcing cpc to 0 from %u\n", 1269 swidget->widget->name, base_config->ibs, base_config->obs, 1270 base_config->cpc); 1271 base_config->cpc = 0; 1272 } else { 1273 dev_dbg(sdev->dev, "%s: ibs / obs / cpc: %u / %u / %u\n", 1274 swidget->widget->name, base_config->ibs, base_config->obs, 1275 base_config->cpc); 1276 } 1277 } 1278 1279 static int sof_ipc4_widget_assign_instance_id(struct snd_sof_dev *sdev, 1280 struct snd_sof_widget *swidget) 1281 { 1282 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 1283 int max_instances = fw_module->man4_module_entry.instance_max_count; 1284 1285 swidget->instance_id = ida_alloc_max(&fw_module->m_ida, max_instances, GFP_KERNEL); 1286 if (swidget->instance_id < 0) { 1287 dev_err(sdev->dev, "failed to assign instance id for widget %s", 1288 swidget->widget->name); 1289 return swidget->instance_id; 1290 } 1291 1292 return 0; 1293 } 1294 1295 /* update hw_params based on the audio stream format */ 1296 static int sof_ipc4_update_hw_params(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params, 1297 struct sof_ipc4_audio_format *fmt, u32 param_to_update) 1298 { 1299 struct snd_interval *i; 1300 1301 if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) { 1302 int valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1303 snd_pcm_format_t snd_fmt; 1304 struct snd_mask *m; 1305 1306 switch (valid_bits) { 1307 case 16: 1308 snd_fmt = SNDRV_PCM_FORMAT_S16_LE; 1309 break; 1310 case 24: 1311 snd_fmt = SNDRV_PCM_FORMAT_S24_LE; 1312 break; 1313 case 32: 1314 snd_fmt = SNDRV_PCM_FORMAT_S32_LE; 1315 break; 1316 default: 1317 dev_err(sdev->dev, "invalid PCM valid_bits %d\n", valid_bits); 1318 return -EINVAL; 1319 } 1320 1321 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1322 snd_mask_none(m); 1323 snd_mask_set_format(m, snd_fmt); 1324 } 1325 1326 if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_RATE)) { 1327 unsigned int rate = fmt->sampling_frequency; 1328 1329 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); 1330 i->min = rate; 1331 i->max = rate; 1332 } 1333 1334 if (param_to_update & BIT(SNDRV_PCM_HW_PARAM_CHANNELS)) { 1335 unsigned int channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1336 1337 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); 1338 i->min = channels; 1339 i->max = channels; 1340 } 1341 1342 return 0; 1343 } 1344 1345 static bool sof_ipc4_is_single_format(struct snd_sof_dev *sdev, 1346 struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size) 1347 { 1348 struct sof_ipc4_audio_format *fmt; 1349 u32 rate, channels, valid_bits; 1350 int i; 1351 1352 fmt = &pin_fmts[0].audio_fmt; 1353 rate = fmt->sampling_frequency; 1354 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1355 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1356 1357 /* check if all output formats in topology are the same */ 1358 for (i = 1; i < pin_fmts_size; i++) { 1359 u32 _rate, _channels, _valid_bits; 1360 1361 fmt = &pin_fmts[i].audio_fmt; 1362 _rate = fmt->sampling_frequency; 1363 _channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1364 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1365 1366 if (_rate != rate || _channels != channels || _valid_bits != valid_bits) 1367 return false; 1368 } 1369 1370 return true; 1371 } 1372 1373 static int sof_ipc4_init_output_audio_fmt(struct snd_sof_dev *sdev, 1374 struct snd_sof_widget *swidget, 1375 struct sof_ipc4_base_module_cfg *base_config, 1376 struct sof_ipc4_available_audio_format *available_fmt, 1377 u32 out_ref_rate, u32 out_ref_channels, 1378 u32 out_ref_valid_bits) 1379 { 1380 struct sof_ipc4_pin_format *pin_fmts = available_fmt->output_pin_fmts; 1381 u32 pin_fmts_size = available_fmt->num_output_formats; 1382 bool single_format; 1383 int i = 0; 1384 1385 if (!pin_fmts_size) { 1386 dev_err(sdev->dev, "no output formats for %s\n", 1387 swidget->widget->name); 1388 return -EINVAL; 1389 } 1390 1391 single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); 1392 1393 /* pick the first format if there's only one available or if all formats are the same */ 1394 if (single_format) 1395 goto out_fmt; 1396 1397 /* 1398 * if there are multiple output formats, then choose the output format that matches 1399 * the reference params 1400 */ 1401 for (i = 0; i < pin_fmts_size; i++) { 1402 struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt; 1403 1404 u32 _out_rate, _out_channels, _out_valid_bits; 1405 1406 _out_rate = fmt->sampling_frequency; 1407 _out_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1408 _out_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1409 1410 if (_out_rate == out_ref_rate && _out_channels == out_ref_channels && 1411 _out_valid_bits == out_ref_valid_bits) 1412 goto out_fmt; 1413 } 1414 1415 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", 1416 __func__, out_ref_rate, out_ref_valid_bits, out_ref_channels); 1417 1418 return -EINVAL; 1419 1420 out_fmt: 1421 base_config->obs = pin_fmts[i].buffer_size; 1422 1423 return i; 1424 } 1425 1426 static int sof_ipc4_get_valid_bits(struct snd_sof_dev *sdev, struct snd_pcm_hw_params *params) 1427 { 1428 switch (params_format(params)) { 1429 case SNDRV_PCM_FORMAT_S16_LE: 1430 return 16; 1431 case SNDRV_PCM_FORMAT_S24_LE: 1432 return 24; 1433 case SNDRV_PCM_FORMAT_S32_LE: 1434 return 32; 1435 default: 1436 dev_err(sdev->dev, "invalid pcm frame format %d\n", params_format(params)); 1437 return -EINVAL; 1438 } 1439 } 1440 1441 static int sof_ipc4_init_input_audio_fmt(struct snd_sof_dev *sdev, 1442 struct snd_sof_widget *swidget, 1443 struct sof_ipc4_base_module_cfg *base_config, 1444 struct snd_pcm_hw_params *params, 1445 struct sof_ipc4_available_audio_format *available_fmt) 1446 { 1447 struct sof_ipc4_pin_format *pin_fmts = available_fmt->input_pin_fmts; 1448 u32 pin_fmts_size = available_fmt->num_input_formats; 1449 u32 valid_bits; 1450 u32 channels; 1451 u32 rate; 1452 bool single_format; 1453 int sample_valid_bits; 1454 int i = 0; 1455 1456 if (!pin_fmts_size) { 1457 dev_err(sdev->dev, "no input formats for %s\n", swidget->widget->name); 1458 return -EINVAL; 1459 } 1460 1461 single_format = sof_ipc4_is_single_format(sdev, pin_fmts, pin_fmts_size); 1462 if (single_format) 1463 goto in_fmt; 1464 1465 sample_valid_bits = sof_ipc4_get_valid_bits(sdev, params); 1466 if (sample_valid_bits < 0) 1467 return sample_valid_bits; 1468 1469 /* 1470 * Search supported input audio formats with pin index 0 to match rate, channels and 1471 * sample_valid_bits from reference params 1472 */ 1473 for (i = 0; i < pin_fmts_size; i++) { 1474 struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt; 1475 1476 if (pin_fmts[i].pin_index) 1477 continue; 1478 1479 rate = fmt->sampling_frequency; 1480 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1481 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1482 if (params_rate(params) == rate && params_channels(params) == channels && 1483 sample_valid_bits == valid_bits) 1484 break; 1485 } 1486 1487 if (i == pin_fmts_size) { 1488 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", 1489 __func__, params_rate(params), sample_valid_bits, params_channels(params)); 1490 return -EINVAL; 1491 } 1492 1493 in_fmt: 1494 /* copy input format */ 1495 memcpy(&base_config->audio_fmt, &pin_fmts[i].audio_fmt, 1496 sizeof(struct sof_ipc4_audio_format)); 1497 1498 /* set base_cfg ibs/obs */ 1499 base_config->ibs = pin_fmts[i].buffer_size; 1500 1501 return i; 1502 } 1503 1504 static void sof_ipc4_unprepare_copier_module(struct snd_sof_widget *swidget) 1505 { 1506 struct sof_ipc4_copier *ipc4_copier = NULL; 1507 struct snd_sof_widget *pipe_widget; 1508 struct sof_ipc4_pipeline *pipeline; 1509 1510 /* reset pipeline memory usage */ 1511 pipe_widget = swidget->spipe->pipe_widget; 1512 pipeline = pipe_widget->private; 1513 pipeline->mem_usage = 0; 1514 1515 if (WIDGET_IS_AIF(swidget->id) || swidget->id == snd_soc_dapm_buffer) { 1516 if (pipeline->use_chain_dma) { 1517 pipeline->msg.primary = 0; 1518 pipeline->msg.extension = 0; 1519 } 1520 ipc4_copier = swidget->private; 1521 } else if (WIDGET_IS_DAI(swidget->id)) { 1522 struct snd_sof_dai *dai = swidget->private; 1523 1524 ipc4_copier = dai->private; 1525 1526 if (pipeline->use_chain_dma) { 1527 /* 1528 * Preserve the DMA Link ID and clear other bits since 1529 * the DMA Link ID is only configured once during 1530 * dai_config, other fields are expected to be 0 for 1531 * re-configuration 1532 */ 1533 pipeline->msg.primary &= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; 1534 pipeline->msg.extension = 0; 1535 } 1536 1537 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { 1538 struct sof_ipc4_alh_configuration_blob *blob; 1539 unsigned int group_id; 1540 1541 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; 1542 if (blob->alh_cfg.device_count > 1) { 1543 group_id = SOF_IPC4_NODE_INDEX(ipc4_copier->data.gtw_cfg.node_id) - 1544 ALH_MULTI_GTW_BASE; 1545 ida_free(&alh_group_ida, group_id); 1546 } 1547 } 1548 } 1549 1550 if (ipc4_copier) { 1551 kfree(ipc4_copier->ipc_config_data); 1552 ipc4_copier->ipc_config_data = NULL; 1553 ipc4_copier->ipc_config_size = 0; 1554 } 1555 } 1556 1557 #if IS_ENABLED(CONFIG_ACPI) && IS_ENABLED(CONFIG_SND_INTEL_NHLT) 1558 static int snd_sof_get_hw_config_params(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, 1559 int *sample_rate, int *channel_count, int *bit_depth) 1560 { 1561 struct snd_soc_tplg_hw_config *hw_config; 1562 struct snd_sof_dai_link *slink; 1563 bool dai_link_found = false; 1564 bool hw_cfg_found = false; 1565 int i; 1566 1567 /* get current hw_config from link */ 1568 list_for_each_entry(slink, &sdev->dai_link_list, list) { 1569 if (!strcmp(slink->link->name, dai->name)) { 1570 dai_link_found = true; 1571 break; 1572 } 1573 } 1574 1575 if (!dai_link_found) { 1576 dev_err(sdev->dev, "%s: no DAI link found for DAI %s\n", __func__, dai->name); 1577 return -EINVAL; 1578 } 1579 1580 for (i = 0; i < slink->num_hw_configs; i++) { 1581 hw_config = &slink->hw_configs[i]; 1582 if (dai->current_config == le32_to_cpu(hw_config->id)) { 1583 hw_cfg_found = true; 1584 break; 1585 } 1586 } 1587 1588 if (!hw_cfg_found) { 1589 dev_err(sdev->dev, "%s: no matching hw_config found for DAI %s\n", __func__, 1590 dai->name); 1591 return -EINVAL; 1592 } 1593 1594 *bit_depth = le32_to_cpu(hw_config->tdm_slot_width); 1595 *channel_count = le32_to_cpu(hw_config->tdm_slots); 1596 *sample_rate = le32_to_cpu(hw_config->fsync_rate); 1597 1598 dev_dbg(sdev->dev, "sample rate: %d sample width: %d channels: %d\n", 1599 *sample_rate, *bit_depth, *channel_count); 1600 1601 return 0; 1602 } 1603 1604 static int 1605 snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, 1606 bool single_bitdepth, 1607 struct snd_pcm_hw_params *params, u32 dai_index, 1608 u32 linktype, u8 dir, u32 **dst, u32 *len) 1609 { 1610 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 1611 struct nhlt_specific_cfg *cfg; 1612 int sample_rate, channel_count; 1613 bool format_change = false; 1614 int bit_depth, ret; 1615 u32 nhlt_type; 1616 int dev_type = 0; 1617 1618 /* convert to NHLT type */ 1619 switch (linktype) { 1620 case SOF_DAI_INTEL_DMIC: 1621 nhlt_type = NHLT_LINK_DMIC; 1622 channel_count = params_channels(params); 1623 sample_rate = params_rate(params); 1624 bit_depth = params_width(params); 1625 /* 1626 * Look for 32-bit blob first instead of 16-bit if copier 1627 * supports multiple formats 1628 */ 1629 if (bit_depth == 16 && !single_bitdepth) { 1630 dev_dbg(sdev->dev, "Looking for 32-bit blob first for DMIC\n"); 1631 format_change = true; 1632 bit_depth = 32; 1633 } 1634 break; 1635 case SOF_DAI_INTEL_SSP: 1636 nhlt_type = NHLT_LINK_SSP; 1637 ret = snd_sof_get_hw_config_params(sdev, dai, &sample_rate, &channel_count, 1638 &bit_depth); 1639 if (ret < 0) 1640 return ret; 1641 1642 /* 1643 * We need to know the type of the external device attached to a SSP 1644 * port to retrieve the blob from NHLT. However, device type is not 1645 * specified in topology. 1646 * Query the type for the port and then pass that information back 1647 * to the blob lookup function. 1648 */ 1649 dev_type = intel_nhlt_ssp_device_type(sdev->dev, ipc4_data->nhlt, 1650 dai_index); 1651 if (dev_type < 0) 1652 return dev_type; 1653 break; 1654 default: 1655 return 0; 1656 } 1657 1658 dev_dbg(sdev->dev, "dai index %d nhlt type %d direction %d dev type %d\n", 1659 dai_index, nhlt_type, dir, dev_type); 1660 1661 /* find NHLT blob with matching params */ 1662 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, dai_index, nhlt_type, 1663 bit_depth, bit_depth, channel_count, sample_rate, 1664 dir, dev_type); 1665 1666 if (!cfg) { 1667 bool get_new_blob = false; 1668 1669 if (format_change) { 1670 /* 1671 * The 32-bit blob was not found in NHLT table, try to 1672 * look for one based on the params 1673 */ 1674 bit_depth = params_width(params); 1675 format_change = false; 1676 get_new_blob = true; 1677 } else if (linktype == SOF_DAI_INTEL_DMIC && !single_bitdepth) { 1678 /* 1679 * The requested 32-bit blob (no format change for the 1680 * blob request) was not found in NHLT table, try to 1681 * look for 16-bit blob if the copier supports multiple 1682 * formats 1683 */ 1684 bit_depth = 16; 1685 format_change = true; 1686 get_new_blob = true; 1687 } 1688 1689 if (get_new_blob) { 1690 cfg = intel_nhlt_get_endpoint_blob(sdev->dev, ipc4_data->nhlt, 1691 dai_index, nhlt_type, 1692 bit_depth, bit_depth, 1693 channel_count, sample_rate, 1694 dir, dev_type); 1695 if (cfg) 1696 goto out; 1697 } 1698 1699 dev_err(sdev->dev, 1700 "no matching blob for sample rate: %d sample width: %d channels: %d\n", 1701 sample_rate, bit_depth, channel_count); 1702 return -EINVAL; 1703 } 1704 1705 out: 1706 /* config length should be in dwords */ 1707 *len = cfg->size >> 2; 1708 *dst = (u32 *)cfg->caps; 1709 1710 if (format_change) { 1711 /* 1712 * Update the params to reflect that different blob was loaded 1713 * instead of the requested bit depth (16 -> 32 or 32 -> 16). 1714 * This information is going to be used by the caller to find 1715 * matching copier format on the dai side. 1716 */ 1717 struct snd_mask *m; 1718 1719 m = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); 1720 snd_mask_none(m); 1721 if (bit_depth == 16) 1722 snd_mask_set_format(m, SNDRV_PCM_FORMAT_S16_LE); 1723 else 1724 snd_mask_set_format(m, SNDRV_PCM_FORMAT_S32_LE); 1725 1726 } 1727 1728 return 0; 1729 } 1730 #else 1731 static int 1732 snd_sof_get_nhlt_endpoint_data(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, 1733 bool single_bitdepth, 1734 struct snd_pcm_hw_params *params, u32 dai_index, 1735 u32 linktype, u8 dir, u32 **dst, u32 *len) 1736 { 1737 return 0; 1738 } 1739 #endif 1740 1741 bool sof_ipc4_copier_is_single_bitdepth(struct snd_sof_dev *sdev, 1742 struct sof_ipc4_pin_format *pin_fmts, 1743 u32 pin_fmts_size) 1744 { 1745 struct sof_ipc4_audio_format *fmt; 1746 u32 valid_bits; 1747 int i; 1748 1749 fmt = &pin_fmts[0].audio_fmt; 1750 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1751 1752 /* check if all formats in topology are the same */ 1753 for (i = 1; i < pin_fmts_size; i++) { 1754 u32 _valid_bits; 1755 1756 fmt = &pin_fmts[i].audio_fmt; 1757 _valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1758 1759 if (_valid_bits != valid_bits) 1760 return false; 1761 } 1762 1763 return true; 1764 } 1765 1766 static int 1767 sof_ipc4_adjust_params_to_dai_format(struct snd_sof_dev *sdev, 1768 struct snd_pcm_hw_params *params, 1769 struct sof_ipc4_pin_format *pin_fmts, 1770 u32 pin_fmts_size) 1771 { 1772 u32 params_mask = BIT(SNDRV_PCM_HW_PARAM_RATE) | 1773 BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 1774 BIT(SNDRV_PCM_HW_PARAM_FORMAT); 1775 struct sof_ipc4_audio_format *fmt; 1776 u32 rate, channels, valid_bits; 1777 int i; 1778 1779 fmt = &pin_fmts[0].audio_fmt; 1780 rate = fmt->sampling_frequency; 1781 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1782 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1783 1784 /* check if parameters in topology defined formats are the same */ 1785 for (i = 1; i < pin_fmts_size; i++) { 1786 u32 val; 1787 1788 fmt = &pin_fmts[i].audio_fmt; 1789 1790 if (params_mask & BIT(SNDRV_PCM_HW_PARAM_RATE)) { 1791 val = fmt->sampling_frequency; 1792 if (val != rate) 1793 params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_RATE); 1794 } 1795 if (params_mask & BIT(SNDRV_PCM_HW_PARAM_CHANNELS)) { 1796 val = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 1797 if (val != channels) 1798 params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_CHANNELS); 1799 } 1800 if (params_mask & BIT(SNDRV_PCM_HW_PARAM_FORMAT)) { 1801 val = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 1802 if (val != valid_bits) 1803 params_mask &= ~BIT(SNDRV_PCM_HW_PARAM_FORMAT); 1804 } 1805 } 1806 1807 if (params_mask) 1808 return sof_ipc4_update_hw_params(sdev, params, 1809 &pin_fmts[0].audio_fmt, 1810 params_mask); 1811 1812 return 0; 1813 } 1814 1815 static int 1816 sof_ipc4_prepare_dai_copier(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, 1817 struct snd_pcm_hw_params *params, int dir) 1818 { 1819 struct sof_ipc4_available_audio_format *available_fmt; 1820 struct snd_pcm_hw_params dai_params = *params; 1821 struct sof_ipc4_copier_data *copier_data; 1822 struct sof_ipc4_pin_format *pin_fmts; 1823 struct sof_ipc4_copier *ipc4_copier; 1824 bool single_bitdepth; 1825 u32 num_pin_fmts; 1826 int ret; 1827 1828 ipc4_copier = dai->private; 1829 copier_data = &ipc4_copier->data; 1830 available_fmt = &ipc4_copier->available_fmt; 1831 1832 /* 1833 * Fixup the params based on the format parameters of the DAI. If any 1834 * of the RATE, CHANNELS, bit depth is static among the formats then 1835 * narrow the params to only allow that specific parameter value. 1836 */ 1837 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 1838 pin_fmts = available_fmt->output_pin_fmts; 1839 num_pin_fmts = available_fmt->num_output_formats; 1840 } else { 1841 pin_fmts = available_fmt->input_pin_fmts; 1842 num_pin_fmts = available_fmt->num_input_formats; 1843 } 1844 1845 ret = sof_ipc4_adjust_params_to_dai_format(sdev, &dai_params, pin_fmts, 1846 num_pin_fmts); 1847 if (ret) 1848 return ret; 1849 1850 single_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, pin_fmts, 1851 num_pin_fmts); 1852 ret = snd_sof_get_nhlt_endpoint_data(sdev, dai, single_bitdepth, 1853 &dai_params, 1854 ipc4_copier->dai_index, 1855 ipc4_copier->dai_type, dir, 1856 &ipc4_copier->copier_config, 1857 &copier_data->gtw_cfg.config_length); 1858 /* Update the params to reflect the changes made in this function */ 1859 if (!ret) 1860 *params = dai_params; 1861 1862 return ret; 1863 } 1864 1865 static int 1866 sof_ipc4_prepare_copier_module(struct snd_sof_widget *swidget, 1867 struct snd_pcm_hw_params *fe_params, 1868 struct snd_sof_platform_stream_params *platform_params, 1869 struct snd_pcm_hw_params *pipeline_params, int dir) 1870 { 1871 struct sof_ipc4_available_audio_format *available_fmt; 1872 struct snd_soc_component *scomp = swidget->scomp; 1873 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1874 struct sof_ipc4_copier_data *copier_data; 1875 int input_fmt_index, output_fmt_index; 1876 struct sof_ipc4_copier *ipc4_copier; 1877 struct snd_pcm_hw_params *ref_params __free(kfree) = NULL; 1878 struct snd_sof_dai *dai; 1879 u32 gtw_cfg_config_length; 1880 u32 dma_config_tlv_size = 0; 1881 void **ipc_config_data; 1882 int *ipc_config_size; 1883 u32 **data; 1884 int ipc_size, ret, out_ref_valid_bits; 1885 u32 out_ref_rate, out_ref_channels; 1886 u32 deep_buffer_dma_ms = 0; 1887 bool single_output_bitdepth; 1888 int i; 1889 1890 switch (swidget->id) { 1891 case snd_soc_dapm_aif_in: 1892 case snd_soc_dapm_aif_out: 1893 { 1894 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 1895 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 1896 struct sof_ipc4_gtw_attributes *gtw_attr; 1897 1898 dev_dbg(sdev->dev, 1899 "Host copier %s, type %d, ChainDMA: %s, stream_tag: %d\n", 1900 swidget->widget->name, swidget->id, 1901 str_yes_no(pipeline->use_chain_dma), 1902 platform_params->stream_tag); 1903 1904 /* parse the deep buffer dma size */ 1905 ret = sof_update_ipc_object(scomp, &deep_buffer_dma_ms, 1906 SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, 1907 swidget->num_tuples, sizeof(u32), 1); 1908 if (ret) { 1909 dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", 1910 swidget->widget->name); 1911 return ret; 1912 } 1913 1914 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; 1915 gtw_attr = ipc4_copier->gtw_attr; 1916 copier_data = &ipc4_copier->data; 1917 available_fmt = &ipc4_copier->available_fmt; 1918 1919 if (pipeline->use_chain_dma) { 1920 u32 host_dma_id; 1921 u32 fifo_size; 1922 1923 host_dma_id = platform_params->stream_tag - 1; 1924 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_HOST_ID(host_dma_id); 1925 1926 /* Set SCS bit for S16_LE format only */ 1927 if (params_format(fe_params) == SNDRV_PCM_FORMAT_S16_LE) 1928 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_SCS_MASK; 1929 1930 /* 1931 * Despite its name the bitfield 'fifo_size' is used to define DMA buffer 1932 * size. The expression calculates 2ms buffer size. 1933 */ 1934 fifo_size = DIV_ROUND_UP((SOF_IPC4_CHAIN_DMA_BUF_SIZE_MS * 1935 params_rate(fe_params) * 1936 params_channels(fe_params) * 1937 params_physical_width(fe_params)), 8000); 1938 pipeline->msg.extension |= SOF_IPC4_GLB_EXT_CHAIN_DMA_FIFO_SIZE(fifo_size); 1939 1940 /* 1941 * Chain DMA does not support stream timestamping, but it 1942 * can use the host side registers for delay calculation. 1943 */ 1944 copier_data->gtw_cfg.node_id = SOF_IPC4_CHAIN_DMA_NODE_ID; 1945 1946 return 0; 1947 } 1948 1949 /* 1950 * Use the input_pin_fmts to match pcm params for playback and the output_pin_fmts 1951 * for capture. 1952 */ 1953 if (dir == SNDRV_PCM_STREAM_PLAYBACK) 1954 ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL); 1955 else 1956 ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL); 1957 if (!ref_params) 1958 return -ENOMEM; 1959 1960 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 1961 copier_data->gtw_cfg.node_id |= 1962 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); 1963 1964 /* set gateway attributes */ 1965 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; 1966 break; 1967 } 1968 case snd_soc_dapm_dai_in: 1969 case snd_soc_dapm_dai_out: 1970 { 1971 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 1972 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 1973 1974 dev_dbg(sdev->dev, "Dai copier %s, type %d, ChainDMA: %s\n", 1975 swidget->widget->name, swidget->id, 1976 str_yes_no(pipeline->use_chain_dma)); 1977 1978 if (pipeline->use_chain_dma) 1979 return 0; 1980 1981 dai = swidget->private; 1982 1983 ipc4_copier = (struct sof_ipc4_copier *)dai->private; 1984 copier_data = &ipc4_copier->data; 1985 available_fmt = &ipc4_copier->available_fmt; 1986 1987 /* 1988 * Use the fe_params as a base for the copier configuration. 1989 * The ref_params might get updated to reflect what format is 1990 * supported by the copier on the DAI side. 1991 * 1992 * In case of capture the ref_params returned will be used to 1993 * find the input configuration of the copier. 1994 */ 1995 ref_params = kmemdup(fe_params, sizeof(*ref_params), GFP_KERNEL); 1996 if (!ref_params) 1997 return -ENOMEM; 1998 1999 ret = sof_ipc4_prepare_dai_copier(sdev, dai, ref_params, dir); 2000 if (ret < 0) 2001 return ret; 2002 2003 /* 2004 * For playback the pipeline_params needs to be used to find the 2005 * input configuration of the copier. 2006 */ 2007 if (dir == SNDRV_PCM_STREAM_PLAYBACK) 2008 memcpy(ref_params, pipeline_params, sizeof(*ref_params)); 2009 2010 break; 2011 } 2012 case snd_soc_dapm_buffer: 2013 { 2014 dev_dbg(sdev->dev, "Module copier %s, type %d\n", 2015 swidget->widget->name, swidget->id); 2016 2017 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; 2018 copier_data = &ipc4_copier->data; 2019 available_fmt = &ipc4_copier->available_fmt; 2020 2021 ref_params = kmemdup(pipeline_params, sizeof(*ref_params), GFP_KERNEL); 2022 if (!ref_params) 2023 return -ENOMEM; 2024 2025 break; 2026 } 2027 default: 2028 dev_err(sdev->dev, "unsupported type %d for copier %s", 2029 swidget->id, swidget->widget->name); 2030 return -EINVAL; 2031 } 2032 2033 /* set input and output audio formats */ 2034 input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2035 &copier_data->base_config, 2036 ref_params, available_fmt); 2037 if (input_fmt_index < 0) 2038 return input_fmt_index; 2039 2040 /* set the reference params for output format selection */ 2041 single_output_bitdepth = sof_ipc4_copier_is_single_bitdepth(sdev, 2042 available_fmt->output_pin_fmts, 2043 available_fmt->num_output_formats); 2044 switch (swidget->id) { 2045 case snd_soc_dapm_aif_in: 2046 case snd_soc_dapm_dai_out: 2047 case snd_soc_dapm_buffer: 2048 { 2049 struct sof_ipc4_audio_format *in_fmt; 2050 2051 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2052 out_ref_rate = in_fmt->sampling_frequency; 2053 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2054 2055 if (!single_output_bitdepth) 2056 out_ref_valid_bits = 2057 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2058 break; 2059 } 2060 case snd_soc_dapm_aif_out: 2061 case snd_soc_dapm_dai_in: 2062 out_ref_rate = params_rate(fe_params); 2063 out_ref_channels = params_channels(fe_params); 2064 if (!single_output_bitdepth) { 2065 out_ref_valid_bits = sof_ipc4_get_valid_bits(sdev, fe_params); 2066 if (out_ref_valid_bits < 0) 2067 return out_ref_valid_bits; 2068 } 2069 break; 2070 default: 2071 /* 2072 * Unsupported type should be caught by the former switch default 2073 * case, this should never happen in reality. 2074 */ 2075 return -EINVAL; 2076 } 2077 2078 /* 2079 * if the output format is the same across all available output formats, choose 2080 * that as the reference. 2081 */ 2082 if (single_output_bitdepth) { 2083 struct sof_ipc4_audio_format *out_fmt; 2084 2085 out_fmt = &available_fmt->output_pin_fmts[0].audio_fmt; 2086 out_ref_valid_bits = 2087 SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(out_fmt->fmt_cfg); 2088 } 2089 2090 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2091 &copier_data->base_config, 2092 available_fmt, out_ref_rate, 2093 out_ref_channels, out_ref_valid_bits); 2094 if (output_fmt_index < 0) 2095 return output_fmt_index; 2096 2097 /* 2098 * Set the output format. Current topology defines pin 0 input and output formats in pairs. 2099 * This assumes that the pin 0 formats are defined before all other pins. 2100 * So pick the output audio format with the same index as the chosen 2101 * input format. This logic will need to be updated when the format definitions 2102 * in topology change. 2103 */ 2104 memcpy(&copier_data->out_format, 2105 &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt, 2106 sizeof(struct sof_ipc4_audio_format)); 2107 2108 switch (swidget->id) { 2109 case snd_soc_dapm_dai_in: 2110 case snd_soc_dapm_dai_out: 2111 { 2112 /* 2113 * Only SOF_DAI_INTEL_ALH needs copier_data to set blob. 2114 * That's why only ALH dai's blob is set after sof_ipc4_init_input_audio_fmt 2115 */ 2116 if (ipc4_copier->dai_type == SOF_DAI_INTEL_ALH) { 2117 struct sof_ipc4_alh_configuration_blob *blob; 2118 struct sof_ipc4_dma_config *dma_config; 2119 struct sof_ipc4_copier_data *alh_data; 2120 struct sof_ipc4_copier *alh_copier; 2121 struct snd_sof_widget *w; 2122 u32 ch_count = 0; 2123 u32 ch_mask = 0; 2124 u32 ch_map; 2125 u32 step; 2126 u32 mask; 2127 2128 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; 2129 2130 blob->gw_attr.lp_buffer_alloc = 0; 2131 2132 /* Get channel_mask from ch_map */ 2133 ch_map = copier_data->base_config.audio_fmt.ch_map; 2134 for (i = 0; ch_map; i++) { 2135 if ((ch_map & 0xf) != 0xf) { 2136 ch_mask |= BIT(i); 2137 ch_count++; 2138 } 2139 ch_map >>= 4; 2140 } 2141 2142 step = ch_count / blob->alh_cfg.device_count; 2143 mask = GENMASK(step - 1, 0); 2144 /* 2145 * Set each gtw_cfg.node_id to blob->alh_cfg.mapping[] 2146 * for all widgets with the same stream name 2147 */ 2148 i = 0; 2149 list_for_each_entry(w, &sdev->widget_list, list) { 2150 u32 node_type; 2151 2152 if (!WIDGET_IS_DAI(w->id) || !w->widget->sname || 2153 strcmp(w->widget->sname, swidget->widget->sname)) 2154 continue; 2155 2156 dai = w->private; 2157 if (dai->type != SOF_DAI_INTEL_ALH) 2158 continue; 2159 alh_copier = (struct sof_ipc4_copier *)dai->private; 2160 alh_data = &alh_copier->data; 2161 node_type = SOF_IPC4_GET_NODE_TYPE(alh_data->gtw_cfg.node_id); 2162 blob->alh_cfg.mapping[i].device = SOF_IPC4_NODE_TYPE(node_type); 2163 blob->alh_cfg.mapping[i].device |= 2164 SOF_IPC4_NODE_INDEX(alh_copier->dai_index); 2165 2166 /* 2167 * The mapping[i] device in ALH blob should be the same as the 2168 * dma_config_tlv[i] mapping device if a dma_config_tlv is present. 2169 * The device id will be used for DMA tlv mapping purposes. 2170 */ 2171 if (ipc4_copier->dma_config_tlv[i].length) { 2172 dma_config = &ipc4_copier->dma_config_tlv[i].dma_config; 2173 blob->alh_cfg.mapping[i].device = 2174 dma_config->dma_stream_channel_map.mapping[0].device; 2175 } 2176 2177 /* 2178 * Set the same channel mask for playback as the audio data is 2179 * duplicated for all speakers. For capture, split the channels 2180 * among the aggregated DAIs. For example, with 4 channels on 2 2181 * aggregated DAIs, the channel_mask should be 0x3 and 0xc for the 2182 * two DAI's. 2183 * The channel masks used depend on the cpu_dais used in the 2184 * dailink at the machine driver level, which actually comes from 2185 * the tables in soc_acpi files depending on the _ADR and devID 2186 * registers for each codec. 2187 */ 2188 if (w->id == snd_soc_dapm_dai_in) 2189 blob->alh_cfg.mapping[i].channel_mask = ch_mask; 2190 else 2191 blob->alh_cfg.mapping[i].channel_mask = mask << (step * i); 2192 2193 i++; 2194 } 2195 if (blob->alh_cfg.device_count > 1) { 2196 int group_id; 2197 2198 group_id = ida_alloc_max(&alh_group_ida, ALH_MULTI_GTW_COUNT - 1, 2199 GFP_KERNEL); 2200 2201 if (group_id < 0) 2202 return group_id; 2203 2204 /* add multi-gateway base */ 2205 group_id += ALH_MULTI_GTW_BASE; 2206 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 2207 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(group_id); 2208 } 2209 } 2210 } 2211 } 2212 2213 /* modify the input params for the next widget */ 2214 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, 2215 &copier_data->out_format, 2216 BIT(SNDRV_PCM_HW_PARAM_FORMAT) | 2217 BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 2218 BIT(SNDRV_PCM_HW_PARAM_RATE)); 2219 if (ret) 2220 return ret; 2221 2222 /* 2223 * Set the gateway dma_buffer_size to 2ms buffer size to meet the FW expectation. In the 2224 * deep buffer case, set the dma_buffer_size depending on the deep_buffer_dma_ms set 2225 * in topology. 2226 */ 2227 switch (swidget->id) { 2228 case snd_soc_dapm_dai_in: 2229 copier_data->gtw_cfg.dma_buffer_size = 2230 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; 2231 break; 2232 case snd_soc_dapm_aif_in: 2233 copier_data->gtw_cfg.dma_buffer_size = 2234 max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) * 2235 copier_data->base_config.ibs; 2236 dev_dbg(sdev->dev, "copier %s, dma buffer%s: %u ms (%u bytes)", 2237 swidget->widget->name, 2238 deep_buffer_dma_ms ? " (using Deep Buffer)" : "", 2239 max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms), 2240 copier_data->gtw_cfg.dma_buffer_size); 2241 break; 2242 case snd_soc_dapm_dai_out: 2243 case snd_soc_dapm_aif_out: 2244 copier_data->gtw_cfg.dma_buffer_size = 2245 SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; 2246 break; 2247 default: 2248 break; 2249 } 2250 2251 data = &ipc4_copier->copier_config; 2252 ipc_config_size = &ipc4_copier->ipc_config_size; 2253 ipc_config_data = &ipc4_copier->ipc_config_data; 2254 2255 /* config_length is DWORD based */ 2256 gtw_cfg_config_length = copier_data->gtw_cfg.config_length * 4; 2257 ipc_size = sizeof(*copier_data) + gtw_cfg_config_length; 2258 2259 dma_config_tlv_size = 0; 2260 for (i = 0; i < SOF_IPC4_DMA_DEVICE_MAX_COUNT; i++) { 2261 if (ipc4_copier->dma_config_tlv[i].type != SOF_IPC4_GTW_DMA_CONFIG_ID) 2262 continue; 2263 dma_config_tlv_size += ipc4_copier->dma_config_tlv[i].length; 2264 dma_config_tlv_size += 2265 ipc4_copier->dma_config_tlv[i].dma_config.dma_priv_config_size; 2266 dma_config_tlv_size += (sizeof(ipc4_copier->dma_config_tlv[i]) - 2267 sizeof(ipc4_copier->dma_config_tlv[i].dma_config)); 2268 } 2269 2270 if (dma_config_tlv_size) { 2271 ipc_size += dma_config_tlv_size; 2272 2273 /* we also need to increase the size at the gtw level */ 2274 copier_data->gtw_cfg.config_length += dma_config_tlv_size / 4; 2275 } 2276 2277 dev_dbg(sdev->dev, "copier %s, IPC size is %d", swidget->widget->name, ipc_size); 2278 2279 *ipc_config_data = kzalloc(ipc_size, GFP_KERNEL); 2280 if (!*ipc_config_data) 2281 return -ENOMEM; 2282 2283 *ipc_config_size = ipc_size; 2284 2285 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2286 input_fmt_index, output_fmt_index); 2287 2288 /* update pipeline memory usage */ 2289 sof_ipc4_update_resource_usage(sdev, swidget, &copier_data->base_config); 2290 2291 /* copy IPC data */ 2292 memcpy(*ipc_config_data, (void *)copier_data, sizeof(*copier_data)); 2293 if (gtw_cfg_config_length) 2294 memcpy(*ipc_config_data + sizeof(*copier_data), 2295 *data, gtw_cfg_config_length); 2296 2297 /* add DMA Config TLV, if configured */ 2298 if (dma_config_tlv_size) 2299 memcpy(*ipc_config_data + sizeof(*copier_data) + 2300 gtw_cfg_config_length, 2301 &ipc4_copier->dma_config_tlv, dma_config_tlv_size); 2302 2303 /* 2304 * Restore gateway config length now that IPC payload is prepared. This avoids 2305 * counting the DMA CONFIG TLV multiple times 2306 */ 2307 copier_data->gtw_cfg.config_length = gtw_cfg_config_length / 4; 2308 2309 return 0; 2310 } 2311 2312 static int sof_ipc4_prepare_gain_module(struct snd_sof_widget *swidget, 2313 struct snd_pcm_hw_params *fe_params, 2314 struct snd_sof_platform_stream_params *platform_params, 2315 struct snd_pcm_hw_params *pipeline_params, int dir) 2316 { 2317 struct snd_soc_component *scomp = swidget->scomp; 2318 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2319 struct sof_ipc4_gain *gain = swidget->private; 2320 struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; 2321 struct sof_ipc4_audio_format *in_fmt; 2322 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2323 int input_fmt_index, output_fmt_index; 2324 2325 input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2326 &gain->data.base_config, 2327 pipeline_params, 2328 available_fmt); 2329 if (input_fmt_index < 0) 2330 return input_fmt_index; 2331 2332 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2333 out_ref_rate = in_fmt->sampling_frequency; 2334 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2335 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2336 2337 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2338 &gain->data.base_config, 2339 available_fmt, 2340 out_ref_rate, 2341 out_ref_channels, 2342 out_ref_valid_bits); 2343 if (output_fmt_index < 0) 2344 return output_fmt_index; 2345 2346 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2347 input_fmt_index, output_fmt_index); 2348 2349 /* update pipeline memory usage */ 2350 sof_ipc4_update_resource_usage(sdev, swidget, &gain->data.base_config); 2351 2352 return 0; 2353 } 2354 2355 static int sof_ipc4_prepare_mixer_module(struct snd_sof_widget *swidget, 2356 struct snd_pcm_hw_params *fe_params, 2357 struct snd_sof_platform_stream_params *platform_params, 2358 struct snd_pcm_hw_params *pipeline_params, int dir) 2359 { 2360 struct snd_soc_component *scomp = swidget->scomp; 2361 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2362 struct sof_ipc4_mixer *mixer = swidget->private; 2363 struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; 2364 struct sof_ipc4_audio_format *in_fmt; 2365 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2366 int input_fmt_index, output_fmt_index; 2367 2368 input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2369 &mixer->base_config, 2370 pipeline_params, 2371 available_fmt); 2372 if (input_fmt_index < 0) 2373 return input_fmt_index; 2374 2375 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2376 out_ref_rate = in_fmt->sampling_frequency; 2377 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2378 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2379 2380 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2381 &mixer->base_config, 2382 available_fmt, 2383 out_ref_rate, 2384 out_ref_channels, 2385 out_ref_valid_bits); 2386 if (output_fmt_index < 0) 2387 return output_fmt_index; 2388 2389 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2390 input_fmt_index, output_fmt_index); 2391 2392 /* update pipeline memory usage */ 2393 sof_ipc4_update_resource_usage(sdev, swidget, &mixer->base_config); 2394 2395 return 0; 2396 } 2397 2398 static int sof_ipc4_prepare_src_module(struct snd_sof_widget *swidget, 2399 struct snd_pcm_hw_params *fe_params, 2400 struct snd_sof_platform_stream_params *platform_params, 2401 struct snd_pcm_hw_params *pipeline_params, int dir) 2402 { 2403 struct snd_soc_component *scomp = swidget->scomp; 2404 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2405 struct sof_ipc4_src *src = swidget->private; 2406 struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; 2407 struct sof_ipc4_audio_format *out_audio_fmt; 2408 struct sof_ipc4_audio_format *in_audio_fmt; 2409 u32 out_ref_rate, out_ref_channels, out_ref_valid_bits; 2410 int output_fmt_index, input_fmt_index; 2411 2412 input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2413 &src->data.base_config, 2414 pipeline_params, 2415 available_fmt); 2416 if (input_fmt_index < 0) 2417 return input_fmt_index; 2418 2419 /* 2420 * For playback, the SRC sink rate will be configured based on the requested output 2421 * format, which is restricted to only deal with DAI's with a single format for now. 2422 */ 2423 if (dir == SNDRV_PCM_STREAM_PLAYBACK && available_fmt->num_output_formats > 1) { 2424 dev_err(sdev->dev, "Invalid number of output formats: %d for SRC %s\n", 2425 available_fmt->num_output_formats, swidget->widget->name); 2426 return -EINVAL; 2427 } 2428 2429 /* 2430 * SRC does not perform format conversion, so the output channels and valid bit depth must 2431 * be the same as that of the input. 2432 */ 2433 in_audio_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2434 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_audio_fmt->fmt_cfg); 2435 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_audio_fmt->fmt_cfg); 2436 2437 /* 2438 * For capture, the SRC module should convert the rate to match the rate requested by the 2439 * PCM hw_params. Set the reference params based on the fe_params unconditionally as it 2440 * will be ignored for playback anyway. 2441 */ 2442 out_ref_rate = params_rate(fe_params); 2443 2444 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2445 &src->data.base_config, 2446 available_fmt, 2447 out_ref_rate, 2448 out_ref_channels, 2449 out_ref_valid_bits); 2450 if (output_fmt_index < 0) 2451 return output_fmt_index; 2452 2453 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2454 input_fmt_index, output_fmt_index); 2455 2456 /* update pipeline memory usage */ 2457 sof_ipc4_update_resource_usage(sdev, swidget, &src->data.base_config); 2458 2459 out_audio_fmt = &available_fmt->output_pin_fmts[output_fmt_index].audio_fmt; 2460 src->data.sink_rate = out_audio_fmt->sampling_frequency; 2461 2462 /* update pipeline_params for sink widgets */ 2463 return sof_ipc4_update_hw_params(sdev, pipeline_params, out_audio_fmt, 2464 BIT(SNDRV_PCM_HW_PARAM_FORMAT) | 2465 BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 2466 BIT(SNDRV_PCM_HW_PARAM_RATE)); 2467 } 2468 2469 static int 2470 sof_ipc4_process_set_pin_formats(struct snd_sof_widget *swidget, int pin_type) 2471 { 2472 struct sof_ipc4_process *process = swidget->private; 2473 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; 2474 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; 2475 struct sof_ipc4_pin_format *pin_format, *format_list_to_search; 2476 struct snd_soc_component *scomp = swidget->scomp; 2477 int num_pins, format_list_count; 2478 int pin_format_offset = 0; 2479 int i, j; 2480 2481 /* set number of pins, offset of pin format and format list to search based on pin type */ 2482 if (pin_type == SOF_PIN_TYPE_INPUT) { 2483 num_pins = swidget->num_input_pins; 2484 format_list_to_search = available_fmt->input_pin_fmts; 2485 format_list_count = available_fmt->num_input_formats; 2486 } else { 2487 num_pins = swidget->num_output_pins; 2488 pin_format_offset = swidget->num_input_pins; 2489 format_list_to_search = available_fmt->output_pin_fmts; 2490 format_list_count = available_fmt->num_output_formats; 2491 } 2492 2493 for (i = pin_format_offset; i < num_pins + pin_format_offset; i++) { 2494 pin_format = &base_cfg_ext->pin_formats[i]; 2495 2496 /* Pin 0 audio formats are derived from the base config input/output format */ 2497 if (i == pin_format_offset) { 2498 if (pin_type == SOF_PIN_TYPE_INPUT) { 2499 pin_format->buffer_size = process->base_config.ibs; 2500 pin_format->audio_fmt = process->base_config.audio_fmt; 2501 } else { 2502 pin_format->buffer_size = process->base_config.obs; 2503 pin_format->audio_fmt = process->output_format; 2504 } 2505 continue; 2506 } 2507 2508 /* 2509 * For all other pins, find the pin formats from those set in topology. If there 2510 * is more than one format specified for a pin, this will pick the first available 2511 * one. 2512 */ 2513 for (j = 0; j < format_list_count; j++) { 2514 struct sof_ipc4_pin_format *pin_format_item = &format_list_to_search[j]; 2515 2516 if (pin_format_item->pin_index == i - pin_format_offset) { 2517 *pin_format = *pin_format_item; 2518 break; 2519 } 2520 } 2521 2522 if (j == format_list_count) { 2523 dev_err(scomp->dev, "%s pin %d format not found for %s\n", 2524 (pin_type == SOF_PIN_TYPE_INPUT) ? "input" : "output", 2525 i - pin_format_offset, swidget->widget->name); 2526 return -EINVAL; 2527 } 2528 } 2529 2530 return 0; 2531 } 2532 2533 static int sof_ipc4_process_add_base_cfg_extn(struct snd_sof_widget *swidget) 2534 { 2535 int ret, i; 2536 2537 /* copy input and output pin formats */ 2538 for (i = 0; i <= SOF_PIN_TYPE_OUTPUT; i++) { 2539 ret = sof_ipc4_process_set_pin_formats(swidget, i); 2540 if (ret < 0) 2541 return ret; 2542 } 2543 2544 return 0; 2545 } 2546 2547 static int sof_ipc4_prepare_process_module(struct snd_sof_widget *swidget, 2548 struct snd_pcm_hw_params *fe_params, 2549 struct snd_sof_platform_stream_params *platform_params, 2550 struct snd_pcm_hw_params *pipeline_params, int dir) 2551 { 2552 struct snd_soc_component *scomp = swidget->scomp; 2553 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 2554 struct sof_ipc4_process *process = swidget->private; 2555 struct sof_ipc4_available_audio_format *available_fmt = &process->available_fmt; 2556 void *cfg = process->ipc_config_data; 2557 int output_fmt_index = 0; 2558 int input_fmt_index = 0; 2559 int ret; 2560 2561 input_fmt_index = sof_ipc4_init_input_audio_fmt(sdev, swidget, 2562 &process->base_config, 2563 pipeline_params, 2564 available_fmt); 2565 if (input_fmt_index < 0) 2566 return input_fmt_index; 2567 2568 /* Configure output audio format only if the module supports output */ 2569 if (available_fmt->num_output_formats) { 2570 struct sof_ipc4_audio_format *in_fmt; 2571 struct sof_ipc4_pin_format *pin_fmt; 2572 u32 out_ref_rate, out_ref_channels; 2573 int out_ref_valid_bits; 2574 2575 in_fmt = &available_fmt->input_pin_fmts[input_fmt_index].audio_fmt; 2576 2577 out_ref_rate = in_fmt->sampling_frequency; 2578 out_ref_channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(in_fmt->fmt_cfg); 2579 out_ref_valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(in_fmt->fmt_cfg); 2580 2581 output_fmt_index = sof_ipc4_init_output_audio_fmt(sdev, swidget, 2582 &process->base_config, 2583 available_fmt, 2584 out_ref_rate, 2585 out_ref_channels, 2586 out_ref_valid_bits); 2587 if (output_fmt_index < 0) 2588 return output_fmt_index; 2589 2590 pin_fmt = &available_fmt->output_pin_fmts[output_fmt_index]; 2591 2592 /* copy Pin output format for Pin 0 only */ 2593 if (pin_fmt->pin_index == 0) { 2594 memcpy(&process->output_format, &pin_fmt->audio_fmt, 2595 sizeof(struct sof_ipc4_audio_format)); 2596 2597 /* modify the pipeline params with the output format */ 2598 ret = sof_ipc4_update_hw_params(sdev, pipeline_params, 2599 &process->output_format, 2600 BIT(SNDRV_PCM_HW_PARAM_FORMAT) | 2601 BIT(SNDRV_PCM_HW_PARAM_CHANNELS) | 2602 BIT(SNDRV_PCM_HW_PARAM_RATE)); 2603 if (ret) 2604 return ret; 2605 } 2606 } 2607 2608 sof_ipc4_dbg_module_audio_format(sdev->dev, swidget, available_fmt, 2609 input_fmt_index, output_fmt_index); 2610 2611 /* update pipeline memory usage */ 2612 sof_ipc4_update_resource_usage(sdev, swidget, &process->base_config); 2613 2614 /* ipc_config_data is composed of the base_config followed by an optional extension */ 2615 memcpy(cfg, &process->base_config, sizeof(struct sof_ipc4_base_module_cfg)); 2616 cfg += sizeof(struct sof_ipc4_base_module_cfg); 2617 2618 if (process->init_config == SOF_IPC4_MODULE_INIT_CONFIG_TYPE_BASE_CFG_WITH_EXT) { 2619 struct sof_ipc4_base_module_cfg_ext *base_cfg_ext = process->base_config_ext; 2620 2621 ret = sof_ipc4_process_add_base_cfg_extn(swidget); 2622 if (ret < 0) 2623 return ret; 2624 2625 memcpy(cfg, base_cfg_ext, process->base_config_ext_size); 2626 } 2627 2628 return 0; 2629 } 2630 2631 static int sof_ipc4_control_load_volume(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) 2632 { 2633 struct sof_ipc4_control_data *control_data; 2634 struct sof_ipc4_msg *msg; 2635 int i; 2636 2637 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); 2638 2639 /* scontrol->ipc_control_data will be freed in sof_control_unload */ 2640 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); 2641 if (!scontrol->ipc_control_data) 2642 return -ENOMEM; 2643 2644 control_data = scontrol->ipc_control_data; 2645 control_data->index = scontrol->index; 2646 2647 msg = &control_data->msg; 2648 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); 2649 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 2650 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 2651 2652 /* volume controls with range 0-1 (off/on) are switch controls */ 2653 if (scontrol->max == 1) 2654 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_SWITCH_CONTROL_PARAM_ID); 2655 else 2656 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_GAIN_PARAM_ID); 2657 2658 for (i = 0; i < scontrol->num_channels; i++) { 2659 control_data->chanv[i].channel = i; 2660 /* 2661 * Default, initial values: 2662 * - 0dB for volume controls 2663 * - off (0) for switch controls - value already zero after 2664 * memory allocation 2665 */ 2666 if (scontrol->max > 1) 2667 control_data->chanv[i].value = SOF_IPC4_VOL_ZERO_DB; 2668 } 2669 2670 return 0; 2671 } 2672 2673 static int sof_ipc4_control_load_enum(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) 2674 { 2675 struct sof_ipc4_control_data *control_data; 2676 struct sof_ipc4_msg *msg; 2677 int i; 2678 2679 scontrol->size = struct_size(control_data, chanv, scontrol->num_channels); 2680 2681 /* scontrol->ipc_control_data will be freed in sof_control_unload */ 2682 scontrol->ipc_control_data = kzalloc(scontrol->size, GFP_KERNEL); 2683 if (!scontrol->ipc_control_data) 2684 return -ENOMEM; 2685 2686 control_data = scontrol->ipc_control_data; 2687 control_data->index = scontrol->index; 2688 2689 msg = &control_data->msg; 2690 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); 2691 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 2692 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 2693 2694 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_ENUM_CONTROL_PARAM_ID); 2695 2696 /* Default, initial value for enums: first enum entry is selected (0) */ 2697 for (i = 0; i < scontrol->num_channels; i++) 2698 control_data->chanv[i].channel = i; 2699 2700 return 0; 2701 } 2702 2703 static int sof_ipc4_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) 2704 { 2705 struct sof_ipc4_control_data *control_data; 2706 struct sof_ipc4_msg *msg; 2707 int ret; 2708 2709 if (scontrol->max_size < (sizeof(*control_data) + sizeof(struct sof_abi_hdr))) { 2710 dev_err(sdev->dev, "insufficient size for a bytes control %s: %zu.\n", 2711 scontrol->name, scontrol->max_size); 2712 return -EINVAL; 2713 } 2714 2715 if (scontrol->priv_size > scontrol->max_size - sizeof(*control_data)) { 2716 dev_err(sdev->dev, "scontrol %s bytes data size %zu exceeds max %zu.\n", 2717 scontrol->name, scontrol->priv_size, 2718 scontrol->max_size - sizeof(*control_data)); 2719 return -EINVAL; 2720 } 2721 2722 scontrol->size = sizeof(struct sof_ipc4_control_data) + scontrol->priv_size; 2723 2724 scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); 2725 if (!scontrol->ipc_control_data) 2726 return -ENOMEM; 2727 2728 control_data = scontrol->ipc_control_data; 2729 control_data->index = scontrol->index; 2730 if (scontrol->priv_size > 0) { 2731 memcpy(control_data->data, scontrol->priv, scontrol->priv_size); 2732 kfree(scontrol->priv); 2733 scontrol->priv = NULL; 2734 2735 if (control_data->data->magic != SOF_IPC4_ABI_MAGIC) { 2736 dev_err(sdev->dev, "Wrong ABI magic (%#x) for control: %s\n", 2737 control_data->data->magic, scontrol->name); 2738 ret = -EINVAL; 2739 goto err; 2740 } 2741 2742 /* TODO: check the ABI version */ 2743 2744 if (control_data->data->size + sizeof(struct sof_abi_hdr) != 2745 scontrol->priv_size) { 2746 dev_err(sdev->dev, "Control %s conflict in bytes %zu vs. priv size %zu.\n", 2747 scontrol->name, 2748 control_data->data->size + sizeof(struct sof_abi_hdr), 2749 scontrol->priv_size); 2750 ret = -EINVAL; 2751 goto err; 2752 } 2753 } 2754 2755 msg = &control_data->msg; 2756 msg->primary = SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_LARGE_CONFIG_SET); 2757 msg->primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 2758 msg->primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 2759 2760 return 0; 2761 2762 err: 2763 kfree(scontrol->ipc_control_data); 2764 scontrol->ipc_control_data = NULL; 2765 return ret; 2766 } 2767 2768 static int sof_ipc4_control_setup(struct snd_sof_dev *sdev, struct snd_sof_control *scontrol) 2769 { 2770 switch (scontrol->info_type) { 2771 case SND_SOC_TPLG_CTL_VOLSW: 2772 case SND_SOC_TPLG_CTL_VOLSW_SX: 2773 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 2774 return sof_ipc4_control_load_volume(sdev, scontrol); 2775 case SND_SOC_TPLG_CTL_BYTES: 2776 return sof_ipc4_control_load_bytes(sdev, scontrol); 2777 case SND_SOC_TPLG_CTL_ENUM: 2778 case SND_SOC_TPLG_CTL_ENUM_VALUE: 2779 return sof_ipc4_control_load_enum(sdev, scontrol); 2780 default: 2781 break; 2782 } 2783 2784 return 0; 2785 } 2786 2787 static int sof_ipc4_widget_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) 2788 { 2789 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 2790 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 2791 struct sof_ipc4_pipeline *pipeline; 2792 struct sof_ipc4_msg *msg; 2793 void *ipc_data = NULL; 2794 u32 ipc_size = 0; 2795 int ret; 2796 2797 switch (swidget->id) { 2798 case snd_soc_dapm_scheduler: 2799 pipeline = swidget->private; 2800 2801 if (pipeline->use_chain_dma) { 2802 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", 2803 swidget->widget->name); 2804 return 0; 2805 } 2806 2807 dev_dbg(sdev->dev, "pipeline: %d memory pages: %d\n", swidget->pipeline_id, 2808 pipeline->mem_usage); 2809 2810 msg = &pipeline->msg; 2811 msg->primary |= pipeline->mem_usage; 2812 2813 swidget->instance_id = ida_alloc_max(&pipeline_ida, ipc4_data->max_num_pipelines, 2814 GFP_KERNEL); 2815 if (swidget->instance_id < 0) { 2816 dev_err(sdev->dev, "failed to assign pipeline id for %s: %d\n", 2817 swidget->widget->name, swidget->instance_id); 2818 return swidget->instance_id; 2819 } 2820 msg->primary &= ~SOF_IPC4_GLB_PIPE_INSTANCE_MASK; 2821 msg->primary |= SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); 2822 break; 2823 case snd_soc_dapm_aif_in: 2824 case snd_soc_dapm_aif_out: 2825 case snd_soc_dapm_buffer: 2826 { 2827 struct sof_ipc4_copier *ipc4_copier = swidget->private; 2828 2829 pipeline = pipe_widget->private; 2830 if (pipeline->use_chain_dma) 2831 return 0; 2832 2833 ipc_size = ipc4_copier->ipc_config_size; 2834 ipc_data = ipc4_copier->ipc_config_data; 2835 2836 msg = &ipc4_copier->msg; 2837 break; 2838 } 2839 case snd_soc_dapm_dai_in: 2840 case snd_soc_dapm_dai_out: 2841 { 2842 struct snd_sof_dai *dai = swidget->private; 2843 struct sof_ipc4_copier *ipc4_copier = dai->private; 2844 2845 pipeline = pipe_widget->private; 2846 if (pipeline->use_chain_dma) 2847 return 0; 2848 2849 ipc_size = ipc4_copier->ipc_config_size; 2850 ipc_data = ipc4_copier->ipc_config_data; 2851 2852 msg = &ipc4_copier->msg; 2853 break; 2854 } 2855 case snd_soc_dapm_pga: 2856 { 2857 struct sof_ipc4_gain *gain = swidget->private; 2858 2859 ipc_size = sizeof(gain->data); 2860 ipc_data = &gain->data; 2861 2862 msg = &gain->msg; 2863 break; 2864 } 2865 case snd_soc_dapm_mixer: 2866 { 2867 struct sof_ipc4_mixer *mixer = swidget->private; 2868 2869 ipc_size = sizeof(mixer->base_config); 2870 ipc_data = &mixer->base_config; 2871 2872 msg = &mixer->msg; 2873 break; 2874 } 2875 case snd_soc_dapm_src: 2876 { 2877 struct sof_ipc4_src *src = swidget->private; 2878 2879 ipc_size = sizeof(src->data); 2880 ipc_data = &src->data; 2881 2882 msg = &src->msg; 2883 break; 2884 } 2885 case snd_soc_dapm_asrc: 2886 { 2887 struct sof_ipc4_asrc *asrc = swidget->private; 2888 2889 ipc_size = sizeof(asrc->data); 2890 ipc_data = &asrc->data; 2891 2892 msg = &asrc->msg; 2893 break; 2894 } 2895 case snd_soc_dapm_effect: 2896 { 2897 struct sof_ipc4_process *process = swidget->private; 2898 2899 if (!process->ipc_config_size) { 2900 dev_err(sdev->dev, "module %s has no config data!\n", 2901 swidget->widget->name); 2902 return -EINVAL; 2903 } 2904 2905 ipc_size = process->ipc_config_size; 2906 ipc_data = process->ipc_config_data; 2907 2908 msg = &process->msg; 2909 break; 2910 } 2911 default: 2912 dev_err(sdev->dev, "widget type %d not supported", swidget->id); 2913 return -EINVAL; 2914 } 2915 2916 if (swidget->id != snd_soc_dapm_scheduler) { 2917 int module_id = msg->primary & SOF_IPC4_MOD_ID_MASK; 2918 2919 ret = sof_ipc4_widget_assign_instance_id(sdev, swidget); 2920 if (ret < 0) { 2921 dev_err(sdev->dev, "failed to assign instance id for %s\n", 2922 swidget->widget->name); 2923 return ret; 2924 } 2925 2926 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; 2927 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); 2928 2929 msg->extension &= ~SOF_IPC4_MOD_EXT_PARAM_SIZE_MASK; 2930 msg->extension |= SOF_IPC4_MOD_EXT_PARAM_SIZE(ipc_size >> 2); 2931 2932 msg->extension &= ~SOF_IPC4_MOD_EXT_PPL_ID_MASK; 2933 msg->extension |= SOF_IPC4_MOD_EXT_PPL_ID(pipe_widget->instance_id); 2934 2935 dev_dbg(sdev->dev, "Create widget %s (pipe %d) - ID %d, instance %d, core %d\n", 2936 swidget->widget->name, swidget->pipeline_id, module_id, 2937 swidget->instance_id, swidget->core); 2938 } else { 2939 dev_dbg(sdev->dev, "Create pipeline %s (pipe %d) - instance %d, core %d\n", 2940 swidget->widget->name, swidget->pipeline_id, 2941 swidget->instance_id, swidget->core); 2942 } 2943 2944 msg->data_size = ipc_size; 2945 msg->data_ptr = ipc_data; 2946 2947 ret = sof_ipc_tx_message_no_reply(sdev->ipc, msg, ipc_size); 2948 if (ret < 0) { 2949 dev_err(sdev->dev, "failed to create module %s\n", swidget->widget->name); 2950 2951 if (swidget->id != snd_soc_dapm_scheduler) { 2952 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 2953 2954 ida_free(&fw_module->m_ida, swidget->instance_id); 2955 } else { 2956 ida_free(&pipeline_ida, swidget->instance_id); 2957 } 2958 } 2959 2960 return ret; 2961 } 2962 2963 static int sof_ipc4_widget_free(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) 2964 { 2965 struct sof_ipc4_fw_module *fw_module = swidget->module_info; 2966 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 2967 int ret = 0; 2968 2969 mutex_lock(&ipc4_data->pipeline_state_mutex); 2970 2971 /* freeing a pipeline frees all the widgets associated with it */ 2972 if (swidget->id == snd_soc_dapm_scheduler) { 2973 struct sof_ipc4_pipeline *pipeline = swidget->private; 2974 struct sof_ipc4_msg msg = {{ 0 }}; 2975 u32 header; 2976 2977 if (pipeline->use_chain_dma) { 2978 dev_warn(sdev->dev, "use_chain_dma set for scheduler %s", 2979 swidget->widget->name); 2980 mutex_unlock(&ipc4_data->pipeline_state_mutex); 2981 return 0; 2982 } 2983 2984 header = SOF_IPC4_GLB_PIPE_INSTANCE_ID(swidget->instance_id); 2985 header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_GLB_DELETE_PIPELINE); 2986 header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 2987 header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_FW_GEN_MSG); 2988 2989 msg.primary = header; 2990 2991 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); 2992 if (ret < 0) 2993 dev_err(sdev->dev, "failed to free pipeline widget %s\n", 2994 swidget->widget->name); 2995 2996 pipeline->mem_usage = 0; 2997 pipeline->state = SOF_IPC4_PIPE_UNINITIALIZED; 2998 ida_free(&pipeline_ida, swidget->instance_id); 2999 swidget->instance_id = -EINVAL; 3000 } else { 3001 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 3002 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 3003 3004 if (!pipeline->use_chain_dma) 3005 ida_free(&fw_module->m_ida, swidget->instance_id); 3006 } 3007 3008 mutex_unlock(&ipc4_data->pipeline_state_mutex); 3009 3010 return ret; 3011 } 3012 3013 static int sof_ipc4_get_queue_id(struct snd_sof_widget *src_widget, 3014 struct snd_sof_widget *sink_widget, bool pin_type) 3015 { 3016 struct snd_sof_widget *current_swidget; 3017 struct snd_soc_component *scomp; 3018 struct ida *queue_ida; 3019 const char *buddy_name; 3020 char **pin_binding; 3021 u32 num_pins; 3022 int i; 3023 3024 if (pin_type == SOF_PIN_TYPE_OUTPUT) { 3025 current_swidget = src_widget; 3026 pin_binding = src_widget->output_pin_binding; 3027 queue_ida = &src_widget->output_queue_ida; 3028 num_pins = src_widget->num_output_pins; 3029 buddy_name = sink_widget->widget->name; 3030 } else { 3031 current_swidget = sink_widget; 3032 pin_binding = sink_widget->input_pin_binding; 3033 queue_ida = &sink_widget->input_queue_ida; 3034 num_pins = sink_widget->num_input_pins; 3035 buddy_name = src_widget->widget->name; 3036 } 3037 3038 scomp = current_swidget->scomp; 3039 3040 if (num_pins < 1) { 3041 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", 3042 (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"), 3043 num_pins, current_swidget->widget->name); 3044 return -EINVAL; 3045 } 3046 3047 /* If there is only one input/output pin, queue id must be 0 */ 3048 if (num_pins == 1) 3049 return 0; 3050 3051 /* Allocate queue ID from pin binding array if it is defined in topology. */ 3052 if (pin_binding) { 3053 for (i = 0; i < num_pins; i++) { 3054 if (!strcmp(pin_binding[i], buddy_name)) 3055 return i; 3056 } 3057 /* 3058 * Fail if no queue ID found from pin binding array, so that we don't 3059 * mixed use pin binding array and ida for queue ID allocation. 3060 */ 3061 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", 3062 (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"), 3063 current_swidget->widget->name); 3064 return -EINVAL; 3065 } 3066 3067 /* If no pin binding array specified in topology, use ida to allocate one */ 3068 return ida_alloc_max(queue_ida, num_pins, GFP_KERNEL); 3069 } 3070 3071 static void sof_ipc4_put_queue_id(struct snd_sof_widget *swidget, int queue_id, 3072 bool pin_type) 3073 { 3074 struct ida *queue_ida; 3075 char **pin_binding; 3076 int num_pins; 3077 3078 if (pin_type == SOF_PIN_TYPE_OUTPUT) { 3079 pin_binding = swidget->output_pin_binding; 3080 queue_ida = &swidget->output_queue_ida; 3081 num_pins = swidget->num_output_pins; 3082 } else { 3083 pin_binding = swidget->input_pin_binding; 3084 queue_ida = &swidget->input_queue_ida; 3085 num_pins = swidget->num_input_pins; 3086 } 3087 3088 /* Nothing to free if queue ID is not allocated with ida. */ 3089 if (num_pins == 1 || pin_binding) 3090 return; 3091 3092 ida_free(queue_ida, queue_id); 3093 } 3094 3095 static int sof_ipc4_set_copier_sink_format(struct snd_sof_dev *sdev, 3096 struct snd_sof_widget *src_widget, 3097 struct snd_sof_widget *sink_widget, 3098 struct snd_sof_route *sroute) 3099 { 3100 struct sof_ipc4_copier_config_set_sink_format format; 3101 const struct sof_ipc_ops *iops = sdev->ipc->ops; 3102 struct sof_ipc4_base_module_cfg *src_config; 3103 const struct sof_ipc4_audio_format *pin_fmt; 3104 struct sof_ipc4_fw_module *fw_module; 3105 struct sof_ipc4_msg msg = {{ 0 }}; 3106 3107 if (WIDGET_IS_DAI(src_widget->id)) { 3108 struct snd_sof_dai *dai = src_widget->private; 3109 3110 src_config = dai->private; 3111 } else { 3112 src_config = src_widget->private; 3113 } 3114 3115 fw_module = src_widget->module_info; 3116 3117 format.sink_id = sroute->src_queue_id; 3118 memcpy(&format.source_fmt, &src_config->audio_fmt, sizeof(format.source_fmt)); 3119 3120 pin_fmt = sof_ipc4_get_input_pin_audio_fmt(sink_widget, sroute->dst_queue_id); 3121 if (!pin_fmt) { 3122 dev_err(sdev->dev, 3123 "Failed to get input audio format of %s:%d for output of %s:%d\n", 3124 sink_widget->widget->name, sroute->dst_queue_id, 3125 src_widget->widget->name, sroute->src_queue_id); 3126 return -EINVAL; 3127 } 3128 3129 memcpy(&format.sink_fmt, pin_fmt, sizeof(format.sink_fmt)); 3130 3131 msg.data_size = sizeof(format); 3132 msg.data_ptr = &format; 3133 3134 msg.primary = fw_module->man4_module_entry.id; 3135 msg.primary |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); 3136 msg.primary |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 3137 msg.primary |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 3138 3139 msg.extension = 3140 SOF_IPC4_MOD_EXT_MSG_PARAM_ID(SOF_IPC4_COPIER_MODULE_CFG_PARAM_SET_SINK_FORMAT); 3141 3142 return iops->set_get_data(sdev, &msg, msg.data_size, true); 3143 } 3144 3145 static int sof_ipc4_route_setup(struct snd_sof_dev *sdev, struct snd_sof_route *sroute) 3146 { 3147 struct snd_sof_widget *src_widget = sroute->src_widget; 3148 struct snd_sof_widget *sink_widget = sroute->sink_widget; 3149 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; 3150 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; 3151 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; 3152 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; 3153 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; 3154 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; 3155 struct sof_ipc4_msg msg = {{ 0 }}; 3156 u32 header, extension; 3157 int ret; 3158 3159 /* no route set up if chain DMA is used */ 3160 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) { 3161 if (!src_pipeline->use_chain_dma || !sink_pipeline->use_chain_dma) { 3162 dev_err(sdev->dev, 3163 "use_chain_dma must be set for both src %s and sink %s pipelines\n", 3164 src_widget->widget->name, sink_widget->widget->name); 3165 return -EINVAL; 3166 } 3167 return 0; 3168 } 3169 3170 if (!src_fw_module || !sink_fw_module) { 3171 dev_err(sdev->dev, 3172 "cannot bind %s -> %s, no firmware module for: %s%s\n", 3173 src_widget->widget->name, sink_widget->widget->name, 3174 src_fw_module ? "" : " source", 3175 sink_fw_module ? "" : " sink"); 3176 3177 return -ENODEV; 3178 } 3179 3180 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 3181 SOF_PIN_TYPE_OUTPUT); 3182 if (sroute->src_queue_id < 0) { 3183 dev_err(sdev->dev, 3184 "failed to get src_queue_id ID from source widget %s\n", 3185 src_widget->widget->name); 3186 return sroute->src_queue_id; 3187 } 3188 3189 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 3190 SOF_PIN_TYPE_INPUT); 3191 if (sroute->dst_queue_id < 0) { 3192 dev_err(sdev->dev, 3193 "failed to get dst_queue_id ID from sink widget %s\n", 3194 sink_widget->widget->name); 3195 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, 3196 SOF_PIN_TYPE_OUTPUT); 3197 return sroute->dst_queue_id; 3198 } 3199 3200 /* Pin 0 format is already set during copier module init */ 3201 if (sroute->src_queue_id > 0 && WIDGET_IS_COPIER(src_widget->id)) { 3202 ret = sof_ipc4_set_copier_sink_format(sdev, src_widget, 3203 sink_widget, sroute); 3204 if (ret < 0) { 3205 dev_err(sdev->dev, 3206 "failed to set sink format for source %s:%d\n", 3207 src_widget->widget->name, sroute->src_queue_id); 3208 goto out; 3209 } 3210 } 3211 3212 dev_dbg(sdev->dev, "bind %s:%d -> %s:%d\n", 3213 src_widget->widget->name, sroute->src_queue_id, 3214 sink_widget->widget->name, sroute->dst_queue_id); 3215 3216 header = src_fw_module->man4_module_entry.id; 3217 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); 3218 header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_BIND); 3219 header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 3220 header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 3221 3222 extension = sink_fw_module->man4_module_entry.id; 3223 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); 3224 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); 3225 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); 3226 3227 msg.primary = header; 3228 msg.extension = extension; 3229 3230 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); 3231 if (ret < 0) { 3232 dev_err(sdev->dev, "failed to bind modules %s:%d -> %s:%d\n", 3233 src_widget->widget->name, sroute->src_queue_id, 3234 sink_widget->widget->name, sroute->dst_queue_id); 3235 goto out; 3236 } 3237 3238 return ret; 3239 3240 out: 3241 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); 3242 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); 3243 return ret; 3244 } 3245 3246 static int sof_ipc4_route_free(struct snd_sof_dev *sdev, struct snd_sof_route *sroute) 3247 { 3248 struct snd_sof_widget *src_widget = sroute->src_widget; 3249 struct snd_sof_widget *sink_widget = sroute->sink_widget; 3250 struct sof_ipc4_fw_module *src_fw_module = src_widget->module_info; 3251 struct sof_ipc4_fw_module *sink_fw_module = sink_widget->module_info; 3252 struct sof_ipc4_msg msg = {{ 0 }}; 3253 struct snd_sof_widget *src_pipe_widget = src_widget->spipe->pipe_widget; 3254 struct snd_sof_widget *sink_pipe_widget = sink_widget->spipe->pipe_widget; 3255 struct sof_ipc4_pipeline *src_pipeline = src_pipe_widget->private; 3256 struct sof_ipc4_pipeline *sink_pipeline = sink_pipe_widget->private; 3257 u32 header, extension; 3258 int ret = 0; 3259 3260 /* no route is set up if chain DMA is used */ 3261 if (src_pipeline->use_chain_dma || sink_pipeline->use_chain_dma) 3262 return 0; 3263 3264 dev_dbg(sdev->dev, "unbind modules %s:%d -> %s:%d\n", 3265 src_widget->widget->name, sroute->src_queue_id, 3266 sink_widget->widget->name, sroute->dst_queue_id); 3267 3268 /* 3269 * routes belonging to the same pipeline will be disconnected by the FW when the pipeline 3270 * is freed. So avoid sending this IPC which will be ignored by the FW anyway. 3271 */ 3272 if (src_widget->spipe->pipe_widget == sink_widget->spipe->pipe_widget) 3273 goto out; 3274 3275 header = src_fw_module->man4_module_entry.id; 3276 header |= SOF_IPC4_MOD_INSTANCE(src_widget->instance_id); 3277 header |= SOF_IPC4_MSG_TYPE_SET(SOF_IPC4_MOD_UNBIND); 3278 header |= SOF_IPC4_MSG_DIR(SOF_IPC4_MSG_REQUEST); 3279 header |= SOF_IPC4_MSG_TARGET(SOF_IPC4_MODULE_MSG); 3280 3281 extension = sink_fw_module->man4_module_entry.id; 3282 extension |= SOF_IPC4_MOD_EXT_DST_MOD_INSTANCE(sink_widget->instance_id); 3283 extension |= SOF_IPC4_MOD_EXT_DST_MOD_QUEUE_ID(sroute->dst_queue_id); 3284 extension |= SOF_IPC4_MOD_EXT_SRC_MOD_QUEUE_ID(sroute->src_queue_id); 3285 3286 msg.primary = header; 3287 msg.extension = extension; 3288 3289 ret = sof_ipc_tx_message_no_reply(sdev->ipc, &msg, 0); 3290 if (ret < 0) 3291 dev_err(sdev->dev, "failed to unbind modules %s:%d -> %s:%d\n", 3292 src_widget->widget->name, sroute->src_queue_id, 3293 sink_widget->widget->name, sroute->dst_queue_id); 3294 out: 3295 sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); 3296 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); 3297 3298 return ret; 3299 } 3300 3301 static int sof_ipc4_dai_config(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, 3302 unsigned int flags, struct snd_sof_dai_config_data *data) 3303 { 3304 struct snd_sof_widget *pipe_widget = swidget->spipe->pipe_widget; 3305 struct sof_ipc4_pipeline *pipeline = pipe_widget->private; 3306 struct snd_sof_dai *dai = swidget->private; 3307 struct sof_ipc4_gtw_attributes *gtw_attr; 3308 struct sof_ipc4_copier_data *copier_data; 3309 struct sof_ipc4_copier *ipc4_copier; 3310 3311 if (!dai || !dai->private) { 3312 dev_err(sdev->dev, "Invalid DAI or DAI private data for %s\n", 3313 swidget->widget->name); 3314 return -EINVAL; 3315 } 3316 3317 ipc4_copier = (struct sof_ipc4_copier *)dai->private; 3318 copier_data = &ipc4_copier->data; 3319 3320 if (!data) 3321 return 0; 3322 3323 if (pipeline->use_chain_dma) { 3324 /* 3325 * Only configure the DMA Link ID for ChainDMA when this op is 3326 * invoked with SOF_DAI_CONFIG_FLAGS_HW_PARAMS 3327 */ 3328 if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { 3329 pipeline->msg.primary &= ~SOF_IPC4_GLB_CHAIN_DMA_LINK_ID_MASK; 3330 pipeline->msg.primary |= SOF_IPC4_GLB_CHAIN_DMA_LINK_ID(data->dai_data); 3331 } 3332 return 0; 3333 } 3334 3335 switch (ipc4_copier->dai_type) { 3336 case SOF_DAI_INTEL_HDA: 3337 gtw_attr = ipc4_copier->gtw_attr; 3338 gtw_attr->lp_buffer_alloc = pipeline->lp_mode; 3339 if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { 3340 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 3341 copier_data->gtw_cfg.node_id |= SOF_IPC4_NODE_INDEX(data->dai_data); 3342 } 3343 break; 3344 case SOF_DAI_INTEL_ALH: 3345 /* 3346 * Do not clear the node ID when this op is invoked with 3347 * SOF_DAI_CONFIG_FLAGS_HW_FREE. It is needed to free the group_ida during 3348 * unprepare. The node_id for multi-gateway DAI's will be overwritten with the 3349 * group_id during copier's ipc_prepare op. 3350 */ 3351 if (flags & SOF_DAI_CONFIG_FLAGS_HW_PARAMS) { 3352 struct sof_ipc4_alh_configuration_blob *blob; 3353 3354 blob = (struct sof_ipc4_alh_configuration_blob *)ipc4_copier->copier_config; 3355 ipc4_copier->dai_index = data->dai_node_id; 3356 3357 /* 3358 * no need to set the node_id for aggregated DAI's. These will be assigned 3359 * a group_id during widget ipc_prepare 3360 */ 3361 if (blob->alh_cfg.device_count == 1) { 3362 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 3363 copier_data->gtw_cfg.node_id |= 3364 SOF_IPC4_NODE_INDEX(data->dai_node_id); 3365 } 3366 } 3367 3368 break; 3369 case SOF_DAI_INTEL_DMIC: 3370 case SOF_DAI_INTEL_SSP: 3371 /* nothing to do for SSP/DMIC */ 3372 break; 3373 default: 3374 dev_err(sdev->dev, "%s: unsupported dai type %d\n", __func__, 3375 ipc4_copier->dai_type); 3376 return -EINVAL; 3377 } 3378 3379 return 0; 3380 } 3381 3382 static int sof_ipc4_parse_manifest(struct snd_soc_component *scomp, int index, 3383 struct snd_soc_tplg_manifest *man) 3384 { 3385 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 3386 struct sof_ipc4_fw_data *ipc4_data = sdev->private; 3387 struct sof_manifest_tlv *manifest_tlv; 3388 struct sof_manifest *manifest; 3389 u32 size = le32_to_cpu(man->priv.size); 3390 u8 *man_ptr = man->priv.data; 3391 u32 len_check; 3392 int i; 3393 3394 if (!size || size < SOF_IPC4_TPLG_ABI_SIZE) { 3395 dev_err(scomp->dev, "%s: Invalid topology ABI size: %u\n", 3396 __func__, size); 3397 return -EINVAL; 3398 } 3399 3400 manifest = (struct sof_manifest *)man_ptr; 3401 3402 dev_info(scomp->dev, 3403 "Topology: ABI %d:%d:%d Kernel ABI %u:%u:%u\n", 3404 le16_to_cpu(manifest->abi_major), le16_to_cpu(manifest->abi_minor), 3405 le16_to_cpu(manifest->abi_patch), 3406 SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH); 3407 3408 /* TODO: Add ABI compatibility check */ 3409 3410 /* no more data after the ABI version */ 3411 if (size <= SOF_IPC4_TPLG_ABI_SIZE) 3412 return 0; 3413 3414 manifest_tlv = manifest->items; 3415 len_check = sizeof(struct sof_manifest); 3416 for (i = 0; i < le16_to_cpu(manifest->count); i++) { 3417 len_check += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); 3418 if (len_check > size) 3419 return -EINVAL; 3420 3421 switch (le32_to_cpu(manifest_tlv->type)) { 3422 case SOF_MANIFEST_DATA_TYPE_NHLT: 3423 /* no NHLT in BIOS, so use the one from topology manifest */ 3424 if (ipc4_data->nhlt) 3425 break; 3426 ipc4_data->nhlt = devm_kmemdup(sdev->dev, manifest_tlv->data, 3427 le32_to_cpu(manifest_tlv->size), GFP_KERNEL); 3428 if (!ipc4_data->nhlt) 3429 return -ENOMEM; 3430 break; 3431 default: 3432 dev_warn(scomp->dev, "Skipping unknown manifest data type %d\n", 3433 manifest_tlv->type); 3434 break; 3435 } 3436 man_ptr += sizeof(struct sof_manifest_tlv) + le32_to_cpu(manifest_tlv->size); 3437 manifest_tlv = (struct sof_manifest_tlv *)man_ptr; 3438 } 3439 3440 return 0; 3441 } 3442 3443 static int sof_ipc4_dai_get_param(struct snd_sof_dev *sdev, struct snd_sof_dai *dai, int param_type) 3444 { 3445 struct sof_ipc4_copier *ipc4_copier = dai->private; 3446 struct snd_soc_tplg_hw_config *hw_config; 3447 struct snd_sof_dai_link *slink; 3448 bool dai_link_found = false; 3449 bool hw_cfg_found = false; 3450 int i; 3451 3452 if (!ipc4_copier) 3453 return 0; 3454 3455 list_for_each_entry(slink, &sdev->dai_link_list, list) { 3456 if (!strcmp(slink->link->name, dai->name)) { 3457 dai_link_found = true; 3458 break; 3459 } 3460 } 3461 3462 if (!dai_link_found) { 3463 dev_err(sdev->dev, "no DAI link found for DAI %s\n", dai->name); 3464 return -EINVAL; 3465 } 3466 3467 for (i = 0; i < slink->num_hw_configs; i++) { 3468 hw_config = &slink->hw_configs[i]; 3469 if (dai->current_config == le32_to_cpu(hw_config->id)) { 3470 hw_cfg_found = true; 3471 break; 3472 } 3473 } 3474 3475 if (!hw_cfg_found) { 3476 dev_err(sdev->dev, "no matching hw_config found for DAI %s\n", dai->name); 3477 return -EINVAL; 3478 } 3479 3480 switch (ipc4_copier->dai_type) { 3481 case SOF_DAI_INTEL_SSP: 3482 switch (param_type) { 3483 case SOF_DAI_PARAM_INTEL_SSP_MCLK: 3484 return le32_to_cpu(hw_config->mclk_rate); 3485 case SOF_DAI_PARAM_INTEL_SSP_BCLK: 3486 return le32_to_cpu(hw_config->bclk_rate); 3487 case SOF_DAI_PARAM_INTEL_SSP_TDM_SLOTS: 3488 return le32_to_cpu(hw_config->tdm_slots); 3489 default: 3490 dev_err(sdev->dev, "invalid SSP param %d\n", param_type); 3491 break; 3492 } 3493 break; 3494 default: 3495 dev_err(sdev->dev, "DAI type %d not supported yet!\n", ipc4_copier->dai_type); 3496 break; 3497 } 3498 3499 return -EINVAL; 3500 } 3501 3502 static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify) 3503 { 3504 /* 3505 * This function is called during system suspend, we need to make sure 3506 * that all streams have been freed up. 3507 * Freeing might have been skipped when xrun happened just at the start 3508 * of the suspend and it sent a SNDRV_PCM_TRIGGER_STOP to the active 3509 * stream. This will call sof_pcm_stream_free() with 3510 * free_widget_list = false which will leave the kernel and firmware out 3511 * of sync during suspend/resume. 3512 * 3513 * This will also make sure that paused streams handled correctly. 3514 */ 3515 3516 return sof_pcm_free_all_streams(sdev); 3517 } 3518 3519 static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link) 3520 { 3521 if (link->no_pcm) 3522 return 0; 3523 3524 /* 3525 * set default trigger order for all links. Exceptions to 3526 * the rule will be handled in sof_pcm_dai_link_fixup() 3527 * For playback, the sequence is the following: start BE, 3528 * start FE, stop FE, stop BE; for Capture the sequence is 3529 * inverted start FE, start BE, stop BE, stop FE 3530 */ 3531 link->trigger[SNDRV_PCM_STREAM_PLAYBACK] = SND_SOC_DPCM_TRIGGER_POST; 3532 link->trigger[SNDRV_PCM_STREAM_CAPTURE] = SND_SOC_DPCM_TRIGGER_PRE; 3533 3534 return 0; 3535 } 3536 3537 /* Tokens needed for different copier variants (aif, dai and buffer) */ 3538 static enum sof_tokens copier_token_list[] = { 3539 SOF_COMP_TOKENS, 3540 SOF_COPIER_TOKENS, 3541 SOF_AUDIO_FMT_NUM_TOKENS, 3542 SOF_IN_AUDIO_FORMAT_TOKENS, 3543 SOF_OUT_AUDIO_FORMAT_TOKENS, 3544 SOF_COMP_EXT_TOKENS, 3545 3546 SOF_COPIER_DEEP_BUFFER_TOKENS, /* for AIF copier */ 3547 SOF_DAI_TOKENS, /* for DAI copier */ 3548 }; 3549 3550 static enum sof_tokens pipeline_token_list[] = { 3551 SOF_SCHED_TOKENS, 3552 SOF_PIPELINE_TOKENS, 3553 }; 3554 3555 static enum sof_tokens pga_token_list[] = { 3556 SOF_COMP_TOKENS, 3557 SOF_GAIN_TOKENS, 3558 SOF_AUDIO_FMT_NUM_TOKENS, 3559 SOF_IN_AUDIO_FORMAT_TOKENS, 3560 SOF_OUT_AUDIO_FORMAT_TOKENS, 3561 SOF_COMP_EXT_TOKENS, 3562 }; 3563 3564 static enum sof_tokens mixer_token_list[] = { 3565 SOF_COMP_TOKENS, 3566 SOF_AUDIO_FMT_NUM_TOKENS, 3567 SOF_IN_AUDIO_FORMAT_TOKENS, 3568 SOF_OUT_AUDIO_FORMAT_TOKENS, 3569 SOF_COMP_EXT_TOKENS, 3570 }; 3571 3572 static enum sof_tokens src_token_list[] = { 3573 SOF_COMP_TOKENS, 3574 SOF_SRC_TOKENS, 3575 SOF_AUDIO_FMT_NUM_TOKENS, 3576 SOF_IN_AUDIO_FORMAT_TOKENS, 3577 SOF_OUT_AUDIO_FORMAT_TOKENS, 3578 SOF_COMP_EXT_TOKENS, 3579 }; 3580 3581 static enum sof_tokens asrc_token_list[] = { 3582 SOF_COMP_TOKENS, 3583 SOF_ASRC_TOKENS, 3584 SOF_AUDIO_FMT_NUM_TOKENS, 3585 SOF_IN_AUDIO_FORMAT_TOKENS, 3586 SOF_OUT_AUDIO_FORMAT_TOKENS, 3587 SOF_COMP_EXT_TOKENS, 3588 }; 3589 3590 static enum sof_tokens process_token_list[] = { 3591 SOF_COMP_TOKENS, 3592 SOF_AUDIO_FMT_NUM_TOKENS, 3593 SOF_IN_AUDIO_FORMAT_TOKENS, 3594 SOF_OUT_AUDIO_FORMAT_TOKENS, 3595 SOF_COMP_EXT_TOKENS, 3596 }; 3597 3598 static const struct sof_ipc_tplg_widget_ops tplg_ipc4_widget_ops[SND_SOC_DAPM_TYPE_COUNT] = { 3599 [snd_soc_dapm_aif_in] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, 3600 copier_token_list, ARRAY_SIZE(copier_token_list), 3601 NULL, sof_ipc4_prepare_copier_module, 3602 sof_ipc4_unprepare_copier_module}, 3603 [snd_soc_dapm_aif_out] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, 3604 copier_token_list, ARRAY_SIZE(copier_token_list), 3605 NULL, sof_ipc4_prepare_copier_module, 3606 sof_ipc4_unprepare_copier_module}, 3607 [snd_soc_dapm_dai_in] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, 3608 copier_token_list, ARRAY_SIZE(copier_token_list), NULL, 3609 sof_ipc4_prepare_copier_module, 3610 sof_ipc4_unprepare_copier_module}, 3611 [snd_soc_dapm_dai_out] = {sof_ipc4_widget_setup_comp_dai, sof_ipc4_widget_free_comp_dai, 3612 copier_token_list, ARRAY_SIZE(copier_token_list), NULL, 3613 sof_ipc4_prepare_copier_module, 3614 sof_ipc4_unprepare_copier_module}, 3615 [snd_soc_dapm_buffer] = {sof_ipc4_widget_setup_pcm, sof_ipc4_widget_free_comp_pcm, 3616 copier_token_list, ARRAY_SIZE(copier_token_list), 3617 NULL, sof_ipc4_prepare_copier_module, 3618 sof_ipc4_unprepare_copier_module}, 3619 [snd_soc_dapm_scheduler] = {sof_ipc4_widget_setup_comp_pipeline, 3620 sof_ipc4_widget_free_comp_pipeline, 3621 pipeline_token_list, ARRAY_SIZE(pipeline_token_list), NULL, 3622 NULL, NULL}, 3623 [snd_soc_dapm_pga] = {sof_ipc4_widget_setup_comp_pga, sof_ipc4_widget_free_comp_pga, 3624 pga_token_list, ARRAY_SIZE(pga_token_list), NULL, 3625 sof_ipc4_prepare_gain_module, 3626 NULL}, 3627 [snd_soc_dapm_mixer] = {sof_ipc4_widget_setup_comp_mixer, sof_ipc4_widget_free_comp_mixer, 3628 mixer_token_list, ARRAY_SIZE(mixer_token_list), 3629 NULL, sof_ipc4_prepare_mixer_module, 3630 NULL}, 3631 [snd_soc_dapm_src] = {sof_ipc4_widget_setup_comp_src, sof_ipc4_widget_free_comp_src, 3632 src_token_list, ARRAY_SIZE(src_token_list), 3633 NULL, sof_ipc4_prepare_src_module, 3634 NULL}, 3635 [snd_soc_dapm_asrc] = {sof_ipc4_widget_setup_comp_asrc, sof_ipc4_widget_free_comp_asrc, 3636 asrc_token_list, ARRAY_SIZE(asrc_token_list), 3637 NULL, sof_ipc4_prepare_src_module, /* Common prepare with SRC */ 3638 NULL}, 3639 [snd_soc_dapm_effect] = {sof_ipc4_widget_setup_comp_process, 3640 sof_ipc4_widget_free_comp_process, 3641 process_token_list, ARRAY_SIZE(process_token_list), 3642 NULL, sof_ipc4_prepare_process_module, 3643 NULL}, 3644 }; 3645 3646 const struct sof_ipc_tplg_ops ipc4_tplg_ops = { 3647 .widget = tplg_ipc4_widget_ops, 3648 .token_list = ipc4_token_list, 3649 .control_setup = sof_ipc4_control_setup, 3650 .control = &tplg_ipc4_control_ops, 3651 .widget_setup = sof_ipc4_widget_setup, 3652 .widget_free = sof_ipc4_widget_free, 3653 .route_setup = sof_ipc4_route_setup, 3654 .route_free = sof_ipc4_route_free, 3655 .dai_config = sof_ipc4_dai_config, 3656 .parse_manifest = sof_ipc4_parse_manifest, 3657 .dai_get_param = sof_ipc4_dai_get_param, 3658 .tear_down_all_pipelines = sof_ipc4_tear_down_all_pipelines, 3659 .link_setup = sof_ipc4_link_setup, 3660 }; 3661