| From 1a9a16b92ac95caea67821067224e19da1597f4c Mon Sep 17 00:00:00 2001 |
| From: Xiubo Li <Li.Xiubo@freescale.com> |
| Date: Sat, 8 Feb 2014 15:59:52 +0800 |
| Subject: ASoC: add snd_soc_of_parse_audio_simple_widgets for DT |
| |
| This patch adds snd_soc_of_parse_audio_simple_widgets() and supports |
| below style of widgets name on DT: |
| |
| "template-wname", "user supplied wname" |
| |
| For instance: |
| simple-audio-widgets = |
| "Microphone", "Microphone Jack", |
| "Line", "Line In Jack", |
| "Line", "Line Out Jack", |
| "Headphone", "Headphone Jack", |
| "Speaker", "Speaker External"; |
| |
| The "template-wname" currently includes: "Microphone", "Line", "Headphone" |
| and "Speaker". |
| |
| Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> |
| Signed-off-by: Mark Brown <broonie@linaro.org> |
| (cherry picked from commit 9a6d48605e632e84db2895cf752c65b3c908cd09) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| include/sound/soc.h | 2 ++ |
| sound/soc/soc-core.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| 2 files changed, 89 insertions(+) |
| |
| diff --git a/include/sound/soc.h b/include/sound/soc.h |
| index 9a001472b96a..465dc6e0674d 100644 |
| --- a/include/sound/soc.h |
| +++ b/include/sound/soc.h |
| @@ -1173,6 +1173,8 @@ void snd_soc_util_exit(void); |
| |
| int snd_soc_of_parse_card_name(struct snd_soc_card *card, |
| const char *propname); |
| +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, |
| + const char *propname); |
| int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, |
| const char *propname); |
| unsigned int snd_soc_of_parse_daifmt(struct device_node *np, |
| diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c |
| index fe1df50805a3..0540cb08e0ea 100644 |
| --- a/sound/soc/soc-core.c |
| +++ b/sound/soc/soc-core.c |
| @@ -4417,6 +4417,93 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card, |
| } |
| EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name); |
| |
| +static const struct snd_soc_dapm_widget simple_widgets[] = { |
| + SND_SOC_DAPM_MIC("Microphone", NULL), |
| + SND_SOC_DAPM_LINE("Line", NULL), |
| + SND_SOC_DAPM_HP("Headphone", NULL), |
| + SND_SOC_DAPM_SPK("Speaker", NULL), |
| +}; |
| + |
| +int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card, |
| + const char *propname) |
| +{ |
| + struct device_node *np = card->dev->of_node; |
| + struct snd_soc_dapm_widget *widgets; |
| + const char *template, *wname; |
| + int i, j, num_widgets, ret; |
| + |
| + num_widgets = of_property_count_strings(np, propname); |
| + if (num_widgets < 0) { |
| + dev_err(card->dev, |
| + "ASoC: Property '%s' does not exist\n", propname); |
| + return -EINVAL; |
| + } |
| + if (num_widgets & 1) { |
| + dev_err(card->dev, |
| + "ASoC: Property '%s' length is not even\n", propname); |
| + return -EINVAL; |
| + } |
| + |
| + num_widgets /= 2; |
| + if (!num_widgets) { |
| + dev_err(card->dev, "ASoC: Property '%s's length is zero\n", |
| + propname); |
| + return -EINVAL; |
| + } |
| + |
| + widgets = devm_kcalloc(card->dev, num_widgets, sizeof(*widgets), |
| + GFP_KERNEL); |
| + if (!widgets) { |
| + dev_err(card->dev, |
| + "ASoC: Could not allocate memory for widgets\n"); |
| + return -ENOMEM; |
| + } |
| + |
| + for (i = 0; i < num_widgets; i++) { |
| + ret = of_property_read_string_index(np, propname, |
| + 2 * i, &template); |
| + if (ret) { |
| + dev_err(card->dev, |
| + "ASoC: Property '%s' index %d read error:%d\n", |
| + propname, 2 * i, ret); |
| + return -EINVAL; |
| + } |
| + |
| + for (j = 0; j < ARRAY_SIZE(simple_widgets); j++) { |
| + if (!strncmp(template, simple_widgets[j].name, |
| + strlen(simple_widgets[j].name))) { |
| + widgets[i] = simple_widgets[j]; |
| + break; |
| + } |
| + } |
| + |
| + if (j >= ARRAY_SIZE(simple_widgets)) { |
| + dev_err(card->dev, |
| + "ASoC: DAPM widget '%s' is not supported\n", |
| + template); |
| + return -EINVAL; |
| + } |
| + |
| + ret = of_property_read_string_index(np, propname, |
| + (2 * i) + 1, |
| + &wname); |
| + if (ret) { |
| + dev_err(card->dev, |
| + "ASoC: Property '%s' index %d read error:%d\n", |
| + propname, (2 * i) + 1, ret); |
| + return -EINVAL; |
| + } |
| + |
| + widgets[i].name = wname; |
| + } |
| + |
| + card->dapm_widgets = widgets; |
| + card->num_dapm_widgets = num_widgets; |
| + |
| + return 0; |
| +} |
| +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_simple_widgets); |
| + |
| int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, |
| const char *propname) |
| { |
| -- |
| 2.1.2 |
| |