TLV320AIC31xx recovery after a SPKVDD power glitch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have a production agriculture display system using a TLV320AIC3120
for sound output to a speaker built into the monitor. The primary
processor is an NXP IMX6 Dual Plus. The system has an internal battery
backup but not all voltage rails are backed by the battery.  In
particular SPKVDD the 5V rail to the TLV320AIC3120 is not backed up.
The rest of the voltage rails to this device are backed by battery.
After a power glitch we do not emit sound.  Using dynamic debug and
adding some additional messages to the log It appears the driver is
working the same both before and after the power glitch.
We developed this a few years ago using the Freescale/NXP (fsl)
eureka-tlv320 (with slight modifications for the tlv320aic31xx) and
tlv320aic31xx.c drivers.

As an experiment i compiled both the eukrea-tlv320 and the
tlv320aic31xx drivers as modules.  This worked as expected before the
glitch.  After a glitch if I manually remove the modules and re-insert
them sound can be restored.

We have a user space application that can detect the power loss and if
the loss is persistent will gracefully shutdown the system.  When
power is restored we would like to use this to tell the driver to
perform some kind of restorative action.  I have tried triggering
through sysfs various resets to the tlv320aic3120 without success.  So
far only a full module remove of both eukrea and tlv320 will restore
sound.  remove and re-insert of either driver by itself does not work.

I have a few questions and areas where I would like advice.

0) What am i missing or doing wrong?  Should I be taking a different
approach altogether to this problem?

1) Should I migrate to simple-audio-card instead of eukrea-tlv320?

2) Suggestions on what needs to be reset/restored after the power rail
comes back?

3) Suggestions on how best to trigger the reset/restore from either
user space or the kernel?

Below is the relevant sections of our devicetree.


        sound {
                compatible = "eukrea,asoc-tlv320";
                eukrea,model = "pp-gen3display-tlv320aic3120";
                ssi-controller = <&ssi2>;
                fsl,mux-int-port = <2>;
                fsl,mux-ext-port = <3>;

                clocks = <&clks IMX6QDL_CLK_CKO>;
        };

&i2c1 {
        clock-frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";

        tlv320aic3120: tlv320aic3120@18 {
            reg = <0x18>;
        };
...

&ssi2 {
        codec-handle = <&tlv320aic3120>;
        status = "okay";
};
&audmux {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_audmux>;
        status = "okay";
};
                pinctrl_audmux: audmuxgrp {
                        fsl,pins = <
                                MX6QDL_PAD_CSI0_DAT7__AUD3_RXD          0x130b0
                                MX6QDL_PAD_CSI0_DAT4__AUD3_TXC          0x130b0
                                MX6QDL_PAD_CSI0_DAT5__AUD3_TXD          0x110b0
                                MX6QDL_PAD_CSI0_DAT6__AUD3_TXFS         0x130b0
                                MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x17059
                                MX6QDL_PAD_CSI0_MCLK__CCM_CLKO1         0x130b0
                        >;
                };


Attached is our changes to the eukrea driver to support the
TLV320AIC31xx in our system.


Thank you,


Dexter Travis

Attachment: Screenshot_2020-04-24_12-35-46.png
Description: PNG image

From d68f0e9a8903667d19b9785d53095051071efccb Mon Sep 17 00:00:00 2001
From: Ryan Allgaier <ryan.allgaier@xxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 16 Jan 2017 11:15:19 -0600
Subject: [PATCH] Ongoing changes to support sound cherry-picked from 4.1

---
 arch/arm/boot/dts/imx6q-pinfunc.h |  0
 sound/soc/fsl/eukrea-tlv320.c     | 26 +++++++++++++++++---------
 2 files changed, 17 insertions(+), 9 deletions(-)
 mode change 100644 => 100755 arch/arm/boot/dts/imx6q-pinfunc.h
 mode change 100644 => 100755 sound/soc/fsl/eukrea-tlv320.c

diff --git a/arch/arm/boot/dts/imx6q-pinfunc.h b/arch/arm/boot/dts/imx6q-pinfunc.h
old mode 100644
new mode 100755
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
old mode 100644
new mode 100755
index 84ef6385736c..64f139a04340
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -22,17 +22,19 @@
 #include <linux/of_platform.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
+#include <linux/clk.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <asm/mach-types.h>
 
 #include "../codecs/tlv320aic23.h"
+#include "../codecs/tlv320aic31xx.h"
 #include "imx-ssi.h"
 #include "fsl_ssi.h"
 #include "imx-audmux.h"
 
-#define CODEC_CLOCK 12000000
+#define CODEC_CLOCK 24000000
 
 static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params)
@@ -43,7 +45,7 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
 	int ret;
 
 	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
-				     CODEC_CLOCK, SND_SOC_CLOCK_OUT);
+				     CODEC_CLOCK, SND_SOC_CLOCK_IN);
 	if (ret) {
 		dev_err(cpu_dai->dev,
 			"Failed to set the codec sysclk.\n");
@@ -69,9 +71,9 @@ static const struct snd_soc_ops eukrea_tlv320_snd_ops = {
 };
 
 static struct snd_soc_dai_link eukrea_tlv320_dai = {
-	.name		= "tlv320aic23",
-	.stream_name	= "TLV320AIC23",
-	.codec_dai_name	= "tlv320aic23-hifi",
+	.name		= "tlv320aic31xx",
+	.stream_name	= "TLV320AIC31XX",
+	.codec_dai_name	= "tlv320aic31xx-hifi",
 	.dai_fmt	= SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 			  SND_SOC_DAIFMT_CBM_CFM,
 	.ops		= &eukrea_tlv320_snd_ops,
@@ -89,6 +91,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 	int int_port = 0, ext_port;
 	struct device_node *np = pdev->dev.of_node;
 	struct device_node *ssi_np = NULL, *codec_np = NULL;
+	struct clk *codec_clk = NULL;
 
 	eukrea_tlv320.dev = &pdev->dev;
 	if (np) {
@@ -140,7 +143,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 	} else {
 		eukrea_tlv320_dai.cpu_dai_name = "imx-ssi.0";
 		eukrea_tlv320_dai.platform_name = "imx-ssi.0";
-		eukrea_tlv320_dai.codec_name = "tlv320aic23-codec.0-001a";
+		eukrea_tlv320_dai.codec_name = "tlv320aic31xx-codec.0-0018";
 		eukrea_tlv320.name = "cpuimx-audio";
 	}
 
@@ -164,9 +167,6 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 		   machine_is_eukrea_cpuimx35sd() ||
 		   machine_is_eukrea_cpuimx51sd() ||
 		   of_find_compatible_node(NULL, NULL, "fsl,imx31-audmux")) {
-		if (!np)
-			ext_port = machine_is_eukrea_cpuimx25sd() ?
-				4 : 3;
 
 		imx_audmux_v2_configure_port(int_port,
 			IMX_AUDMUX_V2_PTCR_SYN |
@@ -196,6 +196,14 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
 		}
 	}
 
+	codec_clk = clk_get(eukrea_tlv320.dev, NULL);
+	if (IS_ERR(codec_clk)) {
+		dev_err(eukrea_tlv320.dev,
+			"codec clock missing or invalid\n");
+	} else {
+		clk_prepare_enable(codec_clk);
+	}
+
 	ret = snd_soc_register_card(&eukrea_tlv320);
 err:
 	if (ret)
-- 
2.24.1


[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux