Discussion:
[PATCH 2/5] ASoC: fsl: add imx-tlv320aic3x machine driver
Dmitry Lavnikevich
2014-09-10 13:46:46 UTC
Permalink
This is driver for i.MX6 boards with tlv320aic3x audio codecs.

Signed-off-by: Dmitry 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 <***@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");
--
2.1.0
Dmitry Lavnikevich
2014-09-10 13:46:45 UTC
Permalink
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 <***@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";

***@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
--
2.1.0
Philipp Zabel
2014-09-11 08:47:18 UTC
Permalink
Post by 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.
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

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-09-12 15:55:46 UTC
Permalink
Post by Philipp Zabel
Post by 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.
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-***@02000000/***@020e0000/i2c2grp
imx6q-pinctrl 20e0000.iomuxc: no groups defined in
/soc/aips-***@02000000/***@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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-09-10 13:46:47 UTC
Permalink
Signed-off-by: Dmitry 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
--
2.1.0
Dmitry Lavnikevich
2014-09-10 13:46:48 UTC
Permalink
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected over SSI
interface.

Signed-off-by: Dmitry 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: ***@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+ sound_3v3: ***@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";

- ***@18 {
- compatible = "ti,tlv320aic3x";
+ codec: ***@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>;
};

***@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
+ >;
+ };
};
};
--
2.1.0
Dmitry Lavnikevich
2014-09-10 13:46:49 UTC
Permalink
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 <***@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
--
2.1.0
Lothar Waßmann
2014-09-10 14:19:22 UTC
Permalink
Hi,
Post by Dmitry Lavnikevich
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.
+
+- 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?
Post by Dmitry Lavnikevich
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,
+ *
+ * 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.
Post by Dmitry Lavnikevich
+/* 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 ...
Post by Dmitry Lavnikevich
+
+/* Logic for a aic3x as connected on a imx */
s/ a / an /g
Post by Dmitry Lavnikevich
+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
--
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Geschäftsführer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | ***@karo-electronics.de
___________________________________________________________
Markus Pargmann
2014-09-10 14:27:40 UTC
Permalink
Hi,
Post by Dmitry Lavnikevich
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
---
.../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
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Nicolin Chen
2014-09-10 18:14:15 UTC
Permalink
Post by Markus Pargmann
Hi,
Post by Dmitry Lavnikevich
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
---
.../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.
Markus Pargmann
2014-09-11 06:40:16 UTC
Permalink
Post by Nicolin Chen
Post by Markus Pargmann
Hi,
Post by Dmitry Lavnikevich
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
---
.../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
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
Dmitry Lavnikevich
2014-09-11 12:41:56 UTC
Permalink
Hi,
Post by Markus Pargmann
Post by Nicolin Chen
Post by Markus Pargmann
Hi,
Post by Dmitry Lavnikevich
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
---
.../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
Nicolin Chen
2014-09-10 18:07:36 UTC
Permalink
Hi Dmitry,
Post by Dmitry Lavnikevich
This is driver for i.MX6 boards with tlv320aic3x audio codecs.
---
.../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
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-09-12 16:04:30 UTC
Permalink
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.

Signed-off-by: Dmitry 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: ***@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ sound_3v3: ***@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";

- ***@18 {
- compatible = "ti,tlv320aic3x";
+ codec: ***@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>;
};

***@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
+ >;
+ };
};
};
--
2.1.0
Alexander Shiyan
2014-09-12 16:14:46 UTC
Permalink
Post by Dmitry Lavnikevich
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.
---
...
Post by Dmitry Lavnikevich
+&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.

---
Dmitry Lavnikevich
2014-09-15 12:04:50 UTC
Permalink
Fri, 12 Sep 2014 19:04:30 +0300 =D0=BE=D1=82 Dmitry Lavnikevich <d.la=
Post by Dmitry Lavnikevich
+&audmux {
+ status =3D "okay";
+
+ ssi2 {
+ fsl,audmux-port =3D <1>;
+ fsl,port-config =3D <0xa5000000 0x00008000>;
+ };
+ pins5 {
+ fsl,audmux-port =3D <4>;
+ fsl,port-config =3D <0x00000000 0x00002000>;
+ };
+};
You should use defines from sound/fsl-imx-audmux.h for audmux.
Ok, will change it in next patchset version.
Alexander Shiyan
2014-09-12 16:26:01 UTC
Permalink
Post by Dmitry Lavnikevich
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.
---
...
Post by Dmitry Lavnikevich
+&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 po
Fabio Estevam
2014-09-12 16:40:02 UTC
Permalink
Fri, 12 Sep 2014 19:04:30 +0300 =D0=BE=D1=82 Dmitry Lavnikevich <d.la=
Audio on phyFLEX boards is presented by tlv320aic3007 codec connecte=
d
over SSI interface.
---
...
+&ssi2 {
+ fsl,mode =3D "i2s-slave";
+ status =3D "okay";
+ #sound-dai-cells =3D <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=3Dfor-next&id=3D36c7e8826cf32dd4dd34c71b526653b800414355
Dmitry Lavnikevich
2014-09-15 12:07:02 UTC
Permalink
Fri, 12 Sep 2014 19:04:30 +0300 =D0=BE=D1=82 Dmitry Lavnikevich <d.l=
Audio on phyFLEX boards is presented by tlv320aic3007 codec connect=
ed
over SSI interface.
---
...
+&ssi2 {
+ fsl,mode =3D "i2s-slave";
+ status =3D "okay";
+ #sound-dai-cells =3D <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/commi=
t/?h=3Dfor-next&id=3D36c7e8826cf32dd4dd34c71b526653b800414355
So should I base my next patchset on for-next branch of
git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
?
Shawn Guo
2014-09-16 01:46:58 UTC
Permalink
Post by Dmitry Lavnikevich
Fri, 12 Sep 2014 19:04:30 +0300 =D0=BE=D1=82 Dmitry Lavnikevich <d.=
Audio on phyFLEX boards is presented by tlv320aic3007 codec connec=
ted
Post by Dmitry Lavnikevich
over SSI interface.
---
...
+&ssi2 {
+ fsl,mode =3D "i2s-slave";
+ status =3D "okay";
+ #sound-dai-cells =3D <0>;
+};
I have already sent patch to add "#sound-dai-cells" into all i.MX D=
T-files.
Post by Dmitry Lavnikevich
Shawn, can you point us to this tree/commit?
https://git.kernel.org/cgit/linux/kernel/git/shawnguo/linux.git/comm=
it/?h=3Dfor-next&id=3D36c7e8826cf32dd4dd34c71b526653b800414355
Post by Dmitry Lavnikevich
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
Dmitry Lavnikevich
2014-09-12 16:04:29 UTC
Permalink
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-***@02000000/***@020e0000/i2c2grp
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-***@02000000/***@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 <***@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";

***@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
--
2.1.0
Dmitry Lavnikevich
2014-09-12 16:04:32 UTC
Permalink
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 <***@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
--
2.1.0
Dmitry Lavnikevich
2014-09-12 16:04:28 UTC
Permalink
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.
Dmitry Lavnikevich
2014-09-12 16:04:31 UTC
Permalink
Used on Phytec PBAB01 board.

Signed-off-by: Dmitry 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
--
2.1.0
Dmitry Lavnikevich
2014-09-16 08:08:19 UTC
Permalink
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.
Dmitry Lavnikevich
2014-09-16 08:08:21 UTC
Permalink
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.

Signed-off-by: Dmitry 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: ***@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ sound_3v3: ***@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";

- ***@18 {
- compatible = "ti,tlv320aic3x";
+ codec: ***@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>;
};

***@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
+ >;
+ };
};
};
--
2.1.0
Fabio Estevam
2014-10-01 12:11:13 UTC
Permalink
On Tue, Sep 16, 2014 at 5:08 AM, Dmitry Lavnikevich
+ regulators {
+ 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'
+&ssi2 {
+ fsl,mode = "i2s-slave";
Please remove this 'fsl,mode' property. It is ignored by the fsl_ssi driver.
Dmitry Lavnikevich
2014-10-01 13:40:17 UTC
Permalink
Post by Fabio Estevam
On Tue, Sep 16, 2014 at 5:08 AM, Dmitry Lavnikevich
+ regulators {
...
Post by Fabio Estevam
+ };
+
@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)
Post by Fabio Estevam
+ 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'
...
Post by Fabio Estevam
+ 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.
Post by Fabio Estevam
+&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.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Fabio Estevam
2014-10-01 13:45:48 UTC
Permalink
On Wed, Oct 1, 2014 at 10:40 AM, Dmitry Lavnikevich
Post by Dmitry Lavnikevich
Post by Fabio Estevam
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'.
Post by Dmitry Lavnikevich
Post by Fabio Estevam
Post by Dmitry Lavnikevich
+&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=topic/fsl-ssi&id=b93427b1c057841602e0fe2005153a6e82f2e658
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-10-01 13:52:29 UTC
Permalink
Post by Fabio Estevam
On Wed, Oct 1, 2014 at 10:40 AM, Dmitry Lavnikevich
Post by Dmitry Lavnikevich
Post by Fabio Estevam
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.
Dmitry Lavnikevich
2014-09-16 08:08:22 UTC
Permalink
Used on Phytec PBAB01 board.

Signed-off-by: Dmitry 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
--
2.1.0
Dmitry Lavnikevich
2014-09-16 08:08:20 UTC
Permalink
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-***@02000000/***@020e0000/i2c2grp
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-***@02000000/***@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 <***@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";

***@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
--
2.1.0
Dmitry Lavnikevich
2014-09-16 08:09:24 UTC
Permalink
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 <***@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
--
2.1.0
Dmitry Lavnikevich
2014-10-03 13:18:54 UTC
Permalink
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.

Signed-off-by: Dmitry Lavnikevich <d.lavnikevich-H6HfJ9slvY0Aspv4Qr0y0gC/***@public.gmane.org>
---
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: ***@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ sound_3v3: ***@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";

- ***@18 {
- compatible = "ti,tlv320aic3x";
+ codec: ***@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>;
};

***@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
+ >;
+ };
};
};
--
2.1.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-10-03 13:18:53 UTC
Permalink
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-***@02000000/***@020e0000/i2c2grp
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-***@02000000/***@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 <***@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";

***@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
--
2.1.1
Dmitry Lavnikevich
2014-10-03 13:18:52 UTC
Permalink
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
Dmitry Lavnikevich
2014-10-03 13:18:55 UTC
Permalink
Used on Phytec PBAB01 board.

Signed-off-by: Dmitry Lavnikevich <d.lavnikevich-H6HfJ9slvY0Aspv4Qr0y0gC/***@public.gmane.org>
---
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
--
2.1.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-10-03 13:18:56 UTC
Permalink
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 <***@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
--
2.1.1
Mark Brown
2014-10-03 15:08:07 UTC
Permalink
Post by Dmitry Lavnikevich
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.
Dmitry Lavnikevich
2014-10-22 09:08:31 UTC
Permalink
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
Dmitry Lavnikevich
2014-10-22 09:08:32 UTC
Permalink
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-***@02000000/***@020e0000/i2c2grp
imx6q-pinctrl 20e0000.iomuxc: no groups defined in /soc/aips-***@02000000/***@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-H6HfJ9slvY0Aspv4Qr0y0gC/***@public.gmane.org>
---
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";

***@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
--
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Dmitry Lavnikevich
2014-10-22 09:11:17 UTC
Permalink
Used on Phytec PBAB01 board.

Signed-off-by: Dmitry 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
--
2.1.2
Dmitry Lavnikevich
2014-10-22 09:12:27 UTC
Permalink
Audio on phyFLEX boards is presented by tlv320aic3007 codec connected
over SSI interface.

Signed-off-by: Dmitry Lavnikevich <d.lavnikevich-H6HfJ9slvY0Aspv4Qr0y0gC/***@public.gmane.org>
---
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: ***@2 {
+ compatible = "regulator-fixed";
+ reg = <2>;
+ regulator-name = "i2s-audio-1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ sound_3v3: ***@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";

- ***@18 {
- compatible = "ti,tlv320aic3x";
+ codec: ***@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>;
};

***@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
+ >;
+ };
};
};
--
2.1.2

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...