framebuffer帧缓冲(简称fb)是linux内核中虚拟出的一个设备,是一个platform类型设备,设备文件位于/dev/fb*
fb的结构和misc极为类似,由内核中的fb框架实现一部分,然后再由设备驱动本身实现一部分。设备驱动本身就是一个普通的platform总线驱动
虽然每家原厂写的fb设备驱动可能有些差异,但是基本的套路还是相同的
当我们板子上的LCD需要更换时,驱动中也需要进行相应的修改
ek070tn93_fb_data
:static struct s3c_platform_fb ek070tn93_fb_data __initdata = {
.hw_ver = 0x62,
.nr_wins = 5,
.default_win = CONFIG_FB_S3C_DEFAULT_WINDOW,
.swap = FB_SWAP_WORD | FB_SWAP_HWORD,
.lcd = &ek070tn93,
.cfg_gpio = ek070tn93_cfg_gpio,
.backlight_on = ek070tn93_backlight_on,
.backlight_onoff = ek070tn93_backlight_off,
.reset_lcd = ek070tn93_reset_lcd,
};
.lcd
这个成员,即结构体ek070tn93
,查看发现里面有时序、分辨率等各种参数,这样我们就可以随便修改参数了static struct s3cfb_lcd ek070tn93 = {
.width = S5PV210_LCD_WIDTH,
.height = S5PV210_LCD_HEIGHT,
.bpp = 32,
.freq = 60,
.timing = {
.h_fp = 210,
.h_bp = 38,
.h_sw = 10,
.v_fp = 22,
.v_fpe = 1,
.v_bp = 18,
.v_bpe = 1,
.v_sw = 7,
},
.polarity = {
.rise_vclk = 0,
.inv_hsync = 1,
.inv_vsync = 1,
.inv_vden = 0,
},
};
对于新的内核,platformdata都包含在了dts中,所以需要在dts中修改LCD的硬件参数。有关设备树详见设备树详解
display-timings {
lq4851lg03:lvds_1280x480_53M{
clock-frequency = <53172000>;
hactive = <1280>;
vactive = <480>;
hback-porch = <268>;
hfront-porch = <70>;
vback-porch = <10>;
vfront-porch = <10>;
hsync-len = <70>;
vsync-len = <25>;
pixelclk-active = <0>;
};
ak070tn93:ttl_1280x480_45M{
clock-frequency = <45000000>;
hactive = <1280>;
vactive = <480>;
hback-porch = <40>;
hfront-porch = <73>;
vback-porch = <20>;
vfront-porch = <23>;
hsync-len = <20>;
vsync-len = <10>;
};
xxxxx:xxxxx{
/*需要添加的参数*/
};
};
pixelclk-active = <0>;
意味着什么呢?这个元素代表时钟的极性,如果显示图片清晰度不足时,可以尝试加入该元素&mxcfb1 {
disp_dev = "lcd";
};
&ldb {
status = "disabled";
};
&lcd {
status = "okay";
native-mode = <&xxxx>;
};
ldb: ldb@020e0008 {
#address-cells = <1>;
#size-cells = <0>;
gpr = <&gpr>;
status = "disabled";
lvds-channel@0 {
reg = <0>;
status = "disabled";
};
&ldb {
status = "okay";
lvds-channel@0 {
native-mode = <&SHARP_LQ123B5LW>;
fsl,data-mapping = "jeida";
status = "okay";
};
};
注意:本段关于logo显示的ne
当kernel启动,在probe函数运行时,一般会往fb中输出一个小企鹅logo(开发板厂商可能会改成其他的)。很多时候产品是不需要这个企鹅logo的,我们要学会去修改它
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
if (fb_prepare_logo( fbdev->fb[pdata->default_win], FB_ROTATE_UR)) {
printk("Start display and show logo\n");
/* Start display and show logo on boot */
fb_set_cmap(&fbdev->fb[pdata->default_win]->cmap, fbdev->fb[pdata->default_win]);
fb_show_logo(fbdev->fb[pdata->default_win], FB_ROTATE_UR);
}
#endif
fb_show_logo
,在进去一层,找到fb_show_logo_line
,查看其定义,发现里面有两行:image.dx = 0;
image.dy = y;
这便是logo图像的坐标偏移量,只需改成恰当的值即可让logo显示到中央了