• Home
  • Raw
  • Download

Lines Matching +full:dont +full:- +full:validate

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-topology.c -- ALSA SoC Topology
29 #include <sound/soc-dapm.h>
30 #include <sound/soc-topology.h>
86 /* check we dont overflow the data for this control chunk */
90 const u8 *end = tplg->pos + elem_size * count; in soc_tplg_check_elem_count()
92 if (end > tplg->fw->data + tplg->fw->size) { in soc_tplg_check_elem_count()
93 dev_err(tplg->dev, "ASoC: %s overflow end of data\n", in soc_tplg_check_elem_count()
95 return -EINVAL; in soc_tplg_check_elem_count()
101 dev_err(tplg->dev, in soc_tplg_check_elem_count()
104 return -EINVAL; in soc_tplg_check_elem_count()
112 const u8 *end = tplg->hdr_pos; in soc_tplg_is_eof()
114 if (end >= tplg->fw->data + tplg->fw->size) in soc_tplg_is_eof()
121 return (unsigned long)(tplg->hdr_pos - tplg->fw->data); in soc_tplg_get_hdr_offset()
126 return (unsigned long)(tplg->pos - tplg->fw->data); in soc_tplg_get_offset()
202 return -EINVAL; in tplc_chan_get_reg()
215 return -EINVAL; in tplc_chan_get_shift()
227 return -EINVAL; in get_widget_id()
233 dev_err(tplg->dev, in soc_bind_err()
235 hdr->ops.get, hdr->ops.put, hdr->ops.info, index, in soc_bind_err()
242 dev_err(tplg->dev, in soc_control_err()
244 name, hdr->ops.get, hdr->ops.put, hdr->ops.info, in soc_control_err()
254 if (tplg->ops && tplg->ops->vendor_load) in soc_tplg_vendor_load()
255 ret = tplg->ops->vendor_load(tplg->comp, tplg->index, hdr); in soc_tplg_vendor_load()
257 dev_err(tplg->dev, "ASoC: no vendor load callback for ID %d\n", in soc_tplg_vendor_load()
258 hdr->vendor_type); in soc_tplg_vendor_load()
259 return -EINVAL; in soc_tplg_vendor_load()
263 dev_err(tplg->dev, in soc_tplg_vendor_load()
267 hdr->type, hdr->vendor_type); in soc_tplg_vendor_load()
276 if (tplg->ops && tplg->ops->widget_load) in soc_tplg_widget_load()
277 return tplg->ops->widget_load(tplg->comp, tplg->index, w, in soc_tplg_widget_load()
288 if (tplg->ops && tplg->ops->widget_ready) in soc_tplg_widget_ready()
289 return tplg->ops->widget_ready(tplg->comp, tplg->index, w, in soc_tplg_widget_ready()
300 if (tplg->ops && tplg->ops->dai_load) in soc_tplg_dai_load()
301 return tplg->ops->dai_load(tplg->comp, tplg->index, dai_drv, in soc_tplg_dai_load()
311 if (tplg->ops && tplg->ops->link_load) in soc_tplg_dai_link_load()
312 return tplg->ops->link_load(tplg->comp, tplg->index, link, cfg); in soc_tplg_dai_link_load()
320 if (tplg->ops && tplg->ops->complete) in soc_tplg_complete()
321 tplg->ops->complete(tplg->comp); in soc_tplg_complete()
331 *kcontrol = snd_soc_cnew(control_new, data, control_new->name, prefix); in soc_tplg_add_dcontrol()
334 control_new->name); in soc_tplg_add_dcontrol()
335 return -ENOMEM; in soc_tplg_add_dcontrol()
341 control_new->name, err); in soc_tplg_add_dcontrol()
352 struct snd_soc_component *comp = tplg->comp; in soc_tplg_add_kcontrol()
354 return soc_tplg_add_dcontrol(comp->card->snd_card, in soc_tplg_add_kcontrol()
355 comp->dev, k, comp->name_prefix, comp, kcontrol); in soc_tplg_add_kcontrol()
362 struct snd_card *card = comp->card->snd_card; in remove_mixer()
370 if (dobj->ops && dobj->ops->control_unload) in remove_mixer()
371 dobj->ops->control_unload(comp, dobj); in remove_mixer()
373 if (dobj->control.kcontrol->tlv.p) in remove_mixer()
374 p = dobj->control.kcontrol->tlv.p; in remove_mixer()
375 snd_ctl_remove(card, dobj->control.kcontrol); in remove_mixer()
376 list_del(&dobj->list); in remove_mixer()
385 struct snd_card *card = comp->card->snd_card; in remove_enum()
391 if (dobj->ops && dobj->ops->control_unload) in remove_enum()
392 dobj->ops->control_unload(comp, dobj); in remove_enum()
394 snd_ctl_remove(card, dobj->control.kcontrol); in remove_enum()
395 list_del(&dobj->list); in remove_enum()
406 struct snd_card *card = comp->card->snd_card; in remove_bytes()
413 if (dobj->ops && dobj->ops->control_unload) in remove_bytes()
414 dobj->ops->control_unload(comp, dobj); in remove_bytes()
416 snd_ctl_remove(card, dobj->control.kcontrol); in remove_bytes()
417 list_del(&dobj->list); in remove_bytes()
431 if (dobj->ops && dobj->ops->dapm_route_unload) in remove_route()
432 dobj->ops->dapm_route_unload(comp, dobj); in remove_route()
434 list_del(&dobj->list); in remove_route()
438 /* remove a widget and it's kcontrols - routes must be removed first */
442 struct snd_card *card = comp->card->snd_card; in remove_widget()
450 if (dobj->ops && dobj->ops->widget_unload) in remove_widget()
451 dobj->ops->widget_unload(comp, dobj); in remove_widget()
453 if (!w->kcontrols) in remove_widget()
460 if (dobj->widget.kcontrol_type == SND_SOC_TPLG_TYPE_ENUM) { in remove_widget()
462 for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) { in remove_widget()
463 struct snd_kcontrol *kcontrol = w->kcontrols[i]; in remove_widget()
465 (struct soc_enum *)kcontrol->private_value; in remove_widget()
474 kfree(w->kcontrol_news[i].name); in remove_widget()
478 for (i = 0; w->kcontrols != NULL && i < w->num_kcontrols; i++) { in remove_widget()
479 struct snd_kcontrol *kcontrol = w->kcontrols[i]; in remove_widget()
481 if (dobj->widget.kcontrol_type in remove_widget()
483 kfree(kcontrol->tlv.p); in remove_widget()
489 kfree((void *)kcontrol->private_value); in remove_widget()
491 kfree(w->kcontrol_news[i].name); in remove_widget()
496 kfree(w->kcontrol_news); in remove_widget()
498 list_del(&dobj->list); in remove_widget()
500 /* widget w is freed by soc-dapm.c */ in remove_widget()
514 if (dobj->ops && dobj->ops->dai_unload) in remove_dai()
515 dobj->ops->dai_unload(comp, dobj); in remove_dai()
518 if (dai->driver == dai_drv) in remove_dai()
521 kfree(dai_drv->playback.stream_name); in remove_dai()
522 kfree(dai_drv->capture.stream_name); in remove_dai()
523 kfree(dai_drv->name); in remove_dai()
524 list_del(&dobj->list); in remove_dai()
538 if (dobj->ops && dobj->ops->link_unload) in remove_link()
539 dobj->ops->link_unload(comp, dobj); in remove_link()
541 list_del(&dobj->list); in remove_link()
542 snd_soc_remove_pcm_runtime(comp->card, in remove_link()
543 snd_soc_get_pcm_runtime(comp->card, link)); in remove_link()
545 kfree(link->name); in remove_link()
546 kfree(link->stream_name); in remove_link()
547 kfree(link->cpus->dai_name); in remove_link()
558 if (dobj->ops && dobj->ops->link_unload) in remove_backend_link()
559 dobj->ops->link_unload(comp, dobj); in remove_backend_link()
566 dobj->type = SND_SOC_DOBJ_NONE; in remove_backend_link()
567 list_del(&dobj->list); in remove_backend_link()
579 if (le32_to_cpu(hdr->ops.info) == SND_SOC_TPLG_CTL_BYTES in soc_tplg_kcontrol_bind_io()
580 && k->iface & SNDRV_CTL_ELEM_IFACE_MIXER in soc_tplg_kcontrol_bind_io()
581 && (k->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ in soc_tplg_kcontrol_bind_io()
582 || k->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) in soc_tplg_kcontrol_bind_io()
583 && k->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { in soc_tplg_kcontrol_bind_io()
587 sbe = (struct soc_bytes_ext *)k->private_value; in soc_tplg_kcontrol_bind_io()
593 k->info = snd_soc_bytes_info_ext; in soc_tplg_kcontrol_bind_io()
594 k->tlv.c = snd_soc_bytes_tlv_callback; in soc_tplg_kcontrol_bind_io()
597 * When a topology-based implementation abuses the in soc_tplg_kcontrol_bind_io()
601 * return an -EINVAL error and prevent the card from in soc_tplg_kcontrol_bind_io()
604 if (IS_ENABLED(CONFIG_SND_CTL_VALIDATION) && sbe->max > 512) in soc_tplg_kcontrol_bind_io()
605 k->access |= SNDRV_CTL_ELEM_ACCESS_SKIP_CHECK; in soc_tplg_kcontrol_bind_io()
607 ext_ops = tplg->bytes_ext_ops; in soc_tplg_kcontrol_bind_io()
608 num_ops = tplg->bytes_ext_ops_count; in soc_tplg_kcontrol_bind_io()
610 if (!sbe->put && in soc_tplg_kcontrol_bind_io()
611 ext_ops[i].id == le32_to_cpu(be->ext_ops.put)) in soc_tplg_kcontrol_bind_io()
612 sbe->put = ext_ops[i].put; in soc_tplg_kcontrol_bind_io()
613 if (!sbe->get && in soc_tplg_kcontrol_bind_io()
614 ext_ops[i].id == le32_to_cpu(be->ext_ops.get)) in soc_tplg_kcontrol_bind_io()
615 sbe->get = ext_ops[i].get; in soc_tplg_kcontrol_bind_io()
618 if ((k->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) && !sbe->get) in soc_tplg_kcontrol_bind_io()
619 return -EINVAL; in soc_tplg_kcontrol_bind_io()
620 if ((k->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) && !sbe->put) in soc_tplg_kcontrol_bind_io()
621 return -EINVAL; in soc_tplg_kcontrol_bind_io()
626 ops = tplg->io_ops; in soc_tplg_kcontrol_bind_io()
627 num_ops = tplg->io_ops_count; in soc_tplg_kcontrol_bind_io()
630 if (k->put == NULL && ops[i].id == le32_to_cpu(hdr->ops.put)) in soc_tplg_kcontrol_bind_io()
631 k->put = ops[i].put; in soc_tplg_kcontrol_bind_io()
632 if (k->get == NULL && ops[i].id == le32_to_cpu(hdr->ops.get)) in soc_tplg_kcontrol_bind_io()
633 k->get = ops[i].get; in soc_tplg_kcontrol_bind_io()
634 if (k->info == NULL && ops[i].id == le32_to_cpu(hdr->ops.info)) in soc_tplg_kcontrol_bind_io()
635 k->info = ops[i].info; in soc_tplg_kcontrol_bind_io()
639 if (k->put && k->get && k->info) in soc_tplg_kcontrol_bind_io()
647 if (k->put == NULL && ops[i].id == le32_to_cpu(hdr->ops.put)) in soc_tplg_kcontrol_bind_io()
648 k->put = ops[i].put; in soc_tplg_kcontrol_bind_io()
649 if (k->get == NULL && ops[i].id == le32_to_cpu(hdr->ops.get)) in soc_tplg_kcontrol_bind_io()
650 k->get = ops[i].get; in soc_tplg_kcontrol_bind_io()
651 if (k->info == NULL && ops[i].id == le32_to_cpu(hdr->ops.info)) in soc_tplg_kcontrol_bind_io()
652 k->info = ops[i].info; in soc_tplg_kcontrol_bind_io()
656 if (k->put && k->get && k->info) in soc_tplg_kcontrol_bind_io()
660 return -EINVAL; in soc_tplg_kcontrol_bind_io()
670 w->event = NULL; in snd_soc_tplg_widget_bind_event()
675 /* found - so assign event */ in snd_soc_tplg_widget_bind_event()
676 w->event = events[i].event_handler; in snd_soc_tplg_widget_bind_event()
682 return -EINVAL; in snd_soc_tplg_widget_bind_event()
690 if (tplg->ops && tplg->ops->control_load) in soc_tplg_init_kcontrol()
691 return tplg->ops->control_load(tplg->comp, tplg->index, k, in soc_tplg_init_kcontrol()
706 return -ENOMEM; in soc_tplg_create_tlv_db_scale()
710 p[2] = le32_to_cpu(scale->min); in soc_tplg_create_tlv_db_scale()
711 p[3] = (le32_to_cpu(scale->step) & TLV_DB_SCALE_MASK) in soc_tplg_create_tlv_db_scale()
712 | (le32_to_cpu(scale->mute) ? TLV_DB_SCALE_MUTE : 0); in soc_tplg_create_tlv_db_scale()
714 kc->tlv.p = (void *)p; in soc_tplg_create_tlv_db_scale()
722 u32 access = le32_to_cpu(tc->access); in soc_tplg_create_tlv()
728 tplg_tlv = &tc->tlv; in soc_tplg_create_tlv()
729 switch (le32_to_cpu(tplg_tlv->type)) { in soc_tplg_create_tlv()
732 &tplg_tlv->scale); in soc_tplg_create_tlv()
736 dev_dbg(tplg->dev, "Unsupported TLV type %d\n", in soc_tplg_create_tlv()
737 tplg_tlv->type); in soc_tplg_create_tlv()
738 return -EINVAL; in soc_tplg_create_tlv()
748 kfree(kc->tlv.p); in soc_tplg_free_tlv()
763 dev_err(tplg->dev, "ASoC: Invalid count %d for byte control\n", in soc_tplg_dbytes_create()
765 return -EINVAL; in soc_tplg_dbytes_create()
769 be = (struct snd_soc_tplg_bytes_control *)tplg->pos; in soc_tplg_dbytes_create()
771 /* validate kcontrol */ in soc_tplg_dbytes_create()
772 if (strnlen(be->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dbytes_create()
774 return -EINVAL; in soc_tplg_dbytes_create()
778 return -ENOMEM; in soc_tplg_dbytes_create()
780 tplg->pos += (sizeof(struct snd_soc_tplg_bytes_control) + in soc_tplg_dbytes_create()
781 le32_to_cpu(be->priv.size)); in soc_tplg_dbytes_create()
783 dev_dbg(tplg->dev, in soc_tplg_dbytes_create()
785 be->hdr.name, be->hdr.access); in soc_tplg_dbytes_create()
788 kc.name = be->hdr.name; in soc_tplg_dbytes_create()
791 kc.access = le32_to_cpu(be->hdr.access); in soc_tplg_dbytes_create()
793 sbe->max = le32_to_cpu(be->max); in soc_tplg_dbytes_create()
794 sbe->dobj.type = SND_SOC_DOBJ_BYTES; in soc_tplg_dbytes_create()
795 sbe->dobj.ops = tplg->ops; in soc_tplg_dbytes_create()
796 INIT_LIST_HEAD(&sbe->dobj.list); in soc_tplg_dbytes_create()
799 err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc, tplg); in soc_tplg_dbytes_create()
801 soc_control_err(tplg, &be->hdr, be->hdr.name); in soc_tplg_dbytes_create()
810 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_dbytes_create()
811 be->hdr.name); in soc_tplg_dbytes_create()
818 &sbe->dobj.control.kcontrol); in soc_tplg_dbytes_create()
820 dev_err(tplg->dev, "ASoC: failed to add %s\n", in soc_tplg_dbytes_create()
821 be->hdr.name); in soc_tplg_dbytes_create()
826 list_add(&sbe->dobj.list, &tplg->comp->dobj_list); in soc_tplg_dbytes_create()
845 dev_err(tplg->dev, "ASoC: invalid count %d for controls\n", in soc_tplg_dmixer_create()
847 return -EINVAL; in soc_tplg_dmixer_create()
851 mc = (struct snd_soc_tplg_mixer_control *)tplg->pos; in soc_tplg_dmixer_create()
853 /* validate kcontrol */ in soc_tplg_dmixer_create()
854 if (strnlen(mc->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dmixer_create()
856 return -EINVAL; in soc_tplg_dmixer_create()
860 return -ENOMEM; in soc_tplg_dmixer_create()
861 tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) + in soc_tplg_dmixer_create()
862 le32_to_cpu(mc->priv.size)); in soc_tplg_dmixer_create()
864 dev_dbg(tplg->dev, in soc_tplg_dmixer_create()
866 mc->hdr.name, mc->hdr.access); in soc_tplg_dmixer_create()
869 kc.name = mc->hdr.name; in soc_tplg_dmixer_create()
872 kc.access = le32_to_cpu(mc->hdr.access); in soc_tplg_dmixer_create()
875 sm->reg = tplc_chan_get_reg(tplg, mc->channel, in soc_tplg_dmixer_create()
877 sm->rreg = tplc_chan_get_reg(tplg, mc->channel, in soc_tplg_dmixer_create()
879 sm->shift = tplc_chan_get_shift(tplg, mc->channel, in soc_tplg_dmixer_create()
881 sm->rshift = tplc_chan_get_shift(tplg, mc->channel, in soc_tplg_dmixer_create()
884 sm->max = le32_to_cpu(mc->max); in soc_tplg_dmixer_create()
885 sm->min = le32_to_cpu(mc->min); in soc_tplg_dmixer_create()
886 sm->invert = le32_to_cpu(mc->invert); in soc_tplg_dmixer_create()
887 sm->platform_max = le32_to_cpu(mc->platform_max); in soc_tplg_dmixer_create()
888 sm->dobj.index = tplg->index; in soc_tplg_dmixer_create()
889 sm->dobj.ops = tplg->ops; in soc_tplg_dmixer_create()
890 sm->dobj.type = SND_SOC_DOBJ_MIXER; in soc_tplg_dmixer_create()
891 INIT_LIST_HEAD(&sm->dobj.list); in soc_tplg_dmixer_create()
894 err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc, tplg); in soc_tplg_dmixer_create()
896 soc_control_err(tplg, &mc->hdr, mc->hdr.name); in soc_tplg_dmixer_create()
902 err = soc_tplg_create_tlv(tplg, &kc, &mc->hdr); in soc_tplg_dmixer_create()
904 dev_err(tplg->dev, "ASoC: failed to create TLV %s\n", in soc_tplg_dmixer_create()
905 mc->hdr.name); in soc_tplg_dmixer_create()
914 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_dmixer_create()
915 mc->hdr.name); in soc_tplg_dmixer_create()
923 &sm->dobj.control.kcontrol); in soc_tplg_dmixer_create()
925 dev_err(tplg->dev, "ASoC: failed to add %s\n", in soc_tplg_dmixer_create()
926 mc->hdr.name); in soc_tplg_dmixer_create()
932 list_add(&sm->dobj.list, &tplg->comp->dobj_list); in soc_tplg_dmixer_create()
943 se->dobj.control.dtexts = in soc_tplg_denum_create_texts()
944 kcalloc(le32_to_cpu(ec->items), sizeof(char *), GFP_KERNEL); in soc_tplg_denum_create_texts()
945 if (se->dobj.control.dtexts == NULL) in soc_tplg_denum_create_texts()
946 return -ENOMEM; in soc_tplg_denum_create_texts()
948 for (i = 0; i < le32_to_cpu(ec->items); i++) { in soc_tplg_denum_create_texts()
950 if (strnlen(ec->texts[i], SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_denum_create_texts()
952 ret = -EINVAL; in soc_tplg_denum_create_texts()
956 se->dobj.control.dtexts[i] = kstrdup(ec->texts[i], GFP_KERNEL); in soc_tplg_denum_create_texts()
957 if (!se->dobj.control.dtexts[i]) { in soc_tplg_denum_create_texts()
958 ret = -ENOMEM; in soc_tplg_denum_create_texts()
963 se->items = le32_to_cpu(ec->items); in soc_tplg_denum_create_texts()
964 se->texts = (const char * const *)se->dobj.control.dtexts; in soc_tplg_denum_create_texts()
968 se->items = i; in soc_tplg_denum_create_texts()
975 int i = se->items; in soc_tplg_denum_remove_texts()
977 for (--i; i >= 0; i--) in soc_tplg_denum_remove_texts()
978 kfree(se->dobj.control.dtexts[i]); in soc_tplg_denum_remove_texts()
979 kfree(se->dobj.control.dtexts); in soc_tplg_denum_remove_texts()
987 if (le32_to_cpu(ec->items) > sizeof(*ec->values)) in soc_tplg_denum_create_values()
988 return -EINVAL; in soc_tplg_denum_create_values()
990 se->dobj.control.dvalues = kzalloc(le32_to_cpu(ec->items) * in soc_tplg_denum_create_values()
991 sizeof(*se->dobj.control.dvalues), in soc_tplg_denum_create_values()
993 if (!se->dobj.control.dvalues) in soc_tplg_denum_create_values()
994 return -ENOMEM; in soc_tplg_denum_create_values()
996 /* convert from little-endian */ in soc_tplg_denum_create_values()
997 for (i = 0; i < le32_to_cpu(ec->items); i++) { in soc_tplg_denum_create_values()
998 se->dobj.control.dvalues[i] = le32_to_cpu(ec->values[i]); in soc_tplg_denum_create_values()
1006 kfree(se->dobj.control.dvalues); in soc_tplg_denum_remove_values()
1022 dev_err(tplg->dev, "ASoC: invalid count %d for enum controls\n", in soc_tplg_denum_create()
1024 return -EINVAL; in soc_tplg_denum_create()
1028 ec = (struct snd_soc_tplg_enum_control *)tplg->pos; in soc_tplg_denum_create()
1030 /* validate kcontrol */ in soc_tplg_denum_create()
1031 if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_denum_create()
1033 return -EINVAL; in soc_tplg_denum_create()
1037 return -ENOMEM; in soc_tplg_denum_create()
1039 tplg->pos += (sizeof(struct snd_soc_tplg_enum_control) + in soc_tplg_denum_create()
1040 le32_to_cpu(ec->priv.size)); in soc_tplg_denum_create()
1042 dev_dbg(tplg->dev, "ASoC: adding enum kcontrol %s size %d\n", in soc_tplg_denum_create()
1043 ec->hdr.name, ec->items); in soc_tplg_denum_create()
1046 kc.name = ec->hdr.name; in soc_tplg_denum_create()
1049 kc.access = le32_to_cpu(ec->hdr.access); in soc_tplg_denum_create()
1051 se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); in soc_tplg_denum_create()
1052 se->shift_l = tplc_chan_get_shift(tplg, ec->channel, in soc_tplg_denum_create()
1054 se->shift_r = tplc_chan_get_shift(tplg, ec->channel, in soc_tplg_denum_create()
1057 se->mask = le32_to_cpu(ec->mask); in soc_tplg_denum_create()
1058 se->dobj.index = tplg->index; in soc_tplg_denum_create()
1059 se->dobj.type = SND_SOC_DOBJ_ENUM; in soc_tplg_denum_create()
1060 se->dobj.ops = tplg->ops; in soc_tplg_denum_create()
1061 INIT_LIST_HEAD(&se->dobj.list); in soc_tplg_denum_create()
1063 switch (le32_to_cpu(ec->hdr.ops.info)) { in soc_tplg_denum_create()
1068 dev_err(tplg->dev, in soc_tplg_denum_create()
1070 ec->hdr.name); in soc_tplg_denum_create()
1079 dev_err(tplg->dev, in soc_tplg_denum_create()
1081 ec->hdr.name); in soc_tplg_denum_create()
1086 err = -EINVAL; in soc_tplg_denum_create()
1087 dev_err(tplg->dev, in soc_tplg_denum_create()
1089 ec->hdr.ops.info, ec->hdr.name); in soc_tplg_denum_create()
1094 err = soc_tplg_kcontrol_bind_io(&ec->hdr, &kc, tplg); in soc_tplg_denum_create()
1096 soc_control_err(tplg, &ec->hdr, ec->hdr.name); in soc_tplg_denum_create()
1104 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_denum_create()
1105 ec->hdr.name); in soc_tplg_denum_create()
1111 &kc, &se->dobj.control.kcontrol); in soc_tplg_denum_create()
1113 dev_err(tplg->dev, "ASoC: could not add kcontrol %s\n", in soc_tplg_denum_create()
1114 ec->hdr.name); in soc_tplg_denum_create()
1118 list_add(&se->dobj.list, &tplg->comp->dobj_list); in soc_tplg_denum_create()
1134 dev_dbg(tplg->dev, "ASoC: adding %d kcontrols at 0x%lx\n", hdr->count, in soc_tplg_kcontrol_elems_load()
1137 for (i = 0; i < le32_to_cpu(hdr->count); i++) { in soc_tplg_kcontrol_elems_load()
1139 control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; in soc_tplg_kcontrol_elems_load()
1141 if (le32_to_cpu(control_hdr->size) != sizeof(*control_hdr)) { in soc_tplg_kcontrol_elems_load()
1142 dev_err(tplg->dev, "ASoC: invalid control size\n"); in soc_tplg_kcontrol_elems_load()
1143 return -EINVAL; in soc_tplg_kcontrol_elems_load()
1146 switch (le32_to_cpu(control_hdr->ops.info)) { in soc_tplg_kcontrol_elems_load()
1155 le32_to_cpu(hdr->payload_size)); in soc_tplg_kcontrol_elems_load()
1163 le32_to_cpu(hdr->payload_size)); in soc_tplg_kcontrol_elems_load()
1167 le32_to_cpu(hdr->payload_size)); in soc_tplg_kcontrol_elems_load()
1171 return -EINVAL; in soc_tplg_kcontrol_elems_load()
1174 dev_err(tplg->dev, "ASoC: invalid control\n"); in soc_tplg_kcontrol_elems_load()
1187 if (tplg->ops && tplg->ops->dapm_route_load) in soc_tplg_add_route()
1188 return tplg->ops->dapm_route_load(tplg->comp, tplg->index, in soc_tplg_add_route()
1197 struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; in soc_tplg_dapm_graph_elems_load()
1203 count = le32_to_cpu(hdr->count); in soc_tplg_dapm_graph_elems_load()
1207 count, le32_to_cpu(hdr->payload_size), "graph")) { in soc_tplg_dapm_graph_elems_load()
1209 dev_err(tplg->dev, "ASoC: invalid count %d for DAPM routes\n", in soc_tplg_dapm_graph_elems_load()
1211 return -EINVAL; in soc_tplg_dapm_graph_elems_load()
1214 dev_dbg(tplg->dev, "ASoC: adding %d DAPM routes for index %d\n", count, in soc_tplg_dapm_graph_elems_load()
1215 hdr->index); in soc_tplg_dapm_graph_elems_load()
1221 return -ENOMEM; in soc_tplg_dapm_graph_elems_load()
1236 return -ENOMEM; in soc_tplg_dapm_graph_elems_load()
1241 elem = (struct snd_soc_tplg_dapm_graph_elem *)tplg->pos; in soc_tplg_dapm_graph_elems_load()
1242 tplg->pos += sizeof(struct snd_soc_tplg_dapm_graph_elem); in soc_tplg_dapm_graph_elems_load()
1244 /* validate routes */ in soc_tplg_dapm_graph_elems_load()
1245 if (strnlen(elem->source, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_graph_elems_load()
1247 ret = -EINVAL; in soc_tplg_dapm_graph_elems_load()
1250 if (strnlen(elem->sink, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_graph_elems_load()
1252 ret = -EINVAL; in soc_tplg_dapm_graph_elems_load()
1255 if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_graph_elems_load()
1257 ret = -EINVAL; in soc_tplg_dapm_graph_elems_load()
1261 routes[i]->source = elem->source; in soc_tplg_dapm_graph_elems_load()
1262 routes[i]->sink = elem->sink; in soc_tplg_dapm_graph_elems_load()
1265 routes[i]->connected = NULL; in soc_tplg_dapm_graph_elems_load()
1266 if (strnlen(elem->control, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == 0) in soc_tplg_dapm_graph_elems_load()
1267 routes[i]->control = NULL; in soc_tplg_dapm_graph_elems_load()
1269 routes[i]->control = elem->control; in soc_tplg_dapm_graph_elems_load()
1272 routes[i]->dobj.type = SND_SOC_DOBJ_GRAPH; in soc_tplg_dapm_graph_elems_load()
1273 routes[i]->dobj.ops = tplg->ops; in soc_tplg_dapm_graph_elems_load()
1274 routes[i]->dobj.index = tplg->index; in soc_tplg_dapm_graph_elems_load()
1275 list_add(&routes[i]->dobj.list, &tplg->comp->dobj_list); in soc_tplg_dapm_graph_elems_load()
1279 dev_err(tplg->dev, "ASoC: topology: add_route failed: %d\n", ret); in soc_tplg_dapm_graph_elems_load()
1326 mc = (struct snd_soc_tplg_mixer_control *)tplg->pos; in soc_tplg_dapm_widget_dmixer_create()
1328 /* validate kcontrol */ in soc_tplg_dapm_widget_dmixer_create()
1329 if (strnlen(mc->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_widget_dmixer_create()
1337 tplg->pos += (sizeof(struct snd_soc_tplg_mixer_control) + in soc_tplg_dapm_widget_dmixer_create()
1338 le32_to_cpu(mc->priv.size)); in soc_tplg_dapm_widget_dmixer_create()
1340 dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n", in soc_tplg_dapm_widget_dmixer_create()
1341 mc->hdr.name, i); in soc_tplg_dapm_widget_dmixer_create()
1344 kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL); in soc_tplg_dapm_widget_dmixer_create()
1348 kc[i].access = le32_to_cpu(mc->hdr.access); in soc_tplg_dapm_widget_dmixer_create()
1351 sm->reg = tplc_chan_get_reg(tplg, mc->channel, in soc_tplg_dapm_widget_dmixer_create()
1353 sm->rreg = tplc_chan_get_reg(tplg, mc->channel, in soc_tplg_dapm_widget_dmixer_create()
1355 sm->shift = tplc_chan_get_shift(tplg, mc->channel, in soc_tplg_dapm_widget_dmixer_create()
1357 sm->rshift = tplc_chan_get_shift(tplg, mc->channel, in soc_tplg_dapm_widget_dmixer_create()
1360 sm->max = le32_to_cpu(mc->max); in soc_tplg_dapm_widget_dmixer_create()
1361 sm->min = le32_to_cpu(mc->min); in soc_tplg_dapm_widget_dmixer_create()
1362 sm->invert = le32_to_cpu(mc->invert); in soc_tplg_dapm_widget_dmixer_create()
1363 sm->platform_max = le32_to_cpu(mc->platform_max); in soc_tplg_dapm_widget_dmixer_create()
1364 sm->dobj.index = tplg->index; in soc_tplg_dapm_widget_dmixer_create()
1365 INIT_LIST_HEAD(&sm->dobj.list); in soc_tplg_dapm_widget_dmixer_create()
1368 err = soc_tplg_kcontrol_bind_io(&mc->hdr, &kc[i], tplg); in soc_tplg_dapm_widget_dmixer_create()
1370 soc_control_err(tplg, &mc->hdr, mc->hdr.name); in soc_tplg_dapm_widget_dmixer_create()
1375 err = soc_tplg_create_tlv(tplg, &kc[i], &mc->hdr); in soc_tplg_dapm_widget_dmixer_create()
1377 dev_err(tplg->dev, "ASoC: failed to create TLV %s\n", in soc_tplg_dapm_widget_dmixer_create()
1378 mc->hdr.name); in soc_tplg_dapm_widget_dmixer_create()
1386 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_dapm_widget_dmixer_create()
1387 mc->hdr.name); in soc_tplg_dapm_widget_dmixer_create()
1394 for (; i >= 0; i--) { in soc_tplg_dapm_widget_dmixer_create()
1418 ec = (struct snd_soc_tplg_enum_control *)tplg->pos; in soc_tplg_dapm_widget_denum_create()
1419 /* validate kcontrol */ in soc_tplg_dapm_widget_denum_create()
1420 if (strnlen(ec->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_widget_denum_create()
1428 tplg->pos += (sizeof(struct snd_soc_tplg_enum_control) + in soc_tplg_dapm_widget_denum_create()
1429 le32_to_cpu(ec->priv.size)); in soc_tplg_dapm_widget_denum_create()
1431 dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n", in soc_tplg_dapm_widget_denum_create()
1432 ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1435 kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL); in soc_tplg_dapm_widget_denum_create()
1439 kc[i].access = le32_to_cpu(ec->hdr.access); in soc_tplg_dapm_widget_denum_create()
1442 se->reg = tplc_chan_get_reg(tplg, ec->channel, SNDRV_CHMAP_FL); in soc_tplg_dapm_widget_denum_create()
1443 se->shift_l = tplc_chan_get_shift(tplg, ec->channel, in soc_tplg_dapm_widget_denum_create()
1445 se->shift_r = tplc_chan_get_shift(tplg, ec->channel, in soc_tplg_dapm_widget_denum_create()
1448 se->items = le32_to_cpu(ec->items); in soc_tplg_dapm_widget_denum_create()
1449 se->mask = le32_to_cpu(ec->mask); in soc_tplg_dapm_widget_denum_create()
1450 se->dobj.index = tplg->index; in soc_tplg_dapm_widget_denum_create()
1452 switch (le32_to_cpu(ec->hdr.ops.info)) { in soc_tplg_dapm_widget_denum_create()
1457 dev_err(tplg->dev, "ASoC: could not create values for %s\n", in soc_tplg_dapm_widget_denum_create()
1458 ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1467 dev_err(tplg->dev, "ASoC: could not create texts for %s\n", in soc_tplg_dapm_widget_denum_create()
1468 ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1473 dev_err(tplg->dev, "ASoC: invalid enum control type %d for %s\n", in soc_tplg_dapm_widget_denum_create()
1474 ec->hdr.ops.info, ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1479 err = soc_tplg_kcontrol_bind_io(&ec->hdr, &kc[i], tplg); in soc_tplg_dapm_widget_denum_create()
1481 soc_control_err(tplg, &ec->hdr, ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1489 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_dapm_widget_denum_create()
1490 ec->hdr.name); in soc_tplg_dapm_widget_denum_create()
1498 for (; i >= 0; i--) { in soc_tplg_dapm_widget_denum_create()
1528 be = (struct snd_soc_tplg_bytes_control *)tplg->pos; in soc_tplg_dapm_widget_dbytes_create()
1530 /* validate kcontrol */ in soc_tplg_dapm_widget_dbytes_create()
1531 if (strnlen(be->hdr.name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_widget_dbytes_create()
1539 tplg->pos += (sizeof(struct snd_soc_tplg_bytes_control) + in soc_tplg_dapm_widget_dbytes_create()
1540 le32_to_cpu(be->priv.size)); in soc_tplg_dapm_widget_dbytes_create()
1542 dev_dbg(tplg->dev, in soc_tplg_dapm_widget_dbytes_create()
1544 be->hdr.name, be->hdr.access); in soc_tplg_dapm_widget_dbytes_create()
1547 kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL); in soc_tplg_dapm_widget_dbytes_create()
1551 kc[i].access = le32_to_cpu(be->hdr.access); in soc_tplg_dapm_widget_dbytes_create()
1553 sbe->max = le32_to_cpu(be->max); in soc_tplg_dapm_widget_dbytes_create()
1554 INIT_LIST_HEAD(&sbe->dobj.list); in soc_tplg_dapm_widget_dbytes_create()
1557 err = soc_tplg_kcontrol_bind_io(&be->hdr, &kc[i], tplg); in soc_tplg_dapm_widget_dbytes_create()
1559 soc_control_err(tplg, &be->hdr, be->hdr.name); in soc_tplg_dapm_widget_dbytes_create()
1567 dev_err(tplg->dev, "ASoC: failed to init %s\n", in soc_tplg_dapm_widget_dbytes_create()
1568 be->hdr.name); in soc_tplg_dapm_widget_dbytes_create()
1576 for (; i >= 0; i--) { in soc_tplg_dapm_widget_dbytes_create()
1589 struct snd_soc_dapm_context *dapm = &tplg->comp->dapm; in soc_tplg_dapm_widget_create()
1592 struct snd_soc_card *card = tplg->comp->card; in soc_tplg_dapm_widget_create()
1596 if (strnlen(w->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_widget_create()
1598 return -EINVAL; in soc_tplg_dapm_widget_create()
1599 if (strnlen(w->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) == in soc_tplg_dapm_widget_create()
1601 return -EINVAL; in soc_tplg_dapm_widget_create()
1603 dev_dbg(tplg->dev, "ASoC: creating DAPM widget %s id %d\n", in soc_tplg_dapm_widget_create()
1604 w->name, w->id); in soc_tplg_dapm_widget_create()
1609 template.id = get_widget_id(le32_to_cpu(w->id)); in soc_tplg_dapm_widget_create()
1614 template.name = kstrdup(w->name, GFP_KERNEL); in soc_tplg_dapm_widget_create()
1616 return -ENOMEM; in soc_tplg_dapm_widget_create()
1617 template.sname = kstrdup(w->sname, GFP_KERNEL); in soc_tplg_dapm_widget_create()
1619 ret = -ENOMEM; in soc_tplg_dapm_widget_create()
1622 template.reg = le32_to_cpu(w->reg); in soc_tplg_dapm_widget_create()
1623 template.shift = le32_to_cpu(w->shift); in soc_tplg_dapm_widget_create()
1624 template.mask = le32_to_cpu(w->mask); in soc_tplg_dapm_widget_create()
1625 template.subseq = le32_to_cpu(w->subseq); in soc_tplg_dapm_widget_create()
1626 template.on_val = w->invert ? 0 : 1; in soc_tplg_dapm_widget_create()
1627 template.off_val = w->invert ? 1 : 0; in soc_tplg_dapm_widget_create()
1628 template.ignore_suspend = le32_to_cpu(w->ignore_suspend); in soc_tplg_dapm_widget_create()
1629 template.event_flags = le16_to_cpu(w->event_flags); in soc_tplg_dapm_widget_create()
1630 template.dobj.index = tplg->index; in soc_tplg_dapm_widget_create()
1632 tplg->pos += in soc_tplg_dapm_widget_create()
1634 le32_to_cpu(w->priv.size)); in soc_tplg_dapm_widget_create()
1636 if (w->num_kcontrols == 0) { in soc_tplg_dapm_widget_create()
1642 control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; in soc_tplg_dapm_widget_create()
1643 dev_dbg(tplg->dev, "ASoC: template %s has %d controls of type %x\n", in soc_tplg_dapm_widget_create()
1644 w->name, w->num_kcontrols, control_hdr->type); in soc_tplg_dapm_widget_create()
1646 switch (le32_to_cpu(control_hdr->ops.info)) { in soc_tplg_dapm_widget_create()
1654 template.num_kcontrols = le32_to_cpu(w->num_kcontrols); in soc_tplg_dapm_widget_create()
1659 ret = -ENOMEM; in soc_tplg_dapm_widget_create()
1669 template.num_kcontrols = le32_to_cpu(w->num_kcontrols); in soc_tplg_dapm_widget_create()
1674 ret = -ENOMEM; in soc_tplg_dapm_widget_create()
1680 template.num_kcontrols = le32_to_cpu(w->num_kcontrols); in soc_tplg_dapm_widget_create()
1685 ret = -ENOMEM; in soc_tplg_dapm_widget_create()
1690 dev_err(tplg->dev, "ASoC: invalid widget control type %d:%d:%d\n", in soc_tplg_dapm_widget_create()
1691 control_hdr->ops.get, control_hdr->ops.put, in soc_tplg_dapm_widget_create()
1692 le32_to_cpu(control_hdr->ops.info)); in soc_tplg_dapm_widget_create()
1693 ret = -EINVAL; in soc_tplg_dapm_widget_create()
1704 if (card->instantiated) in soc_tplg_dapm_widget_create()
1713 widget->dobj.type = SND_SOC_DOBJ_WIDGET; in soc_tplg_dapm_widget_create()
1714 widget->dobj.widget.kcontrol_type = kcontrol_type; in soc_tplg_dapm_widget_create()
1715 widget->dobj.ops = tplg->ops; in soc_tplg_dapm_widget_create()
1716 widget->dobj.index = tplg->index; in soc_tplg_dapm_widget_create()
1717 list_add(&widget->dobj.list, &tplg->comp->dobj_list); in soc_tplg_dapm_widget_create()
1744 count = le32_to_cpu(hdr->count); in soc_tplg_dapm_widget_elems_load()
1746 dev_dbg(tplg->dev, "ASoC: adding %d DAPM widgets\n", count); in soc_tplg_dapm_widget_elems_load()
1749 widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; in soc_tplg_dapm_widget_elems_load()
1750 if (le32_to_cpu(widget->size) != sizeof(*widget)) { in soc_tplg_dapm_widget_elems_load()
1751 dev_err(tplg->dev, "ASoC: invalid widget size\n"); in soc_tplg_dapm_widget_elems_load()
1752 return -EINVAL; in soc_tplg_dapm_widget_elems_load()
1757 dev_err(tplg->dev, "ASoC: failed to load widget %s\n", in soc_tplg_dapm_widget_elems_load()
1758 widget->name); in soc_tplg_dapm_widget_elems_load()
1768 struct snd_soc_card *card = tplg->comp->card; in soc_tplg_dapm_complete()
1774 if (!card || !card->instantiated) { in soc_tplg_dapm_complete()
1775 dev_warn(tplg->dev, "ASoC: Parent card not yet available," in soc_tplg_dapm_complete()
1782 dev_err(tplg->dev, "ASoC: failed to create new widgets %d\n", in soc_tplg_dapm_complete()
1791 stream->stream_name = kstrdup(caps->name, GFP_KERNEL); in set_stream_info()
1792 if (!stream->stream_name) in set_stream_info()
1793 return -ENOMEM; in set_stream_info()
1795 stream->channels_min = le32_to_cpu(caps->channels_min); in set_stream_info()
1796 stream->channels_max = le32_to_cpu(caps->channels_max); in set_stream_info()
1797 stream->rates = le32_to_cpu(caps->rates); in set_stream_info()
1798 stream->rate_min = le32_to_cpu(caps->rate_min); in set_stream_info()
1799 stream->rate_max = le32_to_cpu(caps->rate_max); in set_stream_info()
1800 stream->formats = le64_to_cpu(caps->formats); in set_stream_info()
1801 stream->sig_bits = le32_to_cpu(caps->sig_bits); in set_stream_info()
1810 dai_drv->symmetric_rates = in set_dai_flags()
1814 dai_drv->symmetric_channels = in set_dai_flags()
1819 dai_drv->symmetric_samplebits = in set_dai_flags()
1832 snd_soc_component_get_dapm(tplg->comp); in soc_tplg_dai_create()
1837 return -ENOMEM; in soc_tplg_dai_create()
1839 if (strlen(pcm->dai_name)) { in soc_tplg_dai_create()
1840 dai_drv->name = kstrdup(pcm->dai_name, GFP_KERNEL); in soc_tplg_dai_create()
1841 if (!dai_drv->name) { in soc_tplg_dai_create()
1842 ret = -ENOMEM; in soc_tplg_dai_create()
1846 dai_drv->id = le32_to_cpu(pcm->dai_id); in soc_tplg_dai_create()
1848 if (pcm->playback) { in soc_tplg_dai_create()
1849 stream = &dai_drv->playback; in soc_tplg_dai_create()
1850 caps = &pcm->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; in soc_tplg_dai_create()
1856 if (pcm->capture) { in soc_tplg_dai_create()
1857 stream = &dai_drv->capture; in soc_tplg_dai_create()
1858 caps = &pcm->caps[SND_SOC_TPLG_STREAM_CAPTURE]; in soc_tplg_dai_create()
1864 if (pcm->compress) in soc_tplg_dai_create()
1865 dai_drv->compress_new = snd_soc_new_compress; in soc_tplg_dai_create()
1870 dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); in soc_tplg_dai_create()
1874 dai_drv->dobj.index = tplg->index; in soc_tplg_dai_create()
1875 dai_drv->dobj.ops = tplg->ops; in soc_tplg_dai_create()
1876 dai_drv->dobj.type = SND_SOC_DOBJ_PCM; in soc_tplg_dai_create()
1877 list_add(&dai_drv->dobj.list, &tplg->comp->dobj_list); in soc_tplg_dai_create()
1880 dai = snd_soc_register_dai(tplg->comp, dai_drv, false); in soc_tplg_dai_create()
1882 return -ENOMEM; in soc_tplg_dai_create()
1887 dev_err(dai->dev, "Failed to create DAI widgets %d\n", ret); in soc_tplg_dai_create()
1895 kfree(dai_drv->playback.stream_name); in soc_tplg_dai_create()
1896 kfree(dai_drv->capture.stream_name); in soc_tplg_dai_create()
1897 kfree(dai_drv->name); in soc_tplg_dai_create()
1907 link->symmetric_rates = in set_link_flags()
1911 link->symmetric_channels = in set_link_flags()
1916 link->symmetric_samplebits = in set_link_flags()
1921 link->ignore_suspend = in set_link_flags()
1937 return -ENOMEM; in soc_tplg_fe_link_create()
1941 link->cpus = &dlc[0]; in soc_tplg_fe_link_create()
1942 link->codecs = &dlc[1]; in soc_tplg_fe_link_create()
1943 link->platforms = &dlc[2]; in soc_tplg_fe_link_create()
1945 link->num_cpus = 1; in soc_tplg_fe_link_create()
1946 link->num_codecs = 1; in soc_tplg_fe_link_create()
1947 link->num_platforms = 1; in soc_tplg_fe_link_create()
1949 link->dobj.index = tplg->index; in soc_tplg_fe_link_create()
1950 link->dobj.ops = tplg->ops; in soc_tplg_fe_link_create()
1951 link->dobj.type = SND_SOC_DOBJ_DAI_LINK; in soc_tplg_fe_link_create()
1953 if (strlen(pcm->pcm_name)) { in soc_tplg_fe_link_create()
1954 link->name = kstrdup(pcm->pcm_name, GFP_KERNEL); in soc_tplg_fe_link_create()
1955 link->stream_name = kstrdup(pcm->pcm_name, GFP_KERNEL); in soc_tplg_fe_link_create()
1956 if (!link->name || !link->stream_name) { in soc_tplg_fe_link_create()
1957 ret = -ENOMEM; in soc_tplg_fe_link_create()
1961 link->id = le32_to_cpu(pcm->pcm_id); in soc_tplg_fe_link_create()
1963 if (strlen(pcm->dai_name)) { in soc_tplg_fe_link_create()
1964 link->cpus->dai_name = kstrdup(pcm->dai_name, GFP_KERNEL); in soc_tplg_fe_link_create()
1965 if (!link->cpus->dai_name) { in soc_tplg_fe_link_create()
1966 ret = -ENOMEM; in soc_tplg_fe_link_create()
1971 link->codecs->name = "snd-soc-dummy"; in soc_tplg_fe_link_create()
1972 link->codecs->dai_name = "snd-soc-dummy-dai"; in soc_tplg_fe_link_create()
1974 link->platforms->name = "snd-soc-dummy"; in soc_tplg_fe_link_create()
1977 link->dynamic = 1; in soc_tplg_fe_link_create()
1978 link->dpcm_playback = le32_to_cpu(pcm->playback); in soc_tplg_fe_link_create()
1979 link->dpcm_capture = le32_to_cpu(pcm->capture); in soc_tplg_fe_link_create()
1980 if (pcm->flag_mask) in soc_tplg_fe_link_create()
1982 le32_to_cpu(pcm->flag_mask), in soc_tplg_fe_link_create()
1983 le32_to_cpu(pcm->flags)); in soc_tplg_fe_link_create()
1988 dev_err(tplg->comp->dev, "ASoC: FE link loading failed\n"); in soc_tplg_fe_link_create()
1992 ret = snd_soc_add_pcm_runtime(tplg->comp->card, link); in soc_tplg_fe_link_create()
1994 dev_err(tplg->comp->dev, "ASoC: adding FE link failed\n"); in soc_tplg_fe_link_create()
1998 list_add(&link->dobj.list, &tplg->comp->dobj_list); in soc_tplg_fe_link_create()
2002 kfree(link->name); in soc_tplg_fe_link_create()
2003 kfree(link->stream_name); in soc_tplg_fe_link_create()
2004 kfree(link->cpus->dai_name); in soc_tplg_fe_link_create()
2026 dest->size = cpu_to_le32(sizeof(*dest)); in stream_caps_new_ver()
2027 memcpy(dest->name, src->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); in stream_caps_new_ver()
2028 dest->formats = src->formats; in stream_caps_new_ver()
2029 dest->rates = src->rates; in stream_caps_new_ver()
2030 dest->rate_min = src->rate_min; in stream_caps_new_ver()
2031 dest->rate_max = src->rate_max; in stream_caps_new_ver()
2032 dest->channels_min = src->channels_min; in stream_caps_new_ver()
2033 dest->channels_max = src->channels_max; in stream_caps_new_ver()
2034 dest->periods_min = src->periods_min; in stream_caps_new_ver()
2035 dest->periods_max = src->periods_max; in stream_caps_new_ver()
2036 dest->period_size_min = src->period_size_min; in stream_caps_new_ver()
2037 dest->period_size_max = src->period_size_max; in stream_caps_new_ver()
2038 dest->buffer_size_min = src->buffer_size_min; in stream_caps_new_ver()
2039 dest->buffer_size_max = src->buffer_size_max; in stream_caps_new_ver()
2043 * pcm_new_ver - Create the new version of PCM from the old version.
2060 if (le32_to_cpu(src->size) != sizeof(*src_v4)) { in pcm_new_ver()
2061 dev_err(tplg->dev, "ASoC: invalid PCM size\n"); in pcm_new_ver()
2062 return -EINVAL; in pcm_new_ver()
2065 dev_warn(tplg->dev, "ASoC: old version of PCM\n"); in pcm_new_ver()
2069 return -ENOMEM; in pcm_new_ver()
2071 dest->size = cpu_to_le32(sizeof(*dest)); /* size of latest abi version */ in pcm_new_ver()
2072 memcpy(dest->pcm_name, src_v4->pcm_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); in pcm_new_ver()
2073 memcpy(dest->dai_name, src_v4->dai_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); in pcm_new_ver()
2074 dest->pcm_id = src_v4->pcm_id; in pcm_new_ver()
2075 dest->dai_id = src_v4->dai_id; in pcm_new_ver()
2076 dest->playback = src_v4->playback; in pcm_new_ver()
2077 dest->capture = src_v4->capture; in pcm_new_ver()
2078 dest->compress = src_v4->compress; in pcm_new_ver()
2079 dest->num_streams = src_v4->num_streams; in pcm_new_ver()
2080 for (i = 0; i < le32_to_cpu(dest->num_streams); i++) in pcm_new_ver()
2081 memcpy(&dest->stream[i], &src_v4->stream[i], in pcm_new_ver()
2085 stream_caps_new_ver(&dest->caps[i], &src_v4->caps[i]); in pcm_new_ver()
2101 count = le32_to_cpu(hdr->count); in soc_tplg_pcm_elems_load()
2104 pcm = (struct snd_soc_tplg_pcm *)tplg->pos; in soc_tplg_pcm_elems_load()
2105 size = le32_to_cpu(pcm->size); in soc_tplg_pcm_elems_load()
2108 dev_err(tplg->dev, "ASoC: invalid size %d for PCM elems\n", in soc_tplg_pcm_elems_load()
2110 return -EINVAL; in soc_tplg_pcm_elems_load()
2115 le32_to_cpu(hdr->payload_size), in soc_tplg_pcm_elems_load()
2117 dev_err(tplg->dev, "ASoC: invalid count %d for PCM DAI elems\n", in soc_tplg_pcm_elems_load()
2119 return -EINVAL; in soc_tplg_pcm_elems_load()
2123 pcm = (struct snd_soc_tplg_pcm *)tplg->pos; in soc_tplg_pcm_elems_load()
2124 size = le32_to_cpu(pcm->size); in soc_tplg_pcm_elems_load()
2147 /* offset by version-specific struct size and in soc_tplg_pcm_elems_load()
2150 tplg->pos += size + le32_to_cpu(_pcm->priv.size); in soc_tplg_pcm_elems_load()
2156 dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count); in soc_tplg_pcm_elems_load()
2162 * set_link_hw_format - Set the HW audio format of the physical DAI link.
2178 for (i = 0; i < le32_to_cpu(cfg->num_hw_configs); i++) { in set_link_hw_format()
2179 hw_config = &cfg->hw_config[i]; in set_link_hw_format()
2180 if (hw_config->id != cfg->default_hw_config_id) in set_link_hw_format()
2183 link->dai_fmt = le32_to_cpu(hw_config->fmt) & in set_link_hw_format()
2187 switch (hw_config->clock_gated) { in set_link_hw_format()
2189 link->dai_fmt |= SND_SOC_DAIFMT_GATED; in set_link_hw_format()
2193 link->dai_fmt |= SND_SOC_DAIFMT_CONT; in set_link_hw_format()
2202 invert_bclk = hw_config->invert_bclk; in set_link_hw_format()
2203 invert_fsync = hw_config->invert_fsync; in set_link_hw_format()
2205 link->dai_fmt |= SND_SOC_DAIFMT_NB_NF; in set_link_hw_format()
2207 link->dai_fmt |= SND_SOC_DAIFMT_NB_IF; in set_link_hw_format()
2209 link->dai_fmt |= SND_SOC_DAIFMT_IB_NF; in set_link_hw_format()
2211 link->dai_fmt |= SND_SOC_DAIFMT_IB_IF; in set_link_hw_format()
2214 bclk_master = (hw_config->bclk_master == in set_link_hw_format()
2216 fsync_master = (hw_config->fsync_master == in set_link_hw_format()
2219 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; in set_link_hw_format()
2221 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFM; in set_link_hw_format()
2223 link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFS; in set_link_hw_format()
2225 link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; in set_link_hw_format()
2230 * link_new_ver - Create a new physical link config from the old
2248 if (le32_to_cpu(src->size) != in link_new_ver()
2250 dev_err(tplg->dev, "ASoC: invalid physical link config size\n"); in link_new_ver()
2251 return -EINVAL; in link_new_ver()
2254 dev_warn(tplg->dev, "ASoC: old version of physical link config\n"); in link_new_ver()
2259 return -ENOMEM; in link_new_ver()
2261 dest->size = cpu_to_le32(sizeof(*dest)); in link_new_ver()
2262 dest->id = src_v4->id; in link_new_ver()
2263 dest->num_streams = src_v4->num_streams; in link_new_ver()
2264 for (i = 0; i < le32_to_cpu(dest->num_streams); i++) in link_new_ver()
2265 memcpy(&dest->stream[i], &src_v4->stream[i], in link_new_ver()
2273 * snd_soc_find_dai_link - Find a DAI link
2295 link = rtd->dai_link; in snd_soc_find_dai_link()
2297 if (link->id != id) in snd_soc_find_dai_link()
2300 if (name && (!link->name || strcmp(name, link->name))) in snd_soc_find_dai_link()
2303 if (stream_name && (!link->stream_name in snd_soc_find_dai_link()
2304 || strcmp(stream_name, link->stream_name))) in snd_soc_find_dai_link()
2322 len = strnlen(cfg->name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); in soc_tplg_link_config()
2324 return -EINVAL; in soc_tplg_link_config()
2326 name = cfg->name; in soc_tplg_link_config()
2330 len = strnlen(cfg->stream_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); in soc_tplg_link_config()
2332 return -EINVAL; in soc_tplg_link_config()
2334 stream_name = cfg->stream_name; in soc_tplg_link_config()
2338 link = snd_soc_find_dai_link(tplg->comp->card, le32_to_cpu(cfg->id), in soc_tplg_link_config()
2341 dev_err(tplg->dev, "ASoC: physical link %s (id %d) not exist\n", in soc_tplg_link_config()
2342 name, cfg->id); in soc_tplg_link_config()
2343 return -EINVAL; in soc_tplg_link_config()
2347 if (cfg->num_hw_configs) in soc_tplg_link_config()
2351 if (cfg->flag_mask) in soc_tplg_link_config()
2353 le32_to_cpu(cfg->flag_mask), in soc_tplg_link_config()
2354 le32_to_cpu(cfg->flags)); in soc_tplg_link_config()
2359 dev_err(tplg->dev, "ASoC: physical link loading failed\n"); in soc_tplg_link_config()
2364 link->dobj.index = tplg->index; in soc_tplg_link_config()
2365 link->dobj.ops = tplg->ops; in soc_tplg_link_config()
2366 link->dobj.type = SND_SOC_DOBJ_BACKEND_LINK; in soc_tplg_link_config()
2367 list_add(&link->dobj.list, &tplg->comp->dobj_list); in soc_tplg_link_config()
2383 count = le32_to_cpu(hdr->count); in soc_tplg_link_elems_load()
2386 link = (struct snd_soc_tplg_link_config *)tplg->pos; in soc_tplg_link_elems_load()
2387 size = le32_to_cpu(link->size); in soc_tplg_link_elems_load()
2390 dev_err(tplg->dev, "ASoC: invalid size %d for physical link elems\n", in soc_tplg_link_elems_load()
2392 return -EINVAL; in soc_tplg_link_elems_load()
2397 le32_to_cpu(hdr->payload_size), in soc_tplg_link_elems_load()
2399 dev_err(tplg->dev, "ASoC: invalid count %d for physical link elems\n", in soc_tplg_link_elems_load()
2401 return -EINVAL; in soc_tplg_link_elems_load()
2406 link = (struct snd_soc_tplg_link_config *)tplg->pos; in soc_tplg_link_elems_load()
2407 size = le32_to_cpu(link->size); in soc_tplg_link_elems_load()
2425 /* offset by version-specific struct size and in soc_tplg_link_elems_load()
2428 tplg->pos += size + le32_to_cpu(_link->priv.size); in soc_tplg_link_elems_load()
2438 * soc_tplg_dai_config - Find and configure an existing physical DAI.
2457 dai_component.dai_name = d->dai_name; in soc_tplg_dai_config()
2460 dev_err(tplg->dev, "ASoC: physical DAI %s not registered\n", in soc_tplg_dai_config()
2461 d->dai_name); in soc_tplg_dai_config()
2462 return -EINVAL; in soc_tplg_dai_config()
2465 if (le32_to_cpu(d->dai_id) != dai->id) { in soc_tplg_dai_config()
2466 dev_err(tplg->dev, "ASoC: physical DAI %s id mismatch\n", in soc_tplg_dai_config()
2467 d->dai_name); in soc_tplg_dai_config()
2468 return -EINVAL; in soc_tplg_dai_config()
2471 dai_drv = dai->driver; in soc_tplg_dai_config()
2473 return -EINVAL; in soc_tplg_dai_config()
2475 if (d->playback) { in soc_tplg_dai_config()
2476 stream = &dai_drv->playback; in soc_tplg_dai_config()
2477 caps = &d->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; in soc_tplg_dai_config()
2483 if (d->capture) { in soc_tplg_dai_config()
2484 stream = &dai_drv->capture; in soc_tplg_dai_config()
2485 caps = &d->caps[SND_SOC_TPLG_STREAM_CAPTURE]; in soc_tplg_dai_config()
2491 if (d->flag_mask) in soc_tplg_dai_config()
2493 le32_to_cpu(d->flag_mask), in soc_tplg_dai_config()
2494 le32_to_cpu(d->flags)); in soc_tplg_dai_config()
2499 dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); in soc_tplg_dai_config()
2506 kfree(dai_drv->playback.stream_name); in soc_tplg_dai_config()
2507 kfree(dai_drv->capture.stream_name); in soc_tplg_dai_config()
2519 count = le32_to_cpu(hdr->count); in soc_tplg_dai_elems_load()
2523 dai = (struct snd_soc_tplg_dai *)tplg->pos; in soc_tplg_dai_elems_load()
2524 if (le32_to_cpu(dai->size) != sizeof(*dai)) { in soc_tplg_dai_elems_load()
2525 dev_err(tplg->dev, "ASoC: invalid physical DAI size\n"); in soc_tplg_dai_elems_load()
2526 return -EINVAL; in soc_tplg_dai_elems_load()
2531 dev_err(tplg->dev, "ASoC: failed to configure DAI\n"); in soc_tplg_dai_elems_load()
2535 tplg->pos += (sizeof(*dai) + le32_to_cpu(dai->priv.size)); in soc_tplg_dai_elems_load()
2538 dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count); in soc_tplg_dai_elems_load()
2543 * manifest_new_ver - Create a new version of manifest from the old version
2561 size = le32_to_cpu(src->size); in manifest_new_ver()
2563 dev_warn(tplg->dev, "ASoC: invalid manifest size %d\n", in manifest_new_ver()
2566 return -EINVAL; in manifest_new_ver()
2567 src->size = cpu_to_le32(sizeof(*src_v4)); in manifest_new_ver()
2570 dev_warn(tplg->dev, "ASoC: old version of manifest\n"); in manifest_new_ver()
2573 dest = kzalloc(sizeof(*dest) + le32_to_cpu(src_v4->priv.size), in manifest_new_ver()
2576 return -ENOMEM; in manifest_new_ver()
2578 dest->size = cpu_to_le32(sizeof(*dest)); /* size of latest abi version */ in manifest_new_ver()
2579 dest->control_elems = src_v4->control_elems; in manifest_new_ver()
2580 dest->widget_elems = src_v4->widget_elems; in manifest_new_ver()
2581 dest->graph_elems = src_v4->graph_elems; in manifest_new_ver()
2582 dest->pcm_elems = src_v4->pcm_elems; in manifest_new_ver()
2583 dest->dai_link_elems = src_v4->dai_link_elems; in manifest_new_ver()
2584 dest->priv.size = src_v4->priv.size; in manifest_new_ver()
2585 if (dest->priv.size) in manifest_new_ver()
2586 memcpy(dest->priv.data, src_v4->priv.data, in manifest_new_ver()
2587 le32_to_cpu(src_v4->priv.size)); in manifest_new_ver()
2600 manifest = (struct snd_soc_tplg_manifest *)tplg->pos; in soc_tplg_manifest_load()
2603 if (le32_to_cpu(manifest->size) == sizeof(*manifest)) { in soc_tplg_manifest_load()
2614 if (tplg->ops && tplg->ops->manifest) in soc_tplg_manifest_load()
2615 ret = tplg->ops->manifest(tplg->comp, tplg->index, _manifest); in soc_tplg_manifest_load()
2623 /* validate header magic, size and type */
2627 if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size) in soc_valid_header()
2630 if (le32_to_cpu(hdr->size) != sizeof(*hdr)) { in soc_valid_header()
2631 dev_err(tplg->dev, in soc_valid_header()
2633 le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg), in soc_valid_header()
2634 tplg->fw->size); in soc_valid_header()
2635 return -EINVAL; in soc_valid_header()
2639 if (le32_to_cpu(hdr->magic) == SOC_TPLG_MAGIC_BIG_ENDIAN) { in soc_valid_header()
2640 dev_err(tplg->dev, in soc_valid_header()
2642 tplg->pass, hdr->magic, in soc_valid_header()
2643 soc_tplg_get_hdr_offset(tplg), tplg->fw->size); in soc_valid_header()
2644 return -EINVAL; in soc_valid_header()
2647 if (le32_to_cpu(hdr->magic) != SND_SOC_TPLG_MAGIC) { in soc_valid_header()
2648 dev_err(tplg->dev, in soc_valid_header()
2650 tplg->pass, hdr->magic, in soc_valid_header()
2651 soc_tplg_get_hdr_offset(tplg), tplg->fw->size); in soc_valid_header()
2652 return -EINVAL; in soc_valid_header()
2656 if (le32_to_cpu(hdr->abi) > SND_SOC_TPLG_ABI_VERSION || in soc_valid_header()
2657 le32_to_cpu(hdr->abi) < SND_SOC_TPLG_ABI_VERSION_MIN) { in soc_valid_header()
2658 dev_err(tplg->dev, in soc_valid_header()
2660 tplg->pass, hdr->abi, in soc_valid_header()
2662 tplg->fw->size); in soc_valid_header()
2663 return -EINVAL; in soc_valid_header()
2666 if (hdr->payload_size == 0) { in soc_valid_header()
2667 dev_err(tplg->dev, "ASoC: header has 0 size at offset 0x%lx.\n", in soc_valid_header()
2669 return -EINVAL; in soc_valid_header()
2683 tplg->pos = tplg->hdr_pos + sizeof(struct snd_soc_tplg_hdr); in soc_tplg_load_header()
2686 if (le32_to_cpu(hdr->index) != tplg->req_index && in soc_tplg_load_header()
2687 tplg->req_index != SND_SOC_TPLG_INDEX_ALL) in soc_tplg_load_header()
2690 tplg->index = le32_to_cpu(hdr->index); in soc_tplg_load_header()
2692 switch (le32_to_cpu(hdr->type)) { in soc_tplg_load_header()
2732 if (tplg->pass == hdr_pass) { in soc_tplg_load_header()
2733 dev_dbg(tplg->dev, in soc_tplg_load_header()
2735 hdr->payload_size, hdr->type, hdr->version, in soc_tplg_load_header()
2736 hdr->vendor_type, tplg->pass); in soc_tplg_load_header()
2749 tplg->pass = SOC_TPLG_PASS_START; in soc_tplg_process_headers()
2752 while (tplg->pass <= SOC_TPLG_PASS_END) { in soc_tplg_process_headers()
2754 tplg->hdr_pos = tplg->fw->data; in soc_tplg_process_headers()
2755 hdr = (struct snd_soc_tplg_hdr *)tplg->hdr_pos; in soc_tplg_process_headers()
2762 dev_err(tplg->dev, in soc_tplg_process_headers()
2772 dev_err(tplg->dev, in soc_tplg_process_headers()
2778 tplg->hdr_pos += le32_to_cpu(hdr->payload_size) + in soc_tplg_process_headers()
2780 hdr = (struct snd_soc_tplg_hdr *)tplg->hdr_pos; in soc_tplg_process_headers()
2784 tplg->pass++; in soc_tplg_process_headers()
2790 dev_err(tplg->dev, in soc_tplg_process_headers()
2816 return -EINVAL; in snd_soc_tplg_component_load()
2821 tplg.dev = comp->dev; in snd_soc_tplg_component_load()
2825 tplg.io_ops = ops->io_ops; in snd_soc_tplg_component_load()
2826 tplg.io_ops_count = ops->io_ops_count; in snd_soc_tplg_component_load()
2827 tplg.bytes_ext_ops = ops->bytes_ext_ops; in snd_soc_tplg_component_load()
2828 tplg.bytes_ext_ops_count = ops->bytes_ext_ops_count; in snd_soc_tplg_component_load()
2843 if (w->dobj.type != SND_SOC_DOBJ_WIDGET) in snd_soc_tplg_widget_remove()
2846 remove_widget(w->dapm->component, &w->dobj, SOC_TPLG_PASS_WIDGET); in snd_soc_tplg_widget_remove()
2856 for_each_card_widgets_safe(dapm->card, w, next_w) { in snd_soc_tplg_widget_remove_all()
2859 if (w->dobj.type != SND_SOC_DOBJ_WIDGET || w->dapm != dapm) in snd_soc_tplg_widget_remove_all()
2863 if (w->dobj.index != index && in snd_soc_tplg_widget_remove_all()
2864 w->dobj.index != SND_SOC_TPLG_INDEX_ALL) in snd_soc_tplg_widget_remove_all()
2877 struct snd_card *card = comp->card->snd_card; in snd_soc_tplg_component_remove()
2885 down_write(&card->controls_rwsem); in snd_soc_tplg_component_remove()
2886 list_for_each_entry_safe(dobj, next_dobj, &comp->dobj_list, in snd_soc_tplg_component_remove()
2890 if (dobj->index != index && in snd_soc_tplg_component_remove()
2894 switch (dobj->type) { in snd_soc_tplg_component_remove()
2924 dev_err(comp->dev, "ASoC: invalid component type %d for removal\n", in snd_soc_tplg_component_remove()
2925 dobj->type); in snd_soc_tplg_component_remove()
2929 up_write(&card->controls_rwsem); in snd_soc_tplg_component_remove()
2930 pass--; in snd_soc_tplg_component_remove()
2934 return !list_empty(&comp->dobj_list); in snd_soc_tplg_component_remove()