Adaptation and Optimization of the LT9211 MIPI-to-LVDS Module on the RK3588 Platform with Android 14
Adaptation Background and Platform Characteristic Analysis
Adaptation Background
Currently engaged in industrial display development on the RK3588 platform running Android 14 (kernel version 6.1.99). The work involves adapting the LT9211 MIPI-to-LVDS module to support a 1280×800 LVDS screen and a GT911 touchscreen. The primary goal is to ensure stable display power-on and normal touchscreen functionality.
Platform Characteristic Analysis Before Adaptation
The Android 14 BSP for the platform incorporates a standard DRM framework for its display architecture. The integration of the MIPI DSI bridge focuses on three crucial aspects: ensuring that the driver is correctly compiled into the kernel, configuring hardware resources in the device tree to avoid conflicts, and achieving complete compatibility between the display timing and screen parameters.
Before modifications, the layered rules of the kernel configuration in the compilation environment were verified: the kernel configuration for OK3588-Android 14 consists of three files: rockchip_defconfig (chip-level), -14.config (system-level), and OK3588-C-Android.config (board-level). All board-level custom configurations must be placed in the third file to prevent overwriting during future SDK upgrades. This version compatibility rule is mandatory for industrial-grade development.
Specific Implementation Steps for Adaptation
I. Driver Layer Deployment
1. LT9211 Driver File and Makefile Configuration
The LT9211 is a MIPI-to-LVDS bridge chip from Lontium, classified as a DRM bridge driver. It must be placed in the corresponding driver directory to be correctly recognized by the framework.
Copy the lt9211.c driver file to kernel-6.1/drivers/gpu/drm/bridge, and modify the Makefile in the same directory by adding the following compilation configuration at the end to ensure the driver is compiled into the kernel image:
| Makefile |
|---|
|
# Existing configurations remain unchanged. Add the following at the end: obj-y += lt9211.o |
Complete context reference:
Makefile 27 obj-$(CONFIG_DRM_SIMPLE_BRIDGE) += simple-bridge.o 28 obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o 29 obj-$(CONFIG_DRM_TOSHIBA_TC358762) += tc358762.o 30 obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o 31 obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o 32 obj-$(CONFIG_DRM_TOSHIBA_TC358768) += tc358768.o 33 obj-$(CONFIG_DRM_TOSHIBA_TC358775) += tc358775.o 34 obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ 35 obj-$(CONFIG_DRM_TI_DLPC3433) += ti-dlpc3433.o 36 obj-$(CONFIG_DRM_TI_SN65DSI83) += ti-sn65dsi83.o 37 obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o 38 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o 39 obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o 40 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o 41 obj-$(CONFIG_DRM_ITE_IT66121) += ite-it66121.o 42 obj-y += lt8912b.o 43 44 obj-y += analogix/ 45 obj-y += cadence/ 46 obj-y += imx/ 47 obj-y += lt9211.o
2. Kernel Configuration Modification
This adaptation is paired with a GT911 touchscreen, requiring the activation of the Goodix series touch driver in the kernel. Following the previously confirmed configuration layering rules, modify the board-level configuration file kernel-6.1/kernel/configs/OK3588-C-Android.config by adding the following:
| Plain Text |
|---|
|
# Existing configurations remain unchanged. Add the following content: CONFIG_TOUCHSCREEN_GOODIX=y |
Complete context reference:
Plain Text CONFIG_TOUCHSCREEN_EDT_FT5X06=y CONFIG_GPIO_PCA953X=y CONFIG_GPIO_PCA953X_IRQ=y CONFIG_SND_SOC_NAU8822=y CONFIG_NET_VENDOR_INTEL=y CONFIG_R8169=y CONFIG_E1000E=y CONFIG_RTC_DRV_PCF8563=y CONFIG_RTC_DRV_RX8010=y CONFIG_NXPWIFI=m CONFIG_VIDEO_OV5645=y CONFIG_USB_SERIAL_EXAR=y CONFIG_TOUCHSCREEN_GOODIX=y
II. Device Tree Hardware Resource Configuration
The device tree modification path is kernel-6.1/arch/arm64/boot/dts/rockchip/OK3588-C-Common.dtsi. This adaptation uses the MIPI0 channel as an example. To facilitate future rollback and troubleshooting, all existing conflicting configurations are retained through commenting rather than direct deletion.
1. Addition of Touchscreen Node Definition
In the original device tree, the FT5x06 touchscreen node occupied pins required for the current GT911. The existing node was first commented out, and the GT911 interrupt and reset pin multiplexing configuration was added to prevent pin resource conflicts.
Plain Text
usb-typec {
usbc0_int: usbc0-int {
rockchip,pins = <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
};
typec5v_pwren0: typec5v-pwren0 {
rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
};
usbc1_int: usbc1-int {
rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>;
};
typec5v_pwren1: typec5v-pwren1 {
rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
tp_int {
gt911_dsi1_gpio: gt911-dsi0-gpio {
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>,
<3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
/* Original ft5x06 node comment to avoid pin conflict */
/*
ft5x06_dsi0_gpio: ft5x06-dsi0-gpio {
rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>,
<3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
};
*/
ft5x06_dsi1_gpio: ft5x06-dsi1-gpio {
rockchip,pins = <3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>,
<3 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
};
headphone {
hp_det: hp-det {
rockchip,pins = <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
2. Adding Device Configuration under the I2C2 Node
Both the LT9211 and GT911 are connected to the I2C2 bus. New device node configurations are added under the &i2c2 node, while the conflicting original ft5x06 device node is commented out.
Plain Text
extio: tca6424@23 {
compatible = "ti,tca6424";
reg =;
interrupt-parent = <&gpio1>;
interrupts =;
gpio-controller;
#gpio-cells =;
interrupt-controller;
#interrupt-cells =;
pinctrl-0 = <&extio_int_gpio>;
pinctrl-names = "default";
status = "okay";
};
/* Comment out the original ft5x06 node, kept for reference */
/*
ft5x06_dsi0: ft5x06@38 {
compatible = "edt,edt-ft5406", "edt,edt-ft5x06";
reg =;
pinctrl-names = "ft5x06_default";
pinctrl-0 = <&ft5x06_dsi0_gpio>;
interrupt-parent = <&gpio3>;
interrupts =;
// irq-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
// reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
touchscreen-size-x =;
touchscreen-size-y =;
input-phy = "ft5x06 2 38/input0";
status = "okay";
}
*/
usbc0: fusb302@22 {
compatible = "fcs,fusb302";
reg =;
interrupt-parent = <&gpio1>;
interrupts =;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
vbus-supply = <&vbus5v_typec>;
status = "okay";
};
/* LT9211 MIPI-to-LVDS bridge chip device node */
lt9211: lt9211@2d {
compatible = "lontium,lt9211";
reg =;
// reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
status = "okay";
};
/* GT911 touchscreen device node */
gt911_14: gt911_14_ts@14 {
compatible = "goodix,gt911";
reg =;
pinctrl-names = "default";
pinctrl-0 = <>911_dsi1_gpio>;
interrupt-parent = <&gpio3>;
interrupts =;
irq-gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
// reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
touchscreen-size-x =;
touchscreen-size-y =;
// touchscreen-inverted-x;
// touchscreen-inverted-y;
touchscreen-swapped-x-y;
status = "okay";
};
};
3. Modifying Screen Parameters in the DSI Node
Replace the original 1024×600 timing configuration in the &dsi0 node with timing parameters adapted for the 1280×800 resolution LVDS screen. All parameters must strictly correspond to the screen’s specification sheet to prevent black screens or screen corruption issues.
Plain Text
/* Comment out the original 1024×600 timing configuration, kept for reference */
/*
disp_timings0: display-timings {
native-mode = <&dsi0_timing0>;
dsi0_timing0: timing0 {
hback-porch =;
hfront-porch =;
hactive =;
hsync-len =;
vback-porch =;
vfront-porch =;
vactive =;
vsync-len =;
clock-frequency =;
vsync-active =;
hsync-active =;
de-active =;
pixelclk-active =;
};
};
*/
/* Add timing configuration for the 1280×800 LVDS display */
disp_timings0: display-timings {
native-mode = <&dsi0_timing0>;
dsi0_timing0: timing0 {
hback-porch =;
hfront-porch =;
hactive =;
hsync-len =;
vback-porch =;
vfront-porch =;
vactive =;
vsync-len =;
clock-frequency =;
vsync-active =;
hsync-active =;
de-active =;
pixelclk-active =;
};
};
III. Kernel Compilation and Flashing
To improve validation efficiency, there is no need to compile the entire Android system. The kernel can be compiled separately using commands. After compilation, the generated boot.img image is located in the rockdev/Image-ok3588_c/ directory. Flashing only this image completes the adaptation.
Bash # Navigate to the SDK root directory cd /home/forlinx/work/OK3588-android14-source/ # Load the build environment, select the corresponding product branch source build/envsetup.sh;lunch ok3588_c-userdebug # Compile the kernel separately and generate the boot image ./build.sh -Ku
Verification and Experience Summary
After the modifications and compilation according to the above steps, the generated boot.img is flashed onto the embedded RK3588 development board. Upon power-up, the 1280×800 resolution LVDS screen lights up normally, the Android 14 system desktop displays completely, the GT911 touchscreen responds correctly without drift or missed touches, and a continuous 72-hour power-on test shows no display abnormalities.
The main focus of this adaptation is to align with the DRM display framework for high-version Android on the Rockchip platform. It is crucial to strictly follow the SDK's layered configuration rules. This means that board-level custom configurations must not override chip-level or system-level configuration files, which is important for ensuring future SDK upgrades and maintaining long-term compatibility.
Additionally, adapting the MIPI-to-LVDS bridge requires a comprehensive approach that encompasses three key areas: the driver, the device tree, and timing. Any deviation in these parameters can lead to display issues. In industrial-grade product development, achieving a display is not the ultimate goal. The fundamental principles of embedded development include preserving complete reference configurations, ensuring version compatibility, and guaranteeing long-term stability.


