[alsa-devel] [PATCH 0/5] Add Phytec pbab01 audio support
This patchset implements audio support on Phytec's phyFLEX-i.MX6 boards. This includes creating imx-tlv320aic3x machine driver, fixing tlv320aic3x driver playback speed issue and enabling audio for pbab01 itself.
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 22 ---------------------- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index 584721264121..f1bdcae5b97d 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -28,9 +28,6 @@ };
&i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - clock-frequency = <100000>; status = "okay";
tlv320@18 { @@ -55,9 +52,6 @@ };
&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - clock-frequency = <100000>; status = "okay"; };
@@ -84,19 +78,3 @@ &usdhc3 { status = "okay"; }; - -&iomuxc { - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 2694aa84e187..a927e88ccc98 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -162,6 +162,18 @@ }; };
+&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -235,6 +247,20 @@ >; };
+ pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
Am Mittwoch, den 10.09.2014, 16:46 +0300 schrieb Dmitry Lavnikevich:
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
I have seen boards use the GPIO_3/6 pads instead of EIM_D17/D18 for I2C3, but the EIM_D17/D18 are indeed documented as "I2C1" pins at the pfla02 connector level.
regards Philipp
On 11/09/14 11:47, Philipp Zabel wrote:
Am Mittwoch, den 10.09.2014, 16:46 +0300 schrieb Dmitry Lavnikevich:
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
I have seen boards use the GPIO_3/6 pads instead of EIM_D17/D18 for I2C3, but the EIM_D17/D18 are indeed documented as "I2C1" pins at the pfla02 connector level.
regards Philipp
Yes, that is why I thought about moving it into pfla02. But apart from it, i2c2grp i2c3grp nodes was wrongly placed under iomuxc node while it should be grouped inside of it, like in imx6q-phytec-pfla02 to which it was moved with this patch. Because of this specified i2c wasn't working correctly and caused messages:
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c2grp imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c3grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c2grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c3grp
Added this into commit message with new patchset.
Best regards, Lavnikevich Dmitry
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- .../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt new file mode 100644 index 000000000000..9e6c4443f40f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt @@ -0,0 +1,27 @@ +Audio complex for i.MX6 boards with tlv320aic3x audio codecs. + +Required properties: +- compatible : "fsl,imx-audio-tlv320aic3x" +- model : The user-visible name of this sound complex. +- ssi-controller : The phandle of the SSI controller. +- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX). +- mux-ext-port : The external port of the i.MX audio muxer. + +Note: The AUDMUX port numbering should start at 1, which is consistent with +hardware manual. + +Example: + +sound { + compatible = "fsl,imx-audio-tlv320aic3x"; + model = "imx6q-phyflex-tlv320aic3007"; + ssi-controller = <&ssi2>; + audio-codec = <&codec>; + audio-routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT"; + mux-int-port = <2>; + mux-ext-port = <5>; +}; diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index f3012b645b51..b40884c244bd 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -268,6 +268,19 @@ config SND_SOC_IMX_MC13783 select SND_SOC_MC13783 select SND_SOC_IMX_PCM_DMA
+config SND_SOC_IMX_TLV320AIC3X + tristate "SoC Audio support for i.MX6 boards with tlv320aic3x audio codec" + depends on OF && I2C + select SND_SOC_TLV320AIC3X + select SND_SOC_IMX_PCM_DMA + select SND_SOC_IMX_AUDMUX + select SND_SOC_FSL_SSI + help + SoC audio for i.MX6 boards with codec TLV320AIC3x attached over + SSI interface. + Say Y if you want to add support for SoC audio on phyFLEX-i.MX6 + boards. + endif # SND_IMX_SOC
endmenu diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 9ff59267eac9..83882bcefb0b 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -54,6 +54,7 @@ snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o snd-soc-imx-wm8962-objs := imx-wm8962.o snd-soc-imx-spdif-objs := imx-spdif.o snd-soc-imx-mc13783-objs := imx-mc13783.o +snd-soc-imx-tlv320aic3x-objs := imx-tlv320aic3x.o
obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o @@ -63,3 +64,4 @@ 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 +obj-$(CONFIG_SND_SOC_IMX_TLV320AIC3X) += snd-soc-imx-tlv320aic3x.o diff --git a/sound/soc/fsl/imx-tlv320aic3x.c b/sound/soc/fsl/imx-tlv320aic3x.c new file mode 100644 index 000000000000..f38c68911953 --- /dev/null +++ b/sound/soc/fsl/imx-tlv320aic3x.c @@ -0,0 +1,177 @@ +/* + * Copyright 2014 Dmitry Lavnikevich, + * SaM Solutions d.lavnikevich@sam-solutions.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/i2c.h> +#include <linux/of.h> +#include <linux/of_platform.h> + +#include "../codecs/tlv320aic3x.h" +#include "imx-audmux.h" +#include "imx-ssi.h" + +#define CODEC_CLOCK 19200000 + + +/* machine dapm widgets */ +static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_LINE("Speaker", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), +}; + +static int imx_audmux_config(int int_port, int ext_port) +{ + unsigned int ptcr, pdcr; + + int_port--; + ext_port--; + ptcr = IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(ext_port); + pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port); + imx_audmux_v2_configure_port(int_port, ptcr, pdcr); + + ptcr = 0; + pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(int_port); + imx_audmux_v2_configure_port(ext_port, ptcr, pdcr); + + return 0; +} + +/* Logic for a aic3x as connected on a imx */ +static int imx_aic3x_init(struct snd_soc_pcm_runtime *rtd) +{ + int ret; + + ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, CODEC_CLOCK, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_dai_link imx_tlv320_dai = { + .name = "HiFi", + .stream_name = "HiFi", + .codec_dai_name = "tlv320aic3x-hifi", + .init = &imx_aic3x_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, +}; + +static struct snd_soc_card imx_tlv320_card = { + .num_links = 1, + .owner = THIS_MODULE, + .dai_link = &imx_tlv320_dai, + .dapm_widgets = aic3x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), +}; + +static int imx_tlv320_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *ssi_np, *codec_np; + struct platform_device *ssi_pdev; + struct i2c_client *codec_dev; + int int_port, ext_port; + int ret = 0; + + ret = of_property_read_u32(np, "mux-int-port", &int_port); + if (ret) { + dev_err(&pdev->dev, "mux-int-port missing or invalid\n"); + return ret; + } + ret = of_property_read_u32(np, "mux-ext-port", &ext_port); + if (ret) { + dev_err(&pdev->dev, "mux-ext-port missing or invalid\n"); + return ret; + } + + imx_audmux_config(int_port, ext_port); + + ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0); + codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0); + if (!ssi_np || !codec_np) { + dev_err(&pdev->dev, "phandle missing or invalid\n"); + ret = -EINVAL; + goto fail; + } + + ssi_pdev = of_find_device_by_node(ssi_np); + if (!ssi_pdev) { + dev_err(&pdev->dev, "failed to find SSI platform device\n"); + ret = -EPROBE_DEFER; + goto fail; + } + codec_dev = of_find_i2c_device_by_node(codec_np); + if (!codec_dev) { + dev_err(&pdev->dev, "failed to find codec platform device\n"); + return -EPROBE_DEFER; + } + + imx_tlv320_dai.codec_of_node = codec_np; + imx_tlv320_dai.cpu_of_node = ssi_np; + imx_tlv320_dai.platform_of_node = ssi_np; + + imx_tlv320_card.dev = &pdev->dev; + ret = snd_soc_of_parse_card_name(&imx_tlv320_card, "model"); + if (ret) + goto fail; + ret = snd_soc_of_parse_audio_routing(&imx_tlv320_card, "audio-routing"); + if (ret) + goto fail; + + platform_set_drvdata(pdev, &imx_tlv320_card); + + ret = devm_snd_soc_register_card(&pdev->dev, &imx_tlv320_card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + goto fail; + } + + of_node_put(ssi_np); + of_node_put(codec_np); + + return 0; + +fail: + if (ssi_np) + of_node_put(ssi_np); + if (codec_np) + of_node_put(codec_np); + + return ret; +} + +static const struct of_device_id imx_tlv320_dt_ids[] = { + { .compatible = "fsl,imx-audio-tlv320aic3x", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_tlv320_dt_ids); + +static struct platform_driver imx_tlv320_driver = { + .driver = { + .name = "tlv320aic3x", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + .of_match_table = imx_tlv320_dt_ids, + }, + .probe = imx_tlv320_probe, +}; +module_platform_driver(imx_tlv320_driver); + +MODULE_AUTHOR("Lavnikevich Dmitry"); +MODULE_DESCRIPTION("TLV320AIC3X i.MX6 ASoC driver"); +MODULE_LICENSE("GPL");
Hi,
Dmitry Lavnikevich wrote:
diff --git a/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt new file mode 100644 index 000000000000..9e6c4443f40f --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt @@ -0,0 +1,27 @@ +Audio complex for i.MX6 boards with tlv320aic3x audio codecs.
+Required properties: +- compatible : "fsl,imx-audio-tlv320aic3x" +- model : The user-visible name of this sound complex. +- ssi-controller : The phandle of the SSI controller. +- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX). +- mux-ext-port : The external port of the i.MX audio muxer.
fsl,mux-{int,ext}-port?
diff --git a/sound/soc/fsl/imx-tlv320aic3x.c b/sound/soc/fsl/imx-tlv320aic3x.c new file mode 100644 index 000000000000..f38c68911953 --- /dev/null +++ b/sound/soc/fsl/imx-tlv320aic3x.c @@ -0,0 +1,177 @@ +/*
- Copyright 2014 Dmitry Lavnikevich,
- SaM Solutions d.lavnikevich@sam-solutions.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/i2c.h> +#include <linux/of.h> +#include <linux/of_platform.h>
+#include "../codecs/tlv320aic3x.h" +#include "imx-audmux.h" +#include "imx-ssi.h"
+#define CODEC_CLOCK 19200000
I guess this might be board specific and thus best passed via a clock property in DT.
+/* machine dapm widgets */ +static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
- SND_SOC_DAPM_LINE("Line Out", NULL),
- SND_SOC_DAPM_LINE("Speaker", NULL),
- SND_SOC_DAPM_HP("Headphone Jack", NULL),
- SND_SOC_DAPM_MIC("Mic Jack", NULL),
- SND_SOC_DAPM_LINE("Line In", NULL),
+};
+static int imx_audmux_config(int int_port, int ext_port) +{
- unsigned int ptcr, pdcr;
- int_port--;
- ext_port--;
- ptcr = IMX_AUDMUX_V2_PTCR_TFSDIR |
IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) |
IMX_AUDMUX_V2_PTCR_TCLKDIR |
IMX_AUDMUX_V2_PTCR_TCSEL(ext_port);
- pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port);
- imx_audmux_v2_configure_port(int_port, ptcr, pdcr);
- ptcr = 0;
- pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(int_port);
- imx_audmux_v2_configure_port(ext_port, ptcr, pdcr);
- return 0;
+}
This function could be static void ...
+/* Logic for a aic3x as connected on a imx */
s/ a / an /g
+static int imx_aic3x_init(struct snd_soc_pcm_runtime *rtd) +{
- int ret;
- ret = snd_soc_dai_set_sysclk(rtd->codec_dai, 0, CODEC_CLOCK,
SND_SOC_CLOCK_IN);
- if (ret < 0)
return ret;
- return 0;
+}
+static struct snd_soc_dai_link imx_tlv320_dai = {
- .name = "HiFi",
- .stream_name = "HiFi",
- .codec_dai_name = "tlv320aic3x-hifi",
- .init = &imx_aic3x_init,
- .dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
+};
+static struct snd_soc_card imx_tlv320_card = {
- .num_links = 1,
- .owner = THIS_MODULE,
- .dai_link = &imx_tlv320_dai,
- .dapm_widgets = aic3x_dapm_widgets,
- .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
+};
+static int imx_tlv320_probe(struct platform_device *pdev) +{
- struct device_node *np = pdev->dev.of_node;
- struct device_node *ssi_np, *codec_np;
- struct platform_device *ssi_pdev;
- struct i2c_client *codec_dev;
- int int_port, ext_port;
- int ret = 0;
Useless variable initialization.
Lothar Waßmann
Hi,
On Wed, Sep 10, 2014 at 04:46:46PM +0300, Dmitry Lavnikevich wrote:
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
.../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
Is it possible to use the simple-card (Documentation/devicetree/bindings/sound/simple-card.txt) instead of adding a new audio card driver? There are also DT bindings for the imx audiomultiplexer (imx-audmux.txt).
Best regards,
Markus
On Wed, Sep 10, 2014 at 7:27 AM, Markus Pargmann mpa@pengutronix.de wrote:
Hi,
On Wed, Sep 10, 2014 at 04:46:46PM +0300, Dmitry Lavnikevich wrote:
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
.../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
Is it possible to use the simple-card (Documentation/devicetree/bindings/sound/simple-card.txt) instead of adding a new audio card driver? There are also DT bindings for the imx audiomultiplexer (imx-audmux.txt).
I don't know why my mutt doesn't display this mail.
Anyway, if Simple Card supports audmux, yes, it's also a good idea.
On Wed, Sep 10, 2014 at 11:14:15AM -0700, Nicolin Chen wrote:
On Wed, Sep 10, 2014 at 7:27 AM, Markus Pargmann mpa@pengutronix.de wrote:
Hi,
On Wed, Sep 10, 2014 at 04:46:46PM +0300, Dmitry Lavnikevich wrote:
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
.../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
Is it possible to use the simple-card (Documentation/devicetree/bindings/sound/simple-card.txt) instead of adding a new audio card driver? There are also DT bindings for the imx audiomultiplexer (imx-audmux.txt).
I don't know why my mutt doesn't display this mail.
Anyway, if Simple Card supports audmux, yes, it's also a good idea.
Simple Card doesn't support it. But there are DT bindings for the audmux device node which allow the definition of a default multiplexer setup. That configuration is applied in the probe() function of the audmux driver.
Best regards,
Markus
Hi,
On 11/09/14 09:40, Markus Pargmann wrote:
On Wed, Sep 10, 2014 at 11:14:15AM -0700, Nicolin Chen wrote:
On Wed, Sep 10, 2014 at 7:27 AM, Markus Pargmann mpa@pengutronix.de wrote:
Hi,
On Wed, Sep 10, 2014 at 04:46:46PM +0300, Dmitry Lavnikevich wrote:
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
.../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
Is it possible to use the simple-card (Documentation/devicetree/bindings/sound/simple-card.txt) instead of adding a new audio card driver? There are also DT bindings for the imx audiomultiplexer (imx-audmux.txt).
I don't know why my mutt doesn't display this mail.
Anyway, if Simple Card supports audmux, yes, it's also a good idea.
Simple Card doesn't support it. But there are DT bindings for the audmux device node which allow the definition of a default multiplexer setup. That configuration is applied in the probe() function of the audmux driver.
Best regards,
Markus
Yes, I've checked - it can be implemented with simple card + audmux configuration. Thanks for great suggestion. It will be done in next patchset version.
Best regards, Lavnikevich Dmitry
Hi Dmitry,
On Wed, Sep 10, 2014 at 04:46:46PM +0300, Dmitry Lavnikevich wrote:
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
.../bindings/sound/fsl,imx-audio-tlv320aic3x.txt | 27 ++++ sound/soc/fsl/Kconfig | 13 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-tlv320aic3x.c | 177 +++++++++++++++++++++ 4 files changed, 219 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl,imx-audio-tlv320aic3x.txt create mode 100644 sound/soc/fsl/imx-tlv320aic3x.c
This whole single patch looks pretty clean. So I suggest it may be merged into fsl-asoc-card.c driver whose DT binding is almost identical to yours so that we don't need to add a machine driver with duplicated code. And you can feel free to enable fsl-asoc-card in the defconfig as well -- I was about to do it and to replace imx-wm8962 and imx-sgtl5000 with it.
The only extra trivia you need to tackle is to add a clock binding into your dts for CODEC side.
Thanks Nicolin
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 16cfec4385c8..66a6a5c6e75a 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -213,6 +213,7 @@ CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_IMX_TLV320AIC3X=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MXC=y
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 59 +++++++++++++++++++++++++++- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 15 +++++++ 2 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index f1bdcae5b97d..8f778fe8c0b7 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -13,6 +13,46 @@ chosen { linux,stdout-path = &uart4; }; + + regulators { + sound_1v8: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "i2s-audio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + sound_3v3: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "i2s-audio-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + sound { + compatible = "fsl,imx-audio-tlv320aic3x"; + model = "imx6q-phyflex-tlv320aic3007"; + ssi-controller = <&ssi2>; + audio-codec = <&codec>; + audio-routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + mux-int-port = <2>; + mux-ext-port = <5>; + }; };
&fec { @@ -27,12 +67,27 @@ status = "okay"; };
+&ssi2 { + fsl,mode = "i2s-slave"; + status = "okay"; +}; + +&audmux { + status = "okay"; +}; + &i2c2 { status = "okay";
- tlv320@18 { - compatible = "ti,tlv320aic3x"; + codec: tlv320@18 { + compatible = "ti,tlv320aic3007"; reg = <0x18>; + ai3x-micbias-vg = <2>; + + AVDD-supply = <&sound_3v3>; + IOVDD-supply = <&sound_3v3>; + DRVDD-supply = <&sound_3v3>; + DVDD-supply = <&sound_1v8>; };
stmpe@41 { diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index a927e88ccc98..1c4464dcb497 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -58,6 +58,12 @@ }; };
+&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "disabled"; +}; + &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; @@ -319,6 +325,15 @@ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 >; }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 + >; + }; }; };
Current caching implementation during regcache_sync() call bypasses all register writes of values that are already known as default (regmap reg_defaults). Same time in TLV320AIC3x codecs register 5 (AIC3X_PLL_PROGC_REG) write should be immediately followed by register 6 write (AIC3X_PLL_PROGD_REG) even if it was not changed. Otherwise both registers will not be written.
This brings to issue that appears particulary in case of 44.1kHz playback with 19.2MHz master clock. In this case AIC3X_PLL_PROGC_REG is 0x6e while AIC3X_PLL_PROGD_REG is 0x0 (same as register default). Thus AIC3X_PLL_PROGC_REG also remains not written and we get wrong playback speed.
In this patch snd_soc_read() is used to get cached pll values and snd_soc_write() (unlike regcache_sync() this function doesn't bypasses hardware default values) to write them to registers.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- sound/soc/codecs/tlv320aic3x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64f179ee9834..5e8626ae612b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, static int aic3x_set_power(struct snd_soc_codec *codec, int power) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + unsigned int pll_c, pll_d; int ret;
if (power) { @@ -1138,6 +1139,18 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) /* Sync reg_cache with the hardware */ regcache_cache_only(aic3x->regmap, false); regcache_sync(aic3x->regmap); + + /* Rewrite paired PLL D registers in case cached sync skipped + * writing one of them and thus caused other one also not + * being written + */ + pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG); + pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG); + if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def || + pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) { + snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); + snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); + } } else { /* * Do soft reset to this codec instance in order to clear
Since previous patchset version asoc machine driver imx-tlv320aic3x was replaced with simple-audio-card and audmux. Also changed commit message for first patch, which now explicitly states that it has more than stylistic purpose.
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
This patch fixes i2c2, i2c3 pin configuration which caused messages:
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c2grp imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c3grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c2grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c3grp
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 22 ---------------------- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index 584721264121..f1bdcae5b97d 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -28,9 +28,6 @@ };
&i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - clock-frequency = <100000>; status = "okay";
tlv320@18 { @@ -55,9 +52,6 @@ };
&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - clock-frequency = <100000>; status = "okay"; };
@@ -84,19 +78,3 @@ &usdhc3 { status = "okay"; }; - -&iomuxc { - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 2694aa84e187..a927e88ccc98 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -162,6 +162,18 @@ }; };
+&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -235,6 +247,20 @@ >; };
+ pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 93 +++++++++++++++++++++++++++- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 15 +++++ 2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index f1bdcae5b97d..44cbcc61aff1 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -13,6 +13,69 @@ chosen { linux,stdout-path = &uart4; }; + + regulators { + sound_1v8: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "i2s-audio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + sound_3v3: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "i2s-audio-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + tlv320_mclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "tlv320-mclk"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6-phyflex-tlv320aic3007"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Speaker", "Speaker", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&tlv320_mclk>; + }; + }; + };
&fec { @@ -27,12 +90,38 @@ status = "okay"; };
+&ssi2 { + fsl,mode = "i2s-slave"; + status = "okay"; + #sound-dai-cells = <0>; +}; + +&audmux { + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = <0xa5000000 0x00008000>; + }; + pins5 { + fsl,audmux-port = <4>; + fsl,port-config = <0x00000000 0x00002000>; + }; +}; + &i2c2 { status = "okay";
- tlv320@18 { - compatible = "ti,tlv320aic3x"; + codec: tlv320@18 { + compatible = "ti,tlv320aic3007"; + #sound-dai-cells = <0>; reg = <0x18>; + ai3x-micbias-vg = <2>; + + AVDD-supply = <&sound_3v3>; + IOVDD-supply = <&sound_3v3>; + DRVDD-supply = <&sound_3v3>; + DVDD-supply = <&sound_1v8>; };
stmpe@41 { diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index a927e88ccc98..1c4464dcb497 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -58,6 +58,12 @@ }; };
+&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "disabled"; +}; + &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; @@ -319,6 +325,15 @@ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 >; }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 + >; + }; }; };
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
...
+&audmux {
- status = "okay";
- ssi2 {
fsl,audmux-port = <1>;
fsl,port-config = <0xa5000000 0x00008000>;
- };
- pins5 {
fsl,audmux-port = <4>;
fsl,port-config = <0x00000000 0x00002000>;
- };
+};
You should use defines from sound/fsl-imx-audmux.h for audmux.
---
On 12/09/14 19:14, Alexander Shiyan wrote:
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
+&audmux {
- status = "okay";
- ssi2 {
fsl,audmux-port = <1>;
fsl,port-config = <0xa5000000 0x00008000>;
- };
- pins5 {
fsl,audmux-port = <4>;
fsl,port-config = <0x00000000 0x00002000>;
- };
+};
You should use defines from sound/fsl-imx-audmux.h for audmux.
Ok, will change it in next patchset version.
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
...
+&ssi2 {
- fsl,mode = "i2s-slave";
- status = "okay";
- #sound-dai-cells = <0>;
+};
I have already sent patch to add "#sound-dai-cells" into all i.MX DT-files. Shawn, can you point us to this tree/commit?
---
On Fri, Sep 12, 2014 at 1:26 PM, Alexander Shiyan shc_work@mail.ru wrote:
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
...
+&ssi2 {
fsl,mode = "i2s-slave";
status = "okay";
#sound-dai-cells = <0>;
+};
I have already sent patch to add "#sound-dai-cells" into all i.MX DT-files. Shawn, can you point us to this tree/commit?
https://git.kernel.org/cgit/linux/kernel/git/shawnguo/linux.git/commit/?h=fo...
On 12/09/14 19:40, Fabio Estevam wrote:
On Fri, Sep 12, 2014 at 1:26 PM, Alexander Shiyan shc_work@mail.ru wrote:
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
...
+&ssi2 {
fsl,mode = "i2s-slave";
status = "okay";
#sound-dai-cells = <0>;
+};
I have already sent patch to add "#sound-dai-cells" into all i.MX DT-files. Shawn, can you point us to this tree/commit?
https://git.kernel.org/cgit/linux/kernel/git/shawnguo/linux.git/commit/?h=fo...
So should I base my next patchset on for-next branch of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git ?
On Mon, Sep 15, 2014 at 03:07:02PM +0300, Dmitry Lavnikevich wrote:
On 12/09/14 19:40, Fabio Estevam wrote:
On Fri, Sep 12, 2014 at 1:26 PM, Alexander Shiyan shc_work@mail.ru wrote:
Fri, 12 Sep 2014 19:04:30 +0300 от Dmitry Lavnikevich d.lavnikevich@sam-solutions.com:
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com
...
+&ssi2 {
fsl,mode = "i2s-slave";
status = "okay";
#sound-dai-cells = <0>;
+};
I have already sent patch to add "#sound-dai-cells" into all i.MX DT-files. Shawn, can you point us to this tree/commit?
https://git.kernel.org/cgit/linux/kernel/git/shawnguo/linux.git/commit/?h=fo...
So should I base my next patchset on for-next branch of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git ?
Yes, please.
Shawn
Used on Phytec PBAB01 board.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/configs/imx_v6_v7_defconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 16cfec4385c8..b344290c537b 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -213,6 +213,8 @@ CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_TLV320AIC3X=y +CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_MXC=y
Current caching implementation during regcache_sync() call bypasses all register writes of values that are already known as default (regmap reg_defaults). Same time in TLV320AIC3x codecs register 5 (AIC3X_PLL_PROGC_REG) write should be immediately followed by register 6 write (AIC3X_PLL_PROGD_REG) even if it was not changed. Otherwise both registers will not be written.
This brings to issue that appears particulary in case of 44.1kHz playback with 19.2MHz master clock. In this case AIC3X_PLL_PROGC_REG is 0x6e while AIC3X_PLL_PROGD_REG is 0x0 (same as register default). Thus AIC3X_PLL_PROGC_REG also remains not written and we get wrong playback speed.
In this patch snd_soc_read() is used to get cached pll values and snd_soc_write() (unlike regcache_sync() this function doesn't bypasses hardware default values) to write them to registers.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- sound/soc/codecs/tlv320aic3x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64f179ee9834..5e8626ae612b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, static int aic3x_set_power(struct snd_soc_codec *codec, int power) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + unsigned int pll_c, pll_d; int ret;
if (power) { @@ -1138,6 +1139,18 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) /* Sync reg_cache with the hardware */ regcache_cache_only(aic3x->regmap, false); regcache_sync(aic3x->regmap); + + /* Rewrite paired PLL D registers in case cached sync skipped + * writing one of them and thus caused other one also not + * being written + */ + pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG); + pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG); + if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def || + pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) { + snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); + snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); + } } else { /* * Do soft reset to this codec instance in order to clear
New phyFLEX board audio patchset version.
Defines from dt-bindings/sound/fsl-imx-audmux.h are now used in audmux configuration instead of hardcoded register values.
Also patchset is now based on branch for-next from git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git which means:
- removed #sound-dai-cells in ssi2 node since it was already moved to imx6qdl.dtsi; - patch for imx_v6_v7_defconfig now enables only CONFIG_SND_SOC_TLV320AIC3X since CONFIG_SND_SIMPLE_CARD also was already enabled.
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
This patch fixes i2c2, i2c3 pin configuration which caused messages:
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c2grp imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c3grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c2grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c3grp
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 22 ---------------------- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index 584721264121..f1bdcae5b97d 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -28,9 +28,6 @@ };
&i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - clock-frequency = <100000>; status = "okay";
tlv320@18 { @@ -55,9 +52,6 @@ };
&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - clock-frequency = <100000>; status = "okay"; };
@@ -84,19 +78,3 @@ &usdhc3 { status = "okay"; }; - -&iomuxc { - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 0e50bb0a6b94..aa2275671d2c 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -162,6 +162,18 @@ }; };
+&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -235,6 +247,20 @@ >; };
+ pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 103 ++++++++++++++++++++++++++- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 15 ++++ 2 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index f1bdcae5b97d..c0369673707b 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -9,10 +9,75 @@ * http://www.gnu.org/copyleft/gpl.html */
+#include <dt-bindings/sound/fsl-imx-audmux.h> + / { chosen { linux,stdout-path = &uart4; }; + + regulators { + sound_1v8: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "i2s-audio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + sound_3v3: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "i2s-audio-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + + tlv320_mclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "tlv320-mclk"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6-phyflex-tlv320aic3007"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Speaker", "Speaker", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&tlv320_mclk>; + }; + }; + };
&fec { @@ -27,12 +92,46 @@ status = "okay"; };
+&ssi2 { + fsl,mode = "i2s-slave"; + status = "okay"; +}; + +&audmux { + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(4) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(4)) + IMX_AUDMUX_V2_PDCR_RXDSEL(4) + >; + }; + pins5 { + fsl,audmux-port = <4>; + fsl,port-config = < + 0x00000000 + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + &i2c2 { status = "okay";
- tlv320@18 { - compatible = "ti,tlv320aic3x"; + codec: tlv320@18 { + compatible = "ti,tlv320aic3007"; + #sound-dai-cells = <0>; reg = <0x18>; + ai3x-micbias-vg = <2>; + + AVDD-supply = <&sound_3v3>; + IOVDD-supply = <&sound_3v3>; + DRVDD-supply = <&sound_3v3>; + DVDD-supply = <&sound_1v8>; };
stmpe@41 { diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index aa2275671d2c..d7f34664e008 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -58,6 +58,12 @@ }; };
+&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "disabled"; +}; + &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; @@ -319,6 +325,15 @@ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 >; }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 + >; + }; }; };
On Tue, Sep 16, 2014 at 5:08 AM, Dmitry Lavnikevich d.lavnikevich@sam-solutions.com wrote:
regulators {
sound_1v8: regulator@2 {
We usually start counting from @0.
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "i2s-audio-1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
No need to have this 'regulator-always-on'
};
sound_3v3: regulator@3 {
,so this one should be @1.
compatible = "regulator-fixed";
reg = <3>;
regulator-name = "i2s-audio-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
No need to have this 'regulator-always-on'
+&ssi2 {
fsl,mode = "i2s-slave";
Please remove this 'fsl,mode' property. It is ignored by the fsl_ssi driver.
On 01/10/14 15:11, Fabio Estevam wrote:
On Tue, Sep 16, 2014 at 5:08 AM, Dmitry Lavnikevich d.lavnikevich@sam-solutions.com wrote:
regulators {
sound_1v8: regulator@2 {
We usually start counting from @0.
...
};
sound_3v3: regulator@3 {
,so this one should be @1.
@0 and @1 are used for "usb_otg_vbus" and "usb_h1_vbus" regulators in dts for phyFLEX module (imx6qdl-phytec-pfla02.dtsi) which gets included before base board dts (imx6qdl-phytec-pbab01.dtsi)
compatible = "regulator-fixed";
reg = <2>;
regulator-name = "i2s-audio-1v8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
No need to have this 'regulator-always-on'
...
compatible = "regulator-fixed";
reg = <3>;
regulator-name = "i2s-audio-3v3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
No need to have this 'regulator-always-on'
why is there no need for 'regulator-alweys-on'? I see it in similar fixed regulator descriptions in imx6qdl-sabrelite.dtsi, imx6qdl-wandboard.dtsi, imx6qdl-nitrogen6x.dtsi and many other boards.
+&ssi2 {
fsl,mode = "i2s-slave";
Please remove this 'fsl,mode' property. It is ignored by the fsl_ssi driver.
yes, thanks. It is present in Documentation but now I see that it was actually removed not that long ago. I will remove this property with next patchset.
On Wed, Oct 1, 2014 at 10:40 AM, Dmitry Lavnikevich d.lavnikevich@sam-solutions.com wrote:
No need to have this 'regulator-always-on'
why is there no need for 'regulator-alweys-on'? I see it in
For a regulator that is not GPIO controlled you don't need to pass 'regulator-always-on'.
+&ssi2 {
fsl,mode = "i2s-slave";
Please remove this 'fsl,mode' property. It is ignored by the fsl_ssi driver.
yes, thanks. It is present in Documentation but now I see that it was actually removed not that long ago. I will remove this property with next patchset.
Correct, I recently sent a patch removing it and it is in Mark's tree now: https://git.kernel.org/cgit/linux/kernel/git/broonie/sound.git/commit/?h=top...
On 01/10/14 16:45, Fabio Estevam wrote:
On Wed, Oct 1, 2014 at 10:40 AM, Dmitry Lavnikevich d.lavnikevich@sam-solutions.com wrote:
No need to have this 'regulator-always-on'
why is there no need for 'regulator-alweys-on'? I see it in
For a regulator that is not GPIO controlled you don't need to pass 'regulator-always-on'.
Ok, I will remove it also.
I will wait some time for other notes on patches and resend patchset.
Used on Phytec PBAB01 board.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 8fca6e276b69..cac07d67b933 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -210,6 +210,7 @@ CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y
Current caching implementation during regcache_sync() call bypasses all register writes of values that are already known as default (regmap reg_defaults). Same time in TLV320AIC3x codecs register 5 (AIC3X_PLL_PROGC_REG) write should be immediately followed by register 6 write (AIC3X_PLL_PROGD_REG) even if it was not changed. Otherwise both registers will not be written.
This brings to issue that appears particulary in case of 44.1kHz playback with 19.2MHz master clock. In this case AIC3X_PLL_PROGC_REG is 0x6e while AIC3X_PLL_PROGD_REG is 0x0 (same as register default). Thus AIC3X_PLL_PROGC_REG also remains not written and we get wrong playback speed.
In this patch snd_soc_read() is used to get cached pll values and snd_soc_write() (unlike regcache_sync() this function doesn't bypasses hardware default values) to write them to registers.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- sound/soc/codecs/tlv320aic3x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64f179ee9834..5e8626ae612b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, static int aic3x_set_power(struct snd_soc_codec *codec, int power) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + unsigned int pll_c, pll_d; int ret;
if (power) { @@ -1138,6 +1139,18 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) /* Sync reg_cache with the hardware */ regcache_cache_only(aic3x->regmap, false); regcache_sync(aic3x->regmap); + + /* Rewrite paired PLL D registers in case cached sync skipped + * writing one of them and thus caused other one also not + * being written + */ + pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG); + pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG); + if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def || + pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) { + snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); + snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); + } } else { /* * Do soft reset to this codec instance in order to clear
Hello,
I have resent my patchset rebased on git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git couple weeks ago. Was it lost under other mails or should I change something else?
Best regards, Lavnikevich Dmitry
New phyFLEX board audio patchset version.
Small changes made since last version:
- removed unnecessary 'regulator-always-on' in fixed regulators dts description; - removed 'fsl,mode = "i2s-slave"' from ssi2 node in dts since it was already removed from fsl-ssi driver.
Based on branch for-next from git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
This patch fixes i2c2, i2c3 pin configuration which caused messages:
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c2grp imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c3grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c2grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c3grp
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 22 ---------------------- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index 584721264121..f1bdcae5b97d 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -28,9 +28,6 @@ };
&i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - clock-frequency = <100000>; status = "okay";
tlv320@18 { @@ -55,9 +52,6 @@ };
&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - clock-frequency = <100000>; status = "okay"; };
@@ -84,19 +78,3 @@ &usdhc3 { status = "okay"; }; - -&iomuxc { - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 0e50bb0a6b94..aa2275671d2c 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -162,6 +162,18 @@ }; };
+&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -235,6 +247,20 @@ >; };
+ pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 100 ++++++++++++++++++++++++++- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 15 ++++ 2 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index f1bdcae5b97d..668714052103 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -9,10 +9,73 @@ * http://www.gnu.org/copyleft/gpl.html */
+#include <dt-bindings/sound/fsl-imx-audmux.h> + / { chosen { linux,stdout-path = &uart4; }; + + regulators { + sound_1v8: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "i2s-audio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + sound_3v3: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "i2s-audio-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + + tlv320_mclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "tlv320-mclk"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6-phyflex-tlv320aic3007"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Speaker", "Speaker", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&tlv320_mclk>; + }; + }; + };
&fec { @@ -27,12 +90,45 @@ status = "okay"; };
+&ssi2 { + status = "okay"; +}; + +&audmux { + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(4) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(4)) + IMX_AUDMUX_V2_PDCR_RXDSEL(4) + >; + }; + pins5 { + fsl,audmux-port = <4>; + fsl,port-config = < + 0x00000000 + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + &i2c2 { status = "okay";
- tlv320@18 { - compatible = "ti,tlv320aic3x"; + codec: tlv320@18 { + compatible = "ti,tlv320aic3007"; + #sound-dai-cells = <0>; reg = <0x18>; + ai3x-micbias-vg = <2>; + + AVDD-supply = <&sound_3v3>; + IOVDD-supply = <&sound_3v3>; + DRVDD-supply = <&sound_3v3>; + DVDD-supply = <&sound_1v8>; };
stmpe@41 { diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index aa2275671d2c..d7f34664e008 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -58,6 +58,12 @@ }; };
+&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "disabled"; +}; + &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; @@ -319,6 +325,15 @@ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 >; }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 + >; + }; }; };
Used on Phytec PBAB01 board.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 8fca6e276b69..cac07d67b933 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -210,6 +210,7 @@ CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y
Current caching implementation during regcache_sync() call bypasses all register writes of values that are already known as default (regmap reg_defaults). Same time in TLV320AIC3x codecs register 5 (AIC3X_PLL_PROGC_REG) write should be immediately followed by register 6 write (AIC3X_PLL_PROGD_REG) even if it was not changed. Otherwise both registers will not be written.
This brings to issue that appears particulary in case of 44.1kHz playback with 19.2MHz master clock. In this case AIC3X_PLL_PROGC_REG is 0x6e while AIC3X_PLL_PROGD_REG is 0x0 (same as register default). Thus AIC3X_PLL_PROGC_REG also remains not written and we get wrong playback speed.
In this patch snd_soc_read() is used to get cached pll values and snd_soc_write() (unlike regcache_sync() this function doesn't bypasses hardware default values) to write them to registers.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- sound/soc/codecs/tlv320aic3x.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 64f179ee9834..5e8626ae612b 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1121,6 +1121,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, static int aic3x_set_power(struct snd_soc_codec *codec, int power) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + unsigned int pll_c, pll_d; int ret;
if (power) { @@ -1138,6 +1139,18 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) /* Sync reg_cache with the hardware */ regcache_cache_only(aic3x->regmap, false); regcache_sync(aic3x->regmap); + + /* Rewrite paired PLL D registers in case cached sync skipped + * writing one of them and thus caused other one also not + * being written + */ + pll_c = snd_soc_read(codec, AIC3X_PLL_PROGC_REG); + pll_d = snd_soc_read(codec, AIC3X_PLL_PROGD_REG); + if (pll_c == aic3x_reg[AIC3X_PLL_PROGC_REG].def || + pll_d == aic3x_reg[AIC3X_PLL_PROGD_REG].def) { + snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c); + snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d); + } } else { /* * Do soft reset to this codec instance in order to clear
On Fri, Oct 03, 2014 at 04:18:56PM +0300, Dmitry Lavnikevich wrote:
Current caching implementation during regcache_sync() call bypasses all register writes of values that are already known as default (regmap reg_defaults). Same time in TLV320AIC3x codecs register 5
Applied, thanks. This should really have been sent separately to the other patches - it's not in any way specific to the board and there's no dependency in either direction.
Patch fixing PLL D configuration (number 4 in previous patchset) was already accepted by Mark Brown. No notes or comments on other patches was made so resending them in case they were lost.
Based on branch for-next branch of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
Since pins and frequency are specific to module (pfla02), not base board (pbab02), it is better to be initialized in corresponding dts file.
This patch fixes i2c2, i2c3 pin configuration which caused messages:
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c2grp imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-bus@02000000/iomuxc@020e0000/i2c3grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c2grp imx6q-pinctrl 20e0000.iomuxc: unable to find group for node i2c3grp
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 22 ---------------------- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 22 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index 584721264121..f1bdcae5b97d 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -28,9 +28,6 @@ };
&i2c2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - clock-frequency = <100000>; status = "okay";
tlv320@18 { @@ -55,9 +52,6 @@ };
&i2c3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c3>; - clock-frequency = <100000>; status = "okay"; };
@@ -84,19 +78,3 @@ &usdhc3 { status = "okay"; }; - -&iomuxc { - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 - >; - }; - - pinctrl_i2c3: i2c3grp { - fsl,pins = < - MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 - MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 - >; - }; -}; diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 0e50bb0a6b94..aa2275671d2c 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -162,6 +162,18 @@ }; };
+&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + clock-frequency = <100000>; +}; + +&i2c3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + clock-frequency = <100000>; +}; + &iomuxc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_hog>; @@ -235,6 +247,20 @@ >; };
+ pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D16__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX6QDL_PAD_EIM_D17__I2C3_SCL 0x4001b8b1 + MX6QDL_PAD_EIM_D18__I2C3_SDA 0x4001b8b1 + >; + }; + pinctrl_uart3: uart3grp { fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
Used on Phytec PBAB01 board.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 8fca6e276b69..cac07d67b933 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -210,6 +210,7 @@ CONFIG_SND_SOC_IMX_WM8962=y CONFIG_SND_SOC_IMX_SGTL5000=y CONFIG_SND_SOC_IMX_SPDIF=y CONFIG_SND_SOC_IMX_MC13783=y +CONFIG_SND_SOC_TLV320AIC3X=y CONFIG_SND_SIMPLE_CARD=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI interface.
Signed-off-by: Dmitry Lavnikevich d.lavnikevich@sam-solutions.com --- arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi | 100 ++++++++++++++++++++++++++- arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi | 15 ++++ 2 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi index f1bdcae5b97d..668714052103 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi @@ -9,10 +9,73 @@ * http://www.gnu.org/copyleft/gpl.html */
+#include <dt-bindings/sound/fsl-imx-audmux.h> + / { chosen { linux,stdout-path = &uart4; }; + + regulators { + sound_1v8: regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "i2s-audio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + sound_3v3: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "i2s-audio-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + + tlv320_mclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <19200000>; + clock-output-names = "tlv320-mclk"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "imx6-phyflex-tlv320aic3007"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Line", "Line In", + "Line", "Line Out", + "Speaker", "Speaker", + "Headphone", "Headphone Jack"; + simple-audio-card,routing = + "Line Out", "LLOUT", + "Line Out", "RLOUT", + "Speaker", "SPOP", + "Speaker", "SPOM", + "Headphone Jack", "HPLOUT", + "Headphone Jack", "HPROUT", + "MIC3L", "Mic Jack", + "MIC3R", "Mic Jack", + "Mic Jack", "Mic Bias", + "LINE1L", "Line In", + "LINE1R", "Line In"; + + simple-audio-card,cpu { + sound-dai = <&ssi2>; + }; + + dailink_master: simple-audio-card,codec { + sound-dai = <&codec>; + clocks = <&tlv320_mclk>; + }; + }; + };
&fec { @@ -27,12 +90,45 @@ status = "okay"; };
+&ssi2 { + status = "okay"; +}; + +&audmux { + status = "okay"; + + ssi2 { + fsl,audmux-port = <1>; + fsl,port-config = < + (IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TFSEL(4) | + IMX_AUDMUX_V2_PTCR_TCLKDIR | + IMX_AUDMUX_V2_PTCR_TCSEL(4)) + IMX_AUDMUX_V2_PDCR_RXDSEL(4) + >; + }; + pins5 { + fsl,audmux-port = <4>; + fsl,port-config = < + 0x00000000 + IMX_AUDMUX_V2_PDCR_RXDSEL(1) + >; + }; +}; + &i2c2 { status = "okay";
- tlv320@18 { - compatible = "ti,tlv320aic3x"; + codec: tlv320@18 { + compatible = "ti,tlv320aic3007"; + #sound-dai-cells = <0>; reg = <0x18>; + ai3x-micbias-vg = <2>; + + AVDD-supply = <&sound_3v3>; + IOVDD-supply = <&sound_3v3>; + DRVDD-supply = <&sound_3v3>; + DVDD-supply = <&sound_1v8>; };
stmpe@41 { diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index aa2275671d2c..d7f34664e008 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -58,6 +58,12 @@ }; };
+&audmux { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_audmux>; + status = "disabled"; +}; + &ecspi3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi3>; @@ -319,6 +325,15 @@ MX6QDL_PAD_ENET_TXD1__GPIO1_IO29 0x80000000 >; }; + + pinctrl_audmux: audmuxgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT16__AUD5_TXC 0x130b0 + MX6QDL_PAD_DISP0_DAT18__AUD5_TXFS 0x130b0 + MX6QDL_PAD_DISP0_DAT17__AUD5_TXD 0x110b0 + MX6QDL_PAD_DISP0_DAT19__AUD5_RXD 0x130b0 + >; + }; }; };
participants (10)
-
Alexander Shiyan
-
Dmitry Lavnikevich
-
Dmitry Lavnikevich
-
Fabio Estevam
-
Lothar Waßmann
-
Mark Brown
-
Markus Pargmann
-
Nicolin Chen
-
Philipp Zabel
-
Shawn Guo