Hi,
I’m porting rt5639 on TX2 R32.1.
Please see the change I did as the following.
diff --git a/sources/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts b/sources/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
index 015793e..d7a998f 100644
--- a/sources/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
+++ b/sources/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-a00-00-base.dts
@@ -366,6 +366,15 @@
i2c@c240000 {
clock-frequency = <400000>;
+// added by Yen for rt5639 audio codec
+ pcptx2_rt5639: rt5639.1-001c@1c {
+ status = "okay";
+ compatible = "realtek,rt5640";
+ reg = <0x1c>;
+ realtek,ldo1-en-gpios = <&tegra_main_gpio TEGRA_MAIN_GPIO(J, 6) GPIO_ACTIVE_HIGH>;
+ sel_jd_source = <3>;
+ };
+////
};
cpus {
@@ -442,6 +451,148 @@
};
////
+// added by Yen for rt5639 audio codec
+ tegra_sound: sound {
+ compatible = "nvidia,tegra-audio-t186ref-mobile-rt5639/40";
+ nvidia,model = "tegra-snd-t186ref-mobile-rt5639_40";
+ realtek,in1-differential = <1>;
+ sel_jd_source = <3>;
+ nvidia,num-codec-link = <5>;
+ nvidia,num-clk = <8>;
+ nvidia,hp-det-gpios = <&tegra_main_gpio TEGRA_MAIN_GPIO(J, 5) GPIO_ACTIVE_HIGH>;
+ nvidia,clk-rates = < 270950400 /* PLLA_x11025_RATE */
+ 11289600 /* AUD_MCLK_x11025_RATE */
+ 45158400 /* PLLA_OUT0_x11025_RATE */
+ 45158400 /* AHUB_x11025_RATE */
+ 245760000 /* PLLA_x8000_RATE */
+ 12288000 /* AUD_MCLK_x8000_RATE */
+ 49152000 /* PLLA_OUT0_x8000_RATE */
+ 49152000 >;/* AHUB_x8000_RATE */
+ clocks = <&tegra_car TEGRA186_CLK_PLLP_OUT0>,
+ <&tegra_car TEGRA186_CLK_PLLA>,
+ <&tegra_car TEGRA186_CLK_PLL_A_OUT0>,
+ <&tegra_car TEGRA186_CLK_AHUB>,
+ <&tegra_car TEGRA186_CLK_CLK_M>,
+ <&tegra_car TEGRA186_CLK_AUD_MCLK>;
+ clock-names = "pll_p_out1", "pll_a", "pll_a_out0", "ahub",
+ "clk_m", "extern1";
+ resets = <&tegra_car TEGRA186_RESET_AUD_MCLK>;
+ reset-names = "extern1_rst";
+
+ status = "okay";
+ nvidia,audio-routing =
+ "x Headphone Jack", "x HP L Playback",
+ "x Headphone Jack", "x HP R Playback",
+ "x Int Spk", "x SPORP",
+ "x Int Spk", "x SPORN",
+ "x Int Spk", "x SPOLP",
+ "x Int Spk", "x SPOLN",
+ "x IN2P", "x Mic Jack",
+ "x IN2P", "x Mic Jack",
+ "x DMIC L1", "x Int Mic",
+ "x DMIC L2", "x Int Mic",
+ "x DMIC R1", "x Int Mic",
+ "x DMIC R2", "x Int Mic",
+ "y Headphone", "y OUT",
+ "y IN", "y Mic",
+ "z Headphone", "z OUT",
+ "z IN", "z Mic";
+
+ nvidia,xbar = <&tegra_axbar>;
+
+ rt5640_dai_link: nvidia,dai-link-1 {
+ link-name = "rt5640-playback";
+ cpu-dai = <&tegra_i2s1>;
+ codec-dai = <&pcptx2_rt5639>;
+ /* codec-dai = <&spdif_dit0>; */
+ cpu-dai-name = "I2S1";
+ codec-dai-name = "rt5640-aif1";
+ /* codec-dai-name = "dit-hifi"; */
+ format = "i2s";
+ bitclock-slave;
+ frame-slave;
+ bitclock-noninversion;
+ frame-noninversion;
+ bit-format = "s16_le";
+ bclk_ratio = <0>;
+ srate = <48000>;
+ num-channel = <2>;
+ ignore_suspend;
+ name-prefix = "x";
+ status = "okay";
+ };
+
+ nvidia,dai-link-2 {
+ link-name = "spdif-dit-1";
+ cpu-dai = <&tegra_i2s2>;
+ codec-dai = <&spdif_dit1>;
+ cpu-dai-name = "I2S2";
+ codec-dai-name = "dit-hifi";
+ format = "dsp_a";
+ bitclock-slave;
+ frame-slave;
+ bitclock-inversion;
+ frame-inversion;
+ bit-format = "s16_le";
+ bclk_ratio = <4>;
+ srate = <8000>;
+ num-channel = <1>;
+ ignore_suspend;
+ name-prefix = "y";
+ status = "okay";
+ };
+
+ nvidia,dai-link-3 {
+ link-name = "spdif-dit-2";
+ cpu-dai = <&tegra_i2s3>;
+ codec-dai = <&spdif_dit2>;
+ cpu-dai-name = "I2S3";
+ codec-dai-name = "dit-hifi";
+ format = "i2s";
+ bitclock-slave;
+ frame-slave;
+ bitclock-noninversion;
+ frame-noninversion;
+ bit-format = "s16_le";
+ bclk_ratio = <1>;
+ srate = <48000>;
+ num-channel = <2>;
+ ignore_suspend;
+ name-prefix = "z";
+ status = "okay";
+ };
+
+ dspk_dai_link_1: nvidia,dai-link-4 {
+ link-name = "dspk-playback-r";
+ cpu-dai = <&tegra_dspk1>;
+ codec-dai = <&spdif_dit3>;
+ cpu-dai-name = "DSPK1";
+ codec-dai-name = "dit-hifi";
+ format = "i2s";
+ bit-format = "s16_le";
+ srate = <48000>;
+ num-channel = <2>;
+ ignore_suspend;
+ name-prefix = "d1";
+ status = "okay";
+ };
+ dspk_dai_link_2: nvidia,dai-link-5 {
+ link-name = "dspk-playback-l";
+ cpu-dai = <&tegra_dspk2>;
+ codec-dai = <&spdif_dit4>;
+ cpu-dai-name = "DSPK2";
+ codec-dai-name = "dit-hifi";
+ format = "i2s";
+ bit-format = "s16_le";
+ srate = <48000>;
+ num-channel = <2>;
+ ignore_suspend;
+ name-prefix = "d2";
+ status = "okay";
+ };
+ };
+////
+
};
#if LINUX_VERSION >= 414
diff --git a/sources/kernel/kernel-4.9/arch/arm64/configs/tegra_defconfig b/sources/kernel/kernel-4.9/arch/arm64/configs/tegra_defconfig
index 9fc9760..3566a6d 100644
--- a/sources/kernel/kernel-4.9/arch/arm64/configs/tegra_defconfig
+++ b/sources/kernel/kernel-4.9/arch/arm64/configs/tegra_defconfig
@@ -1123,3 +1123,15 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_ARCH_TEGRA_18x_SOC=y
CONFIG_ARCH_TEGRA_19x_SOC=y
CONFIG_ARCH_TEGRA_23x_SOC=y
+# added by Yen for enable rt5639 audio codec
+# CONFIG_EQOS_APE_HWDEP is not set
+CONFIG_SND_SOC_TEGRA210_ADSP_ALT=y
+CONFIG_TEGRA_NVADSP=y
+CONFIG_TEGRA_NVADSP_ON_SMMU=y
+# CONFIG_TEGRA_ADSP_DFS is not set
+# CONFIG_TEGRA_ADSP_CPUSTAT is not set
+CONFIG_TEGRA_ADSP_CONSOLE=y
+# CONFIG_MBOX_ACK_HANDLER is not set
+CONFIG_FIQ=y
+####
diff --git a/sources/kernel/kernel-4.9/sound/soc/codecs/rt5640.c b/sources/kernel/kernel-4.9/sound/soc/codecs/rt5640.c
index 79d02c9..f53445c 100644
--- a/sources/kernel/kernel-4.9/sound/soc/codecs/rt5640.c
+++ b/sources/kernel/kernel-4.9/sound/soc/codecs/rt5640.c
@@ -133,8 +133,12 @@ static const struct reg_default rt5640_reg[] = {
{ 0x8b, 0x0600 },
{ 0x8c, 0x0228 },
{ 0x8d, 0xa000 },
- { 0x8e, 0x0004 },
- { 0x8f, 0x1100 },
+// modified by Yen for hearing microphone's sound from headphone
+// { 0x8e, 0x0004 },
+// { 0x8f, 0x1100 },
+ { 0x8e, 0x0005 },
+ { 0x8f, 0x1140 },
+////
{ 0x90, 0x0646 },
{ 0x91, 0x0c00 },
{ 0x92, 0x0000 },
@@ -942,8 +946,10 @@ static void hp_amp_power_on(struct snd_soc_codec *codec)
/* depop parameters */
regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200);
- regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
- RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
+// commented out for fixing hearing microphone's sound from headphone
+// regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
+// RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
+////
regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
@@ -1232,6 +1238,12 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
RT5640_PWR_DAC_L1_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R1_BIT, 0, NULL, 0),
+// added by Yen for enable rt5639 audio codec
+ SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
+ RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
+ RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
+////
/* SPK/OUT Mixer */
SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
@@ -1327,10 +1339,12 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = {
rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
RT5640_PWR_MA_BIT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
- RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
- SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
- RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
+// commented out by Yen for enable rt5639 audio codec
+// SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
+// RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
+// SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
+// RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
+////
SND_SOC_DAPM_OUTPUT("MONOP"),
SND_SOC_DAPM_OUTPUT("MONON"),
@@ -2020,6 +2034,10 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
case SND_SOC_BIAS_STANDBY:
if (SND_SOC_BIAS_OFF == snd_soc_codec_get_bias_level(codec)) {
+//added by Yen for microphone
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG2,
+ RT5640_PWR_MB1, RT5640_PWR_MB1);
+////
snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
RT5640_PWR_VREF1 | RT5640_PWR_MB |
RT5640_PWR_BG | RT5640_PWR_VREF2,
@@ -2033,12 +2051,18 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
0x0301, 0x0301);
snd_soc_update_bits(codec, RT5640_MICBIAS,
0x0030, 0x0030);
+//
+ snd_soc_write(codec, RT5640_DEPOP_M1, 0x0005);
+ snd_soc_write(codec, RT5640_DEPOP_M2, 0x1140);
+////
}
break;
case SND_SOC_BIAS_OFF:
- snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
- snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
+// snd_soc_write(codec, RT5640_DEPOP_M1, 0x0004);
+// snd_soc_write(codec, RT5640_DEPOP_M2, 0x1100);
+ snd_soc_write(codec, RT5640_DEPOP_M1, 0x0005);
+ snd_soc_write(codec, RT5640_DEPOP_M2, 0x1140);
snd_soc_update_bits(codec, RT5640_DUMMY1, 0x1, 0);
snd_soc_write(codec, RT5640_PWR_DIG1, 0x0000);
snd_soc_write(codec, RT5640_PWR_DIG2, 0x0000);
diff --git a/sources/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c b/sources/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
index e3428a6..1d7db10 100644
--- a/sources/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
+++ b/sources/kernel/nvidia/sound/soc/tegra-alt/machine_drivers/tegra_machine_driver_mobile.c
@@ -32,11 +33,12 @@
#include <sound/soc.h>
#include <dt-bindings/sound/tas2552.h>
#include "rt5659.h"
+#include "rt5640.h"
#include "tegra_asoc_utils_alt.h"
#include "tegra_asoc_machine_alt.h"
#include "tegra210_xbar_alt.h"
@@ -97,7 +99,8 @@ static int tegra_machine_driver_probe(struct platform_device *);
static void dai_link_setup(struct platform_device *);
static void ignore_suspend(struct snd_soc_card *);
static int tegra_machine_sfc_init(struct snd_soc_pcm_runtime *);
-static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *);
+//static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *);
+static int tegra_machine_rt5639_init(struct snd_soc_pcm_runtime *);
#if IS_ENABLED(CONFIG_SND_SOC_TEGRA210_ADSP_ALT)
static int tegra_machine_compr_set_params(struct snd_compr_stream *);
@@ -533,7 +536,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
if (err < 0)
return err;
- rtd = snd_soc_get_pcm_runtime(card, "rt565x-playback");
+ rtd = snd_soc_get_pcm_runtime(card, "rt5640-playback");
if (rtd) {
dai_params =
(struct snd_soc_pcm_stream *)rtd->dai_link->params;
@@ -544,7 +547,7 @@ static int tegra_machine_dai_init(struct snd_soc_pcm_runtime *runtime,
if (machine->is_hs_supported) {
err = snd_soc_dai_set_sysclk(rtd->codec_dai,
- RT5659_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN);
+ RT5640_SCLK_S_MCLK, clk_out_rate, SND_SOC_CLOCK_IN);
if (err < 0) {
dev_err(card->dev, "codec_dai clock not set\n");
return err;
@@ -782,7 +785,57 @@ static int tegra_machine_compr_set_params(struct snd_compr_stream *cstream)
}
#endif
-static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
+//static int tegra_machine_rt565x_init(struct snd_soc_pcm_runtime *rtd)
+//{
+// struct snd_soc_card *card = rtd->card;
+// struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
+// struct snd_soc_jack *jack;
+// int err;
+//
+// err = tegra_alt_asoc_utils_set_extern_parent(&machine->audio_clock,
+// "pll_a_out0");
+// if (err < 0) {
+// dev_err(card->dev, "Failed to set extern clk parent\n");
+// return err;
+// }
+//
+// jack = devm_kzalloc(card->dev, sizeof(struct snd_soc_jack), GFP_KERNEL);
+// if (!jack)
+// return -ENOMEM;
+//
+// err = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET,
+// jack, NULL, 0);
+// if (err) {
+// dev_err(card->dev, "Headset Jack creation failed %d\n", err);
+// return err;
+// }
+//
+// err = tegra_machine_add_codec_jack_control(card, rtd, jack);
+// if (err) {
+// dev_err(card->dev, "Failed to add jack control: %d\n", err);
+// return err;
+// }
+//
+// err = rt5659_set_jack_detect(rtd->codec, jack);
+// if (err) {
+// dev_err(card->dev, "Failed to set jack for RT565x: %d\n", err);
+// return err;
+// }
+//
+// /* single button supporting play/pause */
+// snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
+//
+// /* multiple buttons supporting play/pause and volume up/down */
+// snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_MEDIA);
+// snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+// snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+//
+// snd_soc_dapm_sync(&card->dapm);
+//
+// return 0;
+//}
+
+static int tegra_machine_rt5639_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_card *card = rtd->card;
struct tegra_machine *machine = snd_soc_card_get_drvdata(card);
@@ -871,7 +924,7 @@ static void dai_link_setup(struct platform_device *pdev)
for (i = 0; i < machine->num_codec_links; i++) {
if (tegra_machine_codec_links[i].name) {
if (strstr(tegra_machine_codec_links[i].name,
- "rt565x-playback") ||
+ "rt5640-playback") ||
strstr(tegra_machine_codec_links[i].name,
"rt565x-codec-sysclk-bclk1")) {
codec_dai_name =
@@ -882,7 +935,7 @@ static void dai_link_setup(struct platform_device *pdev)
} else {
machine->is_hs_supported = true;
tegra_machine_codec_links[i].init =
- tegra_machine_rt565x_init;
+ tegra_machine_rt5639_init;
}
} else if (strstr(tegra_machine_codec_links[i].name,
"dspk-playback-r"))
@@ -966,11 +1019,7 @@ err_alloc_dai_link:
/* structure to match device tree node */
static const struct of_device_id tegra_machine_of_match[] = {
- { .compatible = "nvidia,tegra-audio-t186ref-mobile-rt565x",
- .data = &soc_data_tegra186 },
- { .compatible = "nvidia,tegra-audio-t210ref-mobile-rt565x",
- .data = &soc_data_tegra210 },
- { .compatible = "nvidia,tegra-audio-mystique",
+ { .compatible = "nvidia,tegra-audio-t186ref-mobile-rt5639/40",
.data = &soc_data_tegra186 },
{},
};
I also change Linux_for_Tegra/bootloader/t186ref/BCT/tegra186-mb1-bct-pinmux-quill-p3310-1000-c03.cfg
- pinmux.0x02431040 = 0x00000055; # dap1_sclk_pj0: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
- pinmux.0x02431038 = 0x00000055; # dap1_dout_pj1: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
- pinmux.0x02431030 = 0x00000055; # dap1_din_pj2: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
- pinmux.0x02431028 = 0x00000055; # dap1_fs_pj3: rsvd1, pull-down, tristate-enable, input-enable, lpdr-disable
- pinmux.0x02431020 = 0x00000059; # aud_mclk_pj4: rsvd1, pull-up, tristate-enable, input-enable, lpdr-disable
---
+ pinmux.0x02431040 = 0x00000440; # dap1_sclk_pj0: i2s1, tristate-disable, input-enable
+ pinmux.0x02431038 = 0x00000440; # dap1_dout_pj1: i2s1, tristate-disable, input-enable
+ pinmux.0x02431030 = 0x00000450; # dap1_din_pj2: i2s1, tristate-enable, input-enable
+ pinmux.0x02431028 = 0x00000440; # dap1_fs_pj3: i2s1, tristate-disable, input-enable
+ pinmux.0x02431020 = 0x00000400; # aud_mclk_pj4: aud, tristate-disable, input-disable
Now, I can see rt5639 in dmesg(see attachment), but I can’t play sound via rt5639
[ 5.334918] ALSA device list:
[ 5.334921] #0: tegra-hda at 0x3518000 irq 385
[ 5.334923] #1: tegra-snd-t186ref-mobile-rt5639_40
I tried to copy amixer_settings which I used on R28.3 to rootfs/etc, but it doesn’t work too.
Does anyone know how to let it work?
Thx
Yen
dmesg.txt (97 KB)