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

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: SOF: ipc4: Add support for formats per pins

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

The modules in IPC4 can have multiple 'pins' on their input and output
and these pins can receive or output audio in different formats.
Currently we assume that all pins are using the same format which is a
limitation that needs to be lifted in order to support more complex
components.

This series will extend and rework the format handling to allow
different formats on pins.

+375 -379
+12 -8
include/uapi/sound/sof/tokens.h
··· 88 88 #define SOF_TKN_COMP_CPC 406 89 89 #define SOF_TKN_COMP_IS_PAGES 409 90 90 #define SOF_TKN_COMP_NUM_AUDIO_FORMATS 410 91 - #define SOF_TKN_COMP_NUM_SINK_PINS 411 92 - #define SOF_TKN_COMP_NUM_SOURCE_PINS 412 91 + #define SOF_TKN_COMP_NUM_INPUT_PINS 411 92 + #define SOF_TKN_COMP_NUM_OUTPUT_PINS 412 93 93 /* 94 - * The token for sink/source pin binding, it specifies the widget 95 - * name that the sink/source pin is connected from/to. 94 + * The token for input/output pin binding, it specifies the widget 95 + * name that the input/output pin is connected from/to. 96 96 */ 97 - #define SOF_TKN_COMP_SINK_PIN_BINDING_WNAME 413 98 - #define SOF_TKN_COMP_SRC_PIN_BINDING_WNAME 414 97 + #define SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME 413 98 + #define SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME 414 99 + #define SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS 415 100 + #define SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS 416 99 101 100 102 101 103 /* SSP */ ··· 175 173 /* CAVS AUDIO FORMAT */ 176 174 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE 1900 177 175 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH 1901 178 - #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT 1902 176 + #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_VALID_BIT_DEPTH 1902 179 177 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CHANNELS 1903 180 178 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP 1904 181 179 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG 1905 182 180 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE 1906 183 181 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG 1907 184 182 #define SOF_TKN_CAVS_AUDIO_FORMAT_IN_SAMPLE_TYPE 1908 183 + #define SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX 1909 185 184 /* intentional token numbering discontinuity, reserved for future use */ 186 185 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE 1930 187 186 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH 1931 188 - #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT 1932 187 + #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_VALID_BIT_DEPTH 1932 189 188 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CHANNELS 1933 190 189 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP 1934 191 190 #define SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG 1935 ··· 200 197 201 198 /* COPIER */ 202 199 #define SOF_TKN_INTEL_COPIER_NODE_TYPE 1980 200 + #define SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS 1981 203 201 204 202 /* ACP I2S */ 205 203 #define SOF_TKN_AMD_ACPI2S_RATE 1700
+1 -1
sound/soc/sof/ipc4-pcm.c
··· 389 389 snd_mask_none(fmt); 390 390 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); 391 391 392 - rate->min = ipc4_copier->available_fmt.base_config->audio_fmt.sampling_frequency; 392 + rate->min = ipc4_copier->available_fmt.input_pin_fmts->audio_fmt.sampling_frequency; 393 393 rate->max = rate->min; 394 394 395 395 switch (ipc4_copier->dai_type) {
+254 -283
sound/soc/sof/ipc4-topology.c
··· 41 41 offsetof(struct sof_ipc4_base_module_cfg, is_pages)}, 42 42 }; 43 43 44 - static const struct sof_topology_token ipc4_audio_format_buffer_size_tokens[] = { 45 - {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 46 - offsetof(struct sof_ipc4_base_module_cfg, ibs)}, 47 - {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 48 - offsetof(struct sof_ipc4_base_module_cfg, obs)}, 49 - }; 50 - 51 44 static const struct sof_topology_token ipc4_in_audio_format_tokens[] = { 52 45 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 53 - offsetof(struct sof_ipc4_audio_format, sampling_frequency)}, 46 + offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)}, 54 47 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 55 - offsetof(struct sof_ipc4_audio_format, bit_depth)}, 48 + offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)}, 56 49 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 57 - offsetof(struct sof_ipc4_audio_format, ch_map)}, 50 + offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)}, 58 51 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 59 - offsetof(struct sof_ipc4_audio_format, ch_cfg)}, 52 + offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)}, 60 53 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 61 - get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)}, 54 + get_token_u32, offsetof(struct sof_ipc4_pin_format, 55 + audio_fmt.interleaving_style)}, 62 56 {SOF_TKN_CAVS_AUDIO_FORMAT_IN_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 63 - offsetof(struct sof_ipc4_audio_format, fmt_cfg)}, 57 + offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)}, 58 + {SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 59 + offsetof(struct sof_ipc4_pin_format, pin_index)}, 60 + {SOF_TKN_CAVS_AUDIO_FORMAT_IBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 61 + offsetof(struct sof_ipc4_pin_format, buffer_size)}, 64 62 }; 65 63 66 64 static const struct sof_topology_token ipc4_out_audio_format_tokens[] = { 67 65 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_RATE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 68 - offsetof(struct sof_ipc4_audio_format, sampling_frequency)}, 66 + offsetof(struct sof_ipc4_pin_format, audio_fmt.sampling_frequency)}, 69 67 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_BIT_DEPTH, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 70 - offsetof(struct sof_ipc4_audio_format, bit_depth)}, 68 + offsetof(struct sof_ipc4_pin_format, audio_fmt.bit_depth)}, 71 69 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_MAP, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 72 - offsetof(struct sof_ipc4_audio_format, ch_map)}, 70 + offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_map)}, 73 71 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_CH_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 74 - offsetof(struct sof_ipc4_audio_format, ch_cfg)}, 72 + offsetof(struct sof_ipc4_pin_format, audio_fmt.ch_cfg)}, 75 73 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_INTERLEAVING_STYLE, SND_SOC_TPLG_TUPLE_TYPE_WORD, 76 - get_token_u32, offsetof(struct sof_ipc4_audio_format, interleaving_style)}, 74 + get_token_u32, offsetof(struct sof_ipc4_pin_format, 75 + audio_fmt.interleaving_style)}, 77 76 {SOF_TKN_CAVS_AUDIO_FORMAT_OUT_FMT_CFG, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 78 - offsetof(struct sof_ipc4_audio_format, fmt_cfg)}, 77 + offsetof(struct sof_ipc4_pin_format, audio_fmt.fmt_cfg)}, 78 + {SOF_TKN_CAVS_AUDIO_FORMAT_PIN_INDEX, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 79 + offsetof(struct sof_ipc4_pin_format, pin_index)}, 80 + {SOF_TKN_CAVS_AUDIO_FORMAT_OBS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 81 + offsetof(struct sof_ipc4_pin_format, buffer_size)}, 79 82 }; 80 83 81 - static const struct sof_topology_token ipc4_copier_gateway_cfg_tokens[] = { 82 - {SOF_TKN_CAVS_AUDIO_FORMAT_DMA_BUFFER_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, 84 + static const struct sof_topology_token ipc4_copier_deep_buffer_tokens[] = { 85 + {SOF_TKN_INTEL_COPIER_DEEP_BUFFER_DMA_MS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 0}, 83 86 }; 84 87 85 88 static const struct sof_topology_token ipc4_copier_tokens[] = { ··· 90 87 }; 91 88 92 89 static const struct sof_topology_token ipc4_audio_fmt_num_tokens[] = { 93 - {SOF_TKN_COMP_NUM_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 94 - 0}, 90 + {SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 91 + offsetof(struct sof_ipc4_available_audio_format, num_input_formats)}, 92 + {SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 93 + offsetof(struct sof_ipc4_available_audio_format, num_output_formats)}, 95 94 }; 96 95 97 96 static const struct sof_topology_token dai_tokens[] = { ··· 140 135 ipc4_in_audio_format_tokens, ARRAY_SIZE(ipc4_in_audio_format_tokens)}, 141 136 [SOF_OUT_AUDIO_FORMAT_TOKENS] = {"IPC4 Output Audio format tokens", 142 137 ipc4_out_audio_format_tokens, ARRAY_SIZE(ipc4_out_audio_format_tokens)}, 143 - [SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS] = {"IPC4 Audio format buffer size tokens", 144 - ipc4_audio_format_buffer_size_tokens, 145 - ARRAY_SIZE(ipc4_audio_format_buffer_size_tokens)}, 146 - [SOF_COPIER_GATEWAY_CFG_TOKENS] = {"IPC4 Copier gateway config tokens", 147 - ipc4_copier_gateway_cfg_tokens, ARRAY_SIZE(ipc4_copier_gateway_cfg_tokens)}, 138 + [SOF_COPIER_DEEP_BUFFER_TOKENS] = {"IPC4 Copier deep buffer tokens", 139 + ipc4_copier_deep_buffer_tokens, ARRAY_SIZE(ipc4_copier_deep_buffer_tokens)}, 148 140 [SOF_COPIER_TOKENS] = {"IPC4 Copier tokens", ipc4_copier_tokens, 149 141 ARRAY_SIZE(ipc4_copier_tokens)}, 150 142 [SOF_AUDIO_FMT_NUM_TOKENS] = {"IPC4 Audio format number tokens", ··· 150 148 [SOF_SRC_TOKENS] = {"SRC tokens", src_tokens, ARRAY_SIZE(src_tokens)}, 151 149 }; 152 150 153 - static void sof_ipc4_dbg_audio_format(struct device *dev, 154 - struct sof_ipc4_audio_format *format, 155 - size_t object_size, int num_format) 151 + static void sof_ipc4_dbg_audio_format(struct device *dev, struct sof_ipc4_pin_format *pin_fmt, 152 + int num_formats) 156 153 { 157 - struct sof_ipc4_audio_format *fmt; 158 - void *ptr = format; 159 154 int i; 160 155 161 - for (i = 0; i < num_format; i++, ptr = (u8 *)ptr + object_size) { 162 - fmt = ptr; 156 + for (i = 0; i < num_formats; i++) { 157 + struct sof_ipc4_audio_format *fmt = &pin_fmt[i].audio_fmt; 163 158 dev_dbg(dev, 164 - " #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x)\n", 165 - i, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, 166 - fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg); 159 + "Pin index #%d: %uHz, %ubit (ch_map %#x ch_cfg %u interleaving_style %u fmt_cfg %#x) buffer size %d\n", 160 + pin_fmt[i].pin_index, fmt->sampling_frequency, fmt->bit_depth, fmt->ch_map, 161 + fmt->ch_cfg, fmt->interleaving_style, fmt->fmt_cfg, 162 + pin_fmt[i].buffer_size); 167 163 } 168 164 } 169 165 ··· 170 170 * @scomp: pointer to pointer to SOC component 171 171 * @swidget: pointer to struct snd_sof_widget containing tuples 172 172 * @available_fmt: pointer to struct sof_ipc4_available_audio_format being filling in 173 - * @has_out_format: true if available_fmt contains output format 173 + * @module_base_cfg: Pointer to the base_config in the module init IPC payload 174 174 * 175 175 * Return: 0 if successful 176 176 */ 177 177 static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, 178 178 struct snd_sof_widget *swidget, 179 179 struct sof_ipc4_available_audio_format *available_fmt, 180 - bool has_out_format) 180 + struct sof_ipc4_base_module_cfg *module_base_cfg) 181 181 { 182 - struct sof_ipc4_base_module_cfg *base_config; 183 - struct sof_ipc4_audio_format *out_format; 184 - int audio_fmt_num = 0; 185 - int ret, i; 182 + struct sof_ipc4_pin_format *out_format, *in_format; 183 + int ret; 186 184 187 - ret = sof_update_ipc_object(scomp, &audio_fmt_num, 185 + ret = sof_update_ipc_object(scomp, available_fmt, 188 186 SOF_AUDIO_FMT_NUM_TOKENS, swidget->tuples, 189 - swidget->num_tuples, sizeof(audio_fmt_num), 1); 190 - if (ret || audio_fmt_num <= 0) { 191 - dev_err(scomp->dev, "Invalid number of audio formats: %d\n", audio_fmt_num); 187 + swidget->num_tuples, sizeof(available_fmt), 1); 188 + if (ret) { 189 + dev_err(scomp->dev, "Failed to parse audio format token count\n"); 190 + return ret; 191 + } 192 + 193 + if (!available_fmt->num_input_formats && !available_fmt->num_output_formats) { 194 + dev_err(scomp->dev, "No input/output pin formats set in topology\n"); 192 195 return -EINVAL; 193 196 } 194 - available_fmt->audio_fmt_num = audio_fmt_num; 195 197 196 - dev_dbg(scomp->dev, "Number of audio formats: %d\n", available_fmt->audio_fmt_num); 198 + dev_dbg(scomp->dev, 199 + "Number of input audio formats: %d. Number of output audio formats: %d\n", 200 + available_fmt->num_input_formats, available_fmt->num_output_formats); 197 201 198 - base_config = kcalloc(available_fmt->audio_fmt_num, sizeof(*base_config), GFP_KERNEL); 199 - if (!base_config) 200 - return -ENOMEM; 202 + /* set cpc and is_pages in the module's base_config */ 203 + ret = sof_update_ipc_object(scomp, module_base_cfg, SOF_COMP_TOKENS, swidget->tuples, 204 + swidget->num_tuples, sizeof(*module_base_cfg), 1); 205 + if (ret) { 206 + dev_err(scomp->dev, "parse comp tokens for %s failed, error: %d\n", 207 + swidget->widget->name, ret); 208 + return ret; 209 + } 201 210 202 - /* set cpc and is_pages for all base_cfg */ 203 - for (i = 0; i < available_fmt->audio_fmt_num; i++) { 204 - ret = sof_update_ipc_object(scomp, &base_config[i], 205 - SOF_COMP_TOKENS, swidget->tuples, 206 - swidget->num_tuples, sizeof(*base_config), 1); 211 + dev_dbg(scomp->dev, "widget %s cpc: %d is_pages: %d\n", 212 + swidget->widget->name, module_base_cfg->cpc, module_base_cfg->is_pages); 213 + 214 + if (available_fmt->num_input_formats) { 215 + in_format = kcalloc(available_fmt->num_input_formats, 216 + sizeof(*in_format), GFP_KERNEL); 217 + if (!in_format) 218 + return -ENOMEM; 219 + available_fmt->input_pin_fmts = in_format; 220 + 221 + ret = sof_update_ipc_object(scomp, in_format, 222 + SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, 223 + swidget->num_tuples, sizeof(*in_format), 224 + available_fmt->num_input_formats); 207 225 if (ret) { 208 - dev_err(scomp->dev, "parse comp tokens failed %d\n", ret); 226 + dev_err(scomp->dev, "parse input audio fmt tokens failed %d\n", ret); 209 227 goto err_in; 210 228 } 229 + 230 + dev_dbg(scomp->dev, "Input audio formats for %s\n", swidget->widget->name); 231 + sof_ipc4_dbg_audio_format(scomp->dev, in_format, 232 + available_fmt->num_input_formats); 211 233 } 212 234 213 - /* copy the ibs/obs for each base_cfg */ 214 - ret = sof_update_ipc_object(scomp, base_config, 215 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, swidget->tuples, 216 - swidget->num_tuples, sizeof(*base_config), 217 - available_fmt->audio_fmt_num); 218 - if (ret) { 219 - dev_err(scomp->dev, "parse buffer size tokens failed %d\n", ret); 220 - goto err_in; 235 + if (available_fmt->num_output_formats) { 236 + out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), 237 + GFP_KERNEL); 238 + if (!out_format) { 239 + ret = -ENOMEM; 240 + goto err_in; 241 + } 242 + 243 + ret = sof_update_ipc_object(scomp, out_format, 244 + SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, 245 + swidget->num_tuples, sizeof(*out_format), 246 + available_fmt->num_output_formats); 247 + if (ret) { 248 + dev_err(scomp->dev, "parse output audio fmt tokens failed\n"); 249 + goto err_out; 250 + } 251 + 252 + available_fmt->output_pin_fmts = out_format; 253 + dev_dbg(scomp->dev, "Output audio formats for %s\n", swidget->widget->name); 254 + sof_ipc4_dbg_audio_format(scomp->dev, out_format, 255 + available_fmt->num_output_formats); 221 256 } 222 - 223 - for (i = 0; i < available_fmt->audio_fmt_num; i++) 224 - dev_dbg(scomp->dev, "%d: ibs: %d obs: %d cpc: %d is_pages: %d\n", i, 225 - base_config[i].ibs, base_config[i].obs, 226 - base_config[i].cpc, base_config[i].is_pages); 227 - 228 - ret = sof_update_ipc_object(scomp, &base_config->audio_fmt, 229 - SOF_IN_AUDIO_FORMAT_TOKENS, swidget->tuples, 230 - swidget->num_tuples, sizeof(*base_config), 231 - available_fmt->audio_fmt_num); 232 - if (ret) { 233 - dev_err(scomp->dev, "parse base_config audio_fmt tokens failed %d\n", ret); 234 - goto err_in; 235 - } 236 - 237 - dev_dbg(scomp->dev, "Get input audio formats for %s\n", swidget->widget->name); 238 - sof_ipc4_dbg_audio_format(scomp->dev, &base_config->audio_fmt, 239 - sizeof(*base_config), 240 - available_fmt->audio_fmt_num); 241 - 242 - available_fmt->base_config = base_config; 243 - 244 - if (!has_out_format) 245 - return 0; 246 - 247 - out_format = kcalloc(available_fmt->audio_fmt_num, sizeof(*out_format), GFP_KERNEL); 248 - if (!out_format) { 249 - ret = -ENOMEM; 250 - goto err_in; 251 - } 252 - 253 - ret = sof_update_ipc_object(scomp, out_format, 254 - SOF_OUT_AUDIO_FORMAT_TOKENS, swidget->tuples, 255 - swidget->num_tuples, sizeof(*out_format), 256 - available_fmt->audio_fmt_num); 257 - 258 - if (ret) { 259 - dev_err(scomp->dev, "parse output audio_fmt tokens failed\n"); 260 - goto err_out; 261 - } 262 - 263 - available_fmt->out_audio_fmt = out_format; 264 - dev_dbg(scomp->dev, "Get output audio formats for %s\n", swidget->widget->name); 265 - sof_ipc4_dbg_audio_format(scomp->dev, out_format, sizeof(*out_format), 266 - available_fmt->audio_fmt_num); 267 257 268 258 return 0; 269 259 270 260 err_out: 271 261 kfree(out_format); 272 262 err_in: 273 - kfree(base_config); 274 - 263 + kfree(in_format); 264 + available_fmt->input_pin_fmts = NULL; 275 265 return ret; 276 266 } 277 267 ··· 269 279 static void sof_ipc4_free_audio_fmt(struct sof_ipc4_available_audio_format *available_fmt) 270 280 271 281 { 272 - kfree(available_fmt->base_config); 273 - available_fmt->base_config = NULL; 274 - kfree(available_fmt->out_audio_fmt); 275 - available_fmt->out_audio_fmt = NULL; 282 + kfree(available_fmt->output_pin_fmts); 283 + available_fmt->output_pin_fmts = NULL; 284 + kfree(available_fmt->input_pin_fmts); 285 + available_fmt->input_pin_fmts = NULL; 276 286 } 277 287 278 288 static void sof_ipc4_widget_free_comp_pipeline(struct snd_sof_widget *swidget) ··· 326 336 struct snd_soc_component *scomp = swidget->scomp; 327 337 struct sof_ipc4_copier *ipc4_copier; 328 338 int node_type = 0; 329 - int ret, i; 339 + int ret; 330 340 331 341 ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); 332 342 if (!ipc4_copier) ··· 337 347 338 348 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 339 349 340 - ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true); 350 + ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, 351 + &ipc4_copier->data.base_config); 341 352 if (ret) 342 353 goto free_copier; 343 - 344 - available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32), 345 - GFP_KERNEL); 346 - if (!available_fmt->dma_buffer_size) { 347 - ret = -ENOMEM; 348 - goto free_available_fmt; 349 - } 350 354 351 355 /* 352 356 * This callback is used by host copier and module-to-module copier, ··· 349 365 if (!WIDGET_IS_AIF(swidget->id)) 350 366 goto skip_gtw_cfg; 351 367 352 - ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, 353 - SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples, 354 - swidget->num_tuples, sizeof(u32), 355 - available_fmt->audio_fmt_num); 356 - if (ret) { 357 - dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n", 358 - swidget->widget->name); 359 - goto err; 360 - } 361 - 362 - dev_dbg(scomp->dev, "dma buffer size:\n"); 363 - for (i = 0; i < available_fmt->audio_fmt_num; i++) 364 - dev_dbg(scomp->dev, "%d: %u\n", i, 365 - available_fmt->dma_buffer_size[i]); 366 - 367 368 ret = sof_update_ipc_object(scomp, &node_type, 368 369 SOF_COPIER_TOKENS, swidget->tuples, 369 370 swidget->num_tuples, sizeof(node_type), 1); ··· 356 387 if (ret) { 357 388 dev_err(scomp->dev, "parse host copier node type token failed %d\n", 358 389 ret); 359 - goto err; 390 + goto free_available_fmt; 360 391 } 361 392 dev_dbg(scomp->dev, "host copier '%s' node_type %u\n", swidget->widget->name, node_type); 362 393 ··· 364 395 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); 365 396 if (!ipc4_copier->gtw_attr) { 366 397 ret = -ENOMEM; 367 - goto err; 398 + goto free_available_fmt; 368 399 } 369 400 370 401 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; ··· 395 426 396 427 free_gtw_attr: 397 428 kfree(ipc4_copier->gtw_attr); 398 - err: 399 - kfree(available_fmt->dma_buffer_size); 400 429 free_available_fmt: 401 430 sof_ipc4_free_audio_fmt(available_fmt); 402 431 free_copier: ··· 412 445 return; 413 446 414 447 available_fmt = &ipc4_copier->available_fmt; 415 - kfree(available_fmt->dma_buffer_size); 416 - kfree(available_fmt->base_config); 417 - kfree(available_fmt->out_audio_fmt); 448 + kfree(available_fmt->output_pin_fmts); 418 449 kfree(ipc4_copier->gtw_attr); 419 450 kfree(ipc4_copier); 420 451 swidget->private = NULL; ··· 425 460 struct snd_sof_dai *dai = swidget->private; 426 461 struct sof_ipc4_copier *ipc4_copier; 427 462 int node_type = 0; 428 - int ret, i; 463 + int ret; 429 464 430 465 ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); 431 466 if (!ipc4_copier) ··· 435 470 436 471 dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); 437 472 438 - ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, true); 473 + ret = sof_ipc4_get_audio_fmt(scomp, swidget, available_fmt, 474 + &ipc4_copier->data.base_config); 439 475 if (ret) 440 476 goto free_copier; 441 - 442 - available_fmt->dma_buffer_size = kcalloc(available_fmt->audio_fmt_num, sizeof(u32), 443 - GFP_KERNEL); 444 - if (!available_fmt->dma_buffer_size) { 445 - ret = -ENOMEM; 446 - goto free_available_fmt; 447 - } 448 - 449 - ret = sof_update_ipc_object(scomp, available_fmt->dma_buffer_size, 450 - SOF_COPIER_GATEWAY_CFG_TOKENS, swidget->tuples, 451 - swidget->num_tuples, sizeof(u32), 452 - available_fmt->audio_fmt_num); 453 - if (ret) { 454 - dev_err(scomp->dev, "Failed to parse dma buffer size in audio format for %s\n", 455 - swidget->widget->name); 456 - goto err; 457 - } 458 - 459 - for (i = 0; i < available_fmt->audio_fmt_num; i++) 460 - dev_dbg(scomp->dev, "%d: dma buffer size: %u\n", i, 461 - available_fmt->dma_buffer_size[i]); 462 477 463 478 ret = sof_update_ipc_object(scomp, &node_type, 464 479 SOF_COPIER_TOKENS, swidget->tuples, 465 480 swidget->num_tuples, sizeof(node_type), 1); 466 481 if (ret) { 467 482 dev_err(scomp->dev, "parse dai node type failed %d\n", ret); 468 - goto err; 483 + goto free_available_fmt; 469 484 } 470 485 471 486 ret = sof_update_ipc_object(scomp, ipc4_copier, ··· 453 508 swidget->num_tuples, sizeof(u32), 1); 454 509 if (ret) { 455 510 dev_err(scomp->dev, "parse dai copier node token failed %d\n", ret); 456 - goto err; 511 + goto free_available_fmt; 457 512 } 458 513 459 514 dev_dbg(scomp->dev, "dai %s node_type %u dai_type %u dai_index %d\n", swidget->widget->name, ··· 487 542 blob = kzalloc(sizeof(*blob), GFP_KERNEL); 488 543 if (!blob) { 489 544 ret = -ENOMEM; 490 - goto err; 545 + goto free_available_fmt; 491 546 } 492 547 493 548 list_for_each_entry(w, &sdev->widget_list, list) { ··· 516 571 ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); 517 572 if (!ipc4_copier->gtw_attr) { 518 573 ret = -ENOMEM; 519 - goto err; 574 + goto free_available_fmt; 520 575 } 521 576 522 577 ipc4_copier->copier_config = (uint32_t *)ipc4_copier->gtw_attr; ··· 537 592 538 593 free_copier_config: 539 594 kfree(ipc4_copier->copier_config); 540 - err: 541 - kfree(available_fmt->dma_buffer_size); 542 595 free_available_fmt: 543 596 sof_ipc4_free_audio_fmt(available_fmt); 544 597 free_copier: ··· 564 621 ipc4_copier = dai->private; 565 622 available_fmt = &ipc4_copier->available_fmt; 566 623 567 - kfree(available_fmt->dma_buffer_size); 568 - kfree(available_fmt->base_config); 569 - kfree(available_fmt->out_audio_fmt); 624 + kfree(available_fmt->output_pin_fmts); 570 625 if (ipc4_copier->dai_type != SOF_DAI_INTEL_SSP && 571 626 ipc4_copier->dai_type != SOF_DAI_INTEL_DMIC) 572 627 kfree(ipc4_copier->copier_config); ··· 642 701 gain->data.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; 643 702 gain->data.init_val = SOF_IPC4_VOL_ZERO_DB; 644 703 645 - /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */ 646 - ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, false); 704 + ret = sof_ipc4_get_audio_fmt(scomp, swidget, &gain->available_fmt, &gain->base_config); 647 705 if (ret) 648 706 goto err; 649 707 ··· 707 767 708 768 swidget->private = mixer; 709 769 710 - /* The out_audio_fmt in topology is ignored as it is not required to be sent to the FW */ 711 - ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, false); 770 + ret = sof_ipc4_get_audio_fmt(scomp, swidget, &mixer->available_fmt, 771 + &mixer->base_config); 712 772 if (ret) 713 773 goto err; 714 774 ··· 738 798 739 799 swidget->private = src; 740 800 741 - /* The out_audio_fmt in topology is ignored as it is not required by SRC */ 742 - ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, false); 801 + ret = sof_ipc4_get_audio_fmt(scomp, swidget, &src->available_fmt, &src->base_config); 743 802 if (ret) 744 803 goto err; 745 804 ··· 841 902 static int sof_ipc4_init_audio_fmt(struct snd_sof_dev *sdev, 842 903 struct snd_sof_widget *swidget, 843 904 struct sof_ipc4_base_module_cfg *base_config, 844 - struct sof_ipc4_audio_format *out_format, 845 905 struct snd_pcm_hw_params *params, 846 906 struct sof_ipc4_available_audio_format *available_fmt, 847 - size_t object_offset) 907 + struct sof_ipc4_pin_format *pin_fmts, u32 pin_fmts_size) 848 908 { 849 - void *ptr = available_fmt->ref_audio_fmt; 850 909 u32 valid_bits; 851 910 u32 channels; 852 911 u32 rate; 853 912 int sample_valid_bits; 854 913 int i; 855 914 856 - if (!ptr) { 915 + if (!pin_fmts) { 857 916 dev_err(sdev->dev, "no reference formats for %s\n", swidget->widget->name); 858 917 return -EINVAL; 859 918 } ··· 871 934 return -EINVAL; 872 935 } 873 936 874 - if (!available_fmt->audio_fmt_num) { 937 + if (!pin_fmts_size) { 875 938 dev_err(sdev->dev, "no formats available for %s\n", swidget->widget->name); 876 939 return -EINVAL; 877 940 } 878 941 879 942 /* 880 - * Search supported audio formats to match rate, channels ,and 943 + * Search supported audio formats with pin index 0 to match rate, channels ,and 881 944 * sample_valid_bytes from runtime params 882 945 */ 883 - for (i = 0; i < available_fmt->audio_fmt_num; i++, ptr = (u8 *)ptr + object_offset) { 884 - struct sof_ipc4_audio_format *fmt = ptr; 946 + for (i = 0; i < pin_fmts_size; i++) { 947 + struct sof_ipc4_audio_format *fmt = &pin_fmts[i].audio_fmt; 948 + 949 + if (pin_fmts[i].pin_index) 950 + continue; 885 951 886 952 rate = fmt->sampling_frequency; 887 953 channels = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(fmt->fmt_cfg); 888 954 valid_bits = SOF_IPC4_AUDIO_FORMAT_CFG_V_BIT_DEPTH(fmt->fmt_cfg); 889 955 if (params_rate(params) == rate && params_channels(params) == channels && 890 956 sample_valid_bits == valid_bits) { 891 - dev_dbg(sdev->dev, "matching audio format index for %uHz, %ubit, %u channels: %d\n", 957 + dev_dbg(sdev->dev, "matched audio format index for %uHz, %ubit, %u channels: %d\n", 892 958 rate, valid_bits, channels, i); 893 - 894 - /* copy ibs/obs and input format */ 895 - memcpy(base_config, &available_fmt->base_config[i], 896 - sizeof(struct sof_ipc4_base_module_cfg)); 897 - 898 - /* copy output format */ 899 - if (out_format) 900 - memcpy(out_format, &available_fmt->out_audio_fmt[i], 901 - sizeof(struct sof_ipc4_audio_format)); 902 959 break; 903 960 } 904 961 } 905 962 906 - if (i == available_fmt->audio_fmt_num) { 963 + if (i == pin_fmts_size) { 907 964 dev_err(sdev->dev, "%s: Unsupported audio format: %uHz, %ubit, %u channels\n", 908 965 __func__, params_rate(params), sample_valid_bits, params_channels(params)); 909 966 return -EINVAL; 910 967 } 911 968 912 - dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); 913 - sof_ipc4_dbg_audio_format(sdev->dev, &base_config->audio_fmt, 914 - sizeof(*base_config), 1); 915 - if (out_format) { 916 - dev_dbg(sdev->dev, "Init output audio formats for %s\n", swidget->widget->name); 917 - sof_ipc4_dbg_audio_format(sdev->dev, out_format, 918 - sizeof(*out_format), 1); 969 + /* copy input format */ 970 + if (available_fmt->num_input_formats && i < available_fmt->num_input_formats) { 971 + memcpy(&base_config->audio_fmt, &available_fmt->input_pin_fmts[i].audio_fmt, 972 + sizeof(struct sof_ipc4_audio_format)); 973 + 974 + /* set base_cfg ibs/obs */ 975 + base_config->ibs = available_fmt->input_pin_fmts[i].buffer_size; 976 + 977 + dev_dbg(sdev->dev, "Init input audio formats for %s\n", swidget->widget->name); 978 + sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->input_pin_fmts[i], 1); 919 979 } 980 + 981 + if (available_fmt->num_output_formats && i < available_fmt->num_output_formats) 982 + base_config->obs = available_fmt->output_pin_fmts[i].buffer_size; 920 983 921 984 /* Return the index of the matched format */ 922 985 return i; ··· 1078 1141 struct sof_ipc4_available_audio_format *available_fmt; 1079 1142 struct snd_soc_component *scomp = swidget->scomp; 1080 1143 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1144 + struct sof_ipc4_pin_format *format_list_to_search; 1081 1145 struct sof_ipc4_copier_data *copier_data; 1082 1146 struct snd_pcm_hw_params *ref_params; 1083 1147 struct sof_ipc4_copier *ipc4_copier; 1084 1148 struct snd_sof_dai *dai; 1085 1149 struct snd_mask *fmt; 1086 1150 int out_sample_valid_bits; 1087 - size_t ref_audio_fmt_size; 1088 1151 void **ipc_config_data; 1089 1152 int *ipc_config_size; 1090 1153 u32 **data; 1091 1154 int ipc_size, ret; 1155 + u32 deep_buffer_dma_ms = 0; 1156 + u32 format_list_count; 1092 1157 1093 1158 dev_dbg(sdev->dev, "copier %s, type %d", swidget->widget->name, swidget->id); 1094 1159 ··· 1102 1163 struct snd_sof_widget *pipe_widget; 1103 1164 struct sof_ipc4_pipeline *pipeline; 1104 1165 1166 + /* parse the deep buffer dma size */ 1167 + ret = sof_update_ipc_object(scomp, &deep_buffer_dma_ms, 1168 + SOF_COPIER_DEEP_BUFFER_TOKENS, swidget->tuples, 1169 + swidget->num_tuples, sizeof(u32), 1); 1170 + if (ret) { 1171 + dev_err(scomp->dev, "Failed to parse deep buffer dma size for %s\n", 1172 + swidget->widget->name); 1173 + return ret; 1174 + } 1175 + 1105 1176 pipe_widget = swidget->spipe->pipe_widget; 1106 1177 pipeline = pipe_widget->private; 1107 1178 ipc4_copier = (struct sof_ipc4_copier *)swidget->private; ··· 1120 1171 available_fmt = &ipc4_copier->available_fmt; 1121 1172 1122 1173 /* 1123 - * base_config->audio_fmt and out_audio_fmt represent the input and output audio 1124 - * formats. Use the input format as the reference to match pcm params for playback 1125 - * and the output format as reference for capture. 1174 + * Use the input_pin_fmts to match pcm params for playback and the output_pin_fmts 1175 + * for capture. 1126 1176 */ 1127 1177 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 1128 - available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt; 1129 - ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg); 1178 + format_list_to_search = available_fmt->input_pin_fmts; 1179 + format_list_count = available_fmt->num_input_formats; 1130 1180 } else { 1131 - available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt; 1132 - ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format); 1181 + format_list_to_search = available_fmt->output_pin_fmts; 1182 + format_list_count = available_fmt->num_output_formats; 1133 1183 } 1184 + 1134 1185 copier_data->gtw_cfg.node_id &= ~SOF_IPC4_NODE_INDEX_MASK; 1135 1186 copier_data->gtw_cfg.node_id |= 1136 1187 SOF_IPC4_NODE_INDEX(platform_params->stream_tag - 1); ··· 1149 1200 copier_data = &ipc4_copier->data; 1150 1201 available_fmt = &ipc4_copier->available_fmt; 1151 1202 if (dir == SNDRV_PCM_STREAM_CAPTURE) { 1152 - available_fmt->ref_audio_fmt = available_fmt->out_audio_fmt; 1153 - ref_audio_fmt_size = sizeof(struct sof_ipc4_audio_format); 1203 + format_list_to_search = available_fmt->output_pin_fmts; 1204 + format_list_count = available_fmt->num_output_formats; 1154 1205 1155 1206 /* 1156 1207 * modify the input params for the dai copier as it only supports ··· 1160 1211 snd_mask_none(fmt); 1161 1212 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S32_LE); 1162 1213 } else { 1163 - available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt; 1164 - ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg); 1214 + format_list_to_search = available_fmt->input_pin_fmts; 1215 + format_list_count = available_fmt->num_input_formats; 1165 1216 } 1166 1217 1167 1218 ref_params = pipeline_params; ··· 1181 1232 copier_data = &ipc4_copier->data; 1182 1233 available_fmt = &ipc4_copier->available_fmt; 1183 1234 1184 - /* 1185 - * base_config->audio_fmt represent the input audio formats. Use 1186 - * the input format as the reference to match pcm params 1187 - */ 1188 - available_fmt->ref_audio_fmt = &available_fmt->base_config->audio_fmt; 1189 - ref_audio_fmt_size = sizeof(struct sof_ipc4_base_module_cfg); 1235 + /* Use the input formats to match pcm params */ 1236 + format_list_to_search = available_fmt->input_pin_fmts; 1237 + format_list_count = available_fmt->num_input_formats; 1190 1238 ref_params = pipeline_params; 1191 1239 1192 1240 break; ··· 1195 1249 } 1196 1250 1197 1251 /* set input and output audio formats */ 1198 - ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config, 1199 - &copier_data->out_format, ref_params, 1200 - available_fmt, ref_audio_fmt_size); 1252 + ret = sof_ipc4_init_audio_fmt(sdev, swidget, &copier_data->base_config, ref_params, 1253 + available_fmt, format_list_to_search, format_list_count); 1201 1254 if (ret < 0) 1202 1255 return ret; 1256 + 1257 + /* 1258 + * Set the output format. Current topology defines pin 0 input and output formats in pairs. 1259 + * This assumes that the pin 0 formats are defined before all other pins. 1260 + * So pick the output audio format with the same index as the chosen 1261 + * input format. This logic will need to be updated when the format definitions 1262 + * in topology change. 1263 + */ 1264 + memcpy(&copier_data->out_format, &available_fmt->output_pin_fmts[ret].audio_fmt, 1265 + sizeof(struct sof_ipc4_audio_format)); 1266 + dev_dbg(sdev->dev, "Output audio format for %s\n", swidget->widget->name); 1267 + sof_ipc4_dbg_audio_format(sdev->dev, &available_fmt->output_pin_fmts[ret], 1); 1203 1268 1204 1269 switch (swidget->id) { 1205 1270 case snd_soc_dapm_dai_in: ··· 1319 1362 return -EINVAL; 1320 1363 } 1321 1364 1322 - /* set the gateway dma_buffer_size using the matched ID returned above */ 1323 - copier_data->gtw_cfg.dma_buffer_size = available_fmt->dma_buffer_size[ret]; 1365 + /* 1366 + * Set the gateway dma_buffer_size to 2ms buffer size to meet the FW expectation. In the 1367 + * deep buffer case, set the dma_buffer_size depending on the deep_buffer_dma_ms set 1368 + * in topology. 1369 + */ 1370 + switch (swidget->id) { 1371 + case snd_soc_dapm_dai_in: 1372 + copier_data->gtw_cfg.dma_buffer_size = 1373 + SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.ibs; 1374 + break; 1375 + case snd_soc_dapm_aif_in: 1376 + copier_data->gtw_cfg.dma_buffer_size = 1377 + max((u32)SOF_IPC4_MIN_DMA_BUFFER_SIZE, deep_buffer_dma_ms) * 1378 + copier_data->base_config.ibs; 1379 + break; 1380 + case snd_soc_dapm_dai_out: 1381 + case snd_soc_dapm_aif_out: 1382 + copier_data->gtw_cfg.dma_buffer_size = 1383 + SOF_IPC4_MIN_DMA_BUFFER_SIZE * copier_data->base_config.obs; 1384 + break; 1385 + default: 1386 + break; 1387 + } 1324 1388 1325 1389 data = &ipc4_copier->copier_config; 1326 1390 ipc_config_size = &ipc4_copier->ipc_config_size; ··· 1378 1400 struct snd_soc_component *scomp = swidget->scomp; 1379 1401 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1380 1402 struct sof_ipc4_gain *gain = swidget->private; 1403 + struct sof_ipc4_available_audio_format *available_fmt = &gain->available_fmt; 1381 1404 int ret; 1382 1405 1383 - gain->available_fmt.ref_audio_fmt = &gain->available_fmt.base_config->audio_fmt; 1384 - 1385 - /* output format is not required to be sent to the FW for gain */ 1386 1406 ret = sof_ipc4_init_audio_fmt(sdev, swidget, &gain->base_config, 1387 - NULL, pipeline_params, &gain->available_fmt, 1388 - sizeof(gain->base_config)); 1407 + pipeline_params, available_fmt, 1408 + available_fmt->input_pin_fmts, 1409 + available_fmt->num_input_formats); 1389 1410 if (ret < 0) 1390 1411 return ret; 1391 1412 ··· 1402 1425 struct snd_soc_component *scomp = swidget->scomp; 1403 1426 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1404 1427 struct sof_ipc4_mixer *mixer = swidget->private; 1428 + struct sof_ipc4_available_audio_format *available_fmt = &mixer->available_fmt; 1405 1429 int ret; 1406 1430 1407 - /* only 32bit is supported by mixer */ 1408 - mixer->available_fmt.ref_audio_fmt = &mixer->available_fmt.base_config->audio_fmt; 1409 - 1410 - /* output format is not required to be sent to the FW for mixer */ 1411 1431 ret = sof_ipc4_init_audio_fmt(sdev, swidget, &mixer->base_config, 1412 - NULL, pipeline_params, &mixer->available_fmt, 1413 - sizeof(mixer->base_config)); 1432 + pipeline_params, available_fmt, 1433 + available_fmt->input_pin_fmts, 1434 + available_fmt->num_input_formats); 1414 1435 if (ret < 0) 1415 1436 return ret; 1416 1437 ··· 1426 1451 struct snd_soc_component *scomp = swidget->scomp; 1427 1452 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 1428 1453 struct sof_ipc4_src *src = swidget->private; 1454 + struct sof_ipc4_available_audio_format *available_fmt = &src->available_fmt; 1429 1455 struct snd_interval *rate; 1430 1456 int ret; 1431 1457 1432 - src->available_fmt.ref_audio_fmt = &src->available_fmt.base_config->audio_fmt; 1433 - 1434 - /* output format is not required to be sent to the FW for SRC */ 1435 1458 ret = sof_ipc4_init_audio_fmt(sdev, swidget, &src->base_config, 1436 - NULL, pipeline_params, &src->available_fmt, 1437 - sizeof(src->base_config)); 1459 + pipeline_params, available_fmt, 1460 + available_fmt->input_pin_fmts, 1461 + available_fmt->num_input_formats); 1438 1462 if (ret < 0) 1439 1463 return ret; 1440 1464 ··· 1739 1765 u32 num_pins; 1740 1766 int i; 1741 1767 1742 - if (pin_type == SOF_PIN_TYPE_SOURCE) { 1768 + if (pin_type == SOF_PIN_TYPE_OUTPUT) { 1743 1769 current_swidget = src_widget; 1744 - pin_binding = src_widget->src_pin_binding; 1745 - queue_ida = &src_widget->src_queue_ida; 1746 - num_pins = src_widget->num_source_pins; 1770 + pin_binding = src_widget->output_pin_binding; 1771 + queue_ida = &src_widget->output_queue_ida; 1772 + num_pins = src_widget->num_output_pins; 1747 1773 buddy_name = sink_widget->widget->name; 1748 1774 } else { 1749 1775 current_swidget = sink_widget; 1750 - pin_binding = sink_widget->sink_pin_binding; 1751 - queue_ida = &sink_widget->sink_queue_ida; 1752 - num_pins = sink_widget->num_sink_pins; 1776 + pin_binding = sink_widget->input_pin_binding; 1777 + queue_ida = &sink_widget->input_queue_ida; 1778 + num_pins = sink_widget->num_input_pins; 1753 1779 buddy_name = src_widget->widget->name; 1754 1780 } 1755 1781 ··· 1757 1783 1758 1784 if (num_pins < 1) { 1759 1785 dev_err(scomp->dev, "invalid %s num_pins: %d for queue allocation for %s\n", 1760 - (pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"), 1786 + (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"), 1761 1787 num_pins, current_swidget->widget->name); 1762 1788 return -EINVAL; 1763 1789 } 1764 1790 1765 - /* If there is only one sink/source pin, queue id must be 0 */ 1791 + /* If there is only one input/output pin, queue id must be 0 */ 1766 1792 if (num_pins == 1) 1767 1793 return 0; 1768 1794 ··· 1777 1803 * mixed use pin binding array and ida for queue ID allocation. 1778 1804 */ 1779 1805 dev_err(scomp->dev, "no %s queue id found from pin binding array for %s\n", 1780 - (pin_type == SOF_PIN_TYPE_SOURCE ? "source" : "sink"), 1806 + (pin_type == SOF_PIN_TYPE_OUTPUT ? "output" : "input"), 1781 1807 current_swidget->widget->name); 1782 1808 return -EINVAL; 1783 1809 } ··· 1793 1819 char **pin_binding; 1794 1820 int num_pins; 1795 1821 1796 - if (pin_type == SOF_PIN_TYPE_SOURCE) { 1797 - pin_binding = swidget->src_pin_binding; 1798 - queue_ida = &swidget->src_queue_ida; 1799 - num_pins = swidget->num_source_pins; 1822 + if (pin_type == SOF_PIN_TYPE_OUTPUT) { 1823 + pin_binding = swidget->output_pin_binding; 1824 + queue_ida = &swidget->output_queue_ida; 1825 + num_pins = swidget->num_output_pins; 1800 1826 } else { 1801 - pin_binding = swidget->sink_pin_binding; 1802 - queue_ida = &swidget->sink_queue_ida; 1803 - num_pins = swidget->num_sink_pins; 1827 + pin_binding = swidget->input_pin_binding; 1828 + queue_ida = &swidget->input_queue_ida; 1829 + num_pins = swidget->num_input_pins; 1804 1830 } 1805 1831 1806 1832 /* Nothing to free if queue ID is not allocated with ida. */ ··· 1870 1896 int ret; 1871 1897 1872 1898 sroute->src_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 1873 - SOF_PIN_TYPE_SOURCE); 1899 + SOF_PIN_TYPE_OUTPUT); 1874 1900 if (sroute->src_queue_id < 0) { 1875 1901 dev_err(sdev->dev, "failed to get queue ID for source widget: %s\n", 1876 1902 src_widget->widget->name); ··· 1878 1904 } 1879 1905 1880 1906 sroute->dst_queue_id = sof_ipc4_get_queue_id(src_widget, sink_widget, 1881 - SOF_PIN_TYPE_SINK); 1907 + SOF_PIN_TYPE_INPUT); 1882 1908 if (sroute->dst_queue_id < 0) { 1883 1909 dev_err(sdev->dev, "failed to get queue ID for sink widget: %s\n", 1884 1910 sink_widget->widget->name); 1885 1911 sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, 1886 - SOF_PIN_TYPE_SOURCE); 1912 + SOF_PIN_TYPE_OUTPUT); 1887 1913 return sroute->dst_queue_id; 1888 1914 } 1889 1915 ··· 1927 1953 return ret; 1928 1954 1929 1955 out: 1930 - sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE); 1931 - sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK); 1956 + sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); 1957 + sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); 1932 1958 return ret; 1933 1959 } 1934 1960 ··· 1973 1999 src_widget->widget->name, sroute->src_queue_id, 1974 2000 sink_widget->widget->name, sroute->dst_queue_id); 1975 2001 out: 1976 - sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_SINK); 1977 - sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_SOURCE); 2002 + sof_ipc4_put_queue_id(sink_widget, sroute->dst_queue_id, SOF_PIN_TYPE_INPUT); 2003 + sof_ipc4_put_queue_id(src_widget, sroute->src_queue_id, SOF_PIN_TYPE_OUTPUT); 1978 2004 1979 2005 return ret; 1980 2006 } ··· 2203 2229 static enum sof_tokens common_copier_token_list[] = { 2204 2230 SOF_COMP_TOKENS, 2205 2231 SOF_AUDIO_FMT_NUM_TOKENS, 2206 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 2207 2232 SOF_IN_AUDIO_FORMAT_TOKENS, 2208 2233 SOF_OUT_AUDIO_FORMAT_TOKENS, 2209 - SOF_COPIER_GATEWAY_CFG_TOKENS, 2234 + SOF_COPIER_DEEP_BUFFER_TOKENS, 2210 2235 SOF_COPIER_TOKENS, 2211 2236 SOF_COMP_EXT_TOKENS, 2212 2237 }; ··· 2218 2245 static enum sof_tokens dai_token_list[] = { 2219 2246 SOF_COMP_TOKENS, 2220 2247 SOF_AUDIO_FMT_NUM_TOKENS, 2221 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 2222 2248 SOF_IN_AUDIO_FORMAT_TOKENS, 2223 2249 SOF_OUT_AUDIO_FORMAT_TOKENS, 2224 - SOF_COPIER_GATEWAY_CFG_TOKENS, 2225 2250 SOF_COPIER_TOKENS, 2226 2251 SOF_DAI_TOKENS, 2227 2252 SOF_COMP_EXT_TOKENS, ··· 2229 2258 SOF_COMP_TOKENS, 2230 2259 SOF_GAIN_TOKENS, 2231 2260 SOF_AUDIO_FMT_NUM_TOKENS, 2232 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 2233 2261 SOF_IN_AUDIO_FORMAT_TOKENS, 2262 + SOF_OUT_AUDIO_FORMAT_TOKENS, 2234 2263 SOF_COMP_EXT_TOKENS, 2235 2264 }; 2236 2265 ··· 2238 2267 SOF_COMP_TOKENS, 2239 2268 SOF_AUDIO_FMT_NUM_TOKENS, 2240 2269 SOF_IN_AUDIO_FORMAT_TOKENS, 2241 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 2270 + SOF_OUT_AUDIO_FORMAT_TOKENS, 2242 2271 SOF_COMP_EXT_TOKENS, 2243 2272 }; 2244 2273 ··· 2247 2276 SOF_SRC_TOKENS, 2248 2277 SOF_AUDIO_FMT_NUM_TOKENS, 2249 2278 SOF_IN_AUDIO_FORMAT_TOKENS, 2250 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 2279 + SOF_OUT_AUDIO_FORMAT_TOKENS, 2251 2280 SOF_COMP_EXT_TOKENS, 2252 2281 }; 2253 2282
+26 -10
sound/soc/sof/ipc4-topology.h
··· 55 55 56 56 #define SOF_IPC4_INVALID_NODE_ID 0xffffffff 57 57 58 + /* FW requires minimum 2ms DMA buffer size */ 59 + #define SOF_IPC4_MIN_DMA_BUFFER_SIZE 2 60 + 58 61 /* 59 62 * The base of multi-gateways. Multi-gateways addressing starts from 60 63 * ALH_MULTI_GTW_BASE and there are ALH_MULTI_GTW_COUNT multi-sources ··· 146 143 } __packed; 147 144 148 145 /** 146 + * struct sof_ipc4_pin_format - Module pin format 147 + * @pin_index: pin index 148 + * @buffer_size: buffer size in bytes 149 + * @audio_fmt: audio format for the pin 150 + * 151 + * This structure can be used for both output or input pins and the pin_index is relative to the 152 + * pin type i.e output/input pin 153 + */ 154 + struct sof_ipc4_pin_format { 155 + u32 pin_index; 156 + u32 buffer_size; 157 + struct sof_ipc4_audio_format audio_fmt; 158 + }; 159 + 160 + /** 149 161 * struct sof_ipc4_available_audio_format - Available audio formats 150 - * @base_config: Available base config 151 - * @out_audio_fmt: Available output audio format 152 - * @ref_audio_fmt: Reference audio format to match runtime audio format 153 - * @dma_buffer_size: Available Gateway DMA buffer size (in bytes) 154 - * @audio_fmt_num: Number of available audio formats 162 + * @output_pin_fmts: Available output pin formats 163 + * @input_pin_fmts: Available input pin formats 164 + * @num_input_formats: Number of input pin formats 165 + * @num_output_formats: Number of output pin formats 155 166 */ 156 167 struct sof_ipc4_available_audio_format { 157 - struct sof_ipc4_base_module_cfg *base_config; 158 - struct sof_ipc4_audio_format *out_audio_fmt; 159 - struct sof_ipc4_audio_format *ref_audio_fmt; 160 - u32 *dma_buffer_size; 161 - int audio_fmt_num; 168 + struct sof_ipc4_pin_format *output_pin_fmts; 169 + struct sof_ipc4_pin_format *input_pin_fmts; 170 + u32 num_input_formats; 171 + u32 num_output_formats; 162 172 }; 163 173 164 174 /**
+17 -18
sound/soc/sof/sof-audio.h
··· 30 30 */ 31 31 #define SOF_WIDGET_MAX_NUM_PINS 8 32 32 33 - /* The type of a widget pin is either sink or source */ 34 - #define SOF_PIN_TYPE_SINK 0 35 - #define SOF_PIN_TYPE_SOURCE 1 33 + /* Widget pin type */ 34 + #define SOF_PIN_TYPE_INPUT 0 35 + #define SOF_PIN_TYPE_OUTPUT 1 36 36 37 37 /* max number of FE PCMs before BEs */ 38 38 #define SOF_BE_PCM_BASE 16 ··· 256 256 SOF_COMP_EXT_TOKENS, 257 257 SOF_IN_AUDIO_FORMAT_TOKENS, 258 258 SOF_OUT_AUDIO_FORMAT_TOKENS, 259 - SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS, 260 - SOF_COPIER_GATEWAY_CFG_TOKENS, 259 + SOF_COPIER_DEEP_BUFFER_TOKENS, 261 260 SOF_COPIER_TOKENS, 262 261 SOF_AUDIO_FMT_NUM_TOKENS, 263 262 SOF_COPIER_FORMAT_TOKENS, ··· 432 433 struct snd_sof_tuple *tuples; 433 434 434 435 /* 435 - * The allowed range for num_sink/source_pins is [0, SOF_WIDGET_MAX_NUM_PINS]. 436 - * Widgets may have zero sink or source pins, for example the tone widget has 437 - * zero sink pins. 436 + * The allowed range for num_input/output_pins is [0, SOF_WIDGET_MAX_NUM_PINS]. 437 + * Widgets may have zero input or output pins, for example the tone widget has 438 + * zero input pins. 438 439 */ 439 - u32 num_sink_pins; 440 - u32 num_source_pins; 440 + u32 num_input_pins; 441 + u32 num_output_pins; 441 442 442 443 /* 443 - * The sink/source pin binding array, it takes the form of 444 + * The input/output pin binding array, it takes the form of 444 445 * [widget_name_connected_to_pin0, widget_name_connected_to_pin1, ...], 445 446 * with the index as the queue ID. 446 447 * 447 448 * The array is used for special pin binding. Note that even if there 448 - * is only one sink/source pin requires special pin binding, pin binding 449 - * should be defined for all sink/source pins in topology, for pin(s) that 449 + * is only one input/output pin requires special pin binding, pin binding 450 + * should be defined for all input/output pins in topology, for pin(s) that 450 451 * are not used, give the value "NotConnected". 451 452 * 452 453 * If pin binding is not defined in topology, nothing to parse in the kernel, 453 - * sink_pin_binding and src_pin_binding shall be NULL. 454 + * input_pin_binding and output_pin_binding shall be NULL. 454 455 */ 455 - char **sink_pin_binding; 456 - char **src_pin_binding; 456 + char **input_pin_binding; 457 + char **output_pin_binding; 457 458 458 - struct ida src_queue_ida; 459 - struct ida sink_queue_ida; 459 + struct ida output_queue_ida; 460 + struct ida input_queue_ida; 460 461 461 462 void *private; /* core does not touch this */ 462 463 };
+65 -59
sound/soc/sof/topology.c
··· 416 416 }; 417 417 418 418 static const struct sof_topology_token comp_pin_tokens[] = { 419 - {SOF_TKN_COMP_NUM_SINK_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 420 - offsetof(struct snd_sof_widget, num_sink_pins)}, 421 - {SOF_TKN_COMP_NUM_SOURCE_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 422 - offsetof(struct snd_sof_widget, num_source_pins)}, 419 + {SOF_TKN_COMP_NUM_INPUT_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 420 + offsetof(struct snd_sof_widget, num_input_pins)}, 421 + {SOF_TKN_COMP_NUM_OUTPUT_PINS, SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, 422 + offsetof(struct snd_sof_widget, num_output_pins)}, 423 423 }; 424 424 425 - static const struct sof_topology_token comp_sink_pin_binding_tokens[] = { 426 - {SOF_TKN_COMP_SINK_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING, 425 + static const struct sof_topology_token comp_input_pin_binding_tokens[] = { 426 + {SOF_TKN_COMP_INPUT_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING, 427 427 get_token_string, 0}, 428 428 }; 429 429 430 - static const struct sof_topology_token comp_src_pin_binding_tokens[] = { 431 - {SOF_TKN_COMP_SRC_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING, 430 + static const struct sof_topology_token comp_output_pin_binding_tokens[] = { 431 + {SOF_TKN_COMP_OUTPUT_PIN_BINDING_WNAME, SND_SOC_TPLG_TUPLE_TYPE_STRING, 432 432 get_token_string, 0}, 433 433 }; 434 434 ··· 1231 1231 1232 1232 continue; 1233 1233 case SOF_IN_AUDIO_FORMAT_TOKENS: 1234 - case SOF_OUT_AUDIO_FORMAT_TOKENS: 1235 - case SOF_COPIER_GATEWAY_CFG_TOKENS: 1236 - case SOF_AUDIO_FORMAT_BUFFER_SIZE_TOKENS: 1237 - num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_AUDIO_FORMATS, 1234 + num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_INPUT_AUDIO_FORMATS, 1238 1235 swidget->tuples, swidget->num_tuples); 1239 - 1240 1236 if (num_sets < 0) { 1241 - dev_err(sdev->dev, "Invalid audio format count for %s\n", 1237 + dev_err(sdev->dev, "Invalid input audio format count for %s\n", 1242 1238 swidget->widget->name); 1243 1239 ret = num_sets; 1244 1240 goto err; 1245 1241 } 1246 - 1247 - if (num_sets > 1) { 1248 - struct snd_sof_tuple *new_tuples; 1249 - 1250 - num_tuples += token_list[object_token_list[i]].count * num_sets; 1251 - new_tuples = krealloc(swidget->tuples, 1252 - sizeof(*new_tuples) * num_tuples, GFP_KERNEL); 1253 - if (!new_tuples) { 1254 - ret = -ENOMEM; 1255 - goto err; 1256 - } 1257 - 1258 - swidget->tuples = new_tuples; 1242 + break; 1243 + case SOF_OUT_AUDIO_FORMAT_TOKENS: 1244 + num_sets = sof_get_token_value(SOF_TKN_COMP_NUM_OUTPUT_AUDIO_FORMATS, 1245 + swidget->tuples, swidget->num_tuples); 1246 + if (num_sets < 0) { 1247 + dev_err(sdev->dev, "Invalid output audio format count for %s\n", 1248 + swidget->widget->name); 1249 + ret = num_sets; 1250 + goto err; 1259 1251 } 1260 1252 break; 1261 1253 default: 1262 1254 break; 1255 + } 1256 + 1257 + if (num_sets > 1) { 1258 + struct snd_sof_tuple *new_tuples; 1259 + 1260 + num_tuples += token_list[object_token_list[i]].count * num_sets; 1261 + new_tuples = krealloc(swidget->tuples, 1262 + sizeof(*new_tuples) * num_tuples, GFP_KERNEL); 1263 + if (!new_tuples) { 1264 + ret = -ENOMEM; 1265 + goto err; 1266 + } 1267 + 1268 + swidget->tuples = new_tuples; 1263 1269 } 1264 1270 1265 1271 /* copy one set of tuples per token ID into swidget->tuples */ ··· 1292 1286 u32 num_pins; 1293 1287 int i; 1294 1288 1295 - if (pin_type == SOF_PIN_TYPE_SINK) { 1296 - pin_binding = swidget->sink_pin_binding; 1297 - num_pins = swidget->num_sink_pins; 1289 + if (pin_type == SOF_PIN_TYPE_INPUT) { 1290 + pin_binding = swidget->input_pin_binding; 1291 + num_pins = swidget->num_input_pins; 1298 1292 } else { 1299 - pin_binding = swidget->src_pin_binding; 1300 - num_pins = swidget->num_source_pins; 1293 + pin_binding = swidget->output_pin_binding; 1294 + num_pins = swidget->num_output_pins; 1301 1295 } 1302 1296 1303 1297 if (pin_binding) { ··· 1319 1313 int ret; 1320 1314 int i; 1321 1315 1322 - if (pin_type == SOF_PIN_TYPE_SINK) { 1323 - num_pins = swidget->num_sink_pins; 1324 - pin_binding_token = comp_sink_pin_binding_tokens; 1325 - token_count = ARRAY_SIZE(comp_sink_pin_binding_tokens); 1316 + if (pin_type == SOF_PIN_TYPE_INPUT) { 1317 + num_pins = swidget->num_input_pins; 1318 + pin_binding_token = comp_input_pin_binding_tokens; 1319 + token_count = ARRAY_SIZE(comp_input_pin_binding_tokens); 1326 1320 } else { 1327 - num_pins = swidget->num_source_pins; 1328 - pin_binding_token = comp_src_pin_binding_tokens; 1329 - token_count = ARRAY_SIZE(comp_src_pin_binding_tokens); 1321 + num_pins = swidget->num_output_pins; 1322 + pin_binding_token = comp_output_pin_binding_tokens; 1323 + token_count = ARRAY_SIZE(comp_output_pin_binding_tokens); 1330 1324 } 1331 1325 1332 1326 memset(pin_binding, 0, SOF_WIDGET_MAX_NUM_PINS * sizeof(char *)); ··· 1343 1337 ret = -ENOMEM; 1344 1338 goto err; 1345 1339 } 1346 - if (pin_type == SOF_PIN_TYPE_SINK) 1347 - swidget->sink_pin_binding = pb; 1340 + if (pin_type == SOF_PIN_TYPE_INPUT) 1341 + swidget->input_pin_binding = pb; 1348 1342 else 1349 - swidget->src_pin_binding = pb; 1343 + swidget->output_pin_binding = pb; 1350 1344 } 1351 1345 1352 1346 return 0; ··· 1385 1379 swidget->private = NULL; 1386 1380 mutex_init(&swidget->setup_mutex); 1387 1381 1388 - ida_init(&swidget->src_queue_ida); 1389 - ida_init(&swidget->sink_queue_ida); 1382 + ida_init(&swidget->output_queue_ida); 1383 + ida_init(&swidget->input_queue_ida); 1390 1384 1391 1385 ret = sof_parse_tokens(scomp, swidget, comp_pin_tokens, 1392 1386 ARRAY_SIZE(comp_pin_tokens), priv->array, ··· 1397 1391 goto widget_free; 1398 1392 } 1399 1393 1400 - if (swidget->num_sink_pins > SOF_WIDGET_MAX_NUM_PINS || 1401 - swidget->num_source_pins > SOF_WIDGET_MAX_NUM_PINS) { 1402 - dev_err(scomp->dev, "invalid pins for %s: [sink: %d, src: %d]\n", 1403 - swidget->widget->name, swidget->num_sink_pins, swidget->num_source_pins); 1394 + if (swidget->num_input_pins > SOF_WIDGET_MAX_NUM_PINS || 1395 + swidget->num_output_pins > SOF_WIDGET_MAX_NUM_PINS) { 1396 + dev_err(scomp->dev, "invalid pins for %s: [input: %d, output: %d]\n", 1397 + swidget->widget->name, swidget->num_input_pins, swidget->num_output_pins); 1404 1398 ret = -EINVAL; 1405 1399 goto widget_free; 1406 1400 } 1407 1401 1408 - if (swidget->num_sink_pins > 1) { 1409 - ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_SINK); 1402 + if (swidget->num_input_pins > 1) { 1403 + ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_INPUT); 1410 1404 /* on parsing error, pin binding is not allocated, nothing to free. */ 1411 1405 if (ret < 0) { 1412 - dev_err(scomp->dev, "failed to parse sink pin binding for %s\n", 1406 + dev_err(scomp->dev, "failed to parse input pin binding for %s\n", 1413 1407 w->name); 1414 1408 goto widget_free; 1415 1409 } 1416 1410 } 1417 1411 1418 - if (swidget->num_source_pins > 1) { 1419 - ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_SOURCE); 1412 + if (swidget->num_output_pins > 1) { 1413 + ret = sof_parse_pin_binding(swidget, priv, SOF_PIN_TYPE_OUTPUT); 1420 1414 /* on parsing error, pin binding is not allocated, nothing to free. */ 1421 1415 if (ret < 0) { 1422 - dev_err(scomp->dev, "failed to parse source pin binding for %s\n", 1416 + dev_err(scomp->dev, "failed to parse output pin binding for %s\n", 1423 1417 w->name); 1424 1418 goto widget_free; 1425 1419 } ··· 1428 1422 dev_dbg(scomp->dev, 1429 1423 "tplg: widget %d (%s) is ready [type: %d, pipe: %d, pins: %d / %d, stream: %s]\n", 1430 1424 swidget->comp_id, w->name, swidget->id, index, 1431 - swidget->num_sink_pins, swidget->num_source_pins, 1425 + swidget->num_input_pins, swidget->num_output_pins, 1432 1426 strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none"); 1433 1427 1434 1428 widget_ops = tplg_ops ? tplg_ops->widget : NULL; ··· 1649 1643 if (widget_ops && widget_ops[swidget->id].ipc_free) 1650 1644 widget_ops[swidget->id].ipc_free(swidget); 1651 1645 1652 - ida_destroy(&swidget->src_queue_ida); 1653 - ida_destroy(&swidget->sink_queue_ida); 1646 + ida_destroy(&swidget->output_queue_ida); 1647 + ida_destroy(&swidget->input_queue_ida); 1654 1648 1655 - sof_free_pin_binding(swidget, SOF_PIN_TYPE_SINK); 1656 - sof_free_pin_binding(swidget, SOF_PIN_TYPE_SOURCE); 1649 + sof_free_pin_binding(swidget, SOF_PIN_TYPE_INPUT); 1650 + sof_free_pin_binding(swidget, SOF_PIN_TYPE_OUTPUT); 1657 1651 1658 1652 kfree(swidget->tuples); 1659 1653