【北京迅为】i.MX6ULL终结者Linux LCD驱动实验编写LCD驱动程序

i.MX6ULL的eLCDIF 接口驱动程序 NXP 已经编写好了,因此 LCD 驱动部分
我们不需要去修改。我们需要做的就是按照所使用的 LCD 来修改设备树。重点要注意三个地方:
① LCD 所使用的 IO 配置。
② LCD 屏幕节点修改,修改相应的属性值,换成我们所使用的 LCD 屏幕参数。
③ LCD 背光节点信息修改,要根据实际所使用的背光 IO 来修改相应的设备节点信息。接下来我们依次来看一下上面这两个节点改如何去修改。

1 设备树中LCD屏幕GPIO配置

首先要确定LCD屏幕使用了哪些引脚,其实这些引脚在NXP的设备树文件中已经写好了,我们就来检查一下GPIO引脚是否正确。打开imx6ull-14x14-evk.dts文件,在iomuxc节点下有如下内容:

1 pinctrl_lcdif_dat: lcdifdatgrp {
    
     
2 	fsl,pins = < 
3 			MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 
4 			MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 
5 			MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x79 
6 			MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x79 
7 			MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x79 
8 			MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x79 
9 			MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x79 
10 			MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x79 
11 			MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x79 
12 			MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x79 
13 			MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x79 
14 			MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x79 
15 			MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x79 
16 			MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x79 
17 			MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x79 
18 			MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x79 
19 			MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x79 
20 			MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x79 
21 			MX6UL_PAD_LCD_DATA18__LCDIF_DATA18 0x79 
22 			MX6UL_PAD_LCD_DATA19__LCDIF_DATA19 0x79 
23 			MX6UL_PAD_LCD_DATA20__LCDIF_DATA20 0x79 
24 			MX6UL_PAD_LCD_DATA21__LCDIF_DATA21 0x79 
25 			MX6UL_PAD_LCD_DATA22__LCDIF_DATA22 0x79 
26 			MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79 
27 		>; 
28 }; 
29
30 pinctrl_lcdif_ctrl: lcdifctrlgrp {
    
     
31 		fsl,pins = < 
32 			MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 
33 			MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 
34 			MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 
35 			MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 
36 		>; 
37 pinctrl_pwm1: pwm1grp {
    
     
38 		fsl,pins = < 
39 			MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 
40 		>; 
41 }; 

第 2~27 行,子节点 pinctrl_lcdif_dat,为 RGB LCD 的 24 根数据线配置项。
第 30~36 行,子节点 pinctrl_lcdif_ctrl,RGB LCD 的 4 根控制线配置项,包括 CLK、 ENABLE、VSYNC 和 HSYNC。
第 37~40 行,子节点 pinctrl_pwm1,LCD 背光 PWM 引脚配置项。这个引脚要根据实际情况设置。

2 LCD屏幕参数节点信息

打开imx6ull-14x14-evk.dts文件,找到lcdif节点,内容如下:

1 &lcdif {
    
     
2          pinctrl-names = "default"; 
3          pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */ 
4          &pinctrl_lcdif_ctrl 
5          &pinctrl_lcdif_reset>; 
6          display = <&display0>; 
7          status = "okay"; 
8 
9          display0: display {
    
     /* LCD 属性信息 */ 
10                 bits-per-pixel = <16>; /* 一个像素占用几个 bit */ 
11              bus-width = <24>; /* 总线宽度 */ 
12 
13                 display-timings {
    
     
14                 native-mode = <&timing0>; /* 时序信息 */ 
15                 timing0: timing0 {
    
     
16                     clock-frequency = <9200000>; /* LCD 像素时钟,单位 Hz */ 
17                     hactive = <480>; /* LCD X 轴像素个数 */ 
18                     vactive = <272>; /* LCD Y 轴像素个数 */ 
19                     hfront-porch = <8>; /* LCD hfp 参数 */ 
20                     hback-porch = <4>; /* LCD hbp 参数 */ 
21                     hsync-len = <41>; /* LCD hspw 参数 */ 
22                     vback-porch = <2>; /* LCD vbp 参数 */
23                     vfront-porch = <4>; /* LCD vfp 参数 */ 
24                     vsync-len = <10>; /* LCD vspw 参数 */ 
25 
26                     hsync-active = <0>; /* hsync 数据线极性 */ 
27                     vsync-active = <0>; /* vsync 数据线极性 */ 
28                     de-active = <1>; /* de 数据线极性 */
29                     pixelclk-active = <0>; /* clk 数据线先极性 */ 
30                     };
31             }; 
32         }; 
33 }; 

上面的代码就是根据自己使用的LCD屏幕信息添加的内容。
第 3 行,pinctrl-0 属性,LCD 所使用的 IO 信息,这里用到了 pinctrl_lcdif_dat、pinctrl_lcdif_ctrl和 pinctrl_lcdif_reset 这三个 IO 相关的节点,pinctrl_lcdif_reset 是 LCD 复位 IO 信息节点。
第 6 行,display 属性,指定 LCD 属性信息所在的子节点,这里为 display0,下面就是 display0子节点内容。
第 9~32 行,display0 子节点,描述 LCD 的参数信息,第 10 行的 bits-per-pixel 属性用于指明一个像素占用的 bit 数,默认为 16bit。本教程我们将 LCD 配置为 RGB888 模式,因此一个像素点占用 24bit,bits-per-pixel 属性要改为 24。第 11 行的 bus-width 属性用于设置数据线宽度,因为要配置为 RGB888 模式,因此 bus-width 也要设置为 24。
第 13~30 行,这几行非常重要!因为这几行设置了 LCD 的时序参数信息,NXP 官方的 EVK开发板使用了一个 4.3 寸的 480*272 屏幕,因此这里默认是按照 NXP 官方的那个屏幕参数设置的。每一个属性的含义后面的注释已经写的很详细了,大家自己去看就行了,这些时序参数就是我们重点要修改的,需要根据自己所使用的屏幕去修改。
下面以迅为的7寸屏为例,修改topeet_emmc_4_3.dts文件中的lcdif节点:

1 &lcdif {
    
     
2  pinctrl-names = "default"; 
3  pinctrl-0 = <&pinctrl_lcdif_dat /* 使用到的 IO */ 
4              &pinctrl_lcdif_ctrl>; 
5  display = <&display0>; 
6  status = "okay"; 
7 
8  display0: display {
    
     /* LCD 属性信息 */ 
9      bits-per-pixel = <24>; /* 一个像素占用 24bit */ 
10         bus-width = <24>; /* 总线宽度 */ 
11 
12         display-timings {
    
     
13             native-mode = <&timing0>; /* 时序信息 */
14             timing0: timing0 {
    
     
15             clock-frequency = <70000000>;/* LCD 像素时钟,单位 Hz */ 
16             hactive = <1024>; /* LCD X 轴像素个数 */ 
17             vactive = <600>; /* LCD Y 轴像素个数 */ 
18             hfront-porch = <160>; /* LCD hfp 参数 */ 
19             hback-porch = <140>; /* LCD hbp 参数 */ 
20             hsync-len = <20>; /* LCD hspw 参数 */ 
21             vback-porch = <20>; /* LCD vbp 参数 */
22             vfront-porch = <12>; /* LCD vfp 参数 */ 
23             vsync-len = <3>; /* LCD vspw 参数 */ 
24 
25             hsync-active = <0>; /* hsync 数据线极性 */
26             vsync-active = <0>; /* vsync 数据线极性 */ 
27             de-active = <1>; /* de 数据线极性 */ 
28             pixelclk-active = <0>; /* clk 数据线先极性 */ 
29             }; 
30         }; 
31   }; 
32 }; 

第 3 行,设置 LCD 屏幕所使用的 IO,删除掉原来的 pinctrl_lcdif_reset,因为没有用到屏幕复位 IO,其他的 IO 不变。
第 9 行,使用 RGB888 模式,所以一个像素点是 24bit。
第 15~23 行,7寸屏幕时序参数,或者根据自己所使用的屏幕修改即可。

3 LCD屏幕背光节点信息

i.MX6UL终结者开发板上使用GPIO1_IO08 引脚来作为LCD屏幕的背光控制引脚。GPIO1_IO08 引脚复用为PWM1_OUT功能呢,通过PWM信号来控制LCD屏幕的背光亮度。因为和NXP官方的开发板使用的背光控制引脚相同,所以不同修改设备树中关于背光控制引脚的设备节点信息。因为有的用户可能使用别的引脚来控制背光,所以我们还是来看一下如何来添加背光控制GPIO的设备节点信息。
首先是添加GPIO1_IO08引脚的pinctrl节点,在topeet_emmc_4_3.dts文件中,内容如下:

1 pinctrl_pwm1: pwm1grp {
    
     
2 	fsl,pins = < 
3 		MX6UL_PAD_GPIO1_IO08__PWM1_OUT 0x110b0 
4 	>; 
5 }; 

第3行,设置GPIO1_IO08引脚的复用功能为PWM1_OUT,电气属性为0x110b0。
因为将GPIO1_IO08引脚复用为pwm功能,看一下imx6ull.dtsi文件中PWM1的节点信息:

1 pwm1: pwm@02080000 {
    
    
2      compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm"; 
3      reg = <0x02080000 0x4000>; 
4      interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; 
5      clocks = <&clks IMX6UL_CLK_PWM1>, 
6      <&clks IMX6UL_CLK_PWM1>; 
7      clock-names = "ipg", "per"; 
8        #pwm-cells = <2>; 
9 }; 

如果要修改PWM1节点的信息,不要在imx6ull.dtsi文件中修改,可以在自己的设备树文件中通过引用节点的方式来修改,比如在topeet_emmc_4_3.dts文件中。通过compatible属性值信息可以找到PWM的驱动文件为drivers/pwm/pwm-imx.c。
然后看一下在topeet_emmc_4_3.dts文件中pwm节点修改了哪些内容:

1 &pwm1 {
    
     
2 		pinctrl-names = "default"; 
3 		pinctrl-0 = <&pinctrl_pwm1>; 
4 		status = "okay"; 
5 };

第3行,指定了pwm1使用的pinctrl引脚为GPIO1_IO08。
第 4 行,将 status 设置为 okay。
如果背光控制引脚使用了其他的pwm通道,按照pwm1的设置添加相关的内容就可以了。
在设置pwm1完成后,还需要将pwm1和LCD背光控制连接起来,这个节点就是backlight,backlight 节点描述可以参考 Documentation/devicetree/indings/video/backlight/pwm-backlight.txt 这个文档,此文档详细讲解了backlight 节点该如何去创建,这里大概总结一下:
① 节点名称要为“backlight”。
② 节点的 compatible 属性值要为“pwm-backlight”,因此可以通过在 Linux 内核中搜索 “ pwm-backlight ”来查找 PWM 背光控制驱动程序,这个驱动程序文件为 drivers/video/backlight/pwm_bl.c,感兴趣的可以去看一下这个驱动程序。
③ pwms属性用于描述背光所使用的PWM以及PWM频率,比如本章我们要使用的pwm1,pwm 频率设置为 5KHz(NXP 官方推荐设置)。
④ brightness-levels 属性描述亮度级别,范围为 0~255,0 表示 PWM 占空比为 0%,也就是亮度最低,255 表示 100%占空比,也就是亮度最高。至于设置几级亮度,大家可以自行填写此属性。
⑤ default-brightness-level 属性为默认亮度级别。
根据上面的几点要求,来看一下在topeet_emmc_4_3.dts文件中是如何设置的:

1 backlight {
    
     
2 		compatible = "pwm-backlight";
3 		pwms = <&pwm1 0 5000000>; 
4 		brightness-levels = <0 4 8 16 32 64 128 255>; 
5 		default-brightness-level = <6>; 
6 		status = "okay"; 
7 }; 

第 3 行,设置背光使用 pwm1,PWM 频率为 5KHz。
第 4 行,设置背 8 级背光(0~7),分别为 0、4、8、16、32、64、128、255,对应占空比为0%、1.57%、3.13%、6.27%、12.55%、25.1%、50.19%、100%,如果想要更加精准的控制背光亮度可以自己添加一些其他的背光等级值。
第 5 行,设置默认背光等级为 6,也就是 50.19%的亮度。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/BeiJingXunWei/article/details/112321060