LVDS 屏幕 M215HGE-L21 在 rk3288 上的适配过程
2019-08-09
关键字:LVDS点屏、rk3288 LVDS点屏、奇美LVDS屏幕点屏
奇美M215HGE-L21 是一款 21.5 寸的分辨率达 1920*1080 的不可触摸的 LVDS 型显示屏。
笔者这边的这块屏幕是一种嵌在一块触摸板里的。有两根线需要连接到 rk3288 上,一根是 LVDS 线,用于视频数据的传输,另一根是 USB 线,用于触摸信号的传输。这块屏幕默认并不带触摸功能,所以触摸板是我们这边额外增加的。
在点屏之前首先必须要确认硬件电路,点屏是一种非常依赖硬件的事情,谁也无法确保自己的硬件工程师在设计电路时不会出什么差错。当然,我们作为软件肯定是很难判断电路到底有没有问题的,但是我们必须有这种意识。如果在㤐屏过程中遇到什么很匪夷所思的事情,不无理由不叫上硬件人员一起过来分析一下。
笔者这边的 rk3288 运行的是 Android5.1,rk 原厂 SDK 就已经有很完善的 lvds 屏幕支持了。所以点屏对我们软件来说,基本就是照着屏幕规格书来填一下参数而已。屏幕规格书一般是由硬件或项目经理给到我们,当然也可以在网上找到。
然后需要确认一下你编译 kernel 时所使用的 dts 文件是哪一个。一般 3288 都会有一个编大包的脚本,在这个脚本里可以看到编译命令,如下图所示
一般 dts 的名称与所编译的镜像名称一致。所以,按照上图,笔者这边使用到的 dts 应该是:
./kernel/arch/arm/boot/dts/rk3288_lvds.dts
打开 dts,我们需要关注的是 backlight 节点:
backlight { compatible = "pwm-backlight"; pwms = <&pwm0 0 25000>; brightness-levels = < 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>; default-brightness-level = <200>; enable-gpios = <&gpio7 GPIO_A2 GPIO_ACTIVE_HIGH>; };
这个节点里比较重要的是 pwms 属性与 enable-gpios 属性。这两个属性一般都直接控制着屏幕背光的亮度,它们的值要参照你自己的电路原理图来填。同时还得注意,由于背光的亮度是靠 PWM 来控制的,所以具体的 pwm 还不能忘记把它打开,如下:
&pwm0 { status = "okay"; };
另一个要关注的节点是 lcdc0 节点
&lcdc0 { status = "okay"; rockchip,mirror = <NO_MIRROR>; rockchip,cabc_mode = <0>; power_ctr: power_ctr { rockchip,debug = <1>; lcd_en:lcd_en { rockchip,power_type = <GPIO>; gpios = <&gpio7 GPIO_B1 GPIO_ACTIVE_HIGH>; rockchip,delay = <200>; }; }; };
这个节点控制的主要是 lcdc0 相关的状态,如使能脚、复位脚等等。上面的 backlight 是控制背光亮度,这个则是控制背光灯亮不亮的。它的值也是要参照具体电路图来填写的。
可能有的同学会有疑问,3288 上有好多组 lcdc ,为什么偏偏是 lcdc0 呢?一图胜千言:
第三个要关注的节点是 rk_screen
&rk_screen { display-timings = <&disp_timings>; };
这个是表明依赖的屏幕参数节点的。
第四个则是要注意将 lvds 节点置为 okay 状态,好让编译时去编译 lvds 相关的驱动。
&lvds{ status = "okay"; };
最后一个要关注的节点则是我们在第三点处就提到的屏幕参数节点:
disp_timings: display-timings { native-mode = <&timing0>; timing0: timing0 { screen-type = <SCREEN_DUAL_LVDS>; lvds-format = <LVDS_8BIT_1>; color-mode = <COLOR_RGB>; out-face = <OUT_P888>; clock-frequency = <148000000>; hactive = <1920>; vactive = <1080>; hback-porch = <35>; //屏的行场后肩 hfront-porch = <100>; //屏的行场扫描前肩 vback-porch = <15>; //屏的帧同步后肩 vfront-porch = <20>; //屏的帧同步前肩 hsync-len = <5>; //屏的行同步信号宽度 vsync-len = <10>; //屏的帧同步信号宽度 hsync-active = <0>; //屏的行场同步信号极性 vsync-active = <0>; //屏的帧同步信号极性 de-active = <0>; //屏的 DE 信号极性 pixelclk-active = <1>; //屏的 dclk 极性 swap-rb = <0>; //红蓝颜色交换 swap-rg = <0>; //红绿交换 swap-gb = <0>; //蓝绿交换 }; };
如果你需要点的屏幕型号与笔者的是一样的,那么照着填写就可以了。
上面 disp_timings 节点记载的参数的值都是从屏幕规格书来得到的,下面简单介绍一下屏幕规格书的解读。
在拿到一份屏幕规格书时,首先看一下它的屏幕特性,一般规格书正文的第一块内容就是它。如下图所示
这部分一般我们只需要关注屏幕尺寸: 1920 * 1080。hactive 的值是 1920, vactive 的值是 1080。同时我们也能知道这是一块 “横屏屏幕”。
然后我们就要往下翻,去看一下屏幕的显示时钟特性,如下图所示:
这里我们一般只关注它的典型值。首先第一行,这个是它的时钟频率,为 74.25MHz。它就是上面 disp_timings 节点的 clock-frequency 应该填的值。但是,由于我们这款屏幕的类型是 SCREEN_DUAL_LVDS ,因此实际的时钟值应该再乘个 2。所以,最终填写的值为
clock-frequency = <148000000>;
可能有的同学会说 74.25MHz 乘个 2 以后的值应该是 14.85MHz,对,没错,但其实这条属性的值的要并没有那么严格。它可以填入一个范围内的值。
接下来,我们要记住这几个值:
Tv : 1125
Tvd : 1080
Th : 1100
Thd : 960
另外:
有一些LVDS屏幕的规格书上这些电气值的名称可能不是 Tv, Tvd, Th, Thd,如下图所示:
对于这种我们只要看它前面的描述词即可,如 Horizontal Active Display Term 行的 Total 栏就对应于 Th,Valid 对应于 Thd。以此类推,Vertical Active Display Term 行的 Total 对应于 Tv, Valid 对应于 Tvd。大家仔细体会一下上面两张图的差别就很好理解的了。
我们要根据这几个值算出 disp_timings 中的 hback-porch, hfront-porch, vback-porch, vfront-porch, hsync-len, vsync-len 的值。它们之间的关系如下:
Tv = vback-porch + vfront-porch + vsync-len + Tvd
Th = hback-porch + hfront-porch + hsync-len + Thd
所以:
vback-porch + vfront-porch + vsync-len = 1125 - 1080 = 45
hback-porch + hfront-porch + hsync-len = 1100 - 960 = 140
这里只需要保证这 3 个参数之和等于那个数就可以了,对具体的值没有特别的要求。
最后剩下那几个参数,照着填就好了。
hsync-active = <0>; vsync-active = <0>; de-active = <0>; pixelclk-active = <1>; swap-rb = <0>; swap-rg = <0>; swap-gb = <0>;
最后,再贴一下几个比较重要的属性的可选值,如果怀疑是自己填的参数不对导致屏幕点不亮的话,可以逐个尝试一下。
screen-type 的可选值:
SCREEN_NULL
SCREEN_RGB
SCREEN_LVDS
SCREEN_DUAL_LVDS
SCREEN_MCU
SCREEN_TVOUT
SCREEN_HDMI
SCREEN_MIPI
SCREEN_DUAL_MIPI
SCREEN_EDP
SCREEN_TVOUT_TEST
lvds-format 的可选值:
LVDS_8BIT_1
LVDS_8BIT_2
LVDS_8BIT_3
LVDS_6BIG
LVDS_10BIT_1
LVDS_10BIT_2
out-face 的可选值:
OUT_P888
OUT_P666
OUT_P565
OUT_CCIR656
OUT_S888
OUT_S888DUMY
OUT_YUV_420
OUT_P101010
OUT_YUV_420_10BIT
OUT_P16BPP4
OUT_D888_P666
OUT_D888_P565
关于调试过程
这款屏幕电源正常供电但没有视频信号过去时将会显示纯白色背景。如果发现 LVDS 信号线不管接不接都显示纯白色,那么极有可能是 LVDS 信号线线序不对,要叫硬件检查一下。
如果发现不插信号线显示纯白色,接了信号线后就黑屏了,则说明有信号过去了,但 dts 的配置可能不正确。在 disp_timings 节点的 screen-type, lvds-format, out-face 几个属性检查一下。还有就是里面的宽高尺寸,尺寸不对也会黑屏。
关于触摸屏
笔者手里的屏幕是显示触摸一体式的。显示通过 LVDS 信号线传输,触摸通过 USB 线传输。rk3288 只要配好 USB 模式,触摸板就是即插即用的。触摸板的 USB 口插入后会有如下打印提示
EHCI: rk_ehci_hcd_enable, enable host controller usb 3-1: new full-speed USB device number 3 using ohci-rockchip usb 3-1: New USB device found, idVendor=222a, idProduct=0001 usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 3-1: Product: ILITEK-TP usb 3-1: Manufacturer: ILITEK input: ILITEK ILITEK-TP as /devices/ff520000.usb/usb3/3-1/3-1:1.0/input/input3 gpufreq_input_connect hid-multitouch 0003:222A:0001.0002: input,hiddev0,hidraw0: USB HID v1.10 Mouse [ILITEK ILITEK-TP] on usb-ff520000.usb-1/input0 rockchip-rt5631 rockchip-rt5631.30: ASoC: CODEC (null) not registered rockchip_rt5631_audio_probe() register card failed:-517 platform rockchip-rt5631.30: Driver rockchip-rt5631 requests probe deferral rockchip-rt3261 rockchip-rt3224.31: ASoC: CODEC (null) not registered rockchip_rt3261_audio_probe() register card failed:-517 platform rockchip-rt3224.31: Driver rockchip-rt3261 requests probe deferral
触摸驱动代码主要在
./kernel/drivers/hid/hid-multitouch.c
笔者在适配触摸板时发现触摸坐标点发生了翻转,即屏幕的右下角变成了“坐标原点”。很有可能是驱动程序不匹配导致的。但是偏偏笔者又弄不到合适的驱动程序,所以只能改现有驱动。改动的地方倒也很小,只需将接收并传递触摸坐标的地方将坐标转换一下就好了。
整个操作都在上面提到的 hid-multitouch.c 中实现。首先记录下触摸板的尺寸,然后在转发坐标时做一下翻转。具体如下