[alsa-devel] [PATCH 1/4] ASoC: simple-card: add simple audio card widgets support
For many audio cards there need to add some off-CODEC widgets, and this is hard to be supported by dts only, because maybe some widgets need one or more call backs, such as wevent.
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- .../devicetree/bindings/sound/simple-card.txt | 1 + include/sound/simple_card.h | 14 ++++ sound/soc/generic/Makefile | 3 +- sound/soc/generic/simple-card-widgets.c | 79 ++++++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 sound/soc/generic/simple-card-widgets.c
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index e9e20ec..e626302 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt @@ -15,6 +15,7 @@ Optional properties: Each entry is a pair of strings, the first being the connection's sink, the second being the connection's source. +- simple-sudio-card,widgets : The name of the audio card off-CODEC widgets.
Required subnodes:
diff --git a/include/sound/simple_card.h b/include/sound/simple_card.h index 6c74527..75574f8 100644 --- a/include/sound/simple_card.h +++ b/include/sound/simple_card.h @@ -12,8 +12,16 @@ #ifndef __SIMPLE_CARD_H #define __SIMPLE_CARD_H
+#include <linux/of.h> #include <sound/soc.h>
+struct asoc_simple_card_widgets { + const char *name; + struct list_head list; + const struct snd_soc_dapm_widget *widgets; + unsigned int widgets_cnt; +}; + struct asoc_simple_dai { const char *name; unsigned int fmt; @@ -35,4 +43,10 @@ struct asoc_simple_card_info { struct snd_soc_card snd_card; };
+struct asoc_simple_card_widgets * +asoc_simple_card_get_widgets(struct device_node *); +int asoc_simple_card_widgets_register(struct asoc_simple_card_widgets *); +void +asoc_simple_card_widgets_unregister(struct asoc_simple_card_widgets *); + #endif /* __SIMPLE_CARD_H */ diff --git a/sound/soc/generic/Makefile b/sound/soc/generic/Makefile index 9c3b246..dbacd12 100644 --- a/sound/soc/generic/Makefile +++ b/sound/soc/generic/Makefile @@ -1,3 +1,4 @@ -snd-soc-simple-card-objs := simple-card.o +snd-soc-simple-card-objs := simple-card-widgets.o +snd-soc-simple-card-objs += simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o diff --git a/sound/soc/generic/simple-card-widgets.c b/sound/soc/generic/simple-card-widgets.c new file mode 100644 index 0000000..6eb0c8c --- /dev/null +++ b/sound/soc/generic/simple-card-widgets.c @@ -0,0 +1,79 @@ +/* + * ASoC simple sound card widgets support + * + * Copyright 2013 Freescale Semiconductor, Inc. + * Xiubo Li Li.Xiubo@freescale.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <sound/simple_card.h> + +static DEFINE_MUTEX(simple_widgets_mutex); +static LIST_HEAD(simple_widgets_list); + +void +asoc_simple_card_widgets_unregister(struct asoc_simple_card_widgets *comp) +{ + mutex_lock(&simple_widgets_mutex); + list_del(&comp->list); + mutex_unlock(&simple_widgets_mutex); +} +EXPORT_SYMBOL_GPL(asoc_simple_card_widgets_unregister); + +int +asoc_simple_card_widgets_register(struct asoc_simple_card_widgets *comp) +{ + if (!comp) { + pr_err("Simple Card: Failed to register widgets\n"); + return -EINVAL; + } + + mutex_lock(&simple_widgets_mutex); + list_add(&comp->list, &simple_widgets_list); + mutex_unlock(&simple_widgets_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(asoc_simple_card_widgets_register); + +struct asoc_simple_card_widgets * +asoc_simple_card_get_widgets(struct device_node *np) +{ + struct asoc_simple_card_widgets *comp; + const char *string; + int ret; + + if (!np) + return ERR_PTR(-EINVAL); + + if (!of_property_read_bool(np, "simple-audio-card,widgets")) + return NULL; + + ret = of_property_read_string(np, "simple-audio-card,widgets", + &string); + if (ret < 0) + return ERR_PTR(ret); + + mutex_lock(&simple_widgets_mutex); + list_for_each_entry(comp, &simple_widgets_list, list) { + if (!strcmp(string, comp->name)) { + mutex_unlock(&simple_widgets_mutex); + return comp; + } + + } + mutex_unlock(&simple_widgets_mutex); + + return ERR_PTR(-EPROBE_DEFER); +} +EXPORT_SYMBOL_GPL(asoc_simple_card_get_widgets); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:asoc-simple-card-widgets"); +MODULE_DESCRIPTION("ASoC Simple Sound Card Widgets"); +MODULE_AUTHOR("Xiubo Li Li.Xiubo@freescale.com");
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- sound/soc/generic/simple-card.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index e473dc9..e7cd9bb 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -125,6 +125,7 @@ static int asoc_simple_card_parse_of(struct device_node *node, struct device_node **of_codec, struct device_node **of_platform) { + struct asoc_simple_card_widgets *comp; struct device_node *np; char *name; int ret; @@ -133,6 +134,14 @@ static int asoc_simple_card_parse_of(struct device_node *node, info->daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
+ comp = asoc_simple_card_get_widgets(node); + if (!IS_ERR_OR_NULL(comp)) { + info->snd_card.dapm_widgets = comp->widgets; + info->snd_card.num_dapm_widgets = comp->widgets_cnt; + } else if (IS_ERR(comp)) { + return PTR_ERR(comp); + } + /* DAPM routes */ if (of_property_read_bool(node, "simple-audio-card,routing")) { ret = snd_soc_of_parse_audio_routing(&info->snd_card,
This is the SGTL5000 codec based off-CODEC widgets supports.
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- sound/soc/fsl/Kconfig | 25 ++++++++++++++++++ sound/soc/fsl/Makefile | 3 +++ sound/soc/fsl/snd-soc-simple-card-vf610.c | 44 +++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 sound/soc/fsl/snd-soc-simple-card-vf610.c
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 514c275..fc25d8a 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -216,3 +216,28 @@ config SND_SOC_IMX_MC13783 select SND_SOC_IMX_PCM_DMA
endif # SND_IMX_SOC + +menuconfig SND_VF610_SOC + tristate "SoC Audio for Freescale VF610 CPUs" + select DMA_ENGINE + help + Say Y or M if you want to add support for codecs attached to + the VF610 CPUs. + + This will enable Freeacale SAI and SGTL5000 codec, and an extra + TWR-AUDIO-SGTL sub-board is needed for SGTL5000. + +if SND_VF610_SOC + +config SND_SOC_VF610_SGTL5000 + tristate "SoC Audio support for VF610 boards with SGTL5000" + depends on OF && I2C + select SND_SOC_FSL_SAI + select SND_SOC_SGTL5000 + select SND_SIMPLE_CARD + help + Say Y if you want to add support for SoC audio on an VF610 board with + a SGTL5000 codec and a SAI. + + +endif #SND_VF610_SOC diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index aaccbee..19690c5 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -58,3 +58,6 @@ obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o + +# Simple audio card widgets Support +obj-$(CONFIG_SND_SOC_VF610_SGTL5000) += snd-soc-simple-card-vf610.o diff --git a/sound/soc/fsl/snd-soc-simple-card-vf610.c b/sound/soc/fsl/snd-soc-simple-card-vf610.c new file mode 100644 index 0000000..692561c --- /dev/null +++ b/sound/soc/fsl/snd-soc-simple-card-vf610.c @@ -0,0 +1,44 @@ +/* + * ASoC VF610 SGTL5000 off-CODEC widgets support + * + * Copyright 2013 Freescale Semiconductor, Inc. + * Xiubo Li Li.Xiubo@freescale.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <sound/simple_card.h> +#include <sound/soc-dapm.h> + +static const struct snd_soc_dapm_widget vf610_sgtl5000_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_LINE("Line In Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_SPK("Line Out Jack", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + +struct asoc_simple_card_widgets vf610_sgtl5000_widgets = { + .name = "vf610-sgtl5000", + .widgets = vf610_sgtl5000_dapm_widgets, + .widgets_cnt = ARRAY_SIZE(vf610_sgtl5000_dapm_widgets), +}; + +static int __init __vf610_sgtl5000_widgets_init(void) +{ + return asoc_simple_card_widgets_register(&vf610_sgtl5000_widgets); +} +module_init(__vf610_sgtl5000_widgets_init); + +static void __exit __vf610_sgtl5000_widgets_exit(void) +{ + asoc_simple_card_widgets_unregister(&vf610_sgtl5000_widgets); +} +module_exit(__vf610_sgtl5000_widgets_exit); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:vf610-simple-card-widgets"); +MODULE_DESCRIPTION("ASoC Simple Sound Card Widgets"); +MODULE_AUTHOR("Xiubo Li Li.Xiubo@freescale.com");
On Wed, Jan 08, 2014 at 03:02:35PM +0800, Xiubo Li wrote:
This is the SGTL5000 codec based off-CODEC widgets supports.
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com
sound/soc/fsl/Kconfig | 25 ++++++++++++++++++ sound/soc/fsl/Makefile | 3 +++ sound/soc/fsl/snd-soc-simple-card-vf610.c | 44 +++++++++++++++++++++++++++++++
If we're needing to add explict code for a simple audio card that seems to defeat the point of using the simple audio card - we may as well just have an explicit machine driver.
This is the SGTL5000 codec based off-CODEC widgets supports.
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com
sound/soc/fsl/Kconfig | 25 ++++++++++++++++++ sound/soc/fsl/Makefile | 3 +++ sound/soc/fsl/snd-soc-simple-card-vf610.c | 44
+++++++++++++++++++++++++++++++
If we're needing to add explict code for a simple audio card that seems to defeat the point of using the simple audio card - we may as well just have an explicit machine driver.
IMHO, the simple audio card driver could fulfil most of machine driver's work. And will make some machine driver simpler and eaiser to code.
Thanks,
-- Best Regards, Xiubo
This patch adds and enables SGTL5000 codec support, and also specified the corresponding SAI node.
Signed-off-by: Xiubo Li Li.Xiubo@freescale.com --- arch/arm/boot/dts/vf610-twr.dts | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index e60c20c..f7a1be7 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -34,6 +34,43 @@ }; };
+ regulators { + compatible = "simple-bus"; + + reg_3p3v: 3p3v { + compatible = "regulator-fixed"; + regulator-name = "3P3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,format = "i2s"; + simple-audio-card,widgets = "vf610-sgtl5000"; + simple-audio-card,routing = + "MIC_IN", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE_IN", "Line In Jack", + "Headphone Jack", "HP_OUT", + "Ext Spk", "LINE_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + master-clkdir-out; + frame-master; + bitclock-master; + }; + + simple-audio-card,codec { + sound-dai = <&codec>; + frame-master; + bitclock-master; + }; + }; + };
&dspi0 { @@ -72,9 +109,19 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c0_1>; status = "okay"; + + codec: sgtl5000@0a { + #sound-dai-cells = <0>; + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + VDDA-supply = <®_3p3v>; + VDDIO-supply = <®_3p3v>; + clocks = <&clks VF610_CLK_SAI2>; + }; };
&sai2 { + #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2_1>; status = "okay";
On Wed, Jan 08, 2014 at 03:02:33PM +0800, Xiubo Li wrote:
For many audio cards there need to add some off-CODEC widgets, and this is hard to be supported by dts only, because maybe some widgets need one or more call backs, such as wevent.
The big question here would be why these widgets need to be added - the default thing is that all inputs and outputs are enabled so it can't be that and as you say callbacks are going to need to be added.
If this is used then it probably makes sense for the card to set the fully routed flag since one possible use is to disable unconnected pins on the CODEC.
+- simple-sudio-card,widgets : The name of the audio card off-CODEC widgets.
simple-audio-card. This also needs more documentation about what is supposed to be filled in here.
+void +asoc_simple_card_widgets_unregister(struct asoc_simple_card_widgets *comp)
We always use snd_soc.
One interesting thing here is that this is done separately to the card itself. Is there any actual dependency on the simple card, could this be made into a generic library that any machine driver could use? I can see other machines being able to make use of this.
For many audio cards there need to add some off-CODEC widgets, and this is hard to be supported by dts only, because maybe some widgets need one or more call backs, such as wevent.
The big question here would be why these widgets need to be added
For instance, from the SGTL5000 codec Spec: ---- The analog input block contains a stereo line input and a microphone input with mic bias. Either input can be routed to the ADC. The line input can also be configured to bypass the CODEC and be routed directly to the headphone output. ---- And in the SGTL5000 codec driver there is one "Mic Bias" widget, and this should be routed to one off-CODEC widget, like "Mic Jack"(the microphone input).
the default thing is that all inputs and outputs are enabled so it can't be that and as you say callbacks are going to need to be added.
Some drivers may need like this: ---- SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0, XXX_output_amp_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), ---- ?
If this is used then it probably makes sense for the card to set the fully routed flag since one possible use is to disable unconnected pins on the CODEC.
+- simple-sudio-card,widgets : The name of the audio card off-CODEC
widgets.
simple-audio-card. This also needs more documentation about what is supposed to be filled in here.
Yes, if needed.
+void +asoc_simple_card_widgets_unregister(struct asoc_simple_card_widgets *comp)
We always use snd_soc.
One interesting thing here is that this is done separately to the card itself. Is there any actual dependency on the simple card, could this be made into a generic library that any machine driver could use? I can see other machines being able to make use of this.
No, has no dependency on the simple card.
Thanks,
-- Best Regards, Xiubo
participants (3)
-
Li.Xiubo@freescale.com
-
Mark Brown
-
Xiubo Li