一.屏幕背光概述
背光就是屏幕的从里往照射的光。
LCD 主要由液晶面板、背光、驱动电路等组成,液晶面板不会主动发光,需要背光源才能显示,液晶面板的作用就是通过电压改变某像素光的透过率来显示的,当然此光要求是偏振光,所以LCD面板上下都有偏振片的。
现在的背光源主要是LED的白色面光源,发光都是非常均匀的。
在电子工业中,背光是一种照明的形式,常被用于LCD显示上。背光式和前光式不同之处在于背光是从侧边或是背后照射,而前光顾名思义则从前方照射。他们被用来增加在低光源环境中的照明度和电脑显示器、液晶荧幕上的亮度,以和CRT显示类似的方式产生出光。
二.背光的几个基本概念
背光开关:
背光开光是控制背光的亮灭,在RK的硬件设计上,通常会提供一个GPIO作为背光开光,通过控制这个GPIO的高低电平而控制背光的亮灭。
背光的频率:
由于控制背光亮度的是一个PWM波,因此他是有一个频率的。不同的屏,也会有一个对应的背光频率范围。如果背光不在 要求的范围内,就会出现一个滚动的黑条(水波纹)。
背光占空比:
针对 PWM 背光的屏,用来调节背光的亮度,当正占空比越大时,背光越亮, 越小时,背光就暗。当占空比不在 100%时,使用手机拍照,可以明显看到滚动的黑条。当 占空比为 100%比,这个时候的调光是一条直线,可以看到滚动的黑条消失。
背光极性:
极性简单来说,就是交换PWM波的正反输出。比如正极性时,背光越大,正占空比越多,当背光调到最大时,输出应该就是一条高电平的直线。而负极性时,背光越大,负占空比就越多,当背光调到最大时,输出应该就是一条低电平的直线。
三.常见问题
背光开光:
添加一个背光开光的控制节点来控制背光的熄屏亮屏。
路径:kernel-5.10/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
struct rockchip_hdmi *g_hdmi = NULL;
static int vbo_ctl_open(struct inode *inode, struct file *file)
{
return 0;
}
static int vbo_ctl_release(struct inode *inode, struct file *file)
{
return 0;
}
static const struct file_operations vbo_ctl_fops = {
.open = vbo_ctl_open,
.release = vbo_ctl_release,
};
struct miscdevice vbo_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "vbo_ctl_dev",
.fops = &vbo_ctl_fops,
};
static ssize_t vbo_bl_power_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int value;
struct rockchip_hdmi *hdmi = g_hdmi;//container_of(dev, struct rockchip_hdmi, dev);
value = gpiod_get_value(hdmi->backlight_gpio);
return sprintf(buf, "%d\n", value);
}
static ssize_t vbo_bl_power_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int value;
struct rockchip_hdmi *hdmi = g_hdmi;//container_of(dev, struct rockchip_hdmi, dev);
if (!kstrtoint(buf, 10, &value))
{
dev_info(hdmi->dev, "set backlight gpio value to %d\n", value);
gpiod_set_value(hdmi->backlight_gpio, !!value);
} else
dev_err(hdmi->dev, "%s: error\n", __FUNCTION__);
return count;
}
DEVICE_ATTR_RW(vbo_bl_power);
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
{
....
//这里为控制背光脚的GPIO
hdmi->backlight_gpio = devm_gpiod_get_optional(hdmi->dev, "lcd-bl",
GPIOD_OUT_LOW);
if (IS_ERR(hdmi->backlight_gpio)) {
ret = PTR_ERR(hdmi->backlight_gpio);
dev_err(hdmi->dev, "failed to request lcd-bl-gpio GPIO: %d\n", ret);
return ret;
}
g_hdmi = hdmi;
ret = misc_register(&vbo_device);
if (ret) {
dev_err(hdmi->dev, "vbo_device ERROR: could not register vbo_device\n");
return ret;
}
ret = device_create_file(vbo_device.this_device,
&dev_attr_vbo_bl_power);
if (ret) {
dev_err(hdmi->dev, "failed to create attr vbo_bl_power!\n");
return ret;
}
return 0;
}
添加之后会在/sys/class/misc/vbo_ctl_dev/vbo_bl_power路径下生成控制背光的节点。
固定背光频率:
路径:kernel-5.10/drivers/video/backlight/pwm_bl.c
static int pwm_backlight_probe(struct platform_device *pdev)
{
if (!state.period && (data->pwm_period_ns > 0))
state.period = data->pwm_period_ns;
//这个state.period可以修改背光的频率
}
修改背光占空比:
路径:kernel-5.10\drivers\video\backlight\pwm_bl.c
int mapBrightness(struct pwm_bl_data *pb, int num)
{
//android range(10-255), change to (0-255)
num = (num - 10) * (255 - 0) / (255 - 10);
if (num >= 0 && num <= 255) {
- return pb->min_duty + (num - 0) * (pb->max_duty - pb->min_duty ) / (pb->max_duty - 0);
+ return pb->min_duty + (num - 0) * (pb->max_duty - pb->min_duty ) / (255 - 0);
} else {
- return -1;
+ return 104;
}
}
在此函数里面能修改背光占用比。
修改占空比也能在设备树里面修改:
背光占空比为30%~100%
backlight: backlight {
compatible = "pwm-backlight";
brightness-levels = <
- 0 20 20 21 21 22 22 23
- 23 24 24 25 25 26 26 27
- 27 28 28 29 29 30 30 31
- 31 32 32 33 33 34 34 35
- 35 36 36 37 37 38 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
+ 77 77 78 78 79 79 80 81
+ 82 83 84 85 86 87 87 88
+ 88 89 90 90 91 91 92 93
+ 94 94 95 95 96 96 97 97
+ 98 98 99 99 100 100 101 101
+ 102 103 104 104 105 106 107 107
+ 108 108 109 109 110 111 112 113
+ 114 115 116 116 117 117 118 118
+ 119 119 120 121 122 123 124 124
+ 125 125 126 126 127 127 128 128
+ 129 129 130 130 131 131 132 132
+ 133 133 134 134 135 135 136 136
+ 137 137 138 138 139 139 140 141
+ 142 142 143 144 145 146 146 147
+ 147 148 148 149 149 150 151 151
+ 152 153 153 154 154 155 156 156
+ 157 158 158 159 160 161 162 162
+ 163 163 164 164 165 165 166 166
+ 167 168 168 169 170 171 172 172
+ 173 174 175 175 176 177 178 179
+ 180 181 182 182 183 184 185 186
+ 187 188 189 190 190 191 192 193
+ 194 194 195 196 197 198 199 199
+ 200 201 202 203 204 204 205 206
+ 207 208 209 210 211 211 212 213
+ 214 215 216 216 217 217 218 219
+ 219 220 220 221 222 223 224 224
+ 225 225 226 227 228 229 229 230
+ 231 232 232 233 234 235 236 237
+ 238 239 239 240 240 241 242 242
+ 243 244 245 246 246 247 247 248
+ 249 250 251 251 252 253 254 255
>;
default-brightness-level = <200>;
};
背光亮度极性问题:
在调节背光的时候极性相反会导致背光的亮度相反。
修改背光极性可以修改设备树DTS:
backlight: backlight {
compatible = "pwm-backlight";
+ pwms = <&pwm1 0 5555555 1>;
- pwms = <&pwm1 0 5555555 0>;
brightness-levels = <
.......
>;
default-brightness-level = <235>;
};
以上的修改能让背光的极性相反过来。