static int parse_text_values(snd_config_t *cfg, struct tplg_elem *elem) { struct tplg_texts *texts = elem->texts; snd_config_iterator_t i, next; snd_config_t *n; const char *value = NULL; int j = 0; tplg_dbg(" Text Values: %s\n", elem->id); snd_config_for_each(i, next, cfg) { n = snd_config_iterator_entry(i); if (j == SND_SOC_TPLG_NUM_TEXTS) { tplg_dbg("error: text string number exceeds %d\n", j); return -ENOMEM; } /* get value */ if (snd_config_get_string(n, &value) < 0) continue; elem_copy_text(&texts->items[j][0], value, SNDRV_CTL_ELEM_ID_NAME_MAXLEN); tplg_dbg("\t%s\n", &texts->items[j][0]); j++; }
static int tplg_parse_dapm_mixers(snd_config_t *cfg, struct tplg_elem *elem) { snd_config_iterator_t i, next; snd_config_t *n; const char *value = NULL; tplg_dbg(" DAPM Mixer Controls: %s\n", elem->id); snd_config_for_each(i, next, cfg) { n = snd_config_iterator_entry(i); /* get value */ if (snd_config_get_string(n, &value) < 0) continue; tplg_ref_add(elem, SND_TPLG_TYPE_MIXER, value); tplg_dbg("\t\t %s\n", value); }
static void dump_priv_data(struct tplg_elem *elem) { struct snd_soc_tplg_private *priv = elem->data; unsigned char *p = (unsigned char *)priv->data; unsigned int i, j = 0; tplg_dbg(" elem size = %d, priv data size = %d\n", elem->size, priv->size); for (i = 0; i < priv->size; i++) { if (j++ % 8 == 0) tplg_dbg("\n"); tplg_dbg(" 0x%x", *p++); } tplg_dbg("\n\n"); }
/* copy referenced TLV to the mixer control */ static int copy_tlv(struct tplg_elem *elem, struct tplg_elem *ref) { struct snd_soc_tplg_mixer_control *mixer_ctrl = elem->mixer_ctrl; struct snd_soc_tplg_ctl_tlv *tlv = ref->tlv; tplg_dbg("TLV '%s' used by '%s\n", ref->id, elem->id); /* TLV has a fixed size */ mixer_ctrl->hdr.tlv = *tlv; return 0; }
static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem, int width) { struct snd_soc_tplg_private *priv; const char *value = NULL; int size, esize, off, num; int ret; tplg_dbg(" data: %s\n", elem->id); if (snd_config_get_string(cfg, &value) < 0) return -EINVAL; num = get_hex_num(value); if (num <= 0) { SNDERR("error: malformed hex variable list %s\n", value); return -EINVAL; } size = num * width; priv = elem->data; if (size > TPLG_MAX_PRIV_SIZE) { SNDERR("error: data too big %d\n", size); return -EINVAL; } if (priv != NULL) { off = priv->size; esize = elem->size + size; priv = realloc(priv, esize); } else { off = 0; esize = sizeof(*priv) + size; priv = calloc(1, esize); } if (!priv) return -ENOMEM; elem->data = priv; priv->size += size; elem->size = esize; ret = copy_data_hex(priv->data, off, value, width); dump_priv_data(elem); return ret; }
/* Get Private data from a file. */ static int tplg_parse_data_file(snd_config_t *cfg, struct tplg_elem *elem) { struct snd_soc_tplg_private *priv = NULL; const char *value = NULL; char filename[MAX_FILE]; char *env = getenv(ALSA_CONFIG_TPLG_VAR); FILE *fp; size_t size, bytes_read; int ret = 0; tplg_dbg("data DataFile: %s\n", elem->id); if (snd_config_get_string(cfg, &value) < 0) return -EINVAL; /* prepend alsa config directory to path */ snprintf(filename, sizeof(filename), "%s/%s", env ? env : ALSA_TPLG_DIR, value); fp = fopen(filename, "r"); if (fp == NULL) { SNDERR("error: invalid data file path '%s'\n", filename); ret = -errno; goto err; } fseek(fp, 0L, SEEK_END); size = ftell(fp); fseek(fp, 0L, SEEK_SET); if (size <= 0) { SNDERR("error: invalid data file size %zu\n", size); ret = -EINVAL; goto err; } if (size > TPLG_MAX_PRIV_SIZE) { SNDERR("error: data file too big %zu\n", size); ret = -EINVAL; goto err; } priv = calloc(1, sizeof(*priv) + size); if (!priv) { ret = -ENOMEM; goto err; } bytes_read = fread(&priv->data, 1, size, fp); if (bytes_read != size) { ret = -errno; goto err; } elem->data = priv; priv->size = size; elem->size = sizeof(*priv) + size; return 0; err: if (priv) free(priv); return ret; }