git diff
eth0 disable and ssh still can work.
diff --git a/build/boards/cv180x/cv1800b_milkv_duo_sd/dts_riscv/cv1800b_milkv_duo_sd.dts b/build/boards/cv180x/cv1800b_milkv_duo_sd/dts_riscv/cv1800b_milkv_duo_sd.dts
index e90e2c32a..e970969ff 100644
--- a/build/boards/cv180x/cv1800b_milkv_duo_sd/dts_riscv/cv1800b_milkv_duo_sd.dts
+++ b/build/boards/cv180x/cv1800b_milkv_duo_sd/dts_riscv/cv1800b_milkv_duo_sd.dts
@@ -29,3 +29,40 @@
 	model = "Milk-V Duo";
 };
 
+// [+] youaki, add for speaker
+
+
+&i2s2 {
+	status = "okay";
+	#sound-dai-cells = <0>;
+};
+
+/**/
+
+ðernet0 {
+	status = "disabled";
+};
+
+
+/ {
+	/* codec */
+	max98357a: max98357a {
+		#sound-dai-cells = <0>;
+		compatible = "maxim,max98357a";
+		status = "okay";
+
+		/* this may be necessary, otherwise driver will not load */
+		sdmode-gpios = <&porta 14 0>;
+		/* max98357a has gain & sd_mode gpio. but codec driver just has sdmode */
+
+		clocks = <&i2s_mclk 0>;
+		clock-names = "i2sclk";
+	};
+
+	/* sound_ext3 use external codec */
+	sound_max98357a {
+		compatible = "cvitek,cv1835-max98357a";
+		cvi,card_name = "cv1835_max98357a";
+	};
+
+};
diff --git a/build/boards/cv180x/cv1800b_milkv_duo_sd/linux/cvitek_cv1800b_milkv_duo_sd_defconfig b/build/boards/cv180x/cv1800b_milkv_duo_sd/linux/cvitek_cv1800b_milkv_duo_sd_defconfig
index 4c60136fc..1cdbc64aa 100644
--- a/build/boards/cv180x/cv1800b_milkv_duo_sd/linux/cvitek_cv1800b_milkv_duo_sd_defconfig
+++ b/build/boards/cv180x/cv1800b_milkv_duo_sd/linux/cvitek_cv1800b_milkv_duo_sd_defconfig
@@ -345,3 +345,16 @@ CONFIG_EPOLL=n
 CONFIG_ELF_CORE=y
 CONFIG_COREDUMP=y
 CONFIG_PROC_SYSCTL=y
+
+# youkai add for audio
+CONFIG_SND_PROC_FS=y
+# CONFIG_SND_SOC_CV1835_CONCURRENT_I2S=y  # question
+
+# close dac -- dac gpio used to led
+CONFIG_SND_SOC_CV182XA_CV182XADAC=n
+CONFIG_SND_SOC_CV182XADAC=n
+
+# add max98357a for speaker
+CONFIG_SND_SOC_MAX98357A=y
+CONFIG_SND_SOC_CV1835_MAX98357A=y
+# CONFIG_DEBUG_INFO=y
diff --git a/build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c b/build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c
index 74941cb09..69eb4320d 100644
--- a/build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c
+++ b/build/boards/cv180x/cv1800b_milkv_duo_sd/u-boot/cvi_board_init.c
@@ -41,5 +41,12 @@ int cvi_board_init(void)
 	PINMUX_CONFIG(SD1_D0, SPI2_SDI);
 	PINMUX_CONFIG(SD1_D3, SPI2_CS_X);
 
+	// youkai add for max98357a speaker
+	PINMUX_CONFIG(PAD_ETH_TXP, IIS2_LRCK);
+	PINMUX_CONFIG(PAD_ETH_TXM, IIS2_BCLK);
+	PINMUX_CONFIG(PAD_ETH_RXP, IIS2_DO);
+	PINMUX_CONFIG(PAD_ETH_RXM, IIS2_DI);
+	PINMUX_CONFIG(SD0_PWR_EN, XGPIOA_14);	// sdmode
+
 	return 0;
 }
diff --git a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/dts_riscv/cv1812cp_milkv_duo256m_sd.dts b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/dts_riscv/cv1812cp_milkv_duo256m_sd.dts
index 16734cb47..f08c768ed 100644
--- a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/dts_riscv/cv1812cp_milkv_duo256m_sd.dts
+++ b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/dts_riscv/cv1812cp_milkv_duo256m_sd.dts
@@ -34,3 +34,22 @@
 	model = "Milk-V Duo256M";
 };
 
+// [+] youaki, add for speaker
+
+/ {
+	/* codec */
+	max98357a: max98357a {
+		#sound-dai-cells = <0>;
+		compatible = "maxim,max98357a";
+		status = "okay";
+		/*sdmode-gpios = <&gpio1 14 0>;*/ 
+		/* max98357a has gain & sd_mode gpio. but codec driver just has sdmode */
+	};
+
+	/* sound_ext3 use external codec */
+	sound {
+		compatible = "cvitek,cv1835-max98357a";
+		cvi,card_name = "cv1835_max98357a";
+	};
+
+};
diff --git a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/linux/cvitek_cv1812cp_milkv_duo256m_sd_defconfig b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/linux/cvitek_cv1812cp_milkv_duo256m_sd_defconfig
index 4bfbc511c..368638019 100644
--- a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/linux/cvitek_cv1812cp_milkv_duo256m_sd_defconfig
+++ b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/linux/cvitek_cv1812cp_milkv_duo256m_sd_defconfig
@@ -294,3 +294,16 @@ CONFIG_EPOLL=n
 CONFIG_ELF_CORE=y
 CONFIG_COREDUMP=y
 CONFIG_PROC_SYSCTL=y
+
+# youkai add for audio
+CONFIG_SND_PROC_FS=y
+# CONFIG_SND_SOC_CV1835_CONCURRENT_I2S=y  # question
+
+# close dac -- dac gpio used to led
+CONFIG_SND_SOC_CV182XA_CV182XADAC=n
+CONFIG_SND_SOC_CV182XADAC=n
+
+# add max98357a for speaker
+CONFIG_SND_SOC_MAX98357A=y
+CONFIG_SND_SOC_CV1835_MAX98357A=y
+# CONFIG_DEBUG_INFO=y
diff --git a/build/boards/default/dts/cv180x/cv180x_asic_bga.dtsi b/build/boards/default/dts/cv180x/cv180x_asic_bga.dtsi
index 2bcacfb3a..8d5b60514 100644
--- a/build/boards/default/dts/cv180x/cv180x_asic_bga.dtsi
+++ b/build/boards/default/dts/cv180x/cv180x_asic_bga.dtsi
@@ -5,7 +5,9 @@
 
 / {
 	/delete-node/ i2s@04110000;
-	/delete-node/ i2s@04120000;
+	/*
+		/delete-node/ i2s@04120000;
+	*/
 	/delete-node/ sound_ext1;
 	/delete-node/ sound_ext2;
 	/delete-node/ sound_PDM;
diff --git a/build/boards/default/dts/cv181x/cv181x_asic_qfn.dtsi b/build/boards/default/dts/cv181x/cv181x_asic_qfn.dtsi
index 93081c5d7..7d915d6dd 100644
--- a/build/boards/default/dts/cv181x/cv181x_asic_qfn.dtsi
+++ b/build/boards/default/dts/cv181x/cv181x_asic_qfn.dtsi
@@ -104,7 +104,9 @@
 / {
 	/delete-node/ wifi-sd@4320000;
 	/delete-node/ i2s@04110000;
-	/delete-node/ i2s@04120000;
+	/*
+		/delete-node/ i2s@04120000;
+	*/
 	/delete-node/ sound_ext1;
 	/delete-node/ sound_ext2;
 	/delete-node/ sound_PDM;
diff --git a/buildroot-2021.05/configs/milkv-duo256m_musl_riscv64_defconfig b/buildroot-2021.05/configs/milkv-duo256m_musl_riscv64_defconfig
index 20fa4431e..aee4dbef4 100644
--- a/buildroot-2021.05/configs/milkv-duo256m_musl_riscv64_defconfig
+++ b/buildroot-2021.05/configs/milkv-duo256m_musl_riscv64_defconfig
@@ -510,3 +510,6 @@ BR2_PACKAGE_NCNN=y
 BR2_PACKAGE_NCNN_BENCH=y
 BR2_PACKAGE_NCNN_EXAMPLE=y
 BR2_PACKAGE_CMATRIX=y
+
+# youkai add -- open audio
+BR2_PACKAGE_TINYALSA=y
diff --git a/buildroot-2021.05/configs/milkv-duo_musl_riscv64_defconfig b/buildroot-2021.05/configs/milkv-duo_musl_riscv64_defconfig
index 2bc8cd5e3..f0c014b9c 100644
--- a/buildroot-2021.05/configs/milkv-duo_musl_riscv64_defconfig
+++ b/buildroot-2021.05/configs/milkv-duo_musl_riscv64_defconfig
@@ -519,3 +519,6 @@ BR2_PACKAGE_IPERF3=y
 BR2_PACKAGE_NTP=y
 BR2_PACKAGE_NTP_NTPDATE=y
 BR2_PACKAGE_NTP_NTPTIME=y
+
+# youkai add -- open audio
+BR2_PACKAGE_TINYALSA=y
diff --git a/device/milkv-duo/overlay/mnt/system/usb-rndis.sh b/device/milkv-duo/overlay/mnt/system/usb-rndis.sh
index e0f132b3a..95972ae2f 100755
--- a/device/milkv-duo/overlay/mnt/system/usb-rndis.sh
+++ b/device/milkv-duo/overlay/mnt/system/usb-rndis.sh
@@ -7,6 +7,9 @@
 sleep 0.5
 ifconfig usb0 192.168.42.1
 
+# youkai add for tinyalsa
+ln -s /lib/ld-musl-riscv64v0p7_xthead.so.1 /lib/ld-musl-riscv64.so.1
+
 count=`ps | grep dnsmasq | grep -v grep | wc -l`
 if [ ${count} -lt 1 ] ;then
   echo "/etc/init.d/S80dnsmasq start" >> /tmp/rndis.log 2>&1
diff --git a/device/milkv-duo256m/overlay/mnt/system/usb-rndis.sh b/device/milkv-duo256m/overlay/mnt/system/usb-rndis.sh
index e0f132b3a..95972ae2f 100755
--- a/device/milkv-duo256m/overlay/mnt/system/usb-rndis.sh
+++ b/device/milkv-duo256m/overlay/mnt/system/usb-rndis.sh
@@ -7,6 +7,9 @@
 sleep 0.5
 ifconfig usb0 192.168.42.1
 
+# youkai add for tinyalsa
+ln -s /lib/ld-musl-riscv64v0p7_xthead.so.1 /lib/ld-musl-riscv64.so.1
+
 count=`ps | grep dnsmasq | grep -v grep | wc -l`
 if [ ${count} -lt 1 ] ;then
   echo "/etc/init.d/S80dnsmasq start" >> /tmp/rndis.log 2>&1
diff --git a/linux_5.10/sound/soc/cvitek/Kconfig b/linux_5.10/sound/soc/cvitek/Kconfig
index b2540aa8e..62bd74cac 100644
--- a/linux_5.10/sound/soc/cvitek/Kconfig
+++ b/linux_5.10/sound/soc/cvitek/Kconfig
@@ -190,3 +190,9 @@ config SND_SOC_CV1835_LT9611
 	tristate "Support for the lt9611 card"
 	help
 	  lt9611 codec enable.
+
+# youkai add for extend speaker
+config SND_SOC_CV1835_MAX98357A
+	tristate "Support for the max98357a card"
+	help
+	  max98357a codec enable.
diff --git a/linux_5.10/sound/soc/cvitek/Makefile b/linux_5.10/sound/soc/cvitek/Makefile
index 93060ca2b..f538b0e7f 100644
--- a/linux_5.10/sound/soc/cvitek/Makefile
+++ b/linux_5.10/sound/soc/cvitek/Makefile
@@ -79,3 +79,6 @@ endif
 obj-$(CONFIG_CV1835_I2S_SUBSYS) += cv1835_i2s_subsys.o
 
 obj-$(CONFIG_SND_SOC_CV1835_LT9611) += cv1835_lt9611.o
+
+# youkai add for extend speaker
+obj-$(CONFIG_SND_SOC_CV1835_MAX98357A) += cv1835_max98357a.o
diff --git a/linux_5.10/sound/soc/cvitek/cv1835_i2s.c b/linux_5.10/sound/soc/cvitek/cv1835_i2s.c
index 77f1f2126..d33997acd 100644
--- a/linux_5.10/sound/soc/cvitek/cv1835_i2s.c
+++ b/linux_5.10/sound/soc/cvitek/cv1835_i2s.c
@@ -96,7 +96,9 @@ static void i2s_reset(struct cvi_i2s_dev *dev, u32 stream)
 {
 	u32 retry = 0;
 
-	dev_dbg(dev->dev, "blk_mode=0x%08x, clk_ctrl=0x%08x, i2s_enable=0x%08x\n",
+	dev_err(dev->dev,"%s start ====={",__func__);
+
+	dev_err(dev->dev, "blk_mode=0x%08x, clk_ctrl=0x%08x, i2s_enable=0x%08x\n",
 		i2s_read_reg(dev->i2s_base, BLK_MODE_SETTING),
 		i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0),
 		i2s_read_reg(dev->i2s_base, I2S_ENABLE));
@@ -126,6 +128,8 @@ static void i2s_reset(struct cvi_i2s_dev *dev, u32 stream)
 
 		i2s_write_reg(dev->i2s_base, I2S_RESET, I2S_RESET_TX_PULL_DOWN);
 	}
+
+	dev_err(dev->dev,"%s end =====}",__func__);
 }
 
 static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
@@ -137,7 +141,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
 
 	if (dev->active >= 1) { /* If I2S is really active */
 		if (val & (I2S_INT_RXFO | I2S_INT_RXFU)) {
-			dev_dbg(dev->dev, "WARNING!!! I2S RX FIFO exception occur int_status=0x%x\n", val);
+			dev_err(dev->dev, "WARNING!!! I2S RX FIFO exception occur int_status=0x%x\n", val);
 			i2s_write_reg(dev->i2s_base, I2S_ENABLE, I2S_OFF);
 			i2s_write_reg(dev->i2s_base, I2S_CLK_CTRL0,
 				      (i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0) | AUD_ENABLE));
@@ -145,7 +149,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
 			i2s_reset(dev, SNDRV_PCM_STREAM_CAPTURE);
 			i2s_write_reg(dev->i2s_base, I2S_ENABLE, I2S_ON);
 		} else if (val & (I2S_INT_TXFO | I2S_INT_TXFU)) {
-			dev_dbg(dev->dev, "WARNING!!! I2S TX FIFO exception occur int_status=0x%x\n", val);
+			dev_err(dev->dev, "WARNING!!! I2S TX FIFO exception occur int_status=0x%x\n", val);
 			i2s_write_reg(dev->i2s_base, I2S_ENABLE, I2S_OFF);
 			i2s_write_reg(dev->i2s_base, I2S_CLK_CTRL0,
 				      (i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0) | AUD_ENABLE));
@@ -164,7 +168,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
 static void i2s_start(struct cvi_i2s_dev *dev,
 		      struct snd_pcm_substream *substream)
 {
-
+	dev_err(dev->dev,"%s start ====={",__func__);
 	u32 i2s_enable = i2s_read_reg(dev->i2s_base, I2S_ENABLE);
 	u32 clk_ctrl = i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0);
 	u32 blk_mode_setting = i2s_read_reg(dev->i2s_base, BLK_MODE_SETTING);
@@ -193,7 +197,7 @@ static void i2s_start(struct cvi_i2s_dev *dev,
 	} else
 		dev_err(dev->dev, "WARNING!!!  I2S SHOULD NOT be in ON state\n");
 
-	dev_dbg(dev->dev,
+	dev_err(dev->dev,
 		"blk_mode=0x%08x, clk_ctrl=0x%08x, int_en=0x%08x, frame_setting=0x%08x, slot_setting=0x%08x, data_format=0x%08x\n",
 		i2s_read_reg(dev->i2s_base, BLK_MODE_SETTING),
 		i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0),
@@ -201,6 +205,7 @@ static void i2s_start(struct cvi_i2s_dev *dev,
 		i2s_read_reg(dev->i2s_base, FRAME_SETTING),
 		i2s_read_reg(dev->i2s_base, SLOT_SETTING1),
 		i2s_read_reg(dev->i2s_base, DATA_FORMAT));
+	dev_err(dev->dev,"%s end =====}",__func__);
 }
 
 static void i2s_stop(struct cvi_i2s_dev *dev,
@@ -217,7 +222,7 @@ static void i2s_stop(struct cvi_i2s_dev *dev,
 		u32 clk_ctrl = i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL0);
 
 		if (((blk_mode_setting & ROLE_MASK) == MASTER_MODE) && ((clk_ctrl & AUD_ENABLE) == AUD_ENABLE))	{
-			dev_dbg(dev->dev, "Disable aud_en\n");
+			dev_err(dev->dev, "Disable aud_en\n");
 			i2s_write_reg(dev->i2s_base, I2S_CLK_CTRL0, clk_ctrl & ~(AUD_ENABLE));
 		}
 	}
@@ -234,7 +239,7 @@ static int cvi_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
 {
 	struct cvi_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
 
-	dev_dbg(cpu_dai->dev, "%s start *cpu_dai = %p name = %s\n", __func__, cpu_dai, cpu_dai->name);
+	dev_err(cpu_dai->dev, "%s start *cpu_dai = %p name = %s\n", __func__, cpu_dai, cpu_dai->name);
 	cpu_dai->playback_dma_data = &dev->play_dma_data;
 	cpu_dai->capture_dma_data = &dev->capture_dma_data;
 
@@ -246,7 +251,7 @@ static int cvi_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
 		dev_err(cpu_dai->dev, "%s capture_dma_data == NULL\n", __func__);
 	}
 
-	dev_dbg(cpu_dai->dev, "%s end cpu_dai->playback_dma_data = %p\n", __func__, cpu_dai->playback_dma_data);
+	dev_err(cpu_dai->dev, "%s end cpu_dai->playback_dma_data = %p\n", __func__, cpu_dai->playback_dma_data);
 
 	return 0;
 
@@ -259,16 +264,16 @@ static int cvi_i2s_startup(struct snd_pcm_substream *substream,
 	struct cvi_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
 	union cvi_i2s_snd_dma_data *dma_data = NULL;
 
-	dev_dbg(dev->dev, "%s start *cpu_dai = %p name = %s\n", __func__, cpu_dai, cpu_dai->name);
+	dev_err(dev->dev, "%s start *cpu_dai = %p name = %s\n", __func__, cpu_dai, cpu_dai->name);
 	if (!(dev->capability & CVI_I2S_RECORD) &&
 	    (substream->stream == SNDRV_PCM_STREAM_CAPTURE)) {
-		dev_dbg(dev->dev, "%s return -EINVAL;\n", __func__);
+		dev_err(dev->dev, "%s return -EINVAL;\n", __func__);
 		return -EINVAL;
 	}
 
 	if (!(dev->capability & CVI_I2S_PLAY) &&
 	    (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
-		dev_dbg(dev->dev, "%s return -EINVAL; 2\n", __func__);
+		dev_err(dev->dev, "%s return -EINVAL; 2\n", __func__);
 		return -EINVAL;
 	}
 
@@ -277,12 +282,12 @@ static int cvi_i2s_startup(struct snd_pcm_substream *substream,
 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
 		dma_data = &dev->capture_dma_data;
 	if (dma_data == NULL) {
-		dev_dbg(dev->dev, "%s dma_data == NULL\n", __func__);
+		dev_err(dev->dev, "%s dma_data == NULL\n", __func__);
 	}
 
-	dev_dbg(dev->dev, "%s start *dma_data = %p\n", __func__, dma_data);
+	dev_err(dev->dev, "%s start *dma_data = %p\n", __func__, dma_data);
 	snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
-	dev_dbg(dev->dev, "%s end cpu_dai->playback_dma_data = %p\n",
+	dev_err(dev->dev, "%s end cpu_dai->playback_dma_data = %p\n",
 		__func__, cpu_dai->playback_dma_data);
 	return 0;
 }
@@ -315,6 +320,14 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 
 	config->chan_nr = params_channels(params);
 
+	dev_err(dev->dev,"%s ====={", __func__);
+
+	dev_err(dev->dev,"youkai %s card short name %s\n",__func__,substream->pcm->card->shortname);
+
+	dev_err(dev->dev,"(1) format");
+
+	dev_err(dev->dev, "channel %d format %d\n",params_channels(params),params_format(params));
+
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
 	case SNDRV_PCM_FORMAT_U16_LE:
@@ -349,8 +362,13 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 						frame_setting |= FRAME_LENGTH(16) | FS_ACT_LENGTH(16);
 						break;
 					}
-				} else
+				} else{
 					frame_setting |= FRAME_LENGTH(16) | FS_ACT_LENGTH(16);
+					dev_err(dev->dev,"format 16");
+				}
+			} else if (!strcmp(substream->pcm->card->shortname, "cv1835_max98357a")) {
+				frame_setting |= FRAME_LENGTH(32) | FS_ACT_LENGTH(16);
+				dev_err(dev->dev,"format 16");
 			} else
 				frame_setting |= FRAME_LENGTH(32) | FS_ACT_LENGTH(16);
 
@@ -374,7 +392,8 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 		if (!strcmp(substream->pcm->card->shortname, "cv182x_adc") ||
 			!strcmp(substream->pcm->card->shortname, "cv182x_dac") ||
 			!strcmp(substream->pcm->card->shortname, "cv182xa_adc") ||
-			!strcmp(substream->pcm->card->shortname, "cv182xa_dac")) {
+			!strcmp(substream->pcm->card->shortname, "cv182xa_dac") ||
+			!strcmp(substream->pcm->card->shortname, "cv1835_max98357a")) {
 			dev_err(dev->dev, "24 bit resolution is not supported\n");
 			return -EINVAL;
 		}
@@ -402,7 +421,8 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 		if (!strcmp(substream->pcm->card->shortname, "cv182x_adc") ||
 			!strcmp(substream->pcm->card->shortname, "cv182x_dac") ||
 			!strcmp(substream->pcm->card->shortname, "cv182xa_adc") ||
-			!strcmp(substream->pcm->card->shortname, "cv182xa_dac")
+			!strcmp(substream->pcm->card->shortname, "cv182xa_dac") ||
+			!strcmp(substream->pcm->card->shortname, "cv1835_max98357a")
 			) {
 			dev_err(dev->dev, "32 bit resolution is not supported\n");
 			return -EINVAL;
@@ -431,6 +451,8 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 	}
 	i2s_write_reg(dev->i2s_base, SLOT_SETTING1, slot_setting1);
 	i2s_write_reg(dev->i2s_base, FRAME_SETTING, frame_setting);
+	dev_err(dev->dev, "## slot_setting1 = %d\n", slot_setting1);
+	dev_err(dev->dev, "## frame_setting = %d\n", frame_setting);
 
 #if defined(CONFIG_SND_SOC_CV1835_CONCURRENT_I2S)
 	if ((dev->dev_id != 0) && (dev->dev_id != 3) && (dev->dev_id != i2s_subsys_query_master()))
@@ -438,7 +460,7 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 #endif
 
 	slot_setting1 &= ~SLOT_NUM_MASK;
-	dev_dbg(dev->dev, "CVI-i2s: set slot number=%d\n",	config->chan_nr);
+	dev_err(dev->dev, "CVI-i2s: set slot number=%d\n",	slot_setting1);
 	switch (config->chan_nr) {
 	case EIGHT_CHANNEL_SUPPORT:
 		slot_setting1 |= SLOT_NUM(8);
@@ -467,6 +489,8 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 			data_format |= SKIP_TX_INACT_SLOT;
 		} else
 			slot_setting1 |= SLOT_NUM(1);
+		
+		dev_err(dev->dev, "slot number=%d data_format %d\n", slot_setting1, data_format);
 
 		i2s_write_reg(dev->i2s_base, SLOT_SETTING1, slot_setting1);
 		i2s_write_reg(dev->i2s_base, SLOT_SETTING2, 0x01); /* enable slot 0-3 for TDM */
@@ -478,7 +502,12 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 
 	cvi_i2s_config(dev, substream->stream); /* Config use HW DMA and FIFO threshold here */
 
+	dev_err(dev->dev,"(2) rate");
+
 	config->sample_rate = params_rate(params);
+
+	dev_err(dev->dev, "youkai sample_rate = %d\n",config->sample_rate);
+
 	//audio_clk = clk_get_rate(dev->clk);
 	/* set audio_clk depends on audio format */
 	switch (config->sample_rate) {
@@ -487,12 +516,18 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 	case 44100:
 	case 88200:
 		audio_clk = CVI_22579_MHZ;
+		// if (!strcmp(substream->pcm->card->shortname, "cv1835_max98357a")){
+		// 	audio_clk = CVI_24576_MHZ;
+		// 	config->sample_rate = 48000;
+		// 	dev_err(dev->dev, "youkai match ");
+		// }
 		break;
 	case 8000:
 	case 16000:
 	case 32000:
 		if (!strcmp(substream->pcm->card->shortname, "cv182xa_adc") ||
-			!strcmp(substream->pcm->card->shortname, "cv182xa_dac"))
+			!strcmp(substream->pcm->card->shortname, "cv182xa_dac") ||
+			!strcmp(substream->pcm->card->shortname, "cv1835_max98357a"))
 			audio_clk = CVI_16384_MHZ;
 		else
 			audio_clk = CVI_24576_MHZ;
@@ -543,7 +578,7 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 			!strcmp(substream->pcm->card->shortname, "cv182x_dac")) {
 		/* cv182x internal adc codec need dynamic MCLK frequency input */
 
-		dev_info(dev->dev, "%s set MCLK\n", __func__);
+		dev_err(dev->dev, "%s set MCLK rate=%d\n", __func__, config->sample_rate);
 		switch (config->sample_rate) {
 		case 8000:
 			clk_ctrl1 |= MCLK_DIV(6);
@@ -572,6 +607,27 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 			!strcmp(substream->pcm->card->shortname, "cv182xa_dac")) {
 		/* cv182xa internal adc codec need dynamic MCLK frequency input */
 
+		switch (config->sample_rate) {
+		case 8000:
+		case 16000:
+		case 32000:
+			/* apll is 16.384Mhz, no need to divide */
+			clk_ctrl1 |= MCLK_DIV(1);
+			mclk_div = 1;
+			break;
+		case 11025:
+		case 22050:
+		case 44100:
+		case 48000:
+			clk_ctrl1 |= MCLK_DIV(2);
+			mclk_div = 2;
+			break;
+		default:
+			dev_err(dev->dev, "%s doesn't support this sample rate\n", __func__);
+			break;
+		}
+	} else if (!strcmp(substream->pcm->card->shortname, "cv1835_max98357a")) {
+
 		switch (config->sample_rate) {
 		case 8000:
 		case 16000:
@@ -592,14 +648,23 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 			break;
 		}
 	} else {
+		dev_err(dev->dev, "%s set mclk audio_clk %d\n", substream->pcm->card->shortname,audio_clk);
 		if ((audio_clk == CVI_24576_MHZ) || (audio_clk == CVI_22579_MHZ)){
 			clk_ctrl1 |= MCLK_DIV(2);
 			mclk_div = 2;
+			dev_err(dev->dev, "set mclk ok");
 		}
 		else
 			dev_err(dev->dev, "Get unexpected audio system clk=%d\n", audio_clk);
 	}
 
+	dev_err(dev->dev, "## audio_clk = %d mclk_div %d \n", audio_clk, mclk_div);
+
+	dev_err(dev->dev,"(3) wss");
+
+	dev_err(dev->dev, "## dev->wss = %d\n", dev->wss);
+	dev_err(dev->dev, "## data_format = %d\n", data_format);
+
 	/* Configure I2S word length,  bclk_div and sync_div here*/
 	switch (dev->wss) {
 	case (WSS_32_CLKCYCLE):
@@ -630,22 +695,30 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 		data_format |= WORD_LEN_32;
 		break;
 	case (WSS_16_CLKCYCLE):
+		dev_err(dev->dev, "WSS_16_CLKCYCLE\n");
+
 #if defined(CONFIG_ARCH_CV183X_ASIC)
+			dev_err(dev->dev, "CONFIG_ARCH_CV183X_ASIC\n");
 			bclk_div = (audio_clk / 1000) / (WSS_16_CLKCYCLE * (config->sample_rate / 1000));
 #else
+			dev_err(dev->dev, "no CONFIG_ARCH_CV183X_ASIC\n");
 			bclk_div = (audio_clk / 1000) / (WSS_16_CLKCYCLE * (config->sample_rate / 1000) * mclk_div);
 #endif
+		dev_err(dev->dev, "audio_clk %d rate %d mclk_div %d bclk_div %d\n", audio_clk, config->sample_rate, mclk_div, bclk_div);
 		data_format |= WORD_LEN_16;
 		break;
 	default:
 		dev_err(dev->dev, "resolution not supported\n");
 	}
 
+	dev_err(dev->dev,"(4) word length\n");
+
 	/* Configure word length */
 	i2s_write_reg(dev->i2s_base, DATA_FORMAT, data_format);
+	dev_err(dev->dev, "## data_format = %d\n", data_format);
 
 	clk_ctrl1 |= BCLK_DIV(bclk_div);
-	dev_dbg(dev->dev, "Set clock ctrl1=0x%08x\n", clk_ctrl1);
+	dev_err(dev->dev, "Set clock ctrl1=0x%08x\n", clk_ctrl1);
 	i2s_write_reg(dev->i2s_base, I2S_CLK_CTRL1, clk_ctrl1);
 
 #if defined(CONFIG_SND_SOC_CV1835_CONCURRENT_I2S)
@@ -653,12 +726,14 @@ static int cvi_i2s_hw_params(struct snd_pcm_substream *substream,
 		i2s_set_master_clk(clk_ctrl1);
 #endif
 
-	dev_dbg(dev->dev, "frame_setting=0x%08x, slot_setting1=0x%08x, clk_ctrl1=0x%08x, data_format=0x%08x\n",
+	dev_err(dev->dev, "frame_setting=0x%08x, slot_setting1=0x%08x, clk_ctrl1=0x%08x, data_format=0x%08x\n",
 		i2s_read_reg(dev->i2s_base, FRAME_SETTING),
 		i2s_read_reg(dev->i2s_base, SLOT_SETTING1),
 		i2s_read_reg(dev->i2s_base, I2S_CLK_CTRL1),
 		i2s_read_reg(dev->i2s_base, DATA_FORMAT));
 
+	dev_err(dev->dev,"%s =====}", __func__);
+
 	return 0;
 }
 
@@ -700,7 +775,7 @@ static int cvi_i2s_trigger(struct snd_pcm_substream *substream,
 		dev->active++;
 #if defined(CONFIG_SND_SOC_CV1835_CONCURRENT_I2S)
 		if ((dev->dev_id != 0) && (dev->dev_id != 3) && (dev->dev_id != i2s_subsys_query_master())) {
-			dev_dbg(dev->dev, "enable master clk generation\n");
+			dev_err(dev->dev, "enable master clk generation\n");
 			i2s_master_clk_switch_on(true);
 		}
 #endif
@@ -718,7 +793,7 @@ static int cvi_i2s_trigger(struct snd_pcm_substream *substream,
 		i2s_stop(dev, substream);
 #if defined(CONFIG_SND_SOC_CV1835_CONCURRENT_I2S)
 		if ((dev->dev_id != 0) && (dev->dev_id != 3) && (dev->dev_id != i2s_subsys_query_master())) {
-			dev_dbg(dev->dev, "disable master clk generation\n");
+			dev_err(dev->dev, "disable master clk generation\n");
 			i2s_master_clk_switch_on(false);
 		}
 #endif
@@ -746,7 +821,7 @@ static int cvi_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 
 	int ret = 0;
 
-	dev_dbg(dev->dev, "%s, fmt=0x%08x\n", __func__, fmt);
+	dev_err(dev->dev, "%s, fmt=0x%08x\n", __func__, fmt);
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBM_CFM: /* Set codec to Master mode, so I2S IP need to be Slave mode */
@@ -762,7 +837,7 @@ static int cvi_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		ret = -EINVAL;
 		break;
 	default:
-		dev_dbg(dev->dev, "cvitek : Invalid master/slave format\n");
+		dev_err(dev->dev, "cvitek : Invalid master/slave format\n");
 		ret = -EINVAL;
 		break;
 	}
@@ -789,7 +864,7 @@ static int cvi_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		frame_setting |= FS_ACT_HIGH;
 		break;
 	default:
-		dev_dbg(dev->dev, "cvitek : Invalid frame format\n");
+		dev_err(dev->dev, "cvitek : Invalid frame format\n");
 		ret = -EINVAL;
 		break;
 	}
@@ -833,7 +908,7 @@ static int cvi_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
 		i2s_write_reg(dev->i2s_base, FRAME_SETTING, frame_setting);
 		break;
 	default:
-		dev_dbg(dev->dev, "cvitek : Invalid I2S mode\n");
+		dev_err(dev->dev, "cvitek : Invalid I2S mode\n");
 		ret = -EINVAL;
 		break;
 	}
@@ -965,7 +1040,7 @@ static int cvi_configure_dai(struct cvi_i2s_dev *dev,
 
 
 	if ((!strcmp(capability, "tx")) || (!strcmp(capability, "txrx"))) {
-		dev_dbg(dev->dev, "CV: playback support\n");
+		dev_err(dev->dev, "CV: playback support\n");
 		cvi_i2s_dai->playback.channels_min = 1;
 		cvi_i2s_dai->playback.channels_max = 8;
 		cvi_i2s_dai->playback.formats = SNDRV_PCM_FMTBIT_S32_LE
@@ -977,13 +1052,13 @@ static int cvi_configure_dai(struct cvi_i2s_dev *dev,
 		cvi_i2s_dai->playback.rates = rates;
 	} else {
 		/* this device doesn't have playback capability */
-		dev_dbg(dev->dev, "CV: playback not support\n");
+		dev_err(dev->dev, "CV: playback not support\n");
 		cvi_i2s_dai->playback.channels_min = 0;
 		cvi_i2s_dai->playback.channels_max = 0;
 	}
 
 	if ((!strcmp(capability, "rx")) || (!strcmp(capability, "txrx"))) {
-		dev_dbg(dev->dev, "CV: capature support\n");
+		dev_err(dev->dev, "CV: capature support\n");
 		cvi_i2s_dai->capture.channels_min = 1;
 		cvi_i2s_dai->capture.channels_max = 8;
 		cvi_i2s_dai->capture.formats = SNDRV_PCM_FMTBIT_S32_LE
@@ -992,12 +1067,12 @@ static int cvi_configure_dai(struct cvi_i2s_dev *dev,
 		cvi_i2s_dai->capture.rates = rates;
 	} else {
 		/* this device doesn't have capature capability */
-		dev_dbg(dev->dev, "CV: capature not support\n");
+		dev_err(dev->dev, "CV: capature not support\n");
 		cvi_i2s_dai->capture.channels_min = 0;
 		cvi_i2s_dai->capture.channels_max = 0;
 	}
 
-	dev_dbg(dev->dev, "CV: i2s master/slave mode supported\n");
+	dev_err(dev->dev, "CV: i2s master/slave mode supported\n");
 	dev->capability |= CVI_I2S_MASTER | CVI_I2S_SLAVE;
 
 	dev->fifo_th = I2STDM_FIFO_DEPTH / 2;
@@ -1011,14 +1086,14 @@ static int cvi_configure_dai_by_dt(struct cvi_i2s_dev *dev,
 	int ret;
 	struct device_node *np = dev->dev->of_node;
 
-	dev_dbg(dev->dev, "%s start\n", __func__);
+	dev_err(dev->dev, "%s start\n", __func__);
 	ret = cvi_configure_dai(dev, cvi_i2s_dai, SNDRV_PCM_RATE_8000_192000);
 	if (ret < 0)
 		return ret;
 
 	/* Set TX parameters */
 	if (of_property_match_string(np, "dma-names", "tx") >= 0) {
-		dev_dbg(dev->dev, "%s dma-names  tx\n", __func__);
+		dev_err(dev->dev, "%s dma-names  tx\n", __func__);
 		dev->capability |= CVI_I2S_PLAY;
 		dev->play_dma_data.dt.addr = res->start + TX_WR_PORT_CH0;
 		dev->play_dma_data.dt.addr_width = 4;
@@ -1028,7 +1103,7 @@ static int cvi_configure_dai_by_dt(struct cvi_i2s_dev *dev,
 
 	/* Set RX parameters */
 	if (of_property_match_string(np, "dma-names", "rx") >= 0) {
-		dev_dbg(dev->dev, "%s dma-names  rx\n", __func__);
+		dev_err(dev->dev, "%s dma-names  rx\n", __func__);
 		dev->capability |= CVI_I2S_RECORD;
 		dev->capture_dma_data.dt.addr = res->start + RX_RD_PORT_CH0;
 		dev->capture_dma_data.dt.addr_width = 4;
@@ -1102,7 +1177,7 @@ static int cvi_i2s_probe(struct platform_device *pdev)
 	char *i2s_dev_name;
 	const char *mclk_out;
 
-	dev_info(&pdev->dev, "%s\n", __func__);
+	dev_err(&pdev->dev, "%s\n", __func__);
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -1123,7 +1198,7 @@ static int cvi_i2s_probe(struct platform_device *pdev)
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dev->i2s_base = devm_ioremap_resource(&pdev->dev, res);
-	dev_dbg(&pdev->dev, "I2S get i2s_base=0x%p\n", dev->i2s_base);
+	dev_err(&pdev->dev, "I2S get i2s_base=0x%p\n", dev->i2s_base);
 	if (IS_ERR(dev->i2s_base))
 		return PTR_ERR(dev->i2s_base);
 
@@ -1131,7 +1206,7 @@ static int cvi_i2s_probe(struct platform_device *pdev)
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq >= 0) {
-		dev_dbg(&pdev->dev, "I2S get IRQ=0x%x\n", irq);
+		dev_err(&pdev->dev, "I2S get IRQ=0x%x\n", irq);
 		ret = devm_request_irq(&pdev->dev, irq, i2s_irq_handler, 0,
 				       pdev->name, dev);
 		if (ret < 0) {
diff --git a/u-boot-2021.10/board/cvitek/cv180x/board.c b/u-boot-2021.10/board/cvitek/cv180x/board.c
index bfd1061b1..928aea125 100644
--- a/u-boot-2021.10/board/cvitek/cv180x/board.c
+++ b/u-boot-2021.10/board/cvitek/cv180x/board.c
@@ -157,9 +157,37 @@ void pinmux_config(int io_type)
 
 #include "../cvi_board_init.c"
 
+/*
+0x03009804[0] = 1'b1 (rg_ephy_apb_rw_sel=1, use apb interface)
+0x03009808[4:0] = 5'b00001 (rg_ephy_pll_stable_cnt[4:0] = 5'd1 (10us)
+0x03009800[2] = 0x0905 (rg_ephy_dig_rst_n=1, reset release, other keep default)
+wait 10us
+0x0300907C[12:8]= 5'b00101 (page_sel_mode0 = page 5)
+0x03009078[11:0] = 0xF00 (set to gpio from top)
+0x03009074[10:9 2:1]= 0x606 (set ephy rxp&rxm input&output enable)
+0x03009070[10:9 2:1]= 0x606 (set ephy rxp&rxm input&output enable)
+*/
+// static void cv180x_i2s2_init(void)
+// {
+// 	printk("cv180x_i2s2_init\n");
+// 	mmio_write_32(0x03009804, 0x0001);
+// 	mmio_write_32(0x03009808, 0x0001);
+// 	mmio_write_32(0x03009800, 0x0905);
+
+// 	// Wait PLL_Lock, Lock_Status p5.0x12@[15] = 1
+// 	mdelay(1);
+
+// 	mmio_write_32(0x0300907C, 0x0005);
+// 	mmio_write_32(0x03009078, 0x0F00);
+// 	mmio_write_32(0x03009074, 0x0606);
+// 	mmio_write_32(0x03009070, 0x0606);
+// }
+
 #if defined(CONFIG_PHY_CVITEK)
 static void cv180x_ephy_id_init(void)
 {
+	printk("cv180x_ephy_id_init\n");
+
 	// set rg_ephy_apb_rw_sel 0x0804@[0]=1/APB by using APB interface
 	mmio_write_32(0x03009804, 0x0001);
 
@@ -215,10 +243,14 @@ int board_init(void)
 	mmio_write_16(TIME_RECORDS_FIELD_UBOOT_START, start_time);
 
 #if defined(CONFIG_PHY_CVITEK) /* config cvitek cv180x eth internal phy on ASIC board */
-	cv180x_ephy_id_init();
+	cv180x_ephy_id_init();	// close eth0
 	cv180x_ephy_led_pinmux();
 #endif
 
+// #if defined(CONFIG_SND_SOC_CV1835_MAX98357A)
+	// cv180x_i2s2_init();			// open i2s2
+// #endif
+
 #if defined(CONFIG_NAND_SUPPORT)
 	pinmux_config(PINMUX_SPI_NAND);
 #elif defined(CONFIG_SPI_FLASH)

