[alsa-devel] [PATCH v3 0/4] off-codec widgets
This patch series has removed the code about tdm slot, and need to do more study.
This adds "ASoC: binding: add widgets.txt" new patch.
This also revises some others from Mark's comment.
Xiubo Li (4): ASoC: add snd_soc_of_parse_audio_simple_widgets for DT ASoC: simple-card: add off-codec widgets supports. ASoC: binding: add widgets.txt ASoC: binding: for new properties documenting and usage
.../devicetree/bindings/sound/simple-card.txt | 12 ++- .../devicetree/bindings/sound/widgets.txt | 20 +++++ include/sound/soc.h | 2 + sound/soc/generic/simple-card.c | 8 ++ sound/soc/soc-core.c | 87 ++++++++++++++++++++++ 5 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/widgets.txt
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 --- 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 c4be7ab..21d025e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1188,6 +1188,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 d8daf16..abee5f4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4471,6 +4471,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) {
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- sound/soc/generic/simple-card.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 3177aa8..ec2a65d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -202,6 +202,14 @@ static int asoc_simple_card_parse_of(struct device_node *node, priv->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
+ /* off-codec widgets */ + if (of_property_read_bool(node, "simple-audio-card,widgets")) { + ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, + "simple-audio-card,widgets"); + if (ret) + return ret; + } + /* DAPM routes */ if (of_property_read_bool(node, "simple-audio-card,routing")) { ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
Suggested-by: Mark Brown broonie@linaro.org Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- Documentation/devicetree/bindings/sound/widgets.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/widgets.txt
diff --git a/Documentation/devicetree/bindings/sound/widgets.txt b/Documentation/devicetree/bindings/sound/widgets.txt new file mode 100644 index 0000000..b6de5ba --- /dev/null +++ b/Documentation/devicetree/bindings/sound/widgets.txt @@ -0,0 +1,20 @@ +Widgets: + +This mainly specifies audio off-codec DAPM widgets. + +Each entry is a pair of strings in DT: + + "template-wname", "user-supplied-wname" + +The "template-wname" being the template widget name and currently includes: +"Microphone", "Line", "Headphone" and "Speaker". + +The "user-supplied-wname" being the user specified widget name. + +For instance: + simple-audio-widgets = + "Microphone", "Microphone Jack", + "Line", "Line In Jack", + "Line", "Line Out Jack", + "Headphone", "Headphone Jack", + "Speaker", "Speaker External";
This add the following three new properties documenting and usage for simple card:
"simple-audio-card,name", "simple-audio-card,widgets",
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- Documentation/devicetree/bindings/sound/simple-card.txt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 19c84df..0527358 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -8,9 +8,12 @@ Required properties:
Optional properties:
+- simple-audio-card,name : User specified audio sound card name, one string + property. - simple-audio-card,format : CPU/CODEC common audio format. "i2s", "right_j", "left_j" , "dsp_a" "dsp_b", "ac97", "pdm", "msb", "lsb" +- simple-audio-card,widgets : Please refer to widgets.txt. - simple-audio-card,routing : A list of the connections between audio components. Each entry is a pair of strings, the first being the connection's sink, the second being the connection's @@ -42,11 +45,16 @@ Example:
sound { compatible = "simple-audio-card"; + simple-audio-card,name = "VF610-Tower-Sound-Card"; simple-audio-card,format = "left_j"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Speaker", "External Speaker"; simple-audio-card,routing = - "MIC_IN", "Mic Jack", + "MIC_IN", "Microphone Jack", "Headphone Jack", "HP_OUT", - "Ext Spk", "LINE_OUT"; + "External Speaker", "LINE_OUT";
simple-audio-card,cpu { sound-dai = <&sh_fsi2 0>;
participants (2)
-
Mark Brown
-
Xiubo Li