首先,请先下载附件,该文件并非压缩包,下载后直接将后缀名改成.c即可,并将该文件cp到相应目录:kernel/drivers/video/rockchip/lcdc下,该文件修复了1440x900和1366x768两种分辨率的异常(兼容性有待考证),还有就是RGB颜色问题;准备工作做好之后,自行编译内核进行烧写;
然后,下面的代码便是自动适配分辨率的,这是一个单独的程序,需要各位网友自行cp进行编译,编译完成之后,只需要将执行路径添加到/etc/rc.local文件即可;若网友发现有问题,请相互交流。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NUM_BUFFERS 2
#define RK_FBIOSET_CLEAR_FB 0x4633
#if 0
#define DEBUG_P(format, ...) printf(format, ##__VA_ARGS__)
#else
#define DEBUG_P(format, ...)
#endif
int main(int argc, char *argv[])
{
FILE *fp = fopen("/sys/class/graphics/fb0/screen_info", "r");
if(fp == NULL)
{
perror("fopen err:");
return -1;
}
int xres = 0;
int yres = 0;
char line1[64] = {0};
char line2[64] = {0};
fgets(line1, sizeof(line1), fp);
fgets(line2, sizeof(line2), fp);
sscanf(line1, "xres:%dn", &xres);
sscanf(line2, "yres:%dn", &yres);
fclose(fp);
DEBUG_P("read x:%d, y:%dn", xres, yres);
int fd = open("/dev/fb0", O_RDWR, 0);
if (fd < 0)
{
fprintf(stderr, "No fb devices found!n");
return -errno;
}
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
{
close(fd);
return -errno;
}
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
close(fd);
return -errno;
}
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
info.xoffset = 0;
info.yoffset = 0;
info.width = xres;
info.height = yres;
info.xres = xres;
info.yres = yres;
info.xres_virtual = info.xres;
info.yres_virtual = info.yres * NUM_BUFFERS;
info.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
info.bits_per_pixel = 32;
info.red.offset = 16;
info.red.length = 8;
info.green.offset = 8;
info.green.length = 8;
info.blue.offset = 0;
info.blue.length = 8;
info.transp.offset = 0;
info.transp.length = 0;
info.grayscale &= 0xff;
info.grayscale |= (info.xres<<8) + (info.yres<<20);
info.nonstd &= 0xffffff00;
info.nonstd |= 2;//HAL_PIXEL_FORMAT_RGBX_8888;
ioctl(fd, RK_FBIOSET_CLEAR_FB, NULL);
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
{
perror("FBIOPUT_VSCREENINFO failed");
close(fd);
return -errno;
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
{
fprintf(stderr, "FBIOGET_VSCREENINFO failed.n");
close(fd);
return -errno;
}
int refreshRate = 0;
if ( info.pixclock > 0 )
{
refreshRate = 1000000000000000LLU / ((uint64_t)
(info.upper_margin + info.lower_margin + info.yres + info.hsync_len ) *
(info.left_margin + info.right_margin + info.xres + info.vsync_len ) *
info.pixclock);
if (refreshRate == 0)
{
refreshRate = 60*1000; // 60 Hz
}
}
if ((int)(info.width) <= 0 || (int)(info.height) <= 0)
{
// the driver doesn't return that information
// default to 160 dpi
info.width = ((info.xres * 25.4f)/160.0f + 0.5f);
info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
}
float xdpi = (info.xres * 25.4f) / info.width;
float ydpi = (info.yres * 25.4f) / info.height;
float fps = refreshRate / 1000.0f;
DEBUG_P("using (fd=%d)n"
"id = %sn"
"xres = %d pxn"
"yres = %d pxn"
"xres_virtual = %d pxn"
"yres_virtual = %d pxn"
"bpp = %dn"
"r = %2u:%un"
"g = %2u:%un"
"b = %2u:%un"
"format = %dn",
fd,
finfo.id,
info.xres,
info.yres,
info.xres_virtual,
info.yres_virtual,
info.bits_per_pixel,
info.red.offset, info.red.length,
info.green.offset, info.green.length,
info.blue.offset, info.blue.length,
info.nonstd);
DEBUG_P("width = %d mm (%f dpi)n"
"height = %d mm (%f dpi)n"
"refresh rate = %.2f Hzn",
info.width, xdpi,
info.height, ydpi,
fps);
int videodata[2];
videodata[1] = videodata[0] = finfo.smem_start;
ioctl(fd, 0x5002, videodata);
close(fd);
return 0;
}
原作者:hongyin
|