ASoC: core: Add snd_soc_card_get_kcontrol()
Subsystems (3)
PATCH 1/2 ASoC: core: Add snd_soc_card_get_kcontrol()
This is useful for drivers who want to grab a pointer to snd_kcontrol outside of the kcontrol callbacks.
Signed-off-by Dimitris Papastamos <[email protected]>
--- include/sound/soc.h | 2 ++ sound/soc/soc-core.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+)
include/sound/soc.h +2 -0
@@ -475,6 +475,8 @@ int snd_soc_set_ac97_ops(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,
sound/soc/soc-core.c +16 -0
@@ -2299,6 +2299,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
Signature · 1 line
1.8.3.4
PATCH 2/2 ASoC: wm_adsp: Simplify kcontrol handling
Get rid off the wm_coeff struct and the wm_coeff_add_kcontrol() function. We are now using the snd_soc_card_kcontrol() function to get the kcontrol pointers. No need to call into ALSA code to register the kcontrols.
Signed-off-by Dimitris Papastamos <[email protected]>
--- sound/soc/codecs/wm_adsp.c | 103 ++++++++++++++------------------------------- sound/soc/codecs/wm_adsp.h | 2 +- 2 files changed, 32 insertions(+), 73 deletions(-)
sound/soc/codecs/wm_adsp.c +31 -72
@@ -225,15 +225,9 @@ 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 snd_soc_card *card;struct wm_adsp_alg_region region;struct wm_coeff_ctl_ops ops;struct wm_adsp *adsp;
@@ -378,7 +372,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;
@@ -401,7 +394,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",
@@ -434,7 +427,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;
@@ -457,7 +449,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);
@@ -481,37 +473,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 || !ctl->card)return -EINVAL ; kcontrol =kzalloc (sizeof (*kcontrol),GFP_KERNEL );
@@ -525,14 +498,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 (ctl->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 (ctl->card, + ctl->name); + +list_add (&ctl->list, &adsp->ctl_list);return 0 ; err_kcontrol:
@@ -753,13 +729,12 @@ out: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,
@@ -772,13 +747,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) {
@@ -799,7 +773,7 @@ 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); }
@@ -842,7 +816,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)
@@ -866,7 +840,7 @@ 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->card = codec->card; ctl->adsp = dsp; ctl->len = region->len;
@@ -882,7 +856,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);
@@ -1434,12 +1408,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;
@@ -1460,10 +1434,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 :
@@ -1591,12 +1563,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;
@@ -1637,10 +1609,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,
@@ -1679,49 +1649,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 +1 -1
@@ -57,7 +57,7 @@ struct wm_adsp {struct regulator *dvfs; -struct wm_coeff *wm_coeff; +struct list_head ctl_list; };#define WM_ADSP1 (wname, num) \
Signature · 1 line
1.8.3.4
Quoted 2 lines · Dimitris Papastamos
This is useful for drivers who want to grab a pointer to
snd_kcontroloutside of the kcontrol callbacks.
Applied both, thanks.