aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-07-29 11:13:58 -0400
committerMark Brown <broonie@linaro.org>2013-07-29 13:40:59 -0400
commite84357f7608f230b905acb18fe668609c9b811f0 (patch)
tree560ab5add59bae9f49276076df8cd5647741ec68 /sound/soc
parenteee5d7f99ae95059e1a3d1cfa2dea3ed8dbd94ac (diff)
ASoC: dapm: Wrap kcontrol widget list access
In preparation for adding additional per control data wrap all access to the widget list in helper functions. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/soc-dapm.c119
1 files changed, 78 insertions, 41 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b18ac5b1cc2e..da35b10ce6d1 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -174,14 +174,72 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
174 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); 174 return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL);
175} 175}
176 176
177struct dapm_kcontrol_data {
178 struct snd_soc_dapm_widget_list wlist;
179};
180
181static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
182 struct snd_kcontrol *kcontrol)
183{
184 struct dapm_kcontrol_data *data;
185
186 data = kzalloc(sizeof(*data) + sizeof(widget), GFP_KERNEL);
187 if (!data) {
188 dev_err(widget->dapm->dev,
189 "ASoC: can't allocate kcontrol data for %s\n",
190 widget->name);
191 return -ENOMEM;
192 }
193
194 data->wlist.widgets[0] = widget;
195 data->wlist.num_widgets = 1;
196
197 kcontrol->private_data = data;
198
199 return 0;
200}
201
202static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
203{
204 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl);
205 kfree(data);
206}
207
208static struct snd_soc_dapm_widget_list *dapm_kcontrol_get_wlist(
209 const struct snd_kcontrol *kcontrol)
210{
211 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
212
213 return &data->wlist;
214}
215
216static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
217 struct snd_soc_dapm_widget *widget)
218{
219 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
220 struct dapm_kcontrol_data *new_data;
221 unsigned int n = data->wlist.num_widgets + 1;
222
223 new_data = krealloc(data, sizeof(*data) + sizeof(widget) * n,
224 GFP_KERNEL);
225 if (!data)
226 return -ENOMEM;
227
228 data->wlist.widgets[n - 1] = widget;
229 data->wlist.num_widgets = n;
230
231 kcontrol->private_data = data;
232
233 return 0;
234}
235
177/** 236/**
178 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol 237 * snd_soc_dapm_kcontrol_codec() - Returns the codec associated to a kcontrol
179 * @kcontrol: The kcontrol 238 * @kcontrol: The kcontrol
180 */ 239 */
181struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol) 240struct snd_soc_codec *snd_soc_dapm_kcontrol_codec(struct snd_kcontrol *kcontrol)
182{ 241{
183 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 242 return dapm_kcontrol_get_wlist(kcontrol)->widgets[0]->codec;
184 return wlist->widgets[0]->codec;
185} 243}
186EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec); 244EXPORT_SYMBOL_GPL(snd_soc_dapm_kcontrol_codec);
187 245
@@ -488,11 +546,6 @@ static int dapm_is_shared_kcontrol(struct snd_soc_dapm_context *dapm,
488 return 0; 546 return 0;
489} 547}
490 548
491static void dapm_kcontrol_free(struct snd_kcontrol *kctl)
492{
493 kfree(kctl->private_data);
494}
495
496/* 549/*
497 * Determine if a kcontrol is shared. If it is, look it up. If it isn't, 550 * Determine if a kcontrol is shared. If it is, look it up. If it isn't,
498 * create it. Either way, add the widget into the control's widget list 551 * create it. Either way, add the widget into the control's widget list
@@ -506,9 +559,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
506 size_t prefix_len; 559 size_t prefix_len;
507 int shared; 560 int shared;
508 struct snd_kcontrol *kcontrol; 561 struct snd_kcontrol *kcontrol;
509 struct snd_soc_dapm_widget_list *wlist;
510 int wlistentries;
511 size_t wlistsize;
512 bool wname_in_long_name, kcname_in_long_name; 562 bool wname_in_long_name, kcname_in_long_name;
513 char *long_name; 563 char *long_name;
514 const char *name; 564 const char *name;
@@ -527,25 +577,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
527 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci], 577 shared = dapm_is_shared_kcontrol(dapm, w, &w->kcontrol_news[kci],
528 &kcontrol); 578 &kcontrol);
529 579
530 if (kcontrol) {
531 wlist = kcontrol->private_data;
532 wlistentries = wlist->num_widgets + 1;
533 } else {
534 wlist = NULL;
535 wlistentries = 1;
536 }
537
538 wlistsize = sizeof(struct snd_soc_dapm_widget_list) +
539 wlistentries * sizeof(struct snd_soc_dapm_widget *);
540 wlist = krealloc(wlist, wlistsize, GFP_KERNEL);
541 if (wlist == NULL) {
542 dev_err(dapm->dev, "ASoC: can't allocate widget list for %s\n",
543 w->name);
544 return -ENOMEM;
545 }
546 wlist->num_widgets = wlistentries;
547 wlist->widgets[wlistentries - 1] = w;
548
549 if (!kcontrol) { 580 if (!kcontrol) {
550 if (shared) { 581 if (shared) {
551 wname_in_long_name = false; 582 wname_in_long_name = false;
@@ -568,7 +599,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
568 kcname_in_long_name = false; 599 kcname_in_long_name = false;
569 break; 600 break;
570 default: 601 default:
571 kfree(wlist);
572 return -EINVAL; 602 return -EINVAL;
573 } 603 }
574 } 604 }
@@ -583,10 +613,8 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
583 long_name = kasprintf(GFP_KERNEL, "%s %s", 613 long_name = kasprintf(GFP_KERNEL, "%s %s",
584 w->name + prefix_len, 614 w->name + prefix_len,
585 w->kcontrol_news[kci].name); 615 w->kcontrol_news[kci].name);
586 if (long_name == NULL) { 616 if (long_name == NULL)
587 kfree(wlist);
588 return -ENOMEM; 617 return -ENOMEM;
589 }
590 618
591 name = long_name; 619 name = long_name;
592 } else if (wname_in_long_name) { 620 } else if (wname_in_long_name) {
@@ -597,21 +625,30 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
597 name = w->kcontrol_news[kci].name; 625 name = w->kcontrol_news[kci].name;
598 } 626 }
599 627
600 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], wlist, name, 628 kcontrol = snd_soc_cnew(&w->kcontrol_news[kci], NULL, name,
601 prefix); 629 prefix);
602 kcontrol->private_free = dapm_kcontrol_free; 630 kcontrol->private_free = dapm_kcontrol_free;
603 kfree(long_name); 631 kfree(long_name);
632
633 ret = dapm_kcontrol_data_alloc(w, kcontrol);
634 if (ret) {
635 snd_ctl_free_one(kcontrol);
636 return ret;
637 }
638
604 ret = snd_ctl_add(card, kcontrol); 639 ret = snd_ctl_add(card, kcontrol);
605 if (ret < 0) { 640 if (ret < 0) {
606 dev_err(dapm->dev, 641 dev_err(dapm->dev,
607 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n", 642 "ASoC: failed to add widget %s dapm kcontrol %s: %d\n",
608 w->name, name, ret); 643 w->name, name, ret);
609 kfree(wlist);
610 return ret; 644 return ret;
611 } 645 }
646 } else {
647 ret = dapm_kcontrol_add_widget(kcontrol, w);
648 if (ret)
649 return ret;
612 } 650 }
613 651
614 kcontrol->private_data = wlist;
615 w->kcontrols[kci] = kcontrol; 652 w->kcontrols[kci] = kcontrol;
616 path->kcontrol = kcontrol; 653 path->kcontrol = kcontrol;
617 654
@@ -1443,7 +1480,7 @@ static void dapm_widget_update(struct snd_soc_card *card)
1443 if (!update) 1480 if (!update)
1444 return; 1481 return;
1445 1482
1446 wlist = snd_kcontrol_chip(update->kcontrol); 1483 wlist = dapm_kcontrol_get_wlist(update->kcontrol);
1447 1484
1448 for (wi = 0; wi < wlist->num_widgets; wi++) { 1485 for (wi = 0; wi < wlist->num_widgets; wi++) {
1449 w = wlist->widgets[wi]; 1486 w = wlist->widgets[wi];
@@ -2749,7 +2786,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
2749int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, 2786int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
2750 struct snd_ctl_elem_value *ucontrol) 2787 struct snd_ctl_elem_value *ucontrol)
2751{ 2788{
2752 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2789 struct snd_soc_dapm_widget_list *wlist = dapm_kcontrol_get_wlist(kcontrol);
2753 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2790 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2754 struct snd_soc_codec *codec = widget->codec; 2791 struct snd_soc_codec *codec = widget->codec;
2755 struct snd_soc_card *card = codec->card; 2792 struct snd_soc_card *card = codec->card;
@@ -2802,7 +2839,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
2802int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol, 2839int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
2803 struct snd_ctl_elem_value *ucontrol) 2840 struct snd_ctl_elem_value *ucontrol)
2804{ 2841{
2805 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2842 struct snd_soc_dapm_widget_list *wlist = dapm_kcontrol_get_wlist(kcontrol);
2806 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2843 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2807 2844
2808 ucontrol->value.enumerated.item[0] = widget->value; 2845 ucontrol->value.enumerated.item[0] = widget->value;
@@ -2821,7 +2858,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
2821int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, 2858int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
2822 struct snd_ctl_elem_value *ucontrol) 2859 struct snd_ctl_elem_value *ucontrol)
2823{ 2860{
2824 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2861 struct snd_soc_dapm_widget_list *wlist = dapm_kcontrol_get_wlist(kcontrol);
2825 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2862 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2826 struct snd_soc_codec *codec = widget->codec; 2863 struct snd_soc_codec *codec = widget->codec;
2827 struct snd_soc_card *card = codec->card; 2864 struct snd_soc_card *card = codec->card;
@@ -2901,7 +2938,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
2901int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, 2938int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
2902 struct snd_ctl_elem_value *ucontrol) 2939 struct snd_ctl_elem_value *ucontrol)
2903{ 2940{
2904 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); 2941 struct snd_soc_dapm_widget_list *wlist = dapm_kcontrol_get_wlist(kcontrol);
2905 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; 2942 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
2906 struct snd_soc_codec *codec = widget->codec; 2943 struct snd_soc_codec *codec = widget->codec;
2907 struct snd_soc_card *card = codec->card; 2944 struct snd_soc_card *card = codec->card;