博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
itop4412 LCD设备驱动详解(二)之DRIVER
阅读量:2434 次
发布时间:2019-05-10

本文共 6626 字,大约阅读时间需要 22 分钟。

LCD的工作,在kernel中有device和driver两个描述,这也是必然。

在 分析一中我们看了device,现在我们来看看driver。
注:在驱动分析中,我们会在数据手册和原理图中查看。首先来看看lcd驱动框架(ps 该框图来自网上)
这里写图片描述
由上图可以看出 lcd的应用层 通过 内核的fbmem接口 再调用驱动xxxfb.c的内容
而fbmem接口是内核提供的,所有驱动设计人员主要的任务就是定义一个fb_info 结构体(该结构由内核提供),然后填充结构体中的内容做好相应的初始化后,提交给内核就可以了。
//———————————-
首先驱动文件在: 在kernel/drivers/video/samsung/目录下。我现在用的设备涉及的驱动如下:
(ps:这里以itop 提供的4.3寸WXCAT43屏为参考,(主要贵的买不起的哇%>_<%) )
s3cfb_wa101s.c ——设备参数相关文件
s3cfb_fimd6x.c —— 具体平台硬件相关文件
s3cfb_ops.c ——-fb 操作集合
s3cfb_main.c ——-驱动框架

好,首先来,分析s3cfb_main.c ,当然在介绍该.c时,会把之前所有的.c都牵扯进来,毕竟驱动框架调用了其他c文件的接口。(这一节主要介绍probe函数调用的接口功能,接口具体实现在下一节中介绍)

static struct platform_driver s3cfb_driver = {    .probe      = s3cfb_probe, //探测设备    .remove     = s3cfb_remove,//设备移除#ifndef CONFIG_HAS_EARLYSUSPEND     .suspend    = s3cfb_suspend,//设备暂定    .resume     = s3cfb_resume, //设备恢复#endif    .driver     = {        .name   = S3CFB_NAME, //设备名字,在s3cfb.h 当中定义,与device匹配的关键,定义如下                              //#define S3CFB_NAME      "s3cfb"        .owner  = THIS_MODULE,#ifdef CONFIG_EXYNOS_DEV_PD        .pm = &s3cfb_pm_ops, //pm电源管理集合#endif    },};static int s3cfb_register(void){    platform_driver_register(&s3cfb_driver); 平台设备的注册    return 0;}static void s3cfb_unregister(void){    platform_driver_unregister(&s3cfb_driver);平台设备的卸载}module_init(s3cfb_register);module_exit(s3cfb_unregister);
s3cfb_probe 是重点 ,现在着重介绍:static int s3cfb_probe(struct platform_device *pdev);

probe函数的主要作用是获取device资源,获取设备资源,初始化设备,注册和使能设备等

里面涉及的结构体将在必要时介绍。下面是probe函数代码简化,我把一些出错判断和调试信息等删除了以便分析.
下面是我简单的画的一个数据结构体指向草图,希望对你有帮助。
这里写图片描述
// 现在来看看probe框架,里面函数具体介绍放在probe框架介绍之后

static int s3cfb_probe(struct platform_device *pdev){    struct s3c_platform_fb *pdata = NULL; //s3c平台资源结构体    struct resource *res = NULL; //资源指针    struct s3cfb_global *fbdev[2]; //lcd driver全局指针结构体指针,是分析驱动的核心指针  #ifdef CONFIG_EXYNOS_DEV_PD    /* to use the runtime PM helper functions */    pm_runtime_enable(&pdev->dev);    /* enable the power domain */    pm_runtime_get_sync(&pdev->dev); #endif #ifndef CONFIG_TC4_EVT    lcd_regulator = regulator_get(NULL, "vdd33_lcd");      regulator_enable(lcd_regulator);    //yulu #endif    /*----------------------------------------------*/            pm_runtime_enable ,pm_runtime_get_sysnc 是运行时电源管理(运行时PM)的支持,是在电源管理的核心(PM core)下借助于以下方式实现的。regular_get ,regular_enable   是电源管理制regulator 机制。现在android/linux为模块设备供电有两种,一种GPIO供电,另一个就是电源管理芯片。电源管理芯片可以为多设备供电,且这些设备电压电流有所同。为这些设备提供的稳压器代码模型即为regulator。   这里不做详细要求,如有兴趣请查阅相关资料    /*-----------------------------------------------*/      fbfimd = kzalloc(sizeof(struct s3cfb_fimd_desc), GFP_KERNEL);//创建fimd 设备描述      if (FIMD_MAX == 2)// 接入设备dual 判断,这里显然只有一个,这个宏在s3cfb.h 中        fbfimd->dual = 1;    else        fbfimd->dual = 0;    for (i = 0; i < FIMD_MAX; i++) {
//根据要描述的fimd,进行分配空间,初始化等操作 /* global structure */ //分配全局数据区,通过上面的数据结构体可以很清晰看出来 fbfimd->fbdev[i] = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL); fbdev[i] = fbfimd->fbdev[i]; fbdev[i]->dev = &pdev->dev; //让global指向了platform 的设备,也就是 //上一节中介绍的平台设备描述,struct platform_device s3c_device_fb 里面有设备的io //中断资源等 //这个函数是获取具体设备的参数的,跟s3cfb_wa101s.c有关 // 在这个函数中我们看到如何通过硬件拨码开关选择lcd硬件 //讲在下面介绍 s3cfb_set_lcd_info(fbdev[i]); /* platform_data */ //通过这个函数获得上一篇中介绍的上s3c_platform_fb //现在让我们回顾一下 在dev-fimd-s5p.c 中有 s3cfb_set_platdat 函数中 /* struct s3c_platform_fb *npd;........ s3cfb_get_clk_name(npd->clk_name); npd->cfg_gpio = s3cfb_cfg_gpio; npd->backlight_on = s3cfb_backlight_on; npd->backlight_off = s3cfb_backlight_off; npd->lcd_on = s3cfb_lcd_on; npd->lcd_off = s3cfb_lcd_off; npd->clk_on = s3cfb_clk_on; npd->clk_off = s3cfb_clk_off; */ //现在知道作用了吧 pdata = to_fb_plat(&pdev->dev); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev);//初始化io,将在下面介绍 if (pdata->clk_on) pdata->clk_on(pdev, &fbdev[i]->clock);//初始化时钟 //将在下面介绍 /* io memory */ //从平台设备中获取io资源,申请io资源,映射io资源 res = platform_get_resource(pdev, IORESOURCE_MEM, i); res = request_mem_region(res->start, res->end - res->start + 1, pdev->name); fbdev[i]->regs = ioremap(res->start, res->end - res->start + 1); /* irq */ 从平台驱动获取frame中断 fbdev[i]->irq = platform_get_irq(pdev, 0); request_irq(fbdev[i]->irq, s3cfb_irq_frame, IRQF_SHARED,pdev->name, fbdev[i]) // 如有必要获取fifo中断 #ifdef CONFIG_FB_S5P_TRACE_UNDERRUN if (request_irq(platform_get_irq(pdev, 1), s3cfb_irq_fifo,IRQF_DISABLED, pdev->name, fbdev[i])) s3cfb_set_fifo_interrupt(fbdev[i], 1); dev_info(fbdev[i]->dev, "fifo underrun trace\n"); #endif /* hw setting */ /*故名思议这是对硬件的初始化,里面主要是对exynos4412的寄存器设置所有会调到 s3cfb_fimd6x.c 中的寄存器操作,将在下面详细介绍*/ s3cfb_init_global(fbdev[i]); fbdev[i]->system_state = POWER_ON;//设置设备工作状态power on /* alloc fb_info */ /* 这个函数在s3cfb_ops.c 文件中 -------fb 操作集合*/ /*这个函数的作用是申请struct fb_info 结构体,初始化fb_info 结构体的信息*/ /*fb_info 结构体 上与内核接口耦合的关系,我们写lcd驱动就是除了初始化相关硬件以外*/ /*就是把fb_info 结构体初始化后 注册到内核,供 fb_mem 调用,上层才能跟底层结合起来*/ /*该函数具体内容将在接下来介绍*/ s3cfb_alloc_framebuffer(fbdev[i], i); /* register fb_info */ /*这个函数在s3cfb_ops.c 文件中 主要是向内核注册fb_info ,将在以后介绍*/ if (s3cfb_register_framebuffer(fbdev[i])) /* enable display */ /*s3cfb_set_clock 向VIDCON0 配置相应的时钟参数*/ s3cfb_set_clock(fbdev[i]); /* --------选择windows通道,使能wins窗口,将在接下来*/ s3cfb_enable_window(fbdev[0], pdata->default_win); #ifdef CONFIG_FB_S5P_SOFTBUTTON_UI /* Add Menu UI */ s3cfb_enable_window(fbdev[0], 4); #endif /*设置窗口状态,/* screen: unblanked, hsync: on, vsync: on */ s3cfb_update_power_state(fbdev[i], pdata->default_win, FB_BLANK_UNBLANK); /*2.真正使能lcd模块,设置exynos的基础器,所以与硬件有关*/ /*具体函数在 s3cfb_fimd6x.c 。将在接下来介绍*/ s3cfb_display_on(fbdev[i]); #ifdef CONFIG_FB_S5P_LCD_INIT /* panel control */ if (pdata->backlight_on) //判断是否开启背光 pdata->backlight_on(pdev); if (pdata->lcd_on) //判断是启动lcd pdata->lcd_on(pdev); #endif /*在/sys/class/下创建一个属性文件 okprobe 函数就此结束*/ ret = device_create_file(&(pdev->dev), &dev_attr_win_power); return 0;}

好了我们再来回顾了probe函数的主要作用和流程:

1. 获取平台设备 device中的资源
2. 对设备做了一下相应的初始化
3. 申请了fb_info ,根据要求进行了填充
4. 向内核提交了fb_info
5. 使能设备等
6. 创建属性文件

这是probe功能,remove是做相应的逆操作,在这里不做介绍了。

后:在上面的介绍中是只有简单介绍了probe中主要有哪些函数和一些功能,

那么在下一节中将会介绍,这些函数的具体实现和原理
未完待续。。。。。

你可能感兴趣的文章
Spring自动装配
查看>>
Hibernate入门与实例
查看>>
Jython入门学习
查看>>
Hiberate基础用法实例
查看>>
Maven编译时指定JDK版本
查看>>
Hibernate单向关联N-1
查看>>
Hibernate单向关联1-1
查看>>
jQuery自定义动画
查看>>
Spring-data-redis在shiro中的实例
查看>>
GUN C中__attribute__作用
查看>>
3、系统调用之SYSCALL_DEFINE分析
查看>>
linux的signal_pending及signal
查看>>
OBJDUMP用法
查看>>
c/cplusplus通用makefile
查看>>
JavaScript-密码强度
查看>>
【SSH】1366-InCorrect string value:'\xE9\x99\x88\xE6\x96\xB0...'for column 'name' at row 1
查看>>
SpringCloud前身之微服务
查看>>
纵览全局——SSH
查看>>
纵览全局——Mybatis
查看>>
PC端-中文转拼音后续问题
查看>>