Lines Matching +full:stream +full:- +full:match +full:- +full:mask

1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
18 #include "sof-priv.h"
19 #include "sof-audio.h"
29 * from dB gain 20th root of 10 in Q1.16 fixed-point notation
32 /* 40th root of 10 in Q1.16 fixed-point notation*/
44 * sof_update_ipc_object - Parse multiple sets of tokens within the token array associated with the
66 token_list = tplg_ops ? tplg_ops->token_list : NULL; in sof_update_ipc_object()
72 dev_err(scomp->dev, "Invalid token count for token ID: %d\n", token_id); in sof_update_ipc_object()
73 return -EINVAL; in sof_update_ipc_object()
76 /* No tokens to match */ in sof_update_ipc_object()
82 dev_err(scomp->dev, "Invalid tokens for token id: %d\n", token_id); in sof_update_ipc_object()
83 return -EINVAL; in sof_update_ipc_object()
113 dev_err(scomp->dev, in sof_update_ipc_object()
116 return -EINVAL; in sof_update_ipc_object()
146 return -EINVAL; in get_tlv_data()
166 * Function to truncate an unsigned 64-bit number
167 * by x bits and return 32-bit unsigned number. This
179 return (u32)(((i >> (x - 1)) + 1) >> 1); in vol_shift_64()
184 * a is a fractional number represented by a fixed-point
189 * fixed-point integer with a fractional word length of "fwl"
203 iter = exp * -1; in vol_pow32()
210 * Product of 2 Qx.fwl fixed-point numbers yields a Q2*x.2*fwl in vol_pow32()
249 * compute linear gain represented by fixed-point in vol_compute_gain()
255 f_step = tlv[TLV_STEP] - (tlv[TLV_STEP] / 100); in vol_compute_gain()
273 struct snd_soc_component *scomp = scontrol->scomp; in set_up_volume_table()
277 if (tplg_ops && tplg_ops->control && tplg_ops->control->set_up_volume_table) in set_up_volume_table()
278 return tplg_ops->control->set_up_volume_table(scontrol, tlv, size); in set_up_volume_table()
280 dev_err(scomp->dev, "Mandatory op %s not set\n", __func__); in set_up_volume_table()
281 return -EINVAL; in set_up_volume_table()
354 *val = le32_to_cpu(velem->value); in get_token_u32()
363 *val = (u16)le32_to_cpu(velem->value); in get_token_u16()
372 memcpy(dst, velem->uuid, UUID_SIZE); in get_token_uuid()
388 return -ENOMEM; in get_token_string()
411 offsetof(struct snd_sof_pcm, stream[0].d0i3_compatible)},
413 offsetof(struct snd_sof_pcm, stream[1].d0i3_compatible)},
415 offsetof(struct snd_sof_pcm, stream[0].pause_supported)},
417 offsetof(struct snd_sof_pcm, stream[1].pause_supported)},
446 * sof_parse_uuid_tokens - Parse multiple sets of UUID tokens
466 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { in sof_parse_uuid_tokens()
467 elem = &array->uuid[i]; in sof_parse_uuid_tokens()
471 /* match token type */ in sof_parse_uuid_tokens()
475 /* match token id */ in sof_parse_uuid_tokens()
476 if (tokens[j].token != le32_to_cpu(elem->token)) in sof_parse_uuid_tokens()
479 /* matched - now load token */ in sof_parse_uuid_tokens()
491 * sof_copy_tuples - Parse tokens and copy them to the @tuples array
515 token_list = tplg_ops ? tplg_ops->token_list : NULL; in sof_copy_tuples()
521 dev_err(sdev->dev, "Invalid tuples array\n"); in sof_copy_tuples()
522 return -EINVAL; in sof_copy_tuples()
529 dev_err(sdev->dev, "No token array defined for token ID: %d\n", token_id); in sof_copy_tuples()
530 return -EINVAL; in sof_copy_tuples()
535 dev_err(sdev->dev, "No space in tuples array for new tokens from %s", in sof_copy_tuples()
537 return -EINVAL; in sof_copy_tuples()
541 asize = le32_to_cpu(array->size); in sof_copy_tuples()
545 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize); in sof_copy_tuples()
546 return -EINVAL; in sof_copy_tuples()
550 array_size -= asize; in sof_copy_tuples()
552 dev_err(sdev->dev, "Invalid array size 0x%x\n", asize); in sof_copy_tuples()
553 return -EINVAL; in sof_copy_tuples()
557 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { in sof_copy_tuples()
560 /* match token type */ in sof_copy_tuples()
571 elem = &array->string[i]; in sof_copy_tuples()
573 /* match token id */ in sof_copy_tuples()
574 if (tokens[j].token != le32_to_cpu(elem->token)) in sof_copy_tuples()
579 devm_kasprintf(sdev->dev, GFP_KERNEL, in sof_copy_tuples()
580 "%s", elem->string); in sof_copy_tuples()
582 return -ENOMEM; in sof_copy_tuples()
586 elem = &array->value[i]; in sof_copy_tuples()
588 /* match token id */ in sof_copy_tuples()
589 if (tokens[j].token != le32_to_cpu(elem->token)) in sof_copy_tuples()
594 le32_to_cpu(elem->value); in sof_copy_tuples()
617 * sof_parse_string_tokens - Parse multiple sets of tokens
637 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { in sof_parse_string_tokens()
638 elem = &array->string[i]; in sof_parse_string_tokens()
642 /* match token type */ in sof_parse_string_tokens()
646 /* match token id */ in sof_parse_string_tokens()
647 if (tokens[j].token != le32_to_cpu(elem->token)) in sof_parse_string_tokens()
650 /* matched - now load token */ in sof_parse_string_tokens()
651 ret = tokens[j].get_token(elem->string, object, offset + tokens[j].offset); in sof_parse_string_tokens()
663 * sof_parse_word_tokens - Parse multiple sets of tokens
683 for (i = 0; i < le32_to_cpu(array->num_elems); i++) { in sof_parse_word_tokens()
684 elem = &array->value[i]; in sof_parse_word_tokens()
688 /* match token type */ in sof_parse_word_tokens()
695 /* match token id */ in sof_parse_word_tokens()
696 if (tokens[j].token != le32_to_cpu(elem->token)) in sof_parse_word_tokens()
710 * sof_parse_token_sets - Parse multiple sets of tokens
736 asize = le32_to_cpu(array->size); in sof_parse_token_sets()
739 if (asize < 0) { /* FIXME: A zero-size array makes no sense */ in sof_parse_token_sets()
740 dev_err(scomp->dev, "error: invalid array size 0x%x\n", in sof_parse_token_sets()
742 return -EINVAL; in sof_parse_token_sets()
746 array_size -= asize; in sof_parse_token_sets()
748 dev_err(scomp->dev, "error: invalid array size 0x%x\n", in sof_parse_token_sets()
750 return -EINVAL; in sof_parse_token_sets()
754 switch (le32_to_cpu(array->type)) { in sof_parse_token_sets()
764 dev_err(scomp->dev, "error: no memory to copy string token\n"); in sof_parse_token_sets()
778 dev_err(scomp->dev, "error: unknown token type %d\n", in sof_parse_token_sets()
779 array->type); in sof_parse_token_sets()
780 return -EINVAL; in sof_parse_token_sets()
799 * sof_parse_tokens - Parse one set of tokens
839 unsigned int mask; in sof_control_load_volume() local
843 if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) in sof_control_load_volume()
844 return -EINVAL; in sof_control_load_volume()
849 * pre-defined dapm control types (and related functions) creating the actual control in sof_control_load_volume()
852 if (le32_to_cpu(mc->num_channels) > 2) in sof_control_load_volume()
853 kc->info = snd_sof_volume_info; in sof_control_load_volume()
855 scontrol->comp_id = sdev->next_comp_id; in sof_control_load_volume()
856 scontrol->min_volume_step = le32_to_cpu(mc->min); in sof_control_load_volume()
857 scontrol->max_volume_step = le32_to_cpu(mc->max); in sof_control_load_volume()
858 scontrol->num_channels = le32_to_cpu(mc->num_channels); in sof_control_load_volume()
860 scontrol->max = le32_to_cpu(mc->max); in sof_control_load_volume()
861 if (le32_to_cpu(mc->max) == 1) in sof_control_load_volume()
865 if (!kc->tlv.p || get_tlv_data(kc->tlv.p, tlv) < 0) { in sof_control_load_volume()
866 dev_err(scomp->dev, "error: invalid TLV data\n"); in sof_control_load_volume()
867 return -EINVAL; in sof_control_load_volume()
871 ret = set_up_volume_table(scontrol, tlv, le32_to_cpu(mc->max) + 1); in sof_control_load_volume()
873 dev_err(scomp->dev, "error: setting up volume table\n"); in sof_control_load_volume()
879 ret = sof_parse_tokens(scomp, &scontrol->led_ctl, led_tokens, in sof_control_load_volume()
880 ARRAY_SIZE(led_tokens), mc->priv.array, in sof_control_load_volume()
881 le32_to_cpu(mc->priv.size)); in sof_control_load_volume()
883 dev_err(scomp->dev, "error: parse led tokens failed %d\n", in sof_control_load_volume()
884 le32_to_cpu(mc->priv.size)); in sof_control_load_volume()
888 if (scontrol->led_ctl.use_led) { in sof_control_load_volume()
889 mask = scontrol->led_ctl.direction ? SNDRV_CTL_ELEM_ACCESS_MIC_LED : in sof_control_load_volume()
891 scontrol->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; in sof_control_load_volume()
892 scontrol->access |= mask; in sof_control_load_volume()
893 kc->access &= ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; in sof_control_load_volume()
894 kc->access |= mask; in sof_control_load_volume()
895 sdev->led_present = true; in sof_control_load_volume()
898 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", in sof_control_load_volume()
899 scontrol->comp_id, scontrol->num_channels); in sof_control_load_volume()
904 if (le32_to_cpu(mc->max) > 1) in sof_control_load_volume()
905 kfree(scontrol->volume_table); in sof_control_load_volume()
920 if (le32_to_cpu(ec->num_channels) > SND_SOC_TPLG_MAX_CHAN) in sof_control_load_enum()
921 return -EINVAL; in sof_control_load_enum()
923 scontrol->comp_id = sdev->next_comp_id; in sof_control_load_enum()
924 scontrol->num_channels = le32_to_cpu(ec->num_channels); in sof_control_load_enum()
926 dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d comp_id %d\n", in sof_control_load_enum()
927 scontrol->comp_id, scontrol->num_channels, scontrol->comp_id); in sof_control_load_enum()
940 struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; in sof_control_load_bytes()
941 size_t priv_size = le32_to_cpu(control->priv.size); in sof_control_load_bytes()
943 scontrol->max_size = sbe->max; in sof_control_load_bytes()
944 scontrol->comp_id = sdev->next_comp_id; in sof_control_load_bytes()
946 dev_dbg(scomp->dev, "tplg: load kcontrol index %d\n", scontrol->comp_id); in sof_control_load_bytes()
950 scontrol->priv = kmemdup(control->priv.data, priv_size, GFP_KERNEL); in sof_control_load_bytes()
951 if (!scontrol->priv) in sof_control_load_bytes()
952 return -ENOMEM; in sof_control_load_bytes()
954 scontrol->priv_size = priv_size; in sof_control_load_bytes()
960 /* external kcontrol init - used for any driver specific init */
973 dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n", in sof_control_load()
974 hdr->type, hdr->name); in sof_control_load()
978 return -ENOMEM; in sof_control_load()
980 scontrol->name = kstrdup(hdr->name, GFP_KERNEL); in sof_control_load()
981 if (!scontrol->name) { in sof_control_load()
983 return -ENOMEM; in sof_control_load()
986 scontrol->scomp = scomp; in sof_control_load()
987 scontrol->access = kc->access; in sof_control_load()
988 scontrol->info_type = le32_to_cpu(hdr->ops.info); in sof_control_load()
989 scontrol->index = kc->index; in sof_control_load()
991 switch (le32_to_cpu(hdr->ops.info)) { in sof_control_load()
995 sm = (struct soc_mixer_control *)kc->private_value; in sof_control_load()
996 dobj = &sm->dobj; in sof_control_load()
1000 sbe = (struct soc_bytes_ext *)kc->private_value; in sof_control_load()
1001 dobj = &sbe->dobj; in sof_control_load()
1006 se = (struct soc_enum *)kc->private_value; in sof_control_load()
1007 dobj = &se->dobj; in sof_control_load()
1018 dev_warn(scomp->dev, "control type not supported %d:%d:%d\n", in sof_control_load()
1019 hdr->ops.get, hdr->ops.put, hdr->ops.info); in sof_control_load()
1020 kfree(scontrol->name); in sof_control_load()
1026 kfree(scontrol->name); in sof_control_load()
1031 scontrol->led_ctl.led_value = -1; in sof_control_load()
1033 dobj->private = scontrol; in sof_control_load()
1034 list_add(&scontrol->list, &sdev->kcontrol_list); in sof_control_load()
1043 struct snd_sof_control *scontrol = dobj->private; in sof_control_unload()
1046 dev_dbg(scomp->dev, "tplg: unload control name : %s\n", scontrol->name); in sof_control_unload()
1048 if (tplg_ops && tplg_ops->control_free) { in sof_control_unload()
1049 ret = tplg_ops->control_free(sdev, scontrol); in sof_control_unload()
1051 dev_err(scomp->dev, "failed to free control: %s\n", scontrol->name); in sof_control_unload()
1055 kfree(scontrol->ipc_control_data); in sof_control_unload()
1056 kfree(scontrol->priv); in sof_control_unload()
1057 kfree(scontrol->name); in sof_control_unload()
1058 list_del(&scontrol->list); in sof_control_unload()
1073 struct snd_soc_card *card = scomp->card; in sof_connect_dai_widget()
1076 int stream; in sof_connect_dai_widget() local
1079 if (!w->sname) { in sof_connect_dai_widget()
1080 dev_err(scomp->dev, "Widget %s does not have stream\n", w->name); in sof_connect_dai_widget()
1081 return -EINVAL; in sof_connect_dai_widget()
1084 if (w->id == snd_soc_dapm_dai_out) in sof_connect_dai_widget()
1085 stream = SNDRV_PCM_STREAM_CAPTURE; in sof_connect_dai_widget()
1086 else if (w->id == snd_soc_dapm_dai_in) in sof_connect_dai_widget()
1087 stream = SNDRV_PCM_STREAM_PLAYBACK; in sof_connect_dai_widget()
1093 list_for_each_entry(rtd, &card->rtd_list, list) { in sof_connect_dai_widget()
1094 /* does stream match DAI link ? */ in sof_connect_dai_widget()
1095 if (rtd->dai_link->stream_name) { in sof_connect_dai_widget()
1096 if (!strcmp(rtd->dai_link->stream_name, w->sname)) { in sof_connect_dai_widget()
1099 } else if (strstr(rtd->dai_link->stream_name, w->sname)) { in sof_connect_dai_widget()
1113 if (!snd_soc_dai_get_widget(cpu_dai, stream)) { in sof_connect_dai_widget()
1114 snd_soc_dai_set_widget(cpu_dai, stream, w); in sof_connect_dai_widget()
1118 if (i == rtd->dai_link->num_cpus) { in sof_connect_dai_widget()
1119 dev_err(scomp->dev, "error: can't find BE for DAI %s\n", w->name); in sof_connect_dai_widget()
1121 return -EINVAL; in sof_connect_dai_widget()
1124 dai->name = rtd->dai_link->name; in sof_connect_dai_widget()
1125 dev_dbg(scomp->dev, "tplg: connected widget %s -> DAI link %s\n", in sof_connect_dai_widget()
1126 w->name, rtd->dai_link->name); in sof_connect_dai_widget()
1130 if (!dai->name) { in sof_connect_dai_widget()
1131 dev_err(scomp->dev, "error: can't connect DAI %s stream %s\n", in sof_connect_dai_widget()
1132 w->name, w->sname); in sof_connect_dai_widget()
1133 return -EINVAL; in sof_connect_dai_widget()
1142 struct snd_soc_card *card = scomp->card; in sof_disconnect_dai_widget()
1144 const char *sname = w->sname; in sof_disconnect_dai_widget()
1146 int i, stream; in sof_disconnect_dai_widget() local
1151 if (w->id == snd_soc_dapm_dai_out) in sof_disconnect_dai_widget()
1152 stream = SNDRV_PCM_STREAM_CAPTURE; in sof_disconnect_dai_widget()
1153 else if (w->id == snd_soc_dapm_dai_in) in sof_disconnect_dai_widget()
1154 stream = SNDRV_PCM_STREAM_PLAYBACK; in sof_disconnect_dai_widget()
1158 list_for_each_entry(rtd, &card->rtd_list, list) { in sof_disconnect_dai_widget()
1159 /* does stream match DAI link ? */ in sof_disconnect_dai_widget()
1160 if (!rtd->dai_link->stream_name || in sof_disconnect_dai_widget()
1161 !strstr(rtd->dai_link->stream_name, sname)) in sof_disconnect_dai_widget()
1165 if (snd_soc_dai_get_widget(cpu_dai, stream) == w) { in sof_disconnect_dai_widget()
1166 snd_soc_dai_set_widget(cpu_dai, stream, NULL); in sof_disconnect_dai_widget()
1179 if (sdev->dspless_mode_selected) in spcm_bind()
1183 spcm->pcm.caps[dir].name, in spcm_bind()
1186 dev_err(scomp->dev, "can't find host comp to bind pcm\n"); in spcm_bind()
1187 return -EINVAL; in spcm_bind()
1190 spcm->stream[dir].comp_id = host_widget->comp_id; in spcm_bind()
1200 return -EINVAL; in sof_get_token_value()
1207 return -EINVAL; in sof_get_token_value()
1216 struct snd_soc_tplg_private *private = &tw->priv; in sof_widget_parse_tokens()
1221 token_list = tplg_ops ? tplg_ops->token_list : NULL; in sof_widget_parse_tokens()
1227 dev_err(scomp->dev, "No token list for widget %s\n", swidget->widget->name); in sof_widget_parse_tokens()
1228 return -EINVAL; in sof_widget_parse_tokens()
1236 swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL); in sof_widget_parse_tokens()
1237 if (!swidget->tuples) in sof_widget_parse_tokens()
1238 return -ENOMEM; in sof_widget_parse_tokens()
1245 dev_err(scomp->dev, "Invalid token id %d for widget %s\n", in sof_widget_parse_tokens()
1246 object_token_list[i], swidget->widget->name); in sof_widget_parse_tokens()
1247 ret = -EINVAL; in sof_widget_parse_tokens()
1257 private->array, le32_to_cpu(private->size)); in sof_widget_parse_tokens()
1259 dev_err(scomp->dev, "Failed parsing %s for widget %s\n", in sof_widget_parse_tokens()
1261 swidget->widget->name); in sof_widget_parse_tokens()
1268 swidget->tuples, swidget->num_tuples); in sof_widget_parse_tokens()
1270 dev_err(sdev->dev, "Invalid input audio format count for %s\n", in sof_widget_parse_tokens()
1271 swidget->widget->name); in sof_widget_parse_tokens()
1278 swidget->tuples, swidget->num_tuples); in sof_widget_parse_tokens()
1280 dev_err(sdev->dev, "Invalid output audio format count for %s\n", in sof_widget_parse_tokens()
1281 swidget->widget->name); in sof_widget_parse_tokens()
1293 num_tuples += token_list[object_token_list[i]].count * (num_sets - 1); in sof_widget_parse_tokens()
1294 new_tuples = krealloc_array(swidget->tuples, in sof_widget_parse_tokens()
1297 ret = -ENOMEM; in sof_widget_parse_tokens()
1301 swidget->tuples = new_tuples; in sof_widget_parse_tokens()
1304 /* copy one set of tuples per token ID into swidget->tuples */ in sof_widget_parse_tokens()
1305 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), in sof_widget_parse_tokens()
1306 object_token_list[i], num_sets, swidget->tuples, in sof_widget_parse_tokens()
1307 num_tuples, &swidget->num_tuples); in sof_widget_parse_tokens()
1309 dev_err(scomp->dev, "Failed parsing %s for widget %s err: %d\n", in sof_widget_parse_tokens()
1310 token_list[object_token_list[i]].name, swidget->widget->name, ret); in sof_widget_parse_tokens()
1317 kfree(swidget->tuples); in sof_widget_parse_tokens()
1329 pin_binding = swidget->input_pin_binding; in sof_free_pin_binding()
1330 num_pins = swidget->num_input_pins; in sof_free_pin_binding()
1332 pin_binding = swidget->output_pin_binding; in sof_free_pin_binding()
1333 num_pins = swidget->num_output_pins; in sof_free_pin_binding()
1356 num_pins = swidget->num_input_pins; in sof_parse_pin_binding()
1360 num_pins = swidget->num_output_pins; in sof_parse_pin_binding()
1366 ret = sof_parse_token_sets(swidget->scomp, pin_binding, pin_binding_token, in sof_parse_pin_binding()
1367 token_count, priv->array, le32_to_cpu(priv->size), in sof_parse_pin_binding()
1376 ret = -ENOMEM; in sof_parse_pin_binding()
1380 swidget->input_pin_binding = pb; in sof_parse_pin_binding()
1382 swidget->output_pin_binding = pb; in sof_parse_pin_binding()
1399 w->no_wname_in_kcontrol_name = !!le32_to_cpu(velem->value); in get_w_no_wname_in_long_name()
1408 /* external widget init - used for any driver specific init */
1416 struct snd_soc_tplg_private *priv = &tw->priv; in sof_widget_ready()
1425 return -ENOMEM; in sof_widget_ready()
1427 swidget->scomp = scomp; in sof_widget_ready()
1428 swidget->widget = w; in sof_widget_ready()
1429 swidget->comp_id = sdev->next_comp_id++; in sof_widget_ready()
1430 swidget->id = w->id; in sof_widget_ready()
1431 swidget->pipeline_id = index; in sof_widget_ready()
1432 swidget->private = NULL; in sof_widget_ready()
1433 mutex_init(&swidget->setup_mutex); in sof_widget_ready()
1435 ida_init(&swidget->output_queue_ida); in sof_widget_ready()
1436 ida_init(&swidget->input_queue_ida); in sof_widget_ready()
1439 priv->array, le32_to_cpu(priv->size)); in sof_widget_ready()
1441 dev_err(scomp->dev, "failed to parse dapm widget tokens for %s\n", in sof_widget_ready()
1442 w->name); in sof_widget_ready()
1447 ARRAY_SIZE(comp_pin_tokens), priv->array, in sof_widget_ready()
1448 le32_to_cpu(priv->size)); in sof_widget_ready()
1450 dev_err(scomp->dev, "failed to parse component pin tokens for %s\n", in sof_widget_ready()
1451 w->name); in sof_widget_ready()
1455 if (swidget->num_input_pins > SOF_WIDGET_MAX_NUM_PINS || in sof_widget_ready()
1456 swidget->num_output_pins > SOF_WIDGET_MAX_NUM_PINS) { in sof_widget_ready()
1457 dev_err(scomp->dev, "invalid pins for %s: [input: %d, output: %d]\n", in sof_widget_ready()
1458 swidget->widget->name, swidget->num_input_pins, swidget->num_output_pins); in sof_widget_ready()
1459 ret = -EINVAL; in sof_widget_ready()
1463 if (swidget->num_input_pins > 1) { in sof_widget_ready()
1467 dev_err(scomp->dev, "failed to parse input pin binding for %s\n", in sof_widget_ready()
1468 w->name); in sof_widget_ready()
1473 if (swidget->num_output_pins > 1) { in sof_widget_ready()
1477 dev_err(scomp->dev, "failed to parse output pin binding for %s\n", in sof_widget_ready()
1478 w->name); in sof_widget_ready()
1483 dev_dbg(scomp->dev, in sof_widget_ready()
1484 "tplg: widget %d (%s) is ready [type: %d, pipe: %d, pins: %d / %d, stream: %s]\n", in sof_widget_ready()
1485 swidget->comp_id, w->name, swidget->id, index, in sof_widget_ready()
1486 swidget->num_input_pins, swidget->num_output_pins, in sof_widget_ready()
1487 strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 ? w->sname : "none"); in sof_widget_ready()
1489 widget_ops = tplg_ops ? tplg_ops->widget : NULL; in sof_widget_ready()
1491 token_list = widget_ops[w->id].token_list; in sof_widget_ready()
1492 token_list_size = widget_ops[w->id].token_list_size; in sof_widget_ready()
1496 switch (w->id) { in sof_widget_ready()
1501 ret = -ENOMEM; in sof_widget_ready()
1512 list_add(&dai->list, &sdev->dai_list); in sof_widget_ready()
1513 swidget->private = dai; in sof_widget_ready()
1516 /* check we have some tokens - we need at least process type */ in sof_widget_ready()
1517 if (le32_to_cpu(tw->priv.size) == 0) { in sof_widget_ready()
1518 dev_err(scomp->dev, "error: process tokens not found\n"); in sof_widget_ready()
1519 ret = -EINVAL; in sof_widget_ready()
1525 if (!le32_to_cpu(tw->num_kcontrols)) { in sof_widget_ready()
1526 dev_err(scomp->dev, "invalid kcontrol count %d for volume\n", in sof_widget_ready()
1527 tw->num_kcontrols); in sof_widget_ready()
1528 ret = -EINVAL; in sof_widget_ready()
1549 dev_dbg(scomp->dev, "widget type %d name %s not handled\n", swidget->id, tw->name); in sof_widget_ready()
1555 dev_err(scomp->dev, in sof_widget_ready()
1556 "failed to add widget type %d name : %s stream %s\n", in sof_widget_ready()
1557 swidget->id, tw->name, strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0 in sof_widget_ready()
1558 ? tw->sname : "none"); in sof_widget_ready()
1563 swidget->core = SOF_DSP_PRIMARY_CORE; in sof_widget_ready()
1565 int core = sof_get_token_value(SOF_TKN_COMP_CORE_ID, swidget->tuples, in sof_widget_ready()
1566 swidget->num_tuples); in sof_widget_ready()
1569 swidget->core = core; in sof_widget_ready()
1573 if (tw->event_type) { in sof_widget_ready()
1574 if (widget_ops && widget_ops[w->id].bind_event) { in sof_widget_ready()
1575 ret = widget_ops[w->id].bind_event(scomp, swidget, in sof_widget_ready()
1576 le16_to_cpu(tw->event_type)); in sof_widget_ready()
1578 dev_err(scomp->dev, "widget event binding failed for %s\n", in sof_widget_ready()
1579 swidget->widget->name); in sof_widget_ready()
1586 if (w->id == snd_soc_dapm_scheduler) { in sof_widget_ready()
1591 ret = -ENOMEM; in sof_widget_ready()
1595 spipe->pipe_widget = swidget; in sof_widget_ready()
1596 swidget->spipe = spipe; in sof_widget_ready()
1597 list_add(&spipe->list, &sdev->pipeline_list); in sof_widget_ready()
1600 w->dobj.private = swidget; in sof_widget_ready()
1601 list_add(&swidget->list, &sdev->widget_list); in sof_widget_ready()
1604 kfree(swidget->private); in sof_widget_ready()
1605 kfree(swidget->tuples); in sof_widget_ready()
1616 sroute = dobj->private; in sof_route_unload()
1621 kfree(sroute->private); in sof_route_unload()
1622 list_del(&sroute->list); in sof_route_unload()
1644 swidget = dobj->private; in sof_widget_unload()
1648 widget = swidget->widget; in sof_widget_unload()
1650 switch (swidget->id) { in sof_widget_unload()
1653 dai = swidget->private; in sof_widget_unload()
1656 list_del(&dai->list); in sof_widget_unload()
1663 struct snd_sof_pipeline *spipe = swidget->spipe; in sof_widget_unload()
1665 list_del(&spipe->list); in sof_widget_unload()
1667 swidget->spipe = NULL; in sof_widget_unload()
1673 for (i = 0; i < widget->num_kcontrols; i++) { in sof_widget_unload()
1674 kc = &widget->kcontrol_news[i]; in sof_widget_unload()
1675 switch (widget->dobj.widget.kcontrol_type[i]) { in sof_widget_unload()
1677 sm = (struct soc_mixer_control *)kc->private_value; in sof_widget_unload()
1678 scontrol = sm->dobj.private; in sof_widget_unload()
1679 if (sm->max > 1) in sof_widget_unload()
1680 kfree(scontrol->volume_table); in sof_widget_unload()
1683 se = (struct soc_enum *)kc->private_value; in sof_widget_unload()
1684 scontrol = se->dobj.private; in sof_widget_unload()
1687 sbe = (struct soc_bytes_ext *)kc->private_value; in sof_widget_unload()
1688 scontrol = sbe->dobj.private; in sof_widget_unload()
1691 dev_warn(scomp->dev, "unsupported kcontrol_type\n"); in sof_widget_unload()
1694 kfree(scontrol->ipc_control_data); in sof_widget_unload()
1695 list_del(&scontrol->list); in sof_widget_unload()
1696 kfree(scontrol->name); in sof_widget_unload()
1702 widget_ops = tplg_ops ? tplg_ops->widget : NULL; in sof_widget_unload()
1703 if (widget_ops && widget_ops[swidget->id].ipc_free) in sof_widget_unload()
1704 widget_ops[swidget->id].ipc_free(swidget); in sof_widget_unload()
1706 ida_destroy(&swidget->output_queue_ida); in sof_widget_unload()
1707 ida_destroy(&swidget->input_queue_ida); in sof_widget_unload()
1712 kfree(swidget->tuples); in sof_widget_unload()
1715 list_del(&swidget->list); in sof_widget_unload()
1725 /* FE DAI - used for any driver specific init */
1733 struct snd_soc_tplg_private *private = &pcm->priv; in sof_dai_load()
1735 int stream; in sof_dai_load() local
1744 return -ENOMEM; in sof_dai_load()
1746 spcm->scomp = scomp; in sof_dai_load()
1748 for_each_pcm_streams(stream) { in sof_dai_load()
1749 spcm->stream[stream].comp_id = COMP_ID_UNASSIGNED; in sof_dai_load()
1750 if (pcm->compress) in sof_dai_load()
1751 snd_sof_compr_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); in sof_dai_load()
1753 snd_sof_pcm_init_elapsed_work(&spcm->stream[stream].period_elapsed_work); in sof_dai_load()
1756 spcm->pcm = *pcm; in sof_dai_load()
1757 dev_dbg(scomp->dev, "tplg: load pcm %s\n", pcm->dai_name); in sof_dai_load()
1760 if (ipc_pcm_ops && ipc_pcm_ops->pcm_setup) { in sof_dai_load()
1761 ret = ipc_pcm_ops->pcm_setup(sdev, spcm); in sof_dai_load()
1768 dai_drv->dobj.private = spcm; in sof_dai_load()
1769 list_add(&spcm->list, &sdev->pcm_list); in sof_dai_load()
1772 ARRAY_SIZE(stream_tokens), private->array, in sof_dai_load()
1773 le32_to_cpu(private->size)); in sof_dai_load()
1775 dev_err(scomp->dev, "error: parse stream tokens failed %d\n", in sof_dai_load()
1776 le32_to_cpu(private->size)); in sof_dai_load()
1781 if (!spcm->pcm.playback) in sof_dai_load()
1784 stream = SNDRV_PCM_STREAM_PLAYBACK; in sof_dai_load()
1786 caps = &spcm->pcm.caps[stream]; in sof_dai_load()
1789 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, in sof_dai_load()
1790 PAGE_SIZE, &spcm->stream[stream].page_table); in sof_dai_load()
1792 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", in sof_dai_load()
1793 caps->name, ret); in sof_dai_load()
1799 ret = spcm_bind(scomp, spcm, stream); in sof_dai_load()
1801 dev_err(scomp->dev, in sof_dai_load()
1807 stream = SNDRV_PCM_STREAM_CAPTURE; in sof_dai_load()
1810 if (!spcm->pcm.capture) in sof_dai_load()
1813 caps = &spcm->pcm.caps[stream]; in sof_dai_load()
1816 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev, in sof_dai_load()
1817 PAGE_SIZE, &spcm->stream[stream].page_table); in sof_dai_load()
1819 dev_err(scomp->dev, "error: can't alloc page table for %s %d\n", in sof_dai_load()
1820 caps->name, ret); in sof_dai_load()
1825 ret = spcm_bind(scomp, spcm, stream); in sof_dai_load()
1827 dev_err(scomp->dev, in sof_dai_load()
1829 snd_dma_free_pages(&spcm->stream[stream].page_table); in sof_dai_load()
1836 if (spcm->pcm.playback) in sof_dai_load()
1837 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); in sof_dai_load()
1847 struct snd_sof_pcm *spcm = dobj->private; in sof_dai_unload()
1850 if (spcm->pcm.playback) in sof_dai_unload()
1851 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_PLAYBACK].page_table); in sof_dai_unload()
1853 if (spcm->pcm.capture) in sof_dai_unload()
1854 snd_dma_free_pages(&spcm->stream[SNDRV_PCM_STREAM_CAPTURE].page_table); in sof_dai_unload()
1857 if (ipc_pcm_ops && ipc_pcm_ops->pcm_free) in sof_dai_unload()
1858 ipc_pcm_ops->pcm_free(sdev, spcm); in sof_dai_unload()
1861 list_del(&spcm->list); in sof_dai_unload()
1872 /* DAI link - used for any driver specific init */
1878 struct snd_soc_tplg_private *private = &cfg->priv; in sof_link_load()
1885 if (!link->platforms) { in sof_link_load()
1886 dev_err(scomp->dev, "error: no platforms\n"); in sof_link_load()
1887 return -EINVAL; in sof_link_load()
1889 link->platforms->name = dev_name(scomp->dev); in sof_link_load()
1891 if (tplg_ops && tplg_ops->link_setup) { in sof_link_load()
1892 ret = tplg_ops->link_setup(sdev, link); in sof_link_load()
1898 if (!link->no_pcm) { in sof_link_load()
1899 link->nonatomic = true; in sof_link_load()
1903 /* check we have some tokens - we need at least DAI type */ in sof_link_load()
1904 if (le32_to_cpu(private->size) == 0) { in sof_link_load()
1905 dev_err(scomp->dev, "error: expected tokens for DAI, none found\n"); in sof_link_load()
1906 return -EINVAL; in sof_link_load()
1911 return -ENOMEM; in sof_link_load()
1913 slink->num_hw_configs = le32_to_cpu(cfg->num_hw_configs); in sof_link_load()
1914 slink->hw_configs = kmemdup_array(cfg->hw_config, in sof_link_load()
1915 slink->num_hw_configs, sizeof(*slink->hw_configs), in sof_link_load()
1917 if (!slink->hw_configs) { in sof_link_load()
1919 return -ENOMEM; in sof_link_load()
1922 slink->default_hw_cfg_id = le32_to_cpu(cfg->default_hw_config_id); in sof_link_load()
1923 slink->link = link; in sof_link_load()
1925 dev_dbg(scomp->dev, "tplg: %d hw_configs found, default id: %d for dai link %s!\n", in sof_link_load()
1926 slink->num_hw_configs, slink->default_hw_cfg_id, link->name); in sof_link_load()
1930 private->array, le32_to_cpu(private->size)); in sof_link_load()
1932 dev_err(scomp->dev, "Failed tp parse common DAI link tokens\n"); in sof_link_load()
1933 kfree(slink->hw_configs); in sof_link_load()
1938 token_list = tplg_ops ? tplg_ops->token_list : NULL; in sof_link_load()
1944 num_sets = slink->num_hw_configs; in sof_link_load()
1945 switch (slink->type) { in sof_link_load()
1948 num_tuples += token_list[SOF_SSP_TOKENS].count * slink->num_hw_configs; in sof_link_load()
2002 slink->tuples = kcalloc(num_tuples, sizeof(*slink->tuples), GFP_KERNEL); in sof_link_load()
2003 if (!slink->tuples) { in sof_link_load()
2004 kfree(slink->hw_configs); in sof_link_load()
2006 return -ENOMEM; in sof_link_load()
2011 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), in sof_link_load()
2012 SOF_DAI_LINK_TOKENS, 1, slink->tuples, in sof_link_load()
2013 num_tuples, &slink->num_tuples); in sof_link_load()
2015 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", in sof_link_load()
2016 token_list[SOF_DAI_LINK_TOKENS].name, link->name); in sof_link_load()
2021 /* nothing more to do if there are no DAI type-specific tokens defined */ in sof_link_load()
2025 /* parse "num_sets" sets of DAI-specific tokens */ in sof_link_load()
2026 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), in sof_link_load()
2027 token_id, num_sets, slink->tuples, num_tuples, &slink->num_tuples); in sof_link_load()
2029 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", in sof_link_load()
2030 token_list[token_id].name, link->name); in sof_link_load()
2037 slink->tuples, slink->num_tuples); in sof_link_load()
2040 dev_err(sdev->dev, "Invalid active PDM count for %s\n", link->name); in sof_link_load()
2045 ret = sof_copy_tuples(sdev, private->array, le32_to_cpu(private->size), in sof_link_load()
2046 SOF_DMIC_PDM_TOKENS, num_sets, slink->tuples, in sof_link_load()
2047 num_tuples, &slink->num_tuples); in sof_link_load()
2049 dev_err(scomp->dev, "failed to parse %s for dai link %s\n", in sof_link_load()
2050 token_list[SOF_DMIC_PDM_TOKENS].name, link->name); in sof_link_load()
2055 link->dobj.private = slink; in sof_link_load()
2056 list_add(&slink->list, &sdev->dai_link_list); in sof_link_load()
2061 kfree(slink->tuples); in sof_link_load()
2062 kfree(slink->hw_configs); in sof_link_load()
2070 struct snd_sof_dai_link *slink = dobj->private; in sof_link_unload()
2075 slink->link->platforms->name = NULL; in sof_link_unload()
2077 kfree(slink->tuples); in sof_link_unload()
2078 list_del(&slink->list); in sof_link_unload()
2079 kfree(slink->hw_configs); in sof_link_unload()
2081 dobj->private = NULL; in sof_link_unload()
2086 /* DAI link - used for any driver specific init */
2092 struct snd_soc_dobj *dobj = &route->dobj; in sof_route_load()
2099 return -ENOMEM; in sof_route_load()
2101 sroute->scomp = scomp; in sof_route_load()
2102 dev_dbg(scomp->dev, "sink %s control %s source %s\n", in sof_route_load()
2103 route->sink, route->control ? route->control : "none", in sof_route_load()
2104 route->source); in sof_route_load()
2107 source_swidget = snd_sof_find_swidget(scomp, (char *)route->source); in sof_route_load()
2109 dev_err(scomp->dev, "error: source %s not found\n", in sof_route_load()
2110 route->source); in sof_route_load()
2111 ret = -EINVAL; in sof_route_load()
2121 if (source_swidget->id == snd_soc_dapm_out_drv || in sof_route_load()
2122 source_swidget->id == snd_soc_dapm_output) in sof_route_load()
2126 sink_swidget = snd_sof_find_swidget(scomp, (char *)route->sink); in sof_route_load()
2128 dev_err(scomp->dev, "error: sink %s not found\n", in sof_route_load()
2129 route->sink); in sof_route_load()
2130 ret = -EINVAL; in sof_route_load()
2138 if (sink_swidget->id == snd_soc_dapm_out_drv || in sof_route_load()
2139 sink_swidget->id == snd_soc_dapm_output) in sof_route_load()
2142 sroute->route = route; in sof_route_load()
2143 dobj->private = sroute; in sof_route_load()
2144 sroute->src_widget = source_swidget; in sof_route_load()
2145 sroute->sink_widget = sink_swidget; in sof_route_load()
2148 list_add(&sroute->list, &sdev->route_list); in sof_route_load()
2157 * sof_set_widget_pipeline - Set pipeline for a component
2162 * Return: 0 if successful, -EINVAL on error.
2169 struct snd_sof_widget *pipe_widget = spipe->pipe_widget; in sof_set_widget_pipeline()
2172 if (pipe_widget->dynamic_pipeline_widget) { in sof_set_widget_pipeline()
2174 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) in sof_set_widget_pipeline()
2175 if (scontrol->comp_id == swidget->comp_id && in sof_set_widget_pipeline()
2176 (scontrol->access & SNDRV_CTL_ELEM_ACCESS_VOLATILE)) { in sof_set_widget_pipeline()
2177 dev_err(sdev->dev, in sof_set_widget_pipeline()
2179 swidget->widget->name); in sof_set_widget_pipeline()
2180 return -EINVAL; in sof_set_widget_pipeline()
2185 swidget->spipe = spipe; in sof_set_widget_pipeline()
2186 swidget->dynamic_pipeline_widget = pipe_widget->dynamic_pipeline_widget; in sof_set_widget_pipeline()
2191 /* completion - called at completion of firmware loading */
2201 widget_ops = tplg_ops ? tplg_ops->widget : NULL; in sof_complete()
2204 if (tplg_ops && tplg_ops->control_setup) in sof_complete()
2205 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { in sof_complete()
2206 ret = tplg_ops->control_setup(sdev, scontrol); in sof_complete()
2208 dev_err(sdev->dev, "failed updating IPC struct for control %s\n", in sof_complete()
2209 scontrol->name); in sof_complete()
2215 list_for_each_entry(spipe, &sdev->pipeline_list, list) { in sof_complete()
2216 struct snd_sof_widget *pipe_widget = spipe->pipe_widget; in sof_complete()
2219 pipe_widget->instance_id = -EINVAL; in sof_complete()
2222 if (widget_ops && widget_ops[pipe_widget->id].ipc_setup) { in sof_complete()
2223 ret = widget_ops[pipe_widget->id].ipc_setup(pipe_widget); in sof_complete()
2225 dev_err(sdev->dev, "failed updating IPC struct for %s\n", in sof_complete()
2226 pipe_widget->widget->name); in sof_complete()
2232 list_for_each_entry(swidget, &sdev->widget_list, list) in sof_complete()
2233 if (swidget->widget->id != snd_soc_dapm_scheduler && in sof_complete()
2234 swidget->pipeline_id == pipe_widget->pipeline_id) { in sof_complete()
2239 if (widget_ops && widget_ops[swidget->id].ipc_setup) { in sof_complete()
2240 ret = widget_ops[swidget->id].ipc_setup(swidget); in sof_complete()
2242 dev_err(sdev->dev, in sof_complete()
2244 swidget->widget->name); in sof_complete()
2253 if (tplg_ops && tplg_ops->set_up_all_pipelines && in sof_complete()
2254 tplg_ops->tear_down_all_pipelines) { in sof_complete()
2255 ret = tplg_ops->set_up_all_pipelines(sdev, true); in sof_complete()
2257 dev_err(sdev->dev, "Failed to set up all topology pipelines: %d\n", in sof_complete()
2262 ret = tplg_ops->tear_down_all_pipelines(sdev, true); in sof_complete()
2264 dev_err(sdev->dev, "Failed to tear down topology pipelines: %d\n", in sof_complete()
2272 if (tplg_ops && tplg_ops->set_up_all_pipelines) in sof_complete()
2273 return tplg_ops->set_up_all_pipelines(sdev, false); in sof_complete()
2278 /* manifest - optional to inform component of manifest */
2285 if (tplg_ops && tplg_ops->parse_manifest) in sof_manifest()
2286 return tplg_ops->parse_manifest(scomp, index, man); in sof_manifest()
2306 /* external kcontrol init - used for any driver specific init */
2310 /* external kcontrol init - used for any driver specific init */
2314 /* external widget init - used for any driver specific init */
2319 /* FE DAI - used for any driver specific init */
2323 /* DAI link - used for any driver specific init */
2332 /* manifest - optional to inform component of manifest */
2376 /* external widget init - used for any driver specific init */
2381 struct snd_soc_tplg_private *priv = &tw->priv; in sof_dspless_widget_ready()
2387 priv->array, le32_to_cpu(priv->size)); in sof_dspless_widget_ready()
2389 dev_err(scomp->dev, "failed to parse dapm widget tokens for %s\n", in sof_dspless_widget_ready()
2390 w->name); in sof_dspless_widget_ready()
2394 if (WIDGET_IS_DAI(w->id)) { in sof_dspless_widget_ready()
2403 return -ENOMEM; in sof_dspless_widget_ready()
2408 return -ENOMEM; in sof_dspless_widget_ready()
2411 ret = sof_parse_tokens(scomp, &sdai->type, dai_tokens, ARRAY_SIZE(dai_tokens), in sof_dspless_widget_ready()
2412 priv->array, le32_to_cpu(priv->size)); in sof_dspless_widget_ready()
2414 dev_err(scomp->dev, "Failed to parse DAI tokens for %s\n", tw->name); in sof_dspless_widget_ready()
2427 swidget->scomp = scomp; in sof_dspless_widget_ready()
2428 swidget->widget = w; in sof_dspless_widget_ready()
2429 swidget->private = sdai; in sof_dspless_widget_ready()
2430 mutex_init(&swidget->setup_mutex); in sof_dspless_widget_ready()
2431 w->dobj.private = swidget; in sof_dspless_widget_ready()
2432 list_add(&swidget->list, &sdev->widget_list); in sof_dspless_widget_ready()
2443 if (WIDGET_IS_DAI(w->id)) { in sof_dspless_widget_unload()
2444 struct snd_sof_widget *swidget = dobj->private; in sof_dspless_widget_unload()
2452 list_del(&swidget->list); in sof_dspless_widget_unload()
2453 kfree(swidget->private); in sof_dspless_widget_unload()
2464 link->platforms->name = dev_name(scomp->dev); in sof_dspless_link_load()
2466 /* Set nonatomic property for FE dai links for FE-BE compatibility */ in sof_dspless_link_load()
2467 if (!link->no_pcm) in sof_dspless_link_load()
2468 link->nonatomic = true; in sof_dspless_link_load()
2474 /* external widget init - used for any driver specific init */
2478 /* FE DAI - used for any driver specific init */
2482 /* DAI link - used for any driver specific init */
2497 struct snd_sof_pdata *sof_pdata = sdev->pdata; in snd_sof_load_topology()
2498 const char *tplg_filename_prefix = sof_pdata->tplg_filename_prefix; in snd_sof_load_topology()
2505 tplg_files = kcalloc(scomp->card->num_links, sizeof(char *), GFP_KERNEL); in snd_sof_load_topology()
2507 return -ENOMEM; in snd_sof_load_topology()
2509 if (!sof_pdata->disable_function_topology && !disable_function_topology && in snd_sof_load_topology()
2510 sof_pdata->machine && sof_pdata->machine->get_function_tplg_files) { in snd_sof_load_topology()
2511 tplg_cnt = sof_pdata->machine->get_function_tplg_files(scomp->card, in snd_sof_load_topology()
2512 sof_pdata->machine, in snd_sof_load_topology()
2528 dev_dbg(scomp->dev, "loading topology: %s\n", file); in snd_sof_load_topology()
2530 dev_info(scomp->dev, "Using function topologies instead %s\n", file); in snd_sof_load_topology()
2536 dev_info(scomp->dev, "loading topology %d: %s\n", i, tplg_files[i]); in snd_sof_load_topology()
2538 ret = request_firmware(&fw, tplg_files[i], scomp->dev); in snd_sof_load_topology()
2546 dev_err(scomp->dev, "tplg request firmware %s failed err: %d\n", in snd_sof_load_topology()
2551 if (sdev->dspless_mode_selected) in snd_sof_load_topology()
2559 dev_err(scomp->dev, "tplg %s component load failed %d\n", in snd_sof_load_topology()
2569 if (ret >= 0 && sdev->led_present) in snd_sof_load_topology()