1. 和其它内核代码类似。

显示驱动的分析都是由 drivers/video/fbmem.c开始,fbmem.c是显示驱动的抽象,实际只是一个框架性的东西。

fbmem_init 中实现了一个字符设备驱动,并创建了class,但是没有生成设备文件。

这个字符设备驱动的file_operations里面的函数,实质上都是从struct fb_info *registered_fb[FB_MAX]   这个

fb_info的结构体数组中去调用 fb_ops 这个结构体中函数指针。数组下标为次设备号。那么这个结构体是如何赋值的

呢?

fbmem.c里定义 register_framebuffer这个函数。真正的显示设备都是调用这个函数来给registered_fb这个数组赋值,

然后再去创建设备文件。

2.  我们搜索register_framebuffer这个文件,有如下几处:

drivers/gpu/drm/drm_fb_helper.c

drivers/video/s3c-fb.c

3. 我们先来看看s3c-fb.c

这个文件注册了一个平台总线设备驱动程序,在其probe函数中调用 register_framebuffer。

那么这个驱动的probe的函数什么时候调用呢?

接下来我们看一下内核中实现平台总线驱动代码,注意,平台总线驱动是内核实现的。

4. drivers/base/platform.c

主要看platform_match这个函数,也就是平台总线设备驱动和平台总线设备是如何匹配的,知道了匹配规则,我们

就知道如何去需找对应的平台设备了。

先看这句话

if (pdrv->id_table)
        return platform_match_id(pdrv->id_table, pdev) != NULL;

return (strcmp(pdev->name, drv->name) == 0);

如何平台总线设备驱动中有id_table的话,那么调用platform_match_id这个函数。

我们再看一下platform_match_id函数做个什么。

while (id->name[0]) {
        if (strcmp(pdev->name, id->name) == 0) {
            pdev->id_entry = id;
            return id;
        }
        id++;
    }

很显然,就是拿平台总线设备的name去挨个比较平台总线设备驱动的id_table,匹配成功测返回id。

如果没有匹配成功,则再去比较平台总线设备的名称和平台总线驱动的名称。也就是

return (strcmp(pdev->name, drv->name) == 0);  这句。

一旦匹配成功,那么内核会自动调用平台总线设备驱动的probe函数。

5.  那么接下来,我们就看看s3c-fb.c这个文件里实现的平台总线设备驱动程序的name和id_table

static struct platform_driver s3c_fb_driver = {
    .probe        = s3c_fb_probe,
    .remove        = s3c_fb_remove,
    .id_table    = s3c_fb_driver_ids,
    .driver        = {
        .name    = "s3c-fb",
        .owner    = THIS_MODULE,
        .pm    = &s3cfb_pm_ops,
    },
};

static struct platform_device_id s3c_fb_driver_ids[] = {
    {
        .name        = "s3c-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_64xx,
    }, {
        .name        = "s5pc100-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_s5pc100,
    }, {
        .name        = "s5pv210-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_s5pv210,
    }, {
        .name        = "exynos4-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_exynos4,
    }, {
        .name        = "exynos5-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_exynos5,
    }, {
        .name        = "s3c2443-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_s3c2443,
    }, {
        .name        = "s5p64x0-fb",
        .driver_data    = (unsigned long)&s3c_fb_data_s5p64x0,
    },
    {},
};

有了第4点的分析,我们可以搜索上面红字部分来查找对应的平台总线设备了。

6.  搜索"s3c-fb",找到了

arch/arm/plat-samsung/devs.c这个文件

搜索"exynos4-fb",找到了

arch/arm/mach-exynos/common.c

其它name,我们应该不用理会,都是其它soc名称。

在devs.c里定义了

struct platform_device s3c_device_fb = {
    .name        = "s3c-fb",
    .id        = -1,
    .num_resources    = ARRAY_SIZE(s3c_fb_resource),
    .resource    = s3c_fb_resource,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    },
};

在common.c里是这句 s5p_fb_setname(0,"exynos4-fb");

展开实际是这样s5p_device_fimd0.name = name;

struct platform_device s5p_device_fimd0 = {
    .name        = "s5p-fb",    这块被改为了 "exynos4-fb"
    .id        = 0,
    .num_resources    = ARRAY_SIZE(s5p_fimd0_resource),
    .resource    = s5p_fimd0_resource,
    .dev        = {
        .dma_mask        = &samsung_device_dma_mask,
        .coherent_dma_mask    = DMA_BIT_MASK(32),
    },
};

从以上分析,实际定义了两个设备,"s3c-fb","exynos4-fb"。

7. 现在,找到了,平台总线的设备和驱动后,我们要做的主要事情就是去修改lcd的各种参数,主要是fb_info结构体

的fb_var_screeninfo结构体,这里面记录了lcd的主要9个参数。

行前肩,行后肩,行同步信号脉宽,帧前肩,帧后肩,帧同步信号脉宽,像素时钟频率,x轴像素点,y轴像素点。

分析了s3c_fb.c文件后,发现是这句来赋值,fb_videomode_to_var(&fbinfo->var, &initmode);

经过再次分析后,实际数据是来源于平台总线设备中,pd = pdev->dev.platform_data;

8.  那么我们再次回到devs.c这个文件,因为上面两个平台总线设备均定义在次文件中。

但是查看s3c_device_fb和s5p_device_fimd0这两个平台设备结构体后,没有发现platform_data。那么一定是后面

专门有赋值的地方。查找后,发现

void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd)
{
    s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
             &s3c_device_fb);
}

void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
{
    s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
             &s5p_device_fimd0);
}

经过搜索发现,s5p_fimd0_set_platdata在 下面文件中调用,

arch/arm/mach-exynos/mach-nanopc-t1.c

arch/arm/mach-exynos/mach-smdk4x12.c  这个文件应该没用

s3c_fb_set_platdata没有被任何地方调用,那么s3c_device_fb这个设备应该没有用处,我认为应该去掉。

9. 接下来我们主要分析s5p_device_fimd0这个设备。

在mach-nano-t1.c 这句 两句

nanopc_fb_init_pdata(&nanopc_fb_pdata);

s5p_fimd0_set_platdata(&nanopc_fb_pdata);

实际真正的数据是在nanopc_fb_pdata中,并且在nanopc_fb_init_pdata中得到的值。

再看nanopc_fb_init_pdata这个函数,发现以下几句

lcd = tiny4412_get_lcd();

mode->left_margin    = lcd->timing.h_bp;
    mode->right_margin    = lcd->timing.h_fp;
    mode->upper_margin    = lcd->timing.v_bp;
    mode->lower_margin    = lcd->timing.v_fp;
    mode->hsync_len        = lcd->timing.h_sw;
    mode->vsync_len        = lcd->timing.v_sw;
    mode->xres            = lcd->width;
    mode->yres            = lcd->height;

数据实际来源于tiny4412_get_lcd()。

tiny4412_get_lcd定义在

arch/arm/mach-exynos/tiny4412-lcds.c中

到此,我们终于找到各种屏的参数定义,并且还有hdmi参数的定义。

待续

Tiny 4412 lcd 驱动分析相关推荐

  1. Tiny 4412 lcd 驱动分析 2

    /home/yangjia/samba/linux-3.5/arch/arm/mach-exynos/mach-tiny4412.c  ._initdata 定义在此文件中.平台驱动都重要在这里注册. ...

  2. LCD驱动分析(一)

    LCD驱动分析 转载自http://blog.chinaunix.net/uid-26021340-id-3011787.html S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 ...

  3. 《Linux驱动:s3c2440 lcd 驱动分析》

    文章目录 一,前言 二,LCD原理和硬件分析 2.1 LCD原理解析 2.2 硬件电路 2.2.1 LCD背光电路 2.2.2 LCD屏 2.2.3 S3c2440主控 三,LCD应用平台总线-设备- ...

  4. 高通 android平台LCD驱动分析

    目前手机芯片厂家提供的源码里包含整个LCD驱动框架,一般厂家会定义一个xxx_fb.c的源文件,注册一个平台设备和平台驱动,在驱动的probe函数中来调用register_framebuffer(), ...

  5. Am335x lcd驱动分析

    2019独角兽企业重金招聘Python工程师标准>>> 一 文件列表 本文使用的为sdk6.0 kernel版本为3.2 并未使用dts am335x的lcd驱动相关文件有: (ke ...

  6. LCD驱动分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/21559153 1.S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 其 ...

  7. lcd驱动分析(读书笔记)

    1.S3C2440上LCD驱动 (FrameBuffer)实例开发讲解 其中的代码也可直接参考:drivers/video/s3c2410fb.c 以下为转载文章,文章原地址:http://blog. ...

  8. android 副屏驱动_高通 android平台LCD驱动分析

    目前手机芯片厂家提供的源码里包含整个LCD驱动框架,一般厂家会定义一个xxx_fb.c的源文件,注册一个平台设备和平台驱动,在驱动的probe函数中来调用register_framebuffer(), ...

  9. 高通平台LCD驱动分析

    目前手机芯片厂家提供的源码里包含整个LCD驱动框架,一般厂家会定义一个xxx_fb.c的源文件,注册一个平台设备和平台驱动,在驱动的probe函数中来调用register_framebuffer(), ...

最新文章

  1. mysql源码学习 vc项目解决方案文件_Mysql源码学习——源码目录结构
  2. ping无法访问目标主机 0丢失_预渗透之目标识别
  3. 零基础可以学python吗-python零基础能学吗
  4. 数据结构-堆实现优先队列(java)
  5. python定义函数的组成部分有_Python文档学习笔记(4)--定义函数
  6. 正则 禁止连续逗号_正则
  7. 全面 Severless 化只需要 7天!
  8. 奇偶链表的分割(C++)
  9. html5number最小值,JavaScript Number(数字)
  10. 关于Ajax和@RequestBody配合使用的问题
  11. 最后的人 - 主机程序员十年的分享
  12. 1-学习GPRS_Air202(Air202开发板介绍)
  13. 学习能力篇:“拼图式”学习法
  14. 转载130个原文网站,原文链接:https://blog.csdn.net/qq_43901693/article/details/100606828
  15. 【论文写作】——设置中英文字体
  16. abaqus质量缩放系数取值_ABAQUS中的质量缩放
  17. 【NVMe2.0b 8】NVMe 队列仲裁机制
  18. 我的消费记录怎么查看呢?
  19. 北京杭州差距这么大?程序员在北京准点下班,在杭州12点在还加班
  20. 递归算法中的时间复杂度分析

热门文章

  1. 中国首富许家印入局FF 贾跃亭造车这事儿要成?
  2. 解决python错误:utf-8 codec can't decode byte 0xbb in position3:invalid start byte
  3. 浅谈php国际(I18N)以及config包的使用
  4. vue一些utils
  5. freemarker(FTL)常见语法大全
  6. notepad++ 使用JsonView来格式化json字符串
  7. 两化融合贯标是指什么
  8. OpenCv-C++-KAZE(AKAZE)局部特征检测(一)
  9. 原生js+css 实现轮播图 完整代码
  10. 洛谷P5266 【深基17.例6】学籍管理