We have an ADAU1361 audio codec connected to I2S2 on the Xavier 40 pin expansion header and I am having trouble getting AUD_MCLK to start up on playback. Our codec works fine on the TX2 using a fixed crystal oscillator, but we decided to try and use AUD_MCLK when we ported our hardware to the Xavier.
I followed the “AUD_MCLK for Codec SYSCLK” section of the developer guide and added the following lines to my dtsi to configure AUD_MCLK for 19.2 MHz:
i2c@31e0000 {
adau1361_codec: adau1361@38 {
compatible = "nova,adau1361";
reg = <0x38>;
clocks = <&bpmp_clks TEGRA194_CLK_AUD_MCLK>;
clock-names = "mclk";
};
};
i2s@2901000 {
status = "okay";
};
sound {
assigned-clocks = <&bpmp_clks TEGRA194_CLK_PLLA_OUT0>, <&bpmp_clks TEGRA194_CLK_AUD_MCLK>;
assigned-clock-parents = <&bpmp_clks TEGRA194_CLK_PLLA>, <&bpmp_clks TEGRA194_CLK_CLK_M>;
assigned-clock-rates = <0>, <19200000>;
nvidia,audio-routing =
"m Headphone", "m LOUT",
"m Headphone", "m ROUT",
"m Mic", "m MICBIAS",
"m LINP", "m Mic",
"m LINN", "m Mic",
"m RINP", "m Mic",
"m RINN", "m Mic";
nvidia,dai-link-2 {
link-name = "adau1361-codec";
cpu-dai = <&tegra_i2s2>;
codec-dai = <&adau1361_codec>;
cpu-dai-name = "I2S2";
codec-dai-name = "adau-hifi";
format = "i2s";
bitclock-slave;
frame-slave;
bitclock-noninversion;
frame-noninversion;
bit-format = "s32_le";
bclk_ratio = <1>;
srate = <48000>;
num-channel = <2>;
ignore_suspend;
name-prefix = "m";
status = "okay";
};
};
Next I followed the “Update the Machine Driver to Support a Custom Audio Card” section of the guide to modify tegra_machine_driver_mobile.c
diff --git a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
index fbca4699d..a9bd7d584 100644
--- a/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
+++ b/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
@@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+ #define DEBUG 1
+
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_platform.h>
@@ -431,6 +433,16 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
dai_params->formats = formats;
}
+ rtd = snd_soc_get_pcm_runtime(card, "adau1361-codec");
+ if (rtd) {
+ dai_params =
+ (struct snd_soc_pcm_stream *)rtd->dai_link->params;
+
+ dai_params->rate_min = srate;
+ dai_params->channels_min = channels;
+ dai_params->formats = formats;
+ }
+
return 0;
}
@@ -594,6 +606,27 @@ static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int tegra_machine_adau136x_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_pcm_stream *dai_params =
+ (struct snd_soc_pcm_stream *)rtd->dai_link->params;
+ int err = 0;
+
+ dev_info(card->dev, "%s: setting sysclk to %u\n",
+ __func__, dai_params->rate_min);
+
+ err = snd_soc_dai_set_sysclk(
+ rtd->codec_dai, 0, dai_params->rate_min, SND_SOC_CLOCK_IN);
+
+ if (err) {
+ dev_err(card->dev, "%s: failed to set dai sysclk!\n", __func__);
+ return err;
+ }
+
+ return 0;
+}
+
static int codec_init(struct tegra_machine *machine)
{
struct snd_soc_dai_link *dai_links = machine->asoc->dai_links;
@@ -611,6 +644,8 @@ static int codec_init(struct tegra_machine *machine)
dai_links[i].init = tegra_machine_rt565x_init;
else if (strstr(dai_links[i].name, "fe-pi-audio-z-v2"))
dai_links[i].init = tegra_machine_fepi_init;
+ else if (strstr(dai_links[i].name, "adau1361-codec"))
+ dai_links[i].init = tegra_machine_adau136x_init;
}
return 0;
I also confirmed that my codec was probing properly:
[ 5.689483] adau1761 8-0038: adau1761_i2c_probe
[ 5.689696] adau1761 8-0038: adau1761_i2c_probe success
[ 5.915406] tegra-asoc: sound: tegra_machine_adau136x_init: setting sysclk to 48000
There is data on my I2S lines but nothing from aud_mclk. The only error I could find in dmesg was the following:
[ 3.983514] tegra-asoc: sound: ASoC: CODEC DAI adau-hifi not registered
[ 3.983697] tegra-asoc: sound: snd_soc_register_card failed (-517)
I also noticed that aud_mclk is only reporting 9600000 (exactly half of my assigned rate).
$ sudo cat /sys/kernel/debug/clk/aud_mclk/clk_rate
9600000
How do I get AUD_MCLK to activate at 19.2 MHz when I initiate playback using my audio codec on I2S2?