屏驱动说明
屏源码位置:bsp/artinchip/drv/display/panel/
6.3.6.3.2.1.
6.3.6.3.2.2. LVDS 屏幕
- 通用 LVDS 屏幕驱动
panel_lvds_general.c
,可通过 menuconfig 选择
-
LVDS 接口可配置参数
-
data-mapping
: vesa-24/jeida-24/jeida-18 协议 -
data-channel
: single/dual link 输出 -
link-swap
: link 1 和 link 0 输出互换 -
lines
: link 内部 5 个通道的差分信号输出顺序,允许 5 对差分信号任意互换 -
pols
: link 内部 5 个通道差分信号的极性
-
-
时序参数
-
board.dts
文件 panel_lvds 节点 display-timings 子节点
-
小技巧
参数含义详见 panel_lvds 配置章节和 LVDS Display Interface 配置章节
新屏驱动适配
LCD 屏驱动,即 panel,本质上是一个回调函数和屏参的集合。新屏适配实际上是重新实现一个 struct aic_panel
结构体。
新增一款屏驱动,可以在 panel 源码目录下,根据屏接口选择一个模板,在模版的基础上进行修改。
-
MIPI-DSI 接口可参考 panel_dsi_xm91080.c
-
MIPI-DBI 接口可参考 panel_dbi_ili9486l.c
以 MIPI-DSI 接口为例:
-
拷贝一份模板文件,命名为 panel_dsi_xxx.c,将新文件添加进 Kconifg 和 SConscript 文件中
// bsp/artinchip/drv/display/panel/Kconfig config AIC_PANEL_DSI_XXX bool "ArtInChip MIPI DSI xxx panel" depends on AIC_DISP_MIPI_DSI // bsp/artinchip/SConscript if GetDepend('AIC_PANEL_DSI_XXX'): src += Glob('drv/display/panel/panel_dsi_xxx.c')
-
修改
struct aic_panel
的命名,并将其注册。-
将 struct aic_panel 添加到
panel_com.c
文件的panels[]
指针数组中 -
在
panel_com.h
文件中extern
struct aic_panel。//panel_com.c static struct aic_panel *panels[] = { ... #ifdef AIC_PANEL_DSI_XXX &dsi_xxx, #endif }; //panel_com.h extern struct aic_panel dsi_xxx;
-
-
修改
struct display_timing
结构体,根据 LCD 屏幕规格书修改时序参数。 -
重新实现 aic_panel_funcs 结构体中的
prepare
或者enable
接口,添加初始化操作。
对于 MIPI-DSI 接口屏幕
- 在发送 init_sequence 之前需要调用 panel_mipi_send_perpare 以确保屏幕能正确无误地接受到命令。
- 在发送完 init_sequence 后需要调用 panel_mipi_setup_realmode 设置正确的 mipi 模式。
- panel_dsi.c 为 MIPI-DSI 的 init_sequence 封装了两个接口:
- panel_dsi_dcs_send_seq:发送屏厂根据 mipi 协议扩展的 command
- panel_dsi_generic_send_seq:发送 mipi 协议标准的 command
对于 MIPI-DBI 接口屏幕
-
panel_dbi.c 为 MIPI-DBI 的 init_sequence 封装了 enable 接口 panel_dbi_default_enable
数据结构
- struct
aic_panel
struct aic_panel { const char *name; struct aic_panel_funcs *funcs; struct aic_panel_callbacks callbacks; const struct display_timing *timings; union { struct panel_rgb *rgb; struct panel_lvds *lvds; struct panel_dsi *dsi; }; int connector_type; };
- struct
aic_panel_funcspanel 提供,供 fb 调用的回调。新屏驱动必须实现。
/* Each panel driver should define the follow functions. */ struct aic_panel_funcs { int (*prepare)(void); int (*enable)(struct aic_panel *panel); int (*disable)(struct aic_panel *panel); int (*unprepare)(void); int (*register_callback)(struct aic_panel *panel, struct aic_panel_callbacks *pcallback); };
- struct
aic_panel_callbackspanel 无需实现,由 DE、DI 提供,供 panel 调用的回调。
struct aic_panel_callbacks { int (*di_enable)(void); int (*di_disable)(void); int (*di_send_cmd)(u32 dt, u32 vc, const u8 *data, u32 len); int (*di_set_videomode)(const struct display_timing *timings, int enable); int (*timing_enable)(void); int (*timing_disable)(void); };
- struct
panel_rgbrgb 接口屏幕参数
struct panel_rgb { unsigned int mode; unsigned int format; unsigned int clock_phase; unsigned int data_order; unsigned int data_mirror; };
- struct
panel_lvdslvds 接口屏幕参数
struct panel_lvds { enum lvds_mode mode; enum lvds_link_mode link_mode; };
- struct panel_dsimipi-dsi 接口屏幕参数
struct panel_dsi { enum dsi_mode mode; enum dsi_format format; unsigned int lane_num; };
- struct
panel_dbimipi-dbi 接口屏幕参数
struct panel_dbi_commands { const u8 *buf; size_t len; }; struct spi_cfg { unsigned int qspi_mode; unsigned int vbp_num; unsigned int code1_cfg; unsigned int code[3]; }; struct panel_dbi { unsigned int type; unsigned int format; unsigned int first_line; unsigned int other_line; struct panel_dbi_commands commands; struct spi_cfg *spi; };
函数接口
接口定义 | int panel_default_prepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 prepare 接口函数,使能 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功 负数:失败 |
注意事项 | - |
接口定义 | int panel_default_enable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 enable 接口函数,设置 de 模块的 timing 参数,使能相应的 DI 接口,开启背光 |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_default_unprepare(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 unprepare 接口函数,禁用 regulator |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_default_disable(struct aic_panel *panel) |
---|---|
功能说明 | 默认的 disable 接口函数,禁用背光,禁用 DI 接口,禁用 DE |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | int panel_register_callback(struct aic_panel *panel, struct aic_panel_callbacks *pcallback) |
---|---|
功能说明 | DE,DI 提供的回调函数,供 panel 调用 |
参数定义 | 结构体 aic_panel |
返回值 | 0:成功 |
注意事项 | - |
接口定义 | void panel_di_enable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 使能相应的 DI 接口 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_di_disable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 禁用相应的 DI 接口 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_de_timing_enable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 启用 DE, 设置 de 模块的 timing 参数 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_de_timing_disable(struct aic_panel *panel, u32 ms) |
---|---|
功能说明 | 禁用 DE, 设置 de 模块的 timing 参数 |
参数定义 | 结构体 aic_panel, ms 延时毫秒 |
返回值 | void |
注意事项 | - |
接口定义 | void panel_mipi_send_perpare(struct aic_panel *panel) |
---|---|
功能说明 | 将 dsi 通道切换到 command mode, 准备好给 mipi 屏幕发送初始化命令 |
参数定义 | 结构体 aic_panel |
返回值 | void |
注意事项 | 在 mipi 屏幕发送初始化命令前要先调用这个函数,以确保 mipi 屏幕收到正确的初始化命令 |
接口定义 | void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel) |
---|---|
功能说明 | 给 mipi 屏幕发送初始化命令 |
参数定义 | 结构体 aic_panel , 初始化序列大小 size, 初始化序列 para_cmd |
返回值 | void |
注意事项 | - |
接口定义 | void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel) |
---|---|
功能说明 | 将 dsi 通道切换回正确的模式 |
参数定义 | 结构体 aic_panel |
返回值 | void |
注意事项 | 在 mipi 屏幕发送完初始化命令后调用这个函数,以确保 mipi 通道正常工作 |
接口定义 | #define panel_dsi_generic_send_seq(panel, seq…) |
---|---|
功能说明 | 发送屏厂根据 mipi 协议扩展的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | #define panel_dsi_dcs_send_seq(panel, seq…) |
---|---|
功能说明 | 发送 mipi 协议标准的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | void panel_send_command(u8 *para_cmd, u32 size, struct aic_panel *panel) |
---|---|
功能说明 | 将 dsi 通道切换回正确的模式 |
参数定义 | 结构体 aic_panel |
返回值 | void |
注意事项 | 在 mipi 屏幕发送完初始化命令后调用这个函数,以确保 mipi 通道正常工作 |
接口定义 | #define panel_dsi_generic_send_seq(panel, seq…) |
---|---|
功能说明 | 发送屏厂根据 mipi 协议扩展的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | #define panel_dsi_dcs_send_seq(panel, seq…) |
---|---|
功能说明 | 发送 mipi 协议标准的 command |
参数定义 | 结构体 aic_panel,seq: init command |
返回值 | 0: 成功, 负数:失败 |
注意事项 | - |
接口定义 | int panel_dbi_default_enable(struct aic_panel *panel) |
---|---|
功能说明 | mipi-dbi 接口的默认使能函数, 发送 mipi-dbi 的 init_sequence |
参数定义 | 结构体 aic_panel |
返回值 | 0: 成功, 负数:失败 |
注意事项 | 注意事项 |
屏驱动说明
新屏驱动适配
LCD 屏驱动,即 panel,本质上是一个回调函数和屏参的集合。新屏适配实际上是重新实现一个 struct aic_panel
结构体。
新增一款屏驱动,可以在 panel 源码目录下,根据屏接口选择一个模板,在模版的基础上进行修改。
-
MIPI-DSI 接口可参考 panel_dsi_xm91080.c
-
MIPI-DBI 接口可参考 panel_dbi_ili9486l.c
-
拷贝一份模板文件,命名为 panel_dsi_xxx.c,将新文件添加进 Kconifg 和 SConscript 文件中
// bsp/artinchip/drv/display/panel/Kconfig config AIC_PANEL_DSI_XXX bool "ArtInChip MIPI DSI xxx panel" depends on AIC_DISP_MIPI_DSI // bsp/artinchip/SConscript if GetDepend('AIC_PANEL_DSI_XXX'): src += Glob('drv/display/panel/panel_dsi_xxx.c')
- 修改
struct aic_panel
的命名,并将其注册。-
将 struct aic_panel 添加到
panel_com.c
文件的panels[]
指针数组中 -
在
panel_com.h
文件中extern
struct aic_panel。//panel_com.c static struct aic_panel *panels[] = { ... #ifdef AIC_PANEL_DSI_XXX &dsi_xxx, #endif }; //panel_com.h extern struct aic_panel dsi_xxx;
-
-
修改
struct display_timing
结构体,根据 LCD 屏幕规格书修改时序参数。 -
重新实现 aic_panel_funcs 结构体中的
prepare
或者enable
接口,添加初始化操作。