OLED屏幕不同于普通LED屏幕,不需要单独的背光模块。其背光亮度调节是通过MIPI发送命令调整的,一般调节OLED亮度的命令都是0x51,亮度值范围为0-0xff(即0-255)。
实现OLED背光亮度可调节,需要做如下修改:
1,dts中屏蔽背光相关节点,如下:
backlight: backlight {
- status = "okay";
+ status = "disabled";
compatible = "pwm-backlight";
pwms = <&pwm0 0 25000 0>;
brightness-levels = <
@@ -37,7 +37,6 @@
panel@0 {
compatible ="simple-panel-dsi";
reg = <0>;
- backlight = <&backlight>;
2,修改panel-simple.c中背光设备注册的设备名字,如下:
--- a/kernel-5.10/drivers/gpu/drm/panel/panel-simple.c
+++ b/kernel-5.10/drivers/gpu/drm/panel/panel-simple.c
@@ -5083,7 +5083,7 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
props.max_brightness = 255;
panel->base.backlight =
- devm_backlight_device_register(dev, "dcs-backlight",
+ devm_backlight_device_register(dev, "backlight"/*"dcs-backlight"*/,
dev, panel, &dcs_bl_ops,
&props);
这一步很重要,因为上层调节背光时就是操作的这个背光设备节点(/sys/class/backlight/backlight),如果名字不对,上层调用的通路就没有打通。
3,确保屏幕的初始化代码已经打开了背光调节功能,有时初始化代码不对的话也可能无法调节亮度值。(panel-init-sequence的代码确认没问题)
4,kernel-5.10/drivers/gpu/drm/drm_mipi_dsi.c中mipi_dsi_dcs_set_display_brightness函数就是调节亮度的地方。
这里需要确认的就是屏幕调节亮度的命令,参数,命令类型(general或dcs)。根据实际情况作调整即可。
驱动中背光调节的函数调用流程为:
kernel-5.10/drivers/gpu/drm/panel/panel-simple.c中devm_backlight_device_register函数注册背光设备并同时注册背光调节接口dcs_bl_ops,其中包括设置背光亮度的函数dcs_bl_update_status,这里再调用mipi_dsi_dcs_set_display_brightness函数设置亮度,之后再调用mipi_dsi_dcs_write(kernel-5.10/drivers/gpu/drm/drm_mipi_dsi.c中)发送命令(MIPI_DCS_SET_DISPLAY_BRIGHTNESS,其值为0x51)给屏幕驱动IC最终实现亮度调节。
如果想要调节背光亮度的曲线,还可以在panel-simple.c中增加一个亮度数组,如下:
static const u16 brightness_table[256] = {
0,1,2,3,4,5,6,7,8,9,10,
11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,
41,42,43,44,45,46,47,48,49,50,
51,52,53,54,55,56,57,58,59,60,
61,62,63,64,65,66,67,68,69,70,
71,72,73,74,75,76,77,78,79,80,
81,82,83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100,
101,102,103,104,105,106,107,108,109,110,
111,112,113,114,115,116,117,118,119,120,
121,122,123,124,125,126,127,128,129,130,
131,132,133,134,135,136,137,138,139,140,
141,142,143,144,145,146,147,148,149,150,
151,152,153,154,155,156,157,158,159,160,
161,162,163,164,165,166,167,168,169,170,
171,172,173,174,175,176,177,178,179,180,
181,182,183,184,185,186,187,188,189,190,
191,192,193,194,195,196,197,198,199,200,
201,202,203,204,205,206,207,208,209,210,
211,212,213,214,215,216,217,218,219,220,
221,222,223,224,225,226,227,228,229,230,
231,232,233,234,235,236,237,238,239,240,
241,242,243,244,245,246,247,248,249,250,
251,252,253,254,255
};
之后在dcs_bl_update_status函数中做个映射,通过调整brightness_table中的值就可以对背光亮度的调节曲线作出调整。如下:
static int dcs_bl_update_status(struct backlight_device *bl)
{
struct panel_simple *p = bl_get_data(bl);
struct mipi_dsi_device *dsi = p->dsi;
int ret;
u16 brightness;
if (!p->prepared)
return 0;
dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
brightness = brightness_table[bl->props.brightness];//映射
ret = mipi_dsi_dcs_set_display_brightness(dsi, brightness/*bl->props.brightness*/);
if (ret < 0)
return ret;
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
return 0;
}