Commit 6234eabf authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'asoc/topic/adsp' into asoc-next

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