2026年1月31日 星期六

RV1106 - ES8311 錄音/音效卡接入 Linux Device 設定與採坑

去年因為希望評估 RV1106 瑞芯微系列晶片用於產品,買了 Luckfox 幸狐的開發板開始做了周邊的 POC 和調研,但由於坑實在太多,故此紀錄。

環境設定

我想說,不可能用 Windows 去編譯,請務必使用 WSL Ubuntu



手動編譯 Buildroot

由於我是在 WSL 上編譯,故一定是在 Linux 上面做交叉編譯 [1] ,首先把整個 repo clone 到 WSL  /home/luckfox-pico 路徑裡面。 (建議移動過去,因為原本 Windows 路徑是 NTFS,在 wsl 是 ext4 編譯速度大約可以快 10 倍)。


git clone https://github.com/LuckfoxTECH/luckfox-pico.git


然後,優先清掉整個 wsl 依賴 Windows 的變數:


export PATH=$(echo $PATH | tr ':' '\n' | grep -v "/mnt/c/" | tr '\n' ':' | sed 's/:$//')


清掉之後後面編譯才不會出問題。


首先要選擇版本: 

./build.sh lunch
Lunch menu...pick the Luckfox Pico hardware version:
  选择 Luckfox Pico 硬件版本:
                [0] RV1103_Luckfox_Pico
                [1] RV1103_Luckfox_Pico_Mini
                [2] RV1103_Luckfox_Pico_Plus
                [3] RV1103_Luckfox_Pico_WebBee
                [4] RV1106_Luckfox_Pico_Pro_Max
                [5] RV1106_Luckfox_Pico_Ultra
                [6] RV1106_Luckfox_Pico_Ultra_W
                [7] RV1106_Luckfox_Pico_Pi
                [8] RV1106_Luckfox_Pico_Pi_W
                [9] RV1106_Luckfox_Pico_86Panel
                [10] RV1106_Luckfox_Pico_86Panel_W
                [11] RV1106_Luckfox_Pico_Zero
                [12] custom

Which would you like? [0~12][default:0]: 我是買 Pro Max ,故選擇 4
  Lunch menu...pick the boot medium:

  选择启动媒介:
                [0] SD_CARD
                [1] SPI_NAND
                
Which would you like? [0~1][default:0]: 啟動我是 USB 燒到上面記憶體,所以用 1


設定交叉編譯環境

要去把設定都加到環境變數,使用這個:

cd ~/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf
source env_install_toolchain.sh

注意這裡的交叉編譯版本是 arm-rockchip830-linux-uclibcgnueabihf ,這不需要手動下載,因為整個 SDK 包裡面都有了。 (只是日後需要檢查版本時要記得用這個)


最後執行

./build.sh

開始編譯,編譯完之後,去這個目錄 luckfox-pico\tools\windows\SocToolKit 找到 SocToolKit.exe,打開來之後,下面 Search Path 選到 luckfox-pico\output\image 剛才編譯完的內容。

開始燒錄時,兩隻手按著 reset , boot 按鈕,把 reset 鬆開,或是按著 boot 插上 usd 就可以被偵測到燒錄。  第一次燒錄可以全部都勾選,後面如果只是調整驅動就只要選第一個跟 boot 就可以了。 (只要是僅做 ./build kernel,可以都只燒錄 boot)


ES8311 配置

首先,要去找到設備樹位置

luckfox-pico\sysdrv\source\kernel\arch\arm\boot\dts\rv1106g-luckfox-pico-pro-max.dts

並且進去裡面改內容:


// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
 */

/dts-v1/;

#include "rv1106.dtsi"
#include "rv1106-evb.dtsi"
#include "rv1106-luckfox-pico-pro-max-ipc.dtsi"

/ {
	model = "Luckfox Pico Pro Max";
	compatible = "rockchip,rv1103g-38x38-ipc-v10", "rockchip,rv1106g3";

	/* 音效卡配置 */
    es8311_sound: es8311-sound {
        status = "okay";
        compatible = "rockchip,multicodecs-card"; // 使用 multicodecs-card 驅動支援模式
        rockchip,card-name = "rockchip-es8311"; // 命名

        // MCLK 用 256bit
        simple-audio-card,mclk-fs = <256>;
        rockchip,mclk-fs = <256>;
        
        // 音效卡 routing 點
		// refer to: https://github.com/LuckfoxTECH/luckfox-pico/blob/994243753789e1b40ef91122e8b3688aae8f01b8/sysdrv/source/kernel/sound/soc/codecs/es8311.c#L4
		rockchip,audio-routing =
			"Headphone", "DIFFERENTIAL OUT",
			"Speaker", "DIFFERENTIAL OUT",
			"AMIC", "Main Mic";

        rockchip,format = "i2s"; // 使用 i2s 格式
         
        // 指定下方設備樹描述
        rockchip,cpu = <&i2s0_8ch>;
        rockchip,codec = <&es8311>;

        // bitclock 反轉
		simple-audio-card,bitclock-inversion;

		pinctrl-names = "default";
        pinctrl-0 = <&hp_det>; // 耳機連接 detection
    };
};

// &rgb {
// 	status = "disabled";
// };

/**********CRU**********/
//&cru {
//	assigned-clocks =
//		<&cru PLL_GPLL>, <&cru PLL_CPLL>,
//		<&cru ARMCLK>,
//		<&cru ACLK_PERI_ROOT>, <&cru HCLK_PERI_ROOT>,
//		<&cru PCLK_PERI_ROOT>, <&cru ACLK_BUS_ROOT>,
//		<&cru PCLK_TOP_ROOT>, <&cru PCLK_PMU_ROOT>,
//		<&cru HCLK_PMU_ROOT>, <&cru CLK_500M_SRC>;
//	assigned-clock-rates =
//		<1188000000>, <700000000>,
//		<1104000000>,
//		<400000000>, <200000000>,
//		<100000000>, <300000000>,
//		<100000000>, <100000000>,
//		<200000000>, <700000000>;
//};

/**********NPU**********/
//&npu {
//	assigned-clock-rates = <700000000>;
//};

/**********FLASH**********/
&sfc {
	status = "okay";
	flash@0 {
		compatible = "spi-nand";
		reg = <0>;
		spi-max-frequency = <75000000>;
		spi-rx-bus-width = <4>;
		spi-tx-bus-width = <1>;
	};
};

/**********SDMMC**********/
&sdmmc {
	max-frequency = <50000000>;
	no-mmc;
	bus-width = <4>;
	cap-mmc-highspeed;
	cap-sd-highspeed;
	disable-wp;

	//sdio
	cap-sdio-irq;
	non-removable;
	no-1-8-v;
	supports-sdio;

	pinctrl-names = "default";
	pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_bus4>;
	status = "okay";
};

/**********ETH**********/
&gmac {
	status = "okay";
};

/**********USB**********/
&u2phy {
	status = "okay";
};

&u2phy_otg {
	rockchip,dis-u2-susphy;
	status = "okay";
};

&usbdrd {
	status = "okay";
};

&usbdrd_dwc3 {
	status = "okay";
	dr_mode = "peripheral";
};

/********** SPI **********/
&spi0 { status = "disabled"; };

/********** I2C **********/

&i2c4 {
	// 因為複用先關閉 (但不知道關閉會不會影響到 i2s)
	status = "disabled";
};

// 因為複用先關閉
&uart0 { 
	status = "disabled"; 
};

&uart1 { 
	status = "disabled"; 
};

/********** I2C 配置 **********/
&i2c3 { 
    status = "okay"; 
    pinctrl-names = "default";
    /* 使用自定義引腳配置,確保 Mode 為 5 (I2C 功能) */
    pinctrl-0 = <&i2c3m0_scl &i2c3m0_sda>; 

    es8311: es8311@18 {
        status = "okay";
        compatible = "everest,es8311";
        reg = <0x18>; /* I2C 位址 0x18 */

        /* 時鐘配置:提供 MCLK 給 ES8311 運行 */
        clocks = <&cru I2S0_8CH_MCLKOUT>;
        clock-names = "mclk";

        /* 指定 MCLK 頻率,12.288MHz 是 48kHz 採樣率的整數倍 */
        assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
        assigned-clock-rates = <12288000>;

        #sound-dai-cells = <0>;
    };
};

/********** I2S 配置 **********/
&i2s0_8ch {
    status = "okay";
    pinctrl-names = "default";

	/* 強制開啟 I2S 相關時鐘,同時強制指定內部時鐘與輸出時鐘 */
    assigned-clocks = <&cru MCLK_I2S0_8CH_TX>, 
                      <&cru MCLK_I2S0_8CH_RX>, 
                      <&cru I2S0_8CH_MCLKOUT>;
    assigned-clock-rates = <12288000>, 
                           <12288000>, 
                           <12288000>;

    // assigned-clock-rates = <12288000>;
	#clock-cells = <0>;
	regulator-always-on;
    
    /* 直接引用手寫指定的腳位 SCLK, LRCK, SDI, SDO, MCLK (看 I2C3M0腳位處,官方沒有寫可以復用,但你可以自己強制復用腳位給 I2S) */
    pinctrl-0 = <&i2s0_8ch_m0_sclko 
                 &i2s0_8ch_m0_lrckx 
                 &i2s0_8ch_m0_sdi0 
                 &i2s0_8ch_m0_sdo0 
                 &i2s0_8ch_m0_mclk>;

    /* 時鐘模式:TX (發送) 與 RX (接收) 共用時鐘線: 1 */
    rockchip,clk-trcm = <1>;

    /* 確保時鐘相位沒有偏移 */
	rockchip,tdm-chip-delay = <0>; 

    /* 時鐘來源設定 */
    clocks = <&cru MCLK_I2S0_8CH_TX>, <&cru MCLK_I2S0_8CH_RX>, <&cru HCLK_I2S0>;
    clock-names = "mclk_tx", "mclk_rx", "hclk";

    #sound-dai-cells = <0>;
};

/********** Pin Control 自定義區 **********/
&pinctrl {
    /* 自定義 I2C3 腳位配置,確保模式切換到 5 */
    i2c3 {
        i2c3m0_sda: i2c3m0-sda {
			// ????? 2026/01/08 再次確定一下這裡要 pull up 嗎?
            rockchip,pins = <2 RK_PA7 5 &pcfg_pull_up>; 
        };
        i2c3m0_scl: i2c3m0-scl {
            rockchip,pins = <2 RK_PA6 5 &pcfg_pull_up>;
        };
    };

    /* 如果有特殊按鍵或檢測腳位在此定義 */
    audio_pins {
        hp_det: hp-det {
            rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
        };
    };
	
};

/**********UART**********/
/* UART3_M1 */
&uart3 {
	status = "disabled";
};

/* UART4_M1 */
&uart4 {
	status = "disabled";
};

/**********RTC**********/
&rtc {
	status = "okay";
};



然後,因為我們引用到腳位設定,所以去通用 pinctrl 位置也改一下:

\luckfox-pico\sysdrv\source\kernel\arch\arm\boot\dts\rv1106-pinctrl.dtsi

裡面內容改為:


// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
 */

#include <dt-bindings/pinctrl/rockchip.h>
#include "rockchip-pinconf.dtsi"

/*
 * This file is auto generated by pin2dts tool, please keep these code
 * by adding changes at end of this file.
 */
&pinctrl {
	adc {
		/omit-if-no-ref/
		adc_pins: adc-pins {
			rockchip,pins =
				/* adc_in0 */
				<4 RK_PC0 1 &pcfg_pull_none>,
				/* adc_in1 */
				<4 RK_PC1 1 &pcfg_pull_none>;
		};
	};

	avs {
		/omit-if-no-ref/
		avs_pins: avs-pins {
			rockchip,pins =
				/* avs_arm */
				<1 RK_PA2 2 &pcfg_pull_none>;
		};
	};

	clk {
		/omit-if-no-ref/
		clk_32k: clk-32k {
			rockchip,pins =
				/* clk_32k */
				<0 RK_PA0 2 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		clk_refout: clk-refout {
			rockchip,pins =
				/* clk_refout */
				<0 RK_PA0 3 &pcfg_pull_none>;
		};
	};

	dsmaudio {
		/omit-if-no-ref/
		dsmaudio_pins: dsmaudio-pins {
			rockchip,pins =
				/* dsmaudio_n */
				<1 RK_PD3 7 &pcfg_pull_none>,
				/* dsmaudio_p */
				<1 RK_PD2 7 &pcfg_pull_none>;
		};
	};

	emmc {
		/omit-if-no-ref/
		emmc_bus8: emmc-bus8 {
			rockchip,pins =
				/* emmc_d0 */
				<4 RK_PA4 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d1 */
				<4 RK_PA3 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d2 */
				<4 RK_PA2 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d3 */
				<4 RK_PA6 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d4 */
				<4 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d5 */
				<4 RK_PA7 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d6 */
				<4 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
				/* emmc_d7 */
				<4 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		emmc_clk: emmc-clk {
			rockchip,pins =
				/* emmc_clk */
				<4 RK_PB1 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		emmc_cmd: emmc-cmd {
			rockchip,pins =
				/* emmc_cmd */
				<4 RK_PB0 1 &pcfg_pull_up_drv_level_2>;
		};
	};

	flash {
		/omit-if-no-ref/
		flash_pins: flash-pins {
			rockchip,pins =
				/* flash_trig_out */
				<2 RK_PA6 6 &pcfg_pull_none>;
		};
	};

	fspi {
		/omit-if-no-ref/
		fspi_pins: fspi-pins {
			rockchip,pins =
				/* fspi_clk */
				<4 RK_PB1 2 &pcfg_pull_up_drv_level_2>,
				/* fspi_d0 */
				<4 RK_PA4 2 &pcfg_pull_none>,
				/* fspi_d1 */
				<4 RK_PA3 2 &pcfg_pull_none>,
				/* fspi_d2 */
				<4 RK_PA2 2 &pcfg_pull_none>,
				/* fspi_d3 */
				<4 RK_PA6 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		fspi_cs0: fspi-cs0 {
			rockchip,pins =
				/* fspi_cs0n */
				<4 RK_PB0 2 &pcfg_pull_up>;
		};
	};

	hpmcu {
		/omit-if-no-ref/
		hpmcum0_pins: hpmcum0-pins {
			rockchip,pins =
				/* hpmcu_jtag_tck_m0 */
				<1 RK_PB2 3 &pcfg_pull_none>,
				/* hpmcu_jtag_tms_m0 */
				<1 RK_PB3 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		hpmcum1_pins: hpmcum1-pins {
			rockchip,pins =
				/* hpmcu_jtag_tck_m1 */
				<3 RK_PA7 4 &pcfg_pull_none>,
				/* hpmcu_jtag_tms_m1 */
				<3 RK_PA6 4 &pcfg_pull_none>;
		};
	};

	i2c0 {
		/omit-if-no-ref/
		i2c0m0_xfer: i2c0m0-xfer {
			rockchip,pins =
				/* i2c0_scl_m0 */
				<1 RK_PA3 2 &pcfg_pull_none_smt>,
				/* i2c0_sda_m0 */
				<1 RK_PA4 2 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c0m1_xfer: i2c0m1-xfer {
			rockchip,pins =
				/* i2c0_scl_m1 */
				<4 RK_PA1 4 &pcfg_pull_none_smt>,
				/* i2c0_sda_m1 */
				<4 RK_PA0 4 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c0m2_xfer: i2c0m2-xfer {
			rockchip,pins =
				/* i2c0_scl_m2 */
				<3 RK_PA4 3 &pcfg_pull_none_smt>,
				/* i2c0_sda_m2 */
				<3 RK_PA5 3 &pcfg_pull_none_smt>;
		};
	};

	i2c1 {
		/omit-if-no-ref/
		i2c1m0_xfer: i2c1m0-xfer {
			rockchip,pins =
				/* i2c1_scl_m0 */
				<0 RK_PA5 1 &pcfg_pull_none_smt>,
				/* i2c1_sda_m0 */
				<0 RK_PA6 1 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c1m1_xfer: i2c1m1-xfer {
			rockchip,pins =
				/* i2c1_scl_m1 */
				<2 RK_PB0 2 &pcfg_pull_none_smt>,
				/* i2c1_sda_m1 */
				<2 RK_PB1 2 &pcfg_pull_none_smt>;
		};
	};

	i2c2 {
		/omit-if-no-ref/
		i2c2m0_xfer: i2c2m0-xfer {
			rockchip,pins =
				/* i2c2_scl_m0 */
				<1 RK_PA0 2 &pcfg_pull_none_smt>,
				/* i2c2_sda_m0 */
				<1 RK_PA1 2 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c2m1_xfer: i2c2m1-xfer {
			rockchip,pins =
				/* i2c2_scl_m1 */
				<4 RK_PA7 4 &pcfg_pull_none_smt>,
				/* i2c2_sda_m1 */
				<4 RK_PA5 4 &pcfg_pull_none_smt>;
		};
	};

	i2c3 {
		// 暫時不用這裡的定義了
		// 這裡是原始定義 SCL, SDA
		/omit-if-no-ref/
		i2c3m0_xfer: i2c3m0-xfer {
			/* 強制啟用內部上拉: pcfg_pull_none_smt -> pcfg_pull_up_smt,不然沒有速度 */
			rockchip,pins =
				/* i2c3_scl_m0 - GPIO2 - A6 */
				<2 RK_PA6 5 &pcfg_pull_up>,
				/* i2c3_sda_m0 GPIO2- A7 */
				<2 RK_PA7 5 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		i2c3m1_xfer: i2c3m1-xfer {
			rockchip,pins =
				/* i2c3_scl_m1 */
				<1 RK_PD3 3 &pcfg_pull_none_smt>,
				/* i2c3_sda_m1 */
				<1 RK_PD2 3 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c3m2_xfer: i2c3m2-xfer {
			rockchip,pins =
				/* i2c3_scl_m2 */
				<3 RK_PD1 3 &pcfg_pull_none_smt>,
				/* i2c3_sda_m2 */
				<3 RK_PD2 3 &pcfg_pull_none_smt>;
		};
	};

	i2c4 {
		// 需要參考 i2c3m0_xfer 定義,這裡原本的腳位定義都重複了
		/omit-if-no-ref/
		i2c4m0_xfer: i2c4m0-xfer {
			rockchip,pins =
				// 借用 i2c3 控制腳位
				/* i2c3_scl_m0 - GPIO2 - A6 */
				<2 RK_PA6 5 &pcfg_pull_none_smt>,
				/* i2c3_sda_m0 GPIO2- A7 */
				<2 RK_PA7 5 &pcfg_pull_none_smt>;

				// 以下都重複了,要用上面修改的定義
				/* i2c4_scl_m0 */
				// <2 RK_PA1 5 &pcfg_pull_none_smt>,
				/* i2c4_sda_m0 */
				// <2 RK_PA0 5 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c4m1_xfer: i2c4m1-xfer {
			rockchip,pins =
				/* i2c4_scl_m1 */
				<1 RK_PC2 4 &pcfg_pull_none_smt>,
				/* i2c4_sda_m1 */
				<1 RK_PC3 4 &pcfg_pull_none_smt>;
		};

		/omit-if-no-ref/
		i2c4m2_xfer: i2c4m2-xfer {
			rockchip,pins =
				/* i2c4_scl_m2 */
				<3 RK_PC7 3 &pcfg_pull_none_smt>,
				/* i2c4_sda_m2 */
				<3 RK_PD0 3 &pcfg_pull_none_smt>;
		};
	};

	i2s0 {
		/omit-if-no-ref/
		i2s0_pins: i2s0-pins {
			rockchip,pins =
				/* i2s0_lrck GPIO2 - A1*/
				<2 RK_PA1 2 &pcfg_pull_none>,
				/* i2s0_mclk - GPIO2 - A2 */
				<2 RK_PA2 2 &pcfg_pull_none>,
				/* i2s0_sclk - GPIO2 - A0 */
				<2 RK_PA0 2 &pcfg_pull_none>,
				/* i2s0_sdi0 - GPIO2 - A5 (記得要反過來,DIN 到這裡) */
				<2 RK_PA5 2 &pcfg_pull_none>,
				/* i2s0_sdo0 - GPIO2 - A4 (記得要反過來,DOUT 到這裡)*/
				<2 RK_PA4 2 &pcfg_pull_none>;
				
				// 這兩個是從上面 i2c3 定義拿的
				/* i2c3_scl_m0 - GPIO2 - A6 */
				// <2 RK_PA6 2 &pcfg_pull_none_smt>,
				/* i2c3_sda_m0 GPIO2- A7 */
				// <2 RK_PA7 2 &pcfg_pull_none_smt>;
				


				// 下面註解 (可以考慮做 pcfg_pull_up_smt 上拉電阻)
				/* i2s0_sdo1_sdi3 */
				// <2 RK_PA7 2 &pcfg_pull_none>,
				/* i2s0_sdo2_sdi2 */
				// <2 RK_PA6 2 &pcfg_pull_none>,
				/* i2s0_sdo3_sdi1 */
				// <2 RK_PA3 2 &pcfg_pull_none>;
		};

		// A: 以下都是移植 ES8311 板級定義 (M0),腳位可能會跟其他板子不太一樣
		/omit-if-no-ref/
		// i2s0m0_mclk: i2s0m0-mclk {
		// 	rockchip,pins =
		// 		/* i2s0m0_mclk */
		// 		<2 RK_PA2 2 &pcfg_pull_none>;
		// };

		/* I2S0 Master Clock - 提供給 ES8311 的時鐘 */
        i2s0_8ch_m0_mclk: i2s0-8ch-m0-mclk {
            rockchip,pins = <2 RK_PA2 2 &pcfg_pull_none>;
        };

        /* I2S0 Serial Clock - 位元時鐘 */
        i2s0_8ch_m0_sclko: i2s0-8ch-m0-sclko {
            rockchip,pins = <2 RK_PA0 2 &pcfg_pull_none>;
        };

        /* I2S0 LR Clock - 左右聲道切換時鐘 */
        i2s0_8ch_m0_lrckx: i2s0-8ch-m0-lrckx {
            rockchip,pins = <2 RK_PA1 2 &pcfg_pull_none>;
        };

        /* I2S0 Serial Data Input - 接收 ES8311 的錄音資料 */
        i2s0_8ch_m0_sdi0: i2s0-8ch-m0-sdi0 {
            rockchip,pins = <2 RK_PA5 2 &pcfg_pull_none>;
        };

        /* I2S0 Serial Data Output - 發送播放資料給 ES8311 */
        i2s0_8ch_m0_sdo0: i2s0-8ch-m0-sdo0 {
            rockchip,pins = <2 RK_PA4 2 &pcfg_pull_none>;
        };
	};

	lcd {
		/omit-if-no-ref/
		lcd_pins: lcd-pins {
			rockchip,pins =
				/* lcd_clk */
				<1 RK_PD3 1 &pcfg_pull_none_drv_level_4>,
				/* lcd_d0 */
				<1 RK_PC7 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d1 */
				<1 RK_PC6 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d2 */
				<1 RK_PC5 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d3 */
				<1 RK_PC4 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d4 */
				<1 RK_PC3 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d5 */
				<1 RK_PC2 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d6 */
				<1 RK_PC1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d7 */
				<1 RK_PC0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d8 */
				<2 RK_PA0 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d9 */
				<2 RK_PA1 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d10 */
				<2 RK_PA2 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d11 */
				<2 RK_PA3 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d12 */
				<2 RK_PA4 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d13 */
				<2 RK_PA5 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d14 */
				<2 RK_PA6 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d15 */
				<2 RK_PA7 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d16 */
				<2 RK_PB0 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d17 */
				<2 RK_PB1 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_den */
				<1 RK_PD0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_hsync */
				<1 RK_PD1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_vsync */
				<1 RK_PD2 1 &pcfg_pull_none_drv_level_3>;
		};
	};

	lpmcu {
		/omit-if-no-ref/
		lpmcum0_pins: lpmcum0-pins {
			rockchip,pins =
				/* lpmcu_jtag_tck_m0 */
				<1 RK_PB2 4 &pcfg_pull_none>,
				/* lpmcu_jtag_tms_m0 */
				<1 RK_PB3 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		lpmcum1_pins: lpmcum1-pins {
			rockchip,pins =
				/* lpmcu_jtag_tck_m1 */
				<3 RK_PA4 4 &pcfg_pull_none>,
				/* lpmcu_jtag_tms_m1 */
				<3 RK_PA5 4 &pcfg_pull_none>;
		};
	};

	mipi {
		/omit-if-no-ref/
		mipi_pins: mipi-pins {
			rockchip,pins =
				/* mipi_lvds_ck0n */
				<3 RK_PC0 2 &pcfg_pull_none>,
				/* mipi_lvds_ck0p */
				<3 RK_PC1 2 &pcfg_pull_none>,
				/* mipi_lvds_ck1n */
				<3 RK_PB2 2 &pcfg_pull_none>,
				/* mipi_lvds_ck1p */
				<3 RK_PB3 2 &pcfg_pull_none>,
				/* mipi_lvds_d0n */
				<3 RK_PC2 2 &pcfg_pull_none>,
				/* mipi_lvds_d0p */
				<3 RK_PC3 2 &pcfg_pull_none>,
				/* mipi_lvds_d1n */
				<3 RK_PB6 2 &pcfg_pull_none>,
				/* mipi_lvds_d1p */
				<3 RK_PB7 2 &pcfg_pull_none>,
				/* mipi_lvds_d2n */
				<3 RK_PB4 2 &pcfg_pull_none>,
				/* mipi_lvds_d2p */
				<3 RK_PB5 2 &pcfg_pull_none>,
				/* mipi_lvds_d3n */
				<3 RK_PB0 2 &pcfg_pull_none>,
				/* mipi_lvds_d3p */
				<3 RK_PB1 2 &pcfg_pull_none>;
		};
	};

	pmic {
		/omit-if-no-ref/
		pmicm0_pins: pmicm0-pins {
			rockchip,pins =
				/* pmic_sleep_m0 */
				<0 RK_PA4 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pmicm1_pins: pmicm1-pins {
			rockchip,pins =
				/* pmic_sleep_m1 */
				<0 RK_PA3 1 &pcfg_pull_none>;
		};
	};

	pmu {
		/omit-if-no-ref/
		pmu_pins: pmu-pins {
			rockchip,pins =
				/* pmu_debug */
				<1 RK_PA1 3 &pcfg_pull_none>;
		};
	};

	prelight {
		/omit-if-no-ref/
		prelight_pins: prelight-pins {
			rockchip,pins =
				/* prelight_trig_out */
				<2 RK_PA7 6 &pcfg_pull_none>;
		};
	};

	pwm0 {
		/omit-if-no-ref/
		pwm0m0_pins: pwm0m0-pins {
			rockchip,pins =
				/* pwm0_m0 */
				<1 RK_PA2 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm0m1_pins: pwm0m1-pins {
			rockchip,pins =
				/* pwm0_m1 */
				<1 RK_PD2 6 &pcfg_pull_none>;
		};
	};

	pwm1 {
		/omit-if-no-ref/
		pwm1m0_pins: pwm1m0-pins {
			rockchip,pins =
				/* pwm1_m0 */
				<0 RK_PA4 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm1m1_pins: pwm1m1-pins {
			rockchip,pins =
				/* pwm1_m1 */
				<4 RK_PC1 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm1m2_pins: pwm1m2-pins {
			rockchip,pins =
				/* pwm1_m2 */
				<3 RK_PD3 2 &pcfg_pull_none>;
		};
	};

	pwm2 {
		/omit-if-no-ref/
		pwm2m0_pins: pwm2m0-pins {
			rockchip,pins =
				/* pwm2_m0 */
				<0 RK_PA1 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm2m1_pins: pwm2m1-pins {
			rockchip,pins =
				/* pwm2_m1 */
				<2 RK_PA6 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm2m2_pins: pwm2m2-pins {
			rockchip,pins =
				/* pwm2_m2 */
				<1 RK_PC0 3 &pcfg_pull_none>;
		};
	};

	pwm3 {
		/omit-if-no-ref/
		pwm3m0_pins: pwm3m0-pins {
			rockchip,pins =
				/* pwm3_ir_m0 */
				<0 RK_PA2 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm3m1_pins: pwm3m1-pins {
			rockchip,pins =
				/* pwm3_ir_m1 */
				<1 RK_PB0 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm3m2_pins: pwm3m2-pins {
			rockchip,pins =
				/* pwm3_ir_m2 */
				<1 RK_PD0 3 &pcfg_pull_none>;
		};
	};

	pwm4 {
		/omit-if-no-ref/
		pwm4m0_pins: pwm4m0-pins {
			rockchip,pins =
				/* pwm4_m0 */
				<1 RK_PA1 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm4m1_pins: pwm4m1-pins {
			rockchip,pins =
				/* pwm4_m1 */
				<2 RK_PA7 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm4m2_pins: pwm4m2-pins {
			rockchip,pins =
				/* pwm4_m2 */
				<1 RK_PC1 3 &pcfg_pull_none>;
		};
	};

	pwm5 {
		/omit-if-no-ref/
		pwm5m0_pins: pwm5m0-pins {
			rockchip,pins =
				/* pwm5_m0 */
				<0 RK_PA5 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm5m1_pins: pwm5m1-pins {
			rockchip,pins =
				/* pwm5_m1 */
				<2 RK_PB0 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm5m2_pins: pwm5m2-pins {
			rockchip,pins =
				/* pwm5_m2 */
				<1 RK_PC2 3 &pcfg_pull_none>;
		};
	};

	pwm6 {
		/omit-if-no-ref/
		pwm6m0_pins: pwm6m0-pins {
			rockchip,pins =
				/* pwm6_m0 */
				<0 RK_PA6 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm6m1_pins: pwm6m1-pins {
			rockchip,pins =
				/* pwm6_m1 */
				<2 RK_PB1 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm6m2_pins: pwm6m2-pins {
			rockchip,pins =
				/* pwm6_m2 */
				<1 RK_PC3 3 &pcfg_pull_none>;
		};
	};

	pwm7 {
		/omit-if-no-ref/
		pwm7m0_pins: pwm7m0-pins {
			rockchip,pins =
				/* pwm7_ir_m0 */
				<1 RK_PA0 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm7m1_pins: pwm7m1-pins {
			rockchip,pins =
				/* pwm7_ir_m1 */
				<1 RK_PB1 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm7m2_pins: pwm7m2-pins {
			rockchip,pins =
				/* pwm7_ir_m2 */
				<3 RK_PC6 2 &pcfg_pull_none>;
		};
	};

	pwm8 {
		/omit-if-no-ref/
		pwm8m0_pins: pwm8m0-pins {
			rockchip,pins =
				/* pwm8_m0 */
				<3 RK_PA3 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm8m1_pins: pwm8m1-pins {
			rockchip,pins =
				/* pwm8_m1 */
				<1 RK_PC4 3 &pcfg_pull_none>;
		};
	};

	pwm9 {
		/omit-if-no-ref/
		pwm9m0_pins: pwm9m0-pins {
			rockchip,pins =
				/* pwm9_m0 */
				<3 RK_PA2 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm9m1_pins: pwm9m1-pins {
			rockchip,pins =
				/* pwm9_m1 */
				<1 RK_PC5 3 &pcfg_pull_none>;
		};
	};

	pwm10 {
		/omit-if-no-ref/
		pwm10m0_pins: pwm10m0-pins {
			rockchip,pins =
				/* pwm10_m0 */
				<3 RK_PA4 5 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm10m1_pins: pwm10m1-pins {
			rockchip,pins =
				/* pwm10_m1 */
				<1 RK_PC6 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm10m2_pins: pwm10m2-pins {
			rockchip,pins =
				/* pwm10_m2 */
				<1 RK_PD1 3 &pcfg_pull_none>;
		};
	};

	pwm11 {
		/omit-if-no-ref/
		pwm11m0_pins: pwm11m0-pins {
			rockchip,pins =
				/* pwm11_ir_m0 */
				<3 RK_PA5 5 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm11m1_pins: pwm11m1-pins {
			rockchip,pins =
				/* pwm11_ir_m1 */
				<1 RK_PC7 3 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		pwm11m2_pins: pwm11m2-pins {
			rockchip,pins =
				/* pwm11_ir_m2 */
				<1 RK_PD3 5 &pcfg_pull_none>;
		};
	};

	rtc {
		/omit-if-no-ref/
		rtc_pins: rtc-pins {
			rockchip,pins =
				/* rtc_clko */
				<0 RK_PA0 4 &pcfg_pull_none>;
		};
	};

	sdmmc0 {
		/omit-if-no-ref/
		sdmmc0_bus4: sdmmc0-bus4 {
			rockchip,pins =
				/* sdmmc0_d0 */
				<3 RK_PA3 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc0_d1 */
				<3 RK_PA2 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc0_d2 */
				<3 RK_PA7 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc0_d3 */
				<3 RK_PA6 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc0_clk: sdmmc0-clk {
			rockchip,pins =
				/* sdmmc0_clk */
				<3 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc0_cmd: sdmmc0-cmd {
			rockchip,pins =
				/* sdmmc0_cmd */
				<3 RK_PA5 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc0_det: sdmmc0-det {
			rockchip,pins =
				/* sdmmc0_det */
				<3 RK_PA1 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		sdmmc0_idle_pins: sdmmc0-idle-pins {
			rockchip,pins =
				<3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>,
				<3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>,
				<3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>,
				<3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>,
				<3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_down>,
				<3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>;
		};
	};

	sdmmc1 {
		/omit-if-no-ref/
		sdmmc1m0_bus1: sdmmc1m0-bus1 {
			rockchip,pins =
				/* sdmmc1_d0_m0 */
				<2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m0_bus4: sdmmc1m0-bus4 {
			rockchip,pins =
				/* sdmmc1_d0_m0 */
				<2 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d1_m0 */
				<2 RK_PA0 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d2_m0 */
				<2 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d3_m0 */
				<2 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m0_clk: sdmmc1m0-clk {
			rockchip,pins =
				/* sdmmc1_clk_m0 */
				<2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m0_cmd: sdmmc1m0-cmd {
			rockchip,pins =
				/* sdmmc1_cmd_m0 */
				<2 RK_PA3 1 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m0_idle_pins: sdmmc1m0-idle-pins {
			rockchip,pins =
				<2 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>,
				<2 RK_PA1 RK_FUNC_GPIO &pcfg_pull_down>,
				<2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_down>,
				<2 RK_PA3 RK_FUNC_GPIO &pcfg_pull_down>,
				<2 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>,
				<2 RK_PA5 RK_FUNC_GPIO &pcfg_pull_down>;
		};

		/omit-if-no-ref/
		sdmmc1m1_bus4: sdmmc1m1-bus4 {
			rockchip,pins =
				/* sdmmc1_d0_m1 */
				<1 RK_PC1 5 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d1_m1 */
				<1 RK_PC0 5 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d2_m1 */
				<1 RK_PC5 5 &pcfg_pull_up_drv_level_2>,
				/* sdmmc1_d3_m1 */
				<1 RK_PC4 5 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m1_clk: sdmmc1m1-clk {
			rockchip,pins =
				/* sdmmc1_clk_m1 */
				<1 RK_PC2 5 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m1_cmd: sdmmc1m1-cmd {
			rockchip,pins =
				/* sdmmc1_cmd_m1 */
				<1 RK_PC3 5 &pcfg_pull_up_drv_level_2>;
		};

		/omit-if-no-ref/
		sdmmc1m1_idle_pins: sdmmc1m1-idle-pins {
			rockchip,pins =
				<1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_down>,
				<1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>,
				<1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>,
				<1 RK_PC3 RK_FUNC_GPIO &pcfg_pull_down>,
				<1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>,
				<1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_down>;
		};
	};

	spi0 {
		/omit-if-no-ref/
		spi0m0_pins: spi0m0-pins {
			rockchip,pins =
				/* spi0_clk_m0 */
				<1 RK_PC1 4 &pcfg_pull_none>,
				/* spi0_miso_m0 */
				<1 RK_PC3 6 &pcfg_pull_none>,
				/* spi0_mosi_m0 */
				<1 RK_PC2 6 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		spi0m0_cs0: spi0m0-cs0 {
			rockchip,pins =
				/* spi0_cs0n_m0 */
				<1 RK_PC0 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		spi0m0_cs1: spi0m0-cs1 {
			rockchip,pins =
				/* spi0_cs1n_m0 */
				<1 RK_PD2 5 &pcfg_pull_none>;
		};
	};

	spi1 {
		/omit-if-no-ref/
		spi1m0_pins: spi1m0-pins {
			rockchip,pins =
				/* spi1_clk_m0 */
				<4 RK_PA7 2 &pcfg_pull_none>,
				/* spi1_miso_m0 */
				<4 RK_PA0 2 &pcfg_pull_none>,
				/* spi1_mosi_m0 */
				<4 RK_PA1 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		spi1m0_cs0: spi1m0-cs0 {
			rockchip,pins =
				/* spi1_cs0n_m0 */
				<4 RK_PA5 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		spi1m0_cs1: spi1m0-cs1 {
			rockchip,pins =
				/* spi1_cs1n_m0 */
				<1 RK_PB1 3 &pcfg_pull_none>;
		};
	};

	uart0 {
		/omit-if-no-ref/
		uart0m0_xfer: uart0m0-xfer {
			rockchip,pins =
				/* uart0_rx_m0 */
				<0 RK_PA0 1 &pcfg_pull_up>,
				/* uart0_tx_m0 */
				<0 RK_PA1 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart0m1_xfer: uart0m1-xfer {
			rockchip,pins =
				/* uart0_rx_m1 */
				<2 RK_PB0 1 &pcfg_pull_up>,
				/* uart0_tx_m1 */
				<2 RK_PB1 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart0m1_ctsn: uart0m1-ctsn {
			rockchip,pins =
				/* uart0m1_ctsn */
				<2 RK_PA7 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart0m1_rtsn: uart0m1-rtsn {
			rockchip,pins =
				/* uart0m1_rtsn */
				<2 RK_PA6 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart0m2_xfer: uart0m2-xfer {
			rockchip,pins =
				/* uart0_rx_m2 */
				<4 RK_PA0 3 &pcfg_pull_up>,
				/* uart0_tx_m2 */
				<4 RK_PA1 3 &pcfg_pull_up>;
		};
	};

	uart1 {
		/omit-if-no-ref/
		uart1m0_xfer: uart1m0-xfer {
			rockchip,pins =
				/* uart1_rx_m0 */
				<1 RK_PA4 1 &pcfg_pull_up>,
				/* uart1_tx_m0 */
				<1 RK_PA3 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart1m0_ctsn: uart1m0-ctsn {
			rockchip,pins =
				/* uart1m0_ctsn */
				<0 RK_PA6 2 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart1m0_rtsn: uart1m0-rtsn {
			rockchip,pins =
				/* uart1m0_rtsn */
				<0 RK_PA5 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart1m1_xfer: uart1m1-xfer {
			rockchip,pins =
				/* uart1_rx_m1 */
				<2 RK_PA5 4 &pcfg_pull_up>,
				/* uart1_tx_m1 */
				<2 RK_PA4 4 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart1m1_ctsn: uart1m1-ctsn {
			rockchip,pins =
				/* uart1m1_ctsn */
				<2 RK_PA0 4 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart1m1_rtsn: uart1m1-rtsn {
			rockchip,pins =
				/* uart1m1_rtsn */
				<2 RK_PA1 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart1m2_xfer: uart1m2-xfer {
			rockchip,pins =
				/* uart1_rx_m2 */
				<4 RK_PA7 3 &pcfg_pull_up>,
				/* uart1_tx_m2 */
				<4 RK_PA5 3 &pcfg_pull_up>;
		};
	};

	uart2 {
		/omit-if-no-ref/
		uart2m0_xfer: uart2m0-xfer {
			rockchip,pins =
				/* uart2_rx_m0 */
				<3 RK_PA3 2 &pcfg_pull_up>,
				/* uart2_tx_m0 */
				<3 RK_PA2 2 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart2m1_xfer: uart2m1-xfer {
			rockchip,pins =
				/* uart2_rx_m1 */
				<1 RK_PB3 2 &pcfg_pull_up>,
				/* uart2_tx_m1 */
				<1 RK_PB2 2 &pcfg_pull_up>;
		};
	};

	uart3 {
		/omit-if-no-ref/
		uart3m0_xfer: uart3m0-xfer {
			rockchip,pins =
				/* uart3_rx_m0 */
				<1 RK_PA1 1 &pcfg_pull_up>,
				/* uart3_tx_m0 */
				<1 RK_PA0 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart3m1_xfer: uart3m1-xfer {
			rockchip,pins =
				/* uart3_rx_m1 */
				<1 RK_PD1 5 &pcfg_pull_up>,
				/* uart3_tx_m1 */
				<1 RK_PD0 5 &pcfg_pull_up>;
		};
	};

	uart4 {
		/omit-if-no-ref/
		uart4m0_xfer: uart4m0-xfer {
			rockchip,pins =
				/* uart4_rx_m0 */
				<1 RK_PB0 1 &pcfg_pull_up>,
				/* uart4_tx_m0 */
				<1 RK_PB1 1 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart4m1_xfer: uart4m1-xfer {
			rockchip,pins =
				/* uart4_rx_m1 */
				<1 RK_PC4 4 &pcfg_pull_up>,
				/* uart4_tx_m1 */
				<1 RK_PC5 4 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart4m1_ctsn: uart4m1-ctsn {
			rockchip,pins =
				/* uart4m1_ctsn */
				<1 RK_PC7 4 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart4m1_rtsn: uart4m1-rtsn {
			rockchip,pins =
				/* uart4m1_rtsn */
				<1 RK_PC6 4 &pcfg_pull_none>;
		};
	};

	uart5 {
		/omit-if-no-ref/
		uart5m0_xfer: uart5m0-xfer {
			rockchip,pins =
				/* uart5_rx_m0 */
				<3 RK_PA7 2 &pcfg_pull_up>,
				/* uart5_tx_m0 */
				<3 RK_PA6 2 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart5m0_ctsn: uart5m0-ctsn {
			rockchip,pins =
				/* uart5m0_ctsn */
				<3 RK_PA5 2 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart5m0_rtsn: uart5m0-rtsn {
			rockchip,pins =
				/* uart5m0_rtsn */
				<3 RK_PA4 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart5m1_xfer: uart5m1-xfer {
			rockchip,pins =
				/* uart5_rx_m1 */
				<1 RK_PD2 4 &pcfg_pull_up>,
				/* uart5_tx_m1 */
				<1 RK_PD3 4 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart5m1_ctsn: uart5m1-ctsn {
			rockchip,pins =
				/* uart5m1_ctsn */
				<1 RK_PD1 4 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart5m1_rtsn: uart5m1-rtsn {
			rockchip,pins =
				/* uart5m1_rtsn */
				<1 RK_PD0 4 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		uart5m2_xfer: uart5m2-xfer {
			rockchip,pins =
				/* uart5_rx_m2 */
				<3 RK_PD0 2 &pcfg_pull_up>,
				/* uart5_tx_m2 */
				<3 RK_PC7 2 &pcfg_pull_up>;
		};

		/omit-if-no-ref/
		uart5m2_ctsn: uart5m2-ctsn {
			rockchip,pins =
				/* uart5m2_ctsn */
				<3 RK_PD2 2 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		uart5m2_rtsn: uart5m2-rtsn {
			rockchip,pins =
				/* uart5m2_rtsn */
				<3 RK_PD1 2 &pcfg_pull_none>;
		};
	};

	vicap {
		/omit-if-no-ref/
		vicapm0_pins: vicapm0-pins {
			rockchip,pins =
				/* vicap_clkin_m0 */
				<3 RK_PC2 1 &pcfg_pull_none>,
				/* vicap_d0_m0 */
				<3 RK_PB0 1 &pcfg_pull_none>,
				/* vicap_d1_m0 */
				<3 RK_PB1 1 &pcfg_pull_none>,
				/* vicap_d2_m0 */
				<3 RK_PB2 1 &pcfg_pull_none>,
				/* vicap_d3_m0 */
				<3 RK_PB3 1 &pcfg_pull_none>,
				/* vicap_d4_m0 */
				<3 RK_PB4 1 &pcfg_pull_none>,
				/* vicap_d5_m0 */
				<3 RK_PB5 1 &pcfg_pull_none>,
				/* vicap_d6_m0 */
				<3 RK_PB6 1 &pcfg_pull_none>,
				/* vicap_d7_m0 */
				<3 RK_PB7 1 &pcfg_pull_none>,
				/* vicap_d8_m0 */
				<3 RK_PC0 1 &pcfg_pull_none>,
				/* vicap_d9_m0 */
				<3 RK_PC1 1 &pcfg_pull_none>,
				/* vicap_hsync_m0 */
				<3 RK_PC3 1 &pcfg_pull_none>,
				/* vicap_vsync_m0 */
				<3 RK_PC5 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		vicapm1_pins: vicapm1-pins {
			rockchip,pins =
				/* vicap_clkin_m1 */
				<1 RK_PD0 2 &pcfg_pull_none>,
				/* vicap_d0_m1 */
				<1 RK_PA2 3 &pcfg_pull_none>,
				/* vicap_d1_m1 */
				<1 RK_PB1 4 &pcfg_pull_none>,
				/* vicap_d2_m1 */
				<1 RK_PC0 2 &pcfg_pull_none>,
				/* vicap_d3_m1 */
				<1 RK_PC1 2 &pcfg_pull_none>,
				/* vicap_d4_m1 */
				<1 RK_PC2 2 &pcfg_pull_none>,
				/* vicap_d5_m1 */
				<1 RK_PC3 2 &pcfg_pull_none>,
				/* vicap_d6_m1 */
				<1 RK_PC4 2 &pcfg_pull_none>,
				/* vicap_d7_m1 */
				<1 RK_PC5 2 &pcfg_pull_none>,
				/* vicap_d8_m1 */
				<1 RK_PC6 2 &pcfg_pull_none>,
				/* vicap_d9_m1 */
				<1 RK_PC7 2 &pcfg_pull_none>,
				/* vicap_hsync_m1 */
				<1 RK_PD1 2 &pcfg_pull_none>,
				/* vicap_vsync_m1 */
				<1 RK_PD2 2 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		vicap_d10: vicap-d10 {
			rockchip,pins =
				/* vicap_d10 */
				<3 RK_PC6 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		vicap_d11: vicap-d11 {
			rockchip,pins =
				/* vicap_d11 */
				<3 RK_PC7 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		vicap_d12: vicap-d12 {
			rockchip,pins =
				/* vicap_d12 */
				<3 RK_PD0 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		vicap_d13: vicap-d13 {
			rockchip,pins =
				/* vicap_d13 */
				<3 RK_PD1 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		vicap_d14: vicap-d14 {
			rockchip,pins =
				/* vicap_d14 */
				<3 RK_PD2 1 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		vicap_d15: vicap-d15 {
			rockchip,pins =
				/* vicap_d15 */
				<3 RK_PD3 1 &pcfg_pull_none>;
		};
	};
};

/*
 * This part is edited handly.
 */
&pinctrl {
	vicap {
		/omit-if-no-ref/
		vicap_clkout_m0: vicap-clkout-m0 {
			rockchip,pins =
				/* vicap_clkout_m0 */
				<3 RK_PC4 1 &pcfg_pull_none>;
		};

		/omit-if-no-ref/
		vicap_clkout_m1: vicap-clkout-m1 {
			rockchip,pins =
				/* vicap_clkout_m1 */
				<1 RK_PD3 2 &pcfg_pull_none>;
		};
	};

	mipi {
		/omit-if-no-ref/
		mipi_refclk_out0: mipi-refclk-out0 {
			rockchip,pins =
				/* mipi_refclk_out0 */
				<3 RK_PC4 2 &pcfg_pull_none>;
		};
		/omit-if-no-ref/
		mipi_refclk_out1: mipi-refclk-out1 {
			rockchip,pins =
				/* mipi_refclk_out1 */
				<3 RK_PC6 3 &pcfg_pull_none>;
		};
	};

	lcd {
		/omit-if-no-ref/
		bt1120_pins: bt1120-pins {
			rockchip,pins =
				/* lcd_clk */
				<1 RK_PD3 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d0 */
				<1 RK_PC7 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d1 */
				<1 RK_PC6 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d2 */
				<1 RK_PC5 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d3 */
				<1 RK_PC4 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d4 */
				<1 RK_PC3 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d5 */
				<1 RK_PC2 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d6 */
				<1 RK_PC1 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d7 */
				<1 RK_PC0 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d8 */
				<2 RK_PA0 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d9 */
				<2 RK_PA1 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d10 */
				<2 RK_PA2 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d11 */
				<2 RK_PA3 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d12 */
				<2 RK_PA4 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d13 */
				<2 RK_PA5 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d14 */
				<2 RK_PA6 3 &pcfg_pull_none_drv_level_2>,
				/* lcd_d15 */
				<2 RK_PA7 3 &pcfg_pull_none_drv_level_2>;
		};

		/omit-if-no-ref/
		bt656_pins: bt656-pins {
			rockchip,pins =
				/* lcd_clk */
				<1 RK_PD3 1 &pcfg_pull_none_drv_level_2>,
				/* lcd_d0 */
				<1 RK_PC7 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d1 */
				<1 RK_PC6 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d2 */
				<1 RK_PC5 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d3 */
				<1 RK_PC4 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d4 */
				<1 RK_PC3 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d5 */
				<1 RK_PC2 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d6 */
				<1 RK_PC1 1 &pcfg_pull_none_drv_level_1>,
				/* lcd_d7 */
				<1 RK_PC0 1 &pcfg_pull_none_drv_level_1>;
		};

		/omit-if-no-ref/
		rgb3x8_pins: rgb3x8-pins {
			rockchip,pins =
				/* lcd_clk */
				<1 RK_PD3 1 &pcfg_pull_none_drv_level_4>,
				/* lcd_d0 */
				<1 RK_PC7 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d1 */
				<1 RK_PC6 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d2 */
				<1 RK_PC5 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d3 */
				<1 RK_PC4 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d4 */
				<1 RK_PC3 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d5 */
				<1 RK_PC2 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d6 */
				<1 RK_PC1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d7 */
				<1 RK_PC0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_den */
				<1 RK_PD0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_hsync */
				<1 RK_PD1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_vsync */
				<1 RK_PD2 1 &pcfg_pull_none_drv_level_3>;
		};

		/omit-if-no-ref/
		rgb565_pins: rgb565-pins {
			rockchip,pins =
				/* lcd_clk */
				<1 RK_PD3 1 &pcfg_pull_none_drv_level_4>,
				/* lcd_d0 */
				<1 RK_PC7 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d1 */
				<1 RK_PC6 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d2 */
				<1 RK_PC5 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d3 */
				<1 RK_PC4 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d4 */
				<1 RK_PC3 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d5 */
				<1 RK_PC2 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d6 */
				<1 RK_PC1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d7 */
				<1 RK_PC0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_d8 */
				<2 RK_PA0 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d9 */
				<2 RK_PA1 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d10 */
				<2 RK_PA2 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d11 */
				<2 RK_PA3 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d12 */
				<2 RK_PA4 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d13 */
				<2 RK_PA5 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d14 */
				<2 RK_PA6 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_d15 */
				<2 RK_PA7 3 &pcfg_pull_none_drv_level_3>,
				/* lcd_den */
				<1 RK_PD0 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_hsync */
				<1 RK_PD1 1 &pcfg_pull_none_drv_level_3>,
				/* lcd_vsync */
				<1 RK_PD2 1 &pcfg_pull_none_drv_level_3>;
		};
	};
};


新增驅動


接下來去打開驅動支援

./build.sh kernelconfig

Device Drivers > Sound card support > ALSA for SoC audio support > Rockchip I2S/TDM Device Driver > Rockchip I2S Device Driver > ASoC Simple sound card support > CODEC drivers > ES8311


Device Drivers > Sound card support > ALSA for SoC audio support > Advanced Linux Sound Architecture > ALSA For SoC audio support > CODEC Drivers > ES8311



如果可以也去尋找這個 Config 把 Multicodecs 打開

CONFIG_SND_SOC_ROCKCHIP_I2S_TDM=y

CONFIG_SND_SOC_ROCKCHIP_MULTICODECS=y


然後,請到  \luckfox-pico\sysdrv\source\kernel\arch\arm\boot\dts\ 這些目錄下,把原生的 acodec 先關閉,避免衝突:

/ { chosen { bootargs = "earlycon=uart8250,mmio32,0xff4c0000 console=ttyFIQ0 root=/dev/mmcblk1p7 rootwait snd_soc_core.prealloc_buffer_size_kbytes=16 coherent_pool=0"; }; acodec_sound: acodec-sound { status = "disabled"; // 暫時關閉 compatible = "simple-audio-card";


有搜到 acodec 就進去把 status 給關起來。


編譯燒錄

然後,開始重新編譯

./build kernel

然後開始燒錄。


接角如下:

[root@luckfox root]# luckfox-config show
/usr/bin/luckfox-config: line 262: warning: command substitution: ignored null byte in input
Luckfox_Pico_Pro_Max
+ -USB- +
- FIQtty_TX - GPIO1_B2 | | VBUS - -
- FIQtty_RX - GPIO1_B3 | | VSYS - -
- - GND | | GND - -
PWM11_M1 - UART4_M1_CTS - GPIO1_C7 | | 3V3_EN - -
PWM10_M1 - UART4_M1_RTS - GPIO1_C6 | | 3V3_OUT - -
PWM9_M1 - UART4_M1_TX - GPIO1_C5 | | NC - -
PWM8_M1 - UART4_M1_RX - GPIO1_C4 | | GPIO2_A7 - I2C3_M0_SDA - SDA
- - GND | | GND - -
PWM0_M1 - I2C3_M1_SDA - GPIO1_D2 | | GPIO4_C1 - SARADC_M1 -
PWM11_M2 - I2C3_M1_SCL - GPIO1_D3 | | GPIO4_C0 - SARADC_M0 -
PWM6_M1 - I2C1_M1_SDA - GPIO2_B1 | | RESET - -
PWM2_M2 - SPI0_M0_CS0 - GPIO1_C0 | | GPIO2_A6 - I2C3_M0_SCL - SCL
- - GND | | GND - -
PWM4_M2 - SPI0_M0_CLK - GPIO1_C1 | | GPIO2_A3 - -
PWM5_M2 - SPI0_M0_MOSI - GPIO1_C2 | | GPIO2_A2 - - MCLK
PWM6_M2 - SPI0_M0_MISO - GPIO1_C3 | | GPIO2_A1 - - LRCK
PWM5_M1 - I2C1_M1_SCL - GPIO2_B0 | | GPIO2_A0 - - SCLK
- - GND | | GND - -
PWM3_M2 - UART3_M1_TX - GPIO1_D0 | | GPIO2_A5 - UART1_M1_RX - DIN (接收 es8311 輸出)
PWM10_M2 - UART3_M1_RX - GPIO1_D1 | | GPIO2_A4 - UART1_M1_TX - DOUT (輸出 es8311 )


實際上設備樹的寫法在 rv1106 系列是:

<2 RK_PA1 2 &pcfg_pull_none>,

<[GPIO數字] [RK_PA -> RK_ PIN Analog 數字] [功能 1, 2, 3, 4...]  [內部上拉或下拉電阻,支援史密斯]>

以上的解讀就是 GPIO2_A2 Pin 腳使用 function 2。


實驗除錯開始


開始上電,注意,千萬不可用電腦 USB 接,一定要用單獨變壓器。 接下來如果沒有示波器可以跳過不看。


上電之後,觀察 MCLK 應該要是方波,進系統直接查找:

mount -t debugfs debugfs /sys/kernel/debug
// 這些表示 dts 驅動有生效
[root@luckfox root]# cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep i2s pin 64 (gpio2-0): ffae0000.i2s (GPIO UNCLAIMED) function i2s0 group i2s0-8ch-m0-sclko pin 65 (gpio2-1): ffae0000.i2s (GPIO UNCLAIMED) function i2s0 group i2s0-8ch-m0-lrckx pin 66 (gpio2-2): ffae0000.i2s (GPIO UNCLAIMED) function i2s0 group i2s0-8ch-m0-mclk pin 68 (gpio2-4): ffae0000.i2s (GPIO UNCLAIMED) function i2s0 group i2s0-8ch-m0-sdo0 pin 69 (gpio2-5): ffae0000.i2s (GPIO UNCLAIMED) function i2s0 group i2s0-8ch-m0-sdi0


// 觀察是不是 1228000 clock
cat /sys/kernel/debug/clk/clk_summary | grep i2s
[root@luckfox root]# cat /sys/kernel/debug/clk/clk_summary | grep i2s
          clk_i2s0_8ch_rx_src         1        1        0   594000000          0     0  50000
             clk_i2s0_8ch_rx_frac       1        1        0    12288000          0     0  50000
                clk_i2s0_8ch_rx       1        1        0    12288000          0     0  50000
                   mclk_i2s0_8ch_rx       1        1        0    12288000          0     0  50000
          clk_i2s0_8ch_tx_src         1        1        0   594000000          0     0  50000
             clk_i2s0_8ch_tx_frac       1        1        0    12288000          0     0  50000
                clk_i2s0_8ch_tx       1        1        0    12288000          0     0  50000
                   mclk_i2s0_8ch_tx       3        3        0    12288000          0     0  50000
                      i2s0_8ch_mclkout       2        2        0    12288000          0     0  50000
                hclk_i2s0             1        1        0   198000000          0     0  50000

// 可以看到驅動有被載入
[root@luckfox root]# aplay -l **** List of PLAYBACK Hardware Devices **** card 0: rockchipes8311 [rockchip-es8311], device 0: dailink-multicodecs ES8311 HiFi-0 [dailink-multicodecs ES8311 HiFi-0] Subdevices: 0/1 <----- 在使用中會變 0,或是其他情形會變 0,其餘閒置會變 1 Subdevice #0: subdevice #0


觀察 log

mount -t debugfs debugfs /sys/kernel/debug && dmesg
// 僅偶爾會看到,不是每一次都會  [ 67.030733] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.031405] es8311 3-0018: ASoC: error at snd_soc_component_update_bits on es8311.3-0018: -6 [ 67.181392] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.205170] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.376750] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.377662] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.506097] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.529338] es8311 3-0018: ASoC: error at snd_soc_component_update_bits on es8311.3-0018: -6 [ 67.679244] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [ 67.872574] es8311 3-0018: ASoC: error at soc_component_write_no_lock on es8311.3-0018: -6 [14735.657954] rockchip-i2s-tdm ffae0000.i2s: TX FIFO Underrun



每一個接腳用示波器量測會看到:
MCLK (PA2): 引腳 66 (模式 2) -> 你已經量到 1.8V。
SCLK / BCK (PA3): 引腳 65 (模式 2) -> 播放時應該有 ~3MHz 的方波。
LRCK (PA4): 引腳 64 (模式 2) -> 播放時應該有 48kHz 的方波。
SDO / SDIN (PA6): 引腳 62 (模式 2) -> 播放時有密集數位脈衝。


但因為啟動時發現有 MCLK 訊號微弱的問題:


可以看到波峰低於 100mv


看到別人問到官方是使用

devmem 0xff000004 32 檢查到:

0x00002220 => 解讀為後 4 位是 function mode 數字:

0x00002240
GPIO2_A7GPIO2_A6GPIO2_A2GPIO2_A1
MODE 2MODE 2MODE 4MODE 0

 後面怎麼做都沒辦法讓 GPIO2_A2 的 function 開啟,故改用:

devmem 0xff000004 32 0xffff2220 

這個指令強制把 MCLK 的 function mode 使能


開啟之後頻率對了,是 122800 ,訊號也變強了。


實驗測試 SDO (DOUT) 出去脈衝波會是如何

aplay -D hw:0,0 -f S16_LE -r 48000 -c 2 /dev/zero ------> DOUT 要是平的訊號
while true; do aplay -D hw:0,0 -f S16_LE -r 48000 -c 2 ./tobu.wav; done --------> 數位脈衝波


實際上播放音樂時,DOUT 會是脈衝波 (跟音樂依樣,如果是靜音音樂,就會是平的):



測試時是有一些特徵的,比方說 SCL, SDA 如果有效,那麼播音樂當下聲音會有爆開的感覺。

沒有聲音時,要去調整音效:

alsamixer

可以直接對每個地方按下數字鍵會自動變成 10 倍,出期因為有一個設定會讓聲音慢慢變大,導致很難發現問題,建議全部都先按 0,只把 DAC VOLUME 開成 70%。

然後播放音樂。


測試錄音

測試錄音時,使用指令:

arecord -D hw:0,0 -f S32_LE -r 48000 -c 2 -V mono -d 10 -t wav test_mic.wav

可以成功錄音。

如果錄音一直沒有訊號,可以去調整 alsamixer,或是先撥音樂故意讓 mclk 運作,然後看看錄音有沒有效:

aplay -D hw:0,0 /dev/zero &
arecord -D hw:0,0 -f S32_LE -r 48000 -c 2 -V mono -d 10 -t wav test_mic.wav

如果有,那就是設備樹那邊要調整:

rockchip,tdm-chip-delay = <0>;
rockchip,clk-trcm = <1>;




其他

我也有同時測試 ES8388,其實也是可以用的,上面的驅動是共用 ES8323,所以你應該要比照 ES8323 驅動去接,甚至在 ES8323.c 上面程式碼就已經寫到 ES8388, ES8323 共用驅動了,故不需要手動移植。

如果要新增驅動到目錄下,把 .c / .h 複製到

\luckfox-pico\sysdrv\source\kernel\sound\soc\codecs\

然後去改 Kconfig / Makefile,然後

export PATH=$PATH:$(pwd)/tools/linux/toolchain/arm-rockchip831-linux-uclibcgnueabihf/bin

make ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf- rv1106_defconfig

make ARCH=arm CROSS_COMPILE=arm-rockchip830-linux-uclibcgnueabihf- menuconfig

做這些 config 就可以在  ./build.sh kernelconfig 找到你的設備。



Reference:

[1] https://github.com/Meekdai/meekdai.github.io/issues/45
[2] https://github.com/LuckfoxTECH/luckfox-pico/blob/main/README_CN.md




沒有留言:

張貼留言

© Mac Taylor, 歡迎自由轉貼。
Background Email Pattern by Toby Elliott
Since 2014