Loading include/uapi/sound/asoc.h +42 −2 Original line number Diff line number Diff line Loading @@ -116,6 +116,14 @@ #define SND_SOC_TPLG_STREAM_PLAYBACK 0 #define SND_SOC_TPLG_STREAM_CAPTURE 1 /* vendor tuple types */ #define SND_SOC_TPLG_TUPLE_TYPE_UUID 0 #define SND_SOC_TPLG_TUPLE_TYPE_STRING 1 #define SND_SOC_TPLG_TUPLE_TYPE_BOOL 2 #define SND_SOC_TPLG_TUPLE_TYPE_BYTE 3 #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 /* * Block Header. * This header precedes all object and object arrays below. Loading @@ -132,6 +140,35 @@ struct snd_soc_tplg_hdr { __le32 count; /* number of elements in block */ } __attribute__((packed)); /* vendor tuple for uuid */ struct snd_soc_tplg_vendor_uuid_elem { __le32 token; char uuid[16]; } __attribute__((packed)); /* vendor tuple for a bool/byte/short/word value */ struct snd_soc_tplg_vendor_value_elem { __le32 token; __le32 value; } __attribute__((packed)); /* vendor tuple for string */ struct snd_soc_tplg_vendor_string_elem { __le32 token; char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; } __attribute__((packed)); struct snd_soc_tplg_vendor_array { __le32 size; /* size in bytes of the array, including all elements */ __le32 type; /* SND_SOC_TPLG_TUPLE_TYPE_ */ __le32 num_elems; /* number of elements in array */ union { struct snd_soc_tplg_vendor_uuid_elem uuid[0]; struct snd_soc_tplg_vendor_value_elem value[0]; struct snd_soc_tplg_vendor_string_elem string[0]; }; } __attribute__((packed)); /* * Private data. * All topology objects may have private data that can be used by the driver or Loading @@ -139,7 +176,10 @@ struct snd_soc_tplg_hdr { */ struct snd_soc_tplg_private { __le32 size; /* in bytes of private data */ union { char data[0]; struct snd_soc_tplg_vendor_array array[0]; }; } __attribute__((packed)); /* Loading Loading @@ -383,7 +423,7 @@ struct snd_soc_tplg_pcm { __le32 size; /* in bytes of this structure */ char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; __le32 pcm_id; /* unique ID - used to match */ __le32 pcm_id; /* unique ID - used to match with DAI link */ __le32 dai_id; /* unique ID - used to match */ __le32 playback; /* supports playback mode */ __le32 capture; /* supports capture mode */ Loading sound/soc/soc-topology.c +45 −3 Original line number Diff line number Diff line Loading @@ -1023,6 +1023,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg, control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; if (control_hdr->size != sizeof(*control_hdr)) { dev_err(tplg->dev, "ASoC: invalid control size\n"); return -EINVAL; } switch (control_hdr->ops.info) { case SND_SOC_TPLG_CTL_VOLSW: case SND_SOC_TPLG_CTL_STROBE: Loading Loading @@ -1476,6 +1481,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, widget->dobj.type = SND_SOC_DOBJ_WIDGET; widget->dobj.ops = tplg->ops; widget->dobj.index = tplg->index; kfree(template.sname); kfree(template.name); list_add(&widget->dobj.list, &tplg->comp->dobj_list); return 0; Loading @@ -1499,10 +1506,17 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, for (i = 0; i < count; i++) { widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; if (widget->size != sizeof(*widget)) { dev_err(tplg->dev, "ASoC: invalid widget size\n"); return -EINVAL; } ret = soc_tplg_dapm_widget_create(tplg, widget); if (ret < 0) if (ret < 0) { dev_err(tplg->dev, "ASoC: failed to load widget %s\n", widget->name); return ret; } } return 0; Loading Loading @@ -1586,6 +1600,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, return snd_soc_register_dai(tplg->comp, dai_drv); } /* create the FE DAI link */ static int soc_tplg_link_create(struct soc_tplg *tplg, struct snd_soc_tplg_pcm *pcm) { Loading @@ -1598,6 +1613,16 @@ static int soc_tplg_link_create(struct soc_tplg *tplg, link->name = pcm->pcm_name; link->stream_name = pcm->pcm_name; link->id = pcm->pcm_id; link->cpu_dai_name = pcm->dai_name; link->codec_name = "snd-soc-dummy"; link->codec_dai_name = "snd-soc-dummy-dai"; /* enable DPCM */ link->dynamic = 1; link->dpcm_playback = pcm->playback; link->dpcm_capture = pcm->capture; /* pass control to component driver for optional further init */ ret = soc_tplg_dai_link_load(tplg, link); Loading Loading @@ -1639,8 +1664,6 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, if (tplg->pass != SOC_TPLG_PASS_PCM_DAI) return 0; pcm = (struct snd_soc_tplg_pcm *)tplg->pos; if (soc_tplg_check_elem_count(tplg, sizeof(struct snd_soc_tplg_pcm), count, hdr->payload_size, "PCM DAI")) { Loading @@ -1650,7 +1673,13 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, } /* create the FE DAIs and DAI links */ pcm = (struct snd_soc_tplg_pcm *)tplg->pos; for (i = 0; i < count; i++) { if (pcm->size != sizeof(*pcm)) { dev_err(tplg->dev, "ASoC: invalid pcm size\n"); return -EINVAL; } soc_tplg_pcm_create(tplg, pcm); pcm++; } Loading @@ -1670,6 +1699,11 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, return 0; manifest = (struct snd_soc_tplg_manifest *)tplg->pos; if (manifest->size != sizeof(*manifest)) { dev_err(tplg->dev, "ASoC: invalid manifest size\n"); return -EINVAL; } tplg->pos += sizeof(struct snd_soc_tplg_manifest); if (tplg->comp && tplg->ops && tplg->ops->manifest) Loading @@ -1686,6 +1720,14 @@ static int soc_valid_header(struct soc_tplg *tplg, if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size) return 0; if (hdr->size != sizeof(*hdr)) { dev_err(tplg->dev, "ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n", hdr->type, soc_tplg_get_hdr_offset(tplg), tplg->fw->size); return -EINVAL; } /* big endian firmware objects not supported atm */ if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) { dev_err(tplg->dev, Loading Loading
include/uapi/sound/asoc.h +42 −2 Original line number Diff line number Diff line Loading @@ -116,6 +116,14 @@ #define SND_SOC_TPLG_STREAM_PLAYBACK 0 #define SND_SOC_TPLG_STREAM_CAPTURE 1 /* vendor tuple types */ #define SND_SOC_TPLG_TUPLE_TYPE_UUID 0 #define SND_SOC_TPLG_TUPLE_TYPE_STRING 1 #define SND_SOC_TPLG_TUPLE_TYPE_BOOL 2 #define SND_SOC_TPLG_TUPLE_TYPE_BYTE 3 #define SND_SOC_TPLG_TUPLE_TYPE_WORD 4 #define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5 /* * Block Header. * This header precedes all object and object arrays below. Loading @@ -132,6 +140,35 @@ struct snd_soc_tplg_hdr { __le32 count; /* number of elements in block */ } __attribute__((packed)); /* vendor tuple for uuid */ struct snd_soc_tplg_vendor_uuid_elem { __le32 token; char uuid[16]; } __attribute__((packed)); /* vendor tuple for a bool/byte/short/word value */ struct snd_soc_tplg_vendor_value_elem { __le32 token; __le32 value; } __attribute__((packed)); /* vendor tuple for string */ struct snd_soc_tplg_vendor_string_elem { __le32 token; char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; } __attribute__((packed)); struct snd_soc_tplg_vendor_array { __le32 size; /* size in bytes of the array, including all elements */ __le32 type; /* SND_SOC_TPLG_TUPLE_TYPE_ */ __le32 num_elems; /* number of elements in array */ union { struct snd_soc_tplg_vendor_uuid_elem uuid[0]; struct snd_soc_tplg_vendor_value_elem value[0]; struct snd_soc_tplg_vendor_string_elem string[0]; }; } __attribute__((packed)); /* * Private data. * All topology objects may have private data that can be used by the driver or Loading @@ -139,7 +176,10 @@ struct snd_soc_tplg_hdr { */ struct snd_soc_tplg_private { __le32 size; /* in bytes of private data */ union { char data[0]; struct snd_soc_tplg_vendor_array array[0]; }; } __attribute__((packed)); /* Loading Loading @@ -383,7 +423,7 @@ struct snd_soc_tplg_pcm { __le32 size; /* in bytes of this structure */ char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; __le32 pcm_id; /* unique ID - used to match */ __le32 pcm_id; /* unique ID - used to match with DAI link */ __le32 dai_id; /* unique ID - used to match */ __le32 playback; /* supports playback mode */ __le32 capture; /* supports capture mode */ Loading
sound/soc/soc-topology.c +45 −3 Original line number Diff line number Diff line Loading @@ -1023,6 +1023,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg, control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; if (control_hdr->size != sizeof(*control_hdr)) { dev_err(tplg->dev, "ASoC: invalid control size\n"); return -EINVAL; } switch (control_hdr->ops.info) { case SND_SOC_TPLG_CTL_VOLSW: case SND_SOC_TPLG_CTL_STROBE: Loading Loading @@ -1476,6 +1481,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, widget->dobj.type = SND_SOC_DOBJ_WIDGET; widget->dobj.ops = tplg->ops; widget->dobj.index = tplg->index; kfree(template.sname); kfree(template.name); list_add(&widget->dobj.list, &tplg->comp->dobj_list); return 0; Loading @@ -1499,10 +1506,17 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, for (i = 0; i < count; i++) { widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; if (widget->size != sizeof(*widget)) { dev_err(tplg->dev, "ASoC: invalid widget size\n"); return -EINVAL; } ret = soc_tplg_dapm_widget_create(tplg, widget); if (ret < 0) if (ret < 0) { dev_err(tplg->dev, "ASoC: failed to load widget %s\n", widget->name); return ret; } } return 0; Loading Loading @@ -1586,6 +1600,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg, return snd_soc_register_dai(tplg->comp, dai_drv); } /* create the FE DAI link */ static int soc_tplg_link_create(struct soc_tplg *tplg, struct snd_soc_tplg_pcm *pcm) { Loading @@ -1598,6 +1613,16 @@ static int soc_tplg_link_create(struct soc_tplg *tplg, link->name = pcm->pcm_name; link->stream_name = pcm->pcm_name; link->id = pcm->pcm_id; link->cpu_dai_name = pcm->dai_name; link->codec_name = "snd-soc-dummy"; link->codec_dai_name = "snd-soc-dummy-dai"; /* enable DPCM */ link->dynamic = 1; link->dpcm_playback = pcm->playback; link->dpcm_capture = pcm->capture; /* pass control to component driver for optional further init */ ret = soc_tplg_dai_link_load(tplg, link); Loading Loading @@ -1639,8 +1664,6 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, if (tplg->pass != SOC_TPLG_PASS_PCM_DAI) return 0; pcm = (struct snd_soc_tplg_pcm *)tplg->pos; if (soc_tplg_check_elem_count(tplg, sizeof(struct snd_soc_tplg_pcm), count, hdr->payload_size, "PCM DAI")) { Loading @@ -1650,7 +1673,13 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, } /* create the FE DAIs and DAI links */ pcm = (struct snd_soc_tplg_pcm *)tplg->pos; for (i = 0; i < count; i++) { if (pcm->size != sizeof(*pcm)) { dev_err(tplg->dev, "ASoC: invalid pcm size\n"); return -EINVAL; } soc_tplg_pcm_create(tplg, pcm); pcm++; } Loading @@ -1670,6 +1699,11 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, return 0; manifest = (struct snd_soc_tplg_manifest *)tplg->pos; if (manifest->size != sizeof(*manifest)) { dev_err(tplg->dev, "ASoC: invalid manifest size\n"); return -EINVAL; } tplg->pos += sizeof(struct snd_soc_tplg_manifest); if (tplg->comp && tplg->ops && tplg->ops->manifest) Loading @@ -1686,6 +1720,14 @@ static int soc_valid_header(struct soc_tplg *tplg, if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size) return 0; if (hdr->size != sizeof(*hdr)) { dev_err(tplg->dev, "ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n", hdr->type, soc_tplg_get_hdr_offset(tplg), tplg->fw->size); return -EINVAL; } /* big endian firmware objects not supported atm */ if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) { dev_err(tplg->dev, Loading