Loading include/sound/soc.h +2 −0 Original line number Diff line number Diff line Loading @@ -477,6 +477,8 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, void *data, const char *long_name, const char *prefix); struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, const char *name); int snd_soc_add_codec_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls); int snd_soc_add_platform_controls(struct snd_soc_platform *platform, Loading sound/soc/codecs/wm_adsp.c +42 −82 Original line number Diff line number Diff line Loading @@ -225,15 +225,8 @@ struct wm_coeff_ctl_ops { struct snd_ctl_elem_info *uinfo); }; struct wm_coeff { struct device *dev; struct list_head ctl_list; struct regmap *regmap; }; struct wm_coeff_ctl { const char *name; struct snd_card *card; struct wm_adsp_alg_region region; struct wm_coeff_ctl_ops ops; struct wm_adsp *adsp; Loading Loading @@ -378,7 +371,6 @@ static int wm_coeff_info(struct snd_kcontrol *kcontrol, static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, const void *buf, size_t len) { struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol); struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; struct wm_adsp_alg_region *region = &ctl->region; const struct wm_adsp_region *mem; Loading @@ -401,7 +393,7 @@ static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, if (!scratch) return -ENOMEM; ret = regmap_raw_write(wm_coeff->regmap, reg, scratch, ret = regmap_raw_write(adsp->regmap, reg, scratch, ctl->len); if (ret) { adsp_err(adsp, "Failed to write %zu bytes to %x\n", Loading Loading @@ -434,7 +426,6 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol, static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, void *buf, size_t len) { struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol); struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; struct wm_adsp_alg_region *region = &ctl->region; const struct wm_adsp_region *mem; Loading @@ -457,7 +448,7 @@ static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, if (!scratch) return -ENOMEM; ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len); ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len); if (ret) { adsp_err(adsp, "Failed to read %zu bytes from %x\n", ctl->len, reg); Loading @@ -481,37 +472,18 @@ static int wm_coeff_get(struct snd_kcontrol *kcontrol, return 0; } static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff, struct wm_coeff_ctl *ctl, const struct snd_kcontrol_new *kctl) { int ret; struct snd_kcontrol *kcontrol; kcontrol = snd_ctl_new1(kctl, wm_coeff); ret = snd_ctl_add(ctl->card, kcontrol); if (ret < 0) { dev_err(wm_coeff->dev, "Failed to add %s: %d\n", kctl->name, ret); return ret; } ctl->kcontrol = kcontrol; return 0; } struct wmfw_ctl_work { struct wm_coeff *wm_coeff; struct wm_adsp *adsp; struct wm_coeff_ctl *ctl; struct work_struct work; }; static int wmfw_add_ctl(struct wm_coeff *wm_coeff, struct wm_coeff_ctl *ctl) static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl) { struct snd_kcontrol_new *kcontrol; int ret; if (!wm_coeff || !ctl || !ctl->name || !ctl->card) if (!ctl || !ctl->name) return -EINVAL; kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); Loading @@ -525,14 +497,17 @@ static int wmfw_add_ctl(struct wm_coeff *wm_coeff, kcontrol->put = wm_coeff_put; kcontrol->private_value = (unsigned long)ctl; ret = wm_coeff_add_kcontrol(wm_coeff, ctl, kcontrol); ret = snd_soc_add_card_controls(adsp->card, kcontrol, 1); if (ret < 0) goto err_kcontrol; kfree(kcontrol); list_add(&ctl->list, &wm_coeff->ctl_list); ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card, ctl->name); list_add(&ctl->list, &adsp->ctl_list); return 0; err_kcontrol: Loading Loading @@ -753,13 +728,12 @@ static int wm_adsp_load(struct wm_adsp *dsp) return ret; } static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) static int wm_coeff_init_control_caches(struct wm_adsp *adsp) { struct wm_coeff_ctl *ctl; int ret; list_for_each_entry(ctl, &wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &adsp->ctl_list, list) { if (!ctl->enabled || ctl->set) continue; ret = wm_coeff_read_control(ctl->kcontrol, Loading @@ -772,13 +746,12 @@ static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) return 0; } static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) static int wm_coeff_sync_controls(struct wm_adsp *adsp) { struct wm_coeff_ctl *ctl; int ret; list_for_each_entry(ctl, &wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &adsp->ctl_list, list) { if (!ctl->enabled) continue; if (ctl->set) { Loading @@ -799,15 +772,14 @@ static void wm_adsp_ctl_work(struct work_struct *work) struct wmfw_ctl_work, work); wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl); wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl); kfree(ctl_work); } static int wm_adsp_create_control(struct snd_soc_codec *codec, static int wm_adsp_create_control(struct wm_adsp *dsp, const struct wm_adsp_alg_region *region) { struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); struct wm_coeff_ctl *ctl; struct wmfw_ctl_work *ctl_work; char *name; Loading Loading @@ -842,7 +814,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, snprintf(name, PAGE_SIZE, "DSP%d %s %x", dsp->num, region_name, region->alg); list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list_for_each_entry(ctl, &dsp->ctl_list, list) { if (!strcmp(ctl->name, name)) { if (!ctl->enabled) Loading @@ -866,7 +838,6 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, ctl->set = 0; ctl->ops.xget = wm_coeff_get; ctl->ops.xput = wm_coeff_put; ctl->card = codec->card->snd_card; ctl->adsp = dsp; ctl->len = region->len; Loading @@ -882,7 +853,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, goto err_ctl_cache; } ctl_work->wm_coeff = dsp->wm_coeff; ctl_work->adsp = dsp; ctl_work->ctl = ctl; INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); schedule_work(&ctl_work->work); Loading @@ -903,7 +874,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, return ret; } static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) static int wm_adsp_setup_algs(struct wm_adsp *dsp) { struct regmap *regmap = dsp->regmap; struct wmfw_adsp1_id_hdr adsp1_id; Loading Loading @@ -1091,7 +1062,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp1_alg[i + 1].dm); region->len -= be32_to_cpu(adsp1_alg[i].dm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region DM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); Loading @@ -1108,7 +1079,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp1_alg[i + 1].zm); region->len -= be32_to_cpu(adsp1_alg[i].zm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); Loading Loading @@ -1137,7 +1108,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].xm); region->len -= be32_to_cpu(adsp2_alg[i].xm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region XM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading @@ -1154,7 +1125,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].ym); region->len -= be32_to_cpu(adsp2_alg[i].ym); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region YM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading @@ -1171,7 +1142,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].zm); region->len -= be32_to_cpu(adsp2_alg[i].zm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading Loading @@ -1391,6 +1362,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, int ret; int val; dsp->card = codec->card; switch (event) { case SND_SOC_DAPM_POST_PMU: regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, Loading Loading @@ -1425,7 +1398,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, if (ret != 0) goto err; ret = wm_adsp_setup_algs(dsp, codec); ret = wm_adsp_setup_algs(dsp); if (ret != 0) goto err; Loading @@ -1434,12 +1407,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, goto err; /* Initialize caches for enabled and unset controls */ ret = wm_coeff_init_control_caches(dsp->wm_coeff); ret = wm_coeff_init_control_caches(dsp); if (ret != 0) goto err; /* Sync set controls */ ret = wm_coeff_sync_controls(dsp->wm_coeff); ret = wm_coeff_sync_controls(dsp); if (ret != 0) goto err; Loading @@ -1460,10 +1433,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ADSP1_SYS_ENA, 0); list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &dsp->ctl_list, list) ctl->enabled = 0; } break; default: Loading Loading @@ -1520,6 +1491,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, unsigned int val; int ret; dsp->card = codec->card; switch (event) { case SND_SOC_DAPM_POST_PMU: /* Loading Loading @@ -1582,7 +1555,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, if (ret != 0) goto err; ret = wm_adsp_setup_algs(dsp, codec); ret = wm_adsp_setup_algs(dsp); if (ret != 0) goto err; Loading @@ -1591,12 +1564,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, goto err; /* Initialize caches for enabled and unset controls */ ret = wm_coeff_init_control_caches(dsp->wm_coeff); ret = wm_coeff_init_control_caches(dsp); if (ret != 0) goto err; /* Sync set controls */ ret = wm_coeff_sync_controls(dsp->wm_coeff); ret = wm_coeff_sync_controls(dsp); if (ret != 0) goto err; Loading Loading @@ -1637,10 +1610,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, ret); } list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &dsp->ctl_list, list) ctl->enabled = 0; } while (!list_empty(&dsp->alg_regions)) { alg_region = list_first_entry(&dsp->alg_regions, Loading Loading @@ -1679,49 +1650,38 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) } INIT_LIST_HEAD(&adsp->alg_regions); adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff), GFP_KERNEL); if (!adsp->wm_coeff) return -ENOMEM; adsp->wm_coeff->regmap = adsp->regmap; adsp->wm_coeff->dev = adsp->dev; INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list); INIT_LIST_HEAD(&adsp->ctl_list); if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); if (IS_ERR(adsp->dvfs)) { ret = PTR_ERR(adsp->dvfs); dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); goto out_coeff; return ret; } ret = regulator_enable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", ret); goto out_coeff; return ret; } ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); if (ret != 0) { dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", ret); goto out_coeff; return ret; } ret = regulator_disable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", ret); goto out_coeff; return ret; } } return 0; out_coeff: kfree(adsp->wm_coeff); return ret; } EXPORT_SYMBOL_GPL(wm_adsp2_init); sound/soc/codecs/wm_adsp.h +2 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ struct wm_adsp { int type; struct device *dev; struct regmap *regmap; struct snd_soc_card *card; int base; int sysclk_reg; Loading @@ -57,7 +58,7 @@ struct wm_adsp { struct regulator *dvfs; struct wm_coeff *wm_coeff; struct list_head ctl_list; }; #define WM_ADSP1(wname, num) \ Loading sound/soc/soc-core.c +16 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,22 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev, return 0; } struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, const char *name) { struct snd_card *card = soc_card->snd_card; struct snd_kcontrol *kctl; if (unlikely(!name)) return NULL; list_for_each_entry(kctl, &card->controls, list) if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) return kctl; return NULL; } EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol); /** * snd_soc_add_codec_controls - add an array of controls to a codec. * Convenience function to add a list of controls. Many codecs were Loading Loading
include/sound/soc.h +2 −0 Original line number Diff line number Diff line Loading @@ -477,6 +477,8 @@ int snd_soc_set_ac97_ops_of_reset(struct snd_ac97_bus_ops *ops, struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, void *data, const char *long_name, const char *prefix); struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, const char *name); int snd_soc_add_codec_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls); int snd_soc_add_platform_controls(struct snd_soc_platform *platform, Loading
sound/soc/codecs/wm_adsp.c +42 −82 Original line number Diff line number Diff line Loading @@ -225,15 +225,8 @@ struct wm_coeff_ctl_ops { struct snd_ctl_elem_info *uinfo); }; struct wm_coeff { struct device *dev; struct list_head ctl_list; struct regmap *regmap; }; struct wm_coeff_ctl { const char *name; struct snd_card *card; struct wm_adsp_alg_region region; struct wm_coeff_ctl_ops ops; struct wm_adsp *adsp; Loading Loading @@ -378,7 +371,6 @@ static int wm_coeff_info(struct snd_kcontrol *kcontrol, static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, const void *buf, size_t len) { struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol); struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; struct wm_adsp_alg_region *region = &ctl->region; const struct wm_adsp_region *mem; Loading @@ -401,7 +393,7 @@ static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, if (!scratch) return -ENOMEM; ret = regmap_raw_write(wm_coeff->regmap, reg, scratch, ret = regmap_raw_write(adsp->regmap, reg, scratch, ctl->len); if (ret) { adsp_err(adsp, "Failed to write %zu bytes to %x\n", Loading Loading @@ -434,7 +426,6 @@ static int wm_coeff_put(struct snd_kcontrol *kcontrol, static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, void *buf, size_t len) { struct wm_coeff *wm_coeff= snd_kcontrol_chip(kcontrol); struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; struct wm_adsp_alg_region *region = &ctl->region; const struct wm_adsp_region *mem; Loading @@ -457,7 +448,7 @@ static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, if (!scratch) return -ENOMEM; ret = regmap_raw_read(wm_coeff->regmap, reg, scratch, ctl->len); ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len); if (ret) { adsp_err(adsp, "Failed to read %zu bytes from %x\n", ctl->len, reg); Loading @@ -481,37 +472,18 @@ static int wm_coeff_get(struct snd_kcontrol *kcontrol, return 0; } static int wm_coeff_add_kcontrol(struct wm_coeff *wm_coeff, struct wm_coeff_ctl *ctl, const struct snd_kcontrol_new *kctl) { int ret; struct snd_kcontrol *kcontrol; kcontrol = snd_ctl_new1(kctl, wm_coeff); ret = snd_ctl_add(ctl->card, kcontrol); if (ret < 0) { dev_err(wm_coeff->dev, "Failed to add %s: %d\n", kctl->name, ret); return ret; } ctl->kcontrol = kcontrol; return 0; } struct wmfw_ctl_work { struct wm_coeff *wm_coeff; struct wm_adsp *adsp; struct wm_coeff_ctl *ctl; struct work_struct work; }; static int wmfw_add_ctl(struct wm_coeff *wm_coeff, struct wm_coeff_ctl *ctl) static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl) { struct snd_kcontrol_new *kcontrol; int ret; if (!wm_coeff || !ctl || !ctl->name || !ctl->card) if (!ctl || !ctl->name) return -EINVAL; kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); Loading @@ -525,14 +497,17 @@ static int wmfw_add_ctl(struct wm_coeff *wm_coeff, kcontrol->put = wm_coeff_put; kcontrol->private_value = (unsigned long)ctl; ret = wm_coeff_add_kcontrol(wm_coeff, ctl, kcontrol); ret = snd_soc_add_card_controls(adsp->card, kcontrol, 1); if (ret < 0) goto err_kcontrol; kfree(kcontrol); list_add(&ctl->list, &wm_coeff->ctl_list); ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card, ctl->name); list_add(&ctl->list, &adsp->ctl_list); return 0; err_kcontrol: Loading Loading @@ -753,13 +728,12 @@ static int wm_adsp_load(struct wm_adsp *dsp) return ret; } static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) static int wm_coeff_init_control_caches(struct wm_adsp *adsp) { struct wm_coeff_ctl *ctl; int ret; list_for_each_entry(ctl, &wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &adsp->ctl_list, list) { if (!ctl->enabled || ctl->set) continue; ret = wm_coeff_read_control(ctl->kcontrol, Loading @@ -772,13 +746,12 @@ static int wm_coeff_init_control_caches(struct wm_coeff *wm_coeff) return 0; } static int wm_coeff_sync_controls(struct wm_coeff *wm_coeff) static int wm_coeff_sync_controls(struct wm_adsp *adsp) { struct wm_coeff_ctl *ctl; int ret; list_for_each_entry(ctl, &wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &adsp->ctl_list, list) { if (!ctl->enabled) continue; if (ctl->set) { Loading @@ -799,15 +772,14 @@ static void wm_adsp_ctl_work(struct work_struct *work) struct wmfw_ctl_work, work); wmfw_add_ctl(ctl_work->wm_coeff, ctl_work->ctl); wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl); kfree(ctl_work); } static int wm_adsp_create_control(struct snd_soc_codec *codec, static int wm_adsp_create_control(struct wm_adsp *dsp, const struct wm_adsp_alg_region *region) { struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); struct wm_coeff_ctl *ctl; struct wmfw_ctl_work *ctl_work; char *name; Loading Loading @@ -842,7 +814,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, snprintf(name, PAGE_SIZE, "DSP%d %s %x", dsp->num, region_name, region->alg); list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list_for_each_entry(ctl, &dsp->ctl_list, list) { if (!strcmp(ctl->name, name)) { if (!ctl->enabled) Loading @@ -866,7 +838,6 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, ctl->set = 0; ctl->ops.xget = wm_coeff_get; ctl->ops.xput = wm_coeff_put; ctl->card = codec->card->snd_card; ctl->adsp = dsp; ctl->len = region->len; Loading @@ -882,7 +853,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, goto err_ctl_cache; } ctl_work->wm_coeff = dsp->wm_coeff; ctl_work->adsp = dsp; ctl_work->ctl = ctl; INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); schedule_work(&ctl_work->work); Loading @@ -903,7 +874,7 @@ static int wm_adsp_create_control(struct snd_soc_codec *codec, return ret; } static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) static int wm_adsp_setup_algs(struct wm_adsp *dsp) { struct regmap *regmap = dsp->regmap; struct wmfw_adsp1_id_hdr adsp1_id; Loading Loading @@ -1091,7 +1062,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp1_alg[i + 1].dm); region->len -= be32_to_cpu(adsp1_alg[i].dm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region DM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); Loading @@ -1108,7 +1079,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp1_alg[i + 1].zm); region->len -= be32_to_cpu(adsp1_alg[i].zm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp1_alg[i].alg.id)); Loading Loading @@ -1137,7 +1108,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].xm); region->len -= be32_to_cpu(adsp2_alg[i].xm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region XM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading @@ -1154,7 +1125,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].ym); region->len -= be32_to_cpu(adsp2_alg[i].ym); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region YM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading @@ -1171,7 +1142,7 @@ static int wm_adsp_setup_algs(struct wm_adsp *dsp, struct snd_soc_codec *codec) if (i + 1 < algs) { region->len = be32_to_cpu(adsp2_alg[i + 1].zm); region->len -= be32_to_cpu(adsp2_alg[i].zm); wm_adsp_create_control(codec, region); wm_adsp_create_control(dsp, region); } else { adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", be32_to_cpu(adsp2_alg[i].alg.id)); Loading Loading @@ -1391,6 +1362,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, int ret; int val; dsp->card = codec->card; switch (event) { case SND_SOC_DAPM_POST_PMU: regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, Loading Loading @@ -1425,7 +1398,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, if (ret != 0) goto err; ret = wm_adsp_setup_algs(dsp, codec); ret = wm_adsp_setup_algs(dsp); if (ret != 0) goto err; Loading @@ -1434,12 +1407,12 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, goto err; /* Initialize caches for enabled and unset controls */ ret = wm_coeff_init_control_caches(dsp->wm_coeff); ret = wm_coeff_init_control_caches(dsp); if (ret != 0) goto err; /* Sync set controls */ ret = wm_coeff_sync_controls(dsp->wm_coeff); ret = wm_coeff_sync_controls(dsp); if (ret != 0) goto err; Loading @@ -1460,10 +1433,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w, regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, ADSP1_SYS_ENA, 0); list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &dsp->ctl_list, list) ctl->enabled = 0; } break; default: Loading Loading @@ -1520,6 +1491,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, unsigned int val; int ret; dsp->card = codec->card; switch (event) { case SND_SOC_DAPM_POST_PMU: /* Loading Loading @@ -1582,7 +1555,7 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, if (ret != 0) goto err; ret = wm_adsp_setup_algs(dsp, codec); ret = wm_adsp_setup_algs(dsp); if (ret != 0) goto err; Loading @@ -1591,12 +1564,12 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, goto err; /* Initialize caches for enabled and unset controls */ ret = wm_coeff_init_control_caches(dsp->wm_coeff); ret = wm_coeff_init_control_caches(dsp); if (ret != 0) goto err; /* Sync set controls */ ret = wm_coeff_sync_controls(dsp->wm_coeff); ret = wm_coeff_sync_controls(dsp); if (ret != 0) goto err; Loading Loading @@ -1637,10 +1610,8 @@ int wm_adsp2_event(struct snd_soc_dapm_widget *w, ret); } list_for_each_entry(ctl, &dsp->wm_coeff->ctl_list, list) { list_for_each_entry(ctl, &dsp->ctl_list, list) ctl->enabled = 0; } while (!list_empty(&dsp->alg_regions)) { alg_region = list_first_entry(&dsp->alg_regions, Loading Loading @@ -1679,49 +1650,38 @@ int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) } INIT_LIST_HEAD(&adsp->alg_regions); adsp->wm_coeff = kzalloc(sizeof(*adsp->wm_coeff), GFP_KERNEL); if (!adsp->wm_coeff) return -ENOMEM; adsp->wm_coeff->regmap = adsp->regmap; adsp->wm_coeff->dev = adsp->dev; INIT_LIST_HEAD(&adsp->wm_coeff->ctl_list); INIT_LIST_HEAD(&adsp->ctl_list); if (dvfs) { adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); if (IS_ERR(adsp->dvfs)) { ret = PTR_ERR(adsp->dvfs); dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); goto out_coeff; return ret; } ret = regulator_enable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", ret); goto out_coeff; return ret; } ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); if (ret != 0) { dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", ret); goto out_coeff; return ret; } ret = regulator_disable(adsp->dvfs); if (ret != 0) { dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", ret); goto out_coeff; return ret; } } return 0; out_coeff: kfree(adsp->wm_coeff); return ret; } EXPORT_SYMBOL_GPL(wm_adsp2_init);
sound/soc/codecs/wm_adsp.h +2 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ struct wm_adsp { int type; struct device *dev; struct regmap *regmap; struct snd_soc_card *card; int base; int sysclk_reg; Loading @@ -57,7 +58,7 @@ struct wm_adsp { struct regulator *dvfs; struct wm_coeff *wm_coeff; struct list_head ctl_list; }; #define WM_ADSP1(wname, num) \ Loading
sound/soc/soc-core.c +16 −0 Original line number Diff line number Diff line Loading @@ -2452,6 +2452,22 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev, return 0; } struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card, const char *name) { struct snd_card *card = soc_card->snd_card; struct snd_kcontrol *kctl; if (unlikely(!name)) return NULL; list_for_each_entry(kctl, &card->controls, list) if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name))) return kctl; return NULL; } EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol); /** * snd_soc_add_codec_controls - add an array of controls to a codec. * Convenience function to add a list of controls. Many codecs were Loading