framebuffer驱动详解3——fb驱动分析(具体操作层)

以下内容源于朱有鹏嵌入式课程的学习与整理,如有侵权请告知删除。

前言

博文fb驱动框架分析(核心层)已经对内核驱动维护者编写的fb驱动框架进行讲解。

接下来将对具体的fb驱动文件进行分析。这些驱动文件是驱动工程师要完成的部分。

root@ubuntu:省略部分路径/x210_kernel/drivers/video# cd samsung/
root@ubuntu:省略部分路径/x210_kernel/drivers/video/samsung# ls *.o
built-in.o  s3cfb_fimd6x.o  s3cfb.o
root@ubuntu:省略部分路径/x210_kernel/drivers/video/samsung# 

通过检查内核编译结果相应目录中的.o文件,得知具体操作层主要涉及的文件:

(1)drivers/video/samsung/s3cfb.c,这是驱动主要文件。

(2)drivers/video/samsung/s3cfb_fimd6x.c,里面有很多LCD硬件操作的函数。

(3)arch/arm/mach-s5pv210/mach-x210.c,负责提供platform_device。

(4)arch/arm/plat-s5p/devs.c,为platform_device提供一些硬件描述信息。

这里主要分析drivers/video/samsung/s3cfb.c文件。

1、实现方式为平台总线

这是因为使用到SoC内部的LCD控制器,它属于内部外设,故而可以借用平台总线实现一些机制。

static int __init s3cfb_register(void)
{platform_driver_register(&s3cfb_driver);return 0;
}
static void __exit s3cfb_unregister(void)
{platform_driver_unregister(&s3cfb_driver);
}module_init(s3cfb_register);
module_exit(s3cfb_unregister);

 

2、平台驱动结构体变量:s3cfb_driver

static struct platform_driver s3cfb_driver = {.probe = s3cfb_probe,.remove = __devexit_p(s3cfb_remove),.driver = {.name = S3CFB_NAME,  //#define S3CFB_NAME	"s3cfb".owner = THIS_MODULE,},
};

由于平台总线下,驱动与设备是根据name来进行匹配的,这里驱动的名字是“s3cfb”,因此和驱动匹配的设备的名字应该也叫“s3cfb”。

 

3、s3c_device_fb设备

(1)我们找一下名字叫“s3cfb”的平台设备。在linux系统x210_kernel目录下,使用“ grep -nr “s3cfb” ./ ”命令查找贴切的设备定义,得知其位于arch/arm/plat-s5p/devs.c文件中,内容如下所示。由此可知,s3c_device_fb这个平台设备的名字叫做“s3cfb”。

struct platform_device s3c_device_fb = {.name		  = "s3cfb",                 //定义在这里.id		  = -1,   //id表示次设备号,-1表示自动分配次设备号.num_resources	  = ARRAY_SIZE(s3cfb_resource),.resource	  = s3cfb_resource,.dev		  = {.dma_mask		= &fb_dma_mask,.coherent_dma_mask	= 0xffffffffUL}
};

(2)在板级文件mach-x210.c中,s3c_device_fb这个平台设备与其他平台设备一样,被写入平台设备数组smdkc110_devices[ ]中,然后再利用smdkc110_machine_init()函数对这些平台设备进行注册,过程如下所示。

static struct platform_device *smdkc110_devices[] __initdata = {
#ifdef CONFIG_FIQ_DEBUGGER&s5pv210_device_fiqdbg_uart2,
#endif
//省略部分代码#ifdef CONFIG_FB_S3C&s3c_device_fb,   //这里
#endif
//省略部分代码}
static void __init smdkc110_machine_init(void)
{//省略部分代码platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));//省略部分代码
}

(3)我们再看一下s3cfb_resource,其内容如下。

static struct resource s3cfb_resource[] = {[0] = {.start = S5P_PA_LCD,.end   = S5P_PA_LCD + S5P_SZ_LCD - 1,.flags = IORESOURCE_MEM,},[1] = {.start = IRQ_LCD1,.end   = IRQ_LCD1,.flags = IORESOURCE_IRQ,},[2] = {.start = IRQ_LCD0,.end   = IRQ_LCD0,.flags = IORESOURCE_IRQ,},
};

 

4、s3cfb_probe()函数分析

s3cfb_probe()函数内容如下:

static int __devinit s3cfb_probe(struct platform_device *pdev)
{struct s3c_platform_fb *pdata;struct s3cfb_global *fbdev;struct resource *res;int i, j, ret = 0;fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL);if (!fbdev) {dev_err(&pdev->dev, "failed to allocate for ""global fb structure\n");ret = -ENOMEM;goto err_global;}fbdev->dev = &pdev->dev;fbdev->regulator = regulator_get(&pdev->dev, "pd");if (!fbdev->regulator) {dev_err(fbdev->dev, "failed to get regulator\n");ret = -EINVAL;goto err_regulator;}ret = regulator_enable(fbdev->regulator);if (ret < 0) {dev_err(fbdev->dev, "failed to enable regulator\n");ret = -EINVAL;goto err_regulator;}pdata = to_fb_plat(&pdev->dev);if (!pdata) {dev_err(fbdev->dev, "failed to get platform data\n");ret = -EINVAL;goto err_pdata;}fbdev->lcd = (struct s3cfb_lcd *)pdata->lcd;if (pdata->cfg_gpio)pdata->cfg_gpio(pdev);if (pdata->clk_on)pdata->clk_on(pdev, &fbdev->clock);res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (!res) {dev_err(fbdev->dev, "failed to get io memory region\n");ret = -EINVAL;goto err_io;}res = request_mem_region(res->start,res->end - res->start + 1, pdev->name);if (!res) {dev_err(fbdev->dev, "failed to request io memory region\n");ret = -EINVAL;goto err_io;}fbdev->regs = ioremap(res->start, res->end - res->start + 1);if (!fbdev->regs) {dev_err(fbdev->dev, "failed to remap io region\n");ret = -EINVAL;goto err_mem;}s3cfb_set_vsync_interrupt(fbdev, 1);s3cfb_set_global_interrupt(fbdev, 1);s3cfb_init_global(fbdev);if (s3cfb_alloc_framebuffer(fbdev)) {ret = -ENOMEM;goto err_alloc;}if (s3cfb_register_framebuffer(fbdev)) {ret = -EINVAL;goto err_register;}s3cfb_set_clock(fbdev);s3cfb_set_window(fbdev, pdata->default_win, 1);s3cfb_display_on(fbdev);fbdev->irq = platform_get_irq(pdev, 0);if (request_irq(fbdev->irq, s3cfb_irq_frame, IRQF_SHARED,pdev->name, fbdev)) {dev_err(fbdev->dev, "request_irq failed\n");ret = -EINVAL;goto err_irq;}#ifdef CONFIG_FB_S3C_LCD_INITif (pdata->backlight_on)pdata->backlight_on(pdev);if (!bootloaderfb && pdata->reset_lcd)pdata->reset_lcd(pdev);
#endif#ifdef CONFIG_HAS_EARLYSUSPENDfbdev->early_suspend.suspend = s3cfb_early_suspend;fbdev->early_suspend.resume = s3cfb_late_resume;fbdev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;register_early_suspend(&fbdev->early_suspend);
#endifret = device_create_file(&(pdev->dev), &dev_attr_win_power);if (ret < 0)dev_err(fbdev->dev, "failed to add sysfs entries\n");dev_info(fbdev->dev, "registered successfully\n");#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);}
#endifmdelay(100);if (pdata->backlight_on)pdata->backlight_on(pdev);return 0;err_irq:s3cfb_display_off(fbdev);s3cfb_set_window(fbdev, pdata->default_win, 0);for (i = pdata->default_win;i < pdata->nr_wins + pdata->default_win; i++) {j = i % pdata->nr_wins;unregister_framebuffer(fbdev->fb[j]);}
err_register:for (i = 0; i < pdata->nr_wins; i++) {if (i == pdata->default_win)s3cfb_unmap_default_video_memory(fbdev->fb[i]);framebuffer_release(fbdev->fb[i]);}kfree(fbdev->fb);err_alloc:iounmap(fbdev->regs);err_mem:release_mem_region(res->start,res->end - res->start + 1);err_io:pdata->clk_off(pdev, &fbdev->clock);err_pdata:regulator_disable(fbdev->regulator);err_regulator:kfree(fbdev);err_global:return ret;
}

(1)struct s3c_platform_fb 结构体

这个结构体是fb的platform_data结构体,这个结构体变量就是platform设备的私有数据,这个数据在platform_device.device.platform_data中存储。在mach文件中去准备并填充这些数据,在probe函数中通过传参的platform_device指针取出来。

(2)struct s3cfb_global 结构体

在具体操作层的两个文件(s3cfb.c和s3cfb_fimd6x.c)的函数中传递数据。

(3)struct resource 结构体


(4)struct regulator 结构体


(5)platform_data的传递过程

1)to_fb_plat

2)s3cfb_set_platdata

3)smdkc110_machine_init

4)struct s3cfb_lcd

5)pdata->cfg_gpio

6)pdata->clk_on


(6)resource的处理

板级文件mach-x210.c中提供resource结构体数组,s3cfb_probe()函数的platform_get_resource函数取出resource并且按FLAG分头处理。

(7)一些硬件操作

1)s3cfb_set_vsync_interrupt
2)s3cfb_set_global_interrupt


(8)s3cfb_init_global


(9)向框架注册该fb设备

1)s3cfb_alloc_framebuffer

2)s3cfb_register_framebuffer


(10)一些硬件操作
1)s3cfb_set_clock

2)s3cfb_set_window

3)s3cfb_display_on

(11)驱动中处理中断

1)platform_get_irq

2)request_irq

(12)logo显示

fb_show_logo
(13)backlight点亮

 

5、更多分析

与LCD有关的更多内容,参见以下博客:

修改内核的启动logo_天糊土的博客-CSDN博客

应用层为何不能设置分辨率_天糊土的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461167.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

各种分页存储过程 (转)

在项目中&#xff0c;我们经常遇到或用到分页&#xff0c;那么在大数据量&#xff08;百万级以上&#xff09;下&#xff0c;哪种分页算法效率最优呢&#xff1f;我们不妨用事实说话。 测试环境 硬件&#xff1a;CPU 酷睿双核T5750 内存&#xff1a;2G 软件:Windows server 20…

java连接phpstudy_PHPStudy快速自动搞定所有配置文件

phpStudy 是一个 PHP 调试环境的程序集成包。该程序包集成最新的 ApachePHPMySQLphpMyAdminZendOptimizer, 一次性安装 , 无须配置即可使用 , 是非常方便、好用的 PHP 调试环 境 . 该程序不仅包括 PHP 调试环境 , 还包括了开发工具、开发手册等 . 总之学习 PHP 只需一个包 . 对…

ViewBag 找不到编译动态表达式所需的一种或多种类型,是否缺少引用?

症状&#xff1a; 类似上面的警告提示&#xff0c;运行程序不会有任何错误&#xff0c;但若干地方都提示警告&#xff0c;并且明明dll的引用都是正确的。 解决方案&#xff1a; 删除&#xff1a;C:\Users\{your computer name}\AppData\Local\Temp\Temporary ASP.NET Files 该目…

framebuffer驱动详解4——framebuffer驱动分析2(probe函数讲解)

以下内容源于朱有鹏《物联网大讲堂》课程的学习&#xff0c;如有侵权&#xff0c;请告知删除。 主要在填充fbdev这个结构体。 二、framebuffer驱动分析2 1、probe函数分析 &#xff08;1&#xff09;struct s3c_platform_fb 这个结构体是fb的platform_data结构体&#xff1…

Zend Framework学习之Zend_Mail

Zend_Mail组件提供了通用化的功能来创建和发送文本。Zend_Mail通过PHP内建的mail()函数或者直接通过SMTP连接来发送邮件。一个简单的邮件由收件人、主题、邮件内容以及发件人等内容组成。步骤如下1.创建对象2.设置邮件内容3.发送案例&#xff1a; <?php require_once "…

XenDesktop 5 SQL Server Mirror事务日志比较大的原因分析

在实施XenDesktop5项目过程中&#xff0c;发现XenDesktop5版本的数据库镜像事务日志很大&#xff0c;在XenDesktop4和XenApp版本中不存在该问题&#xff1b;于是我根据该现象探究XenDesktop5及以上版本镜像数据库事务日志为何如此之大以及我们今后实施的过程中该如何来维护这么…

nanotime java 博客园_System.nanoTime (计时工具类)

转自&#xff1a;http://blog.csdn.net/yuansuruanjian/article/details/8562890JDK1.5之后java中的计时给出了更精确的方法&#xff1a;System.nanoTime()&#xff0c;输出的精度是纳秒级别&#xff0c;这个给一些性能测试提供了更准确的参考。但是这个方法有个需要注意的地方…

input子系统详解1——input子系统简介

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 转载博客&#xff1a;input输入子系统 - 涛少& - 博客园​​​​​​​ 前言 Linux系统支持的输入设备繁多&#xff0c;例如键盘、鼠标、触摸屏、手柄等等&#xff0c;Linux系统是如何管理如此…

ie compatibility

http://www.red-team-design.com/how-to-solve-common-ie-bugs转载于:https://www.cnblogs.com/daishuguang/archive/2013/04/20/3031900.html

【04】Effective Java - 类和接口

为什么80%的码农都做不了架构师&#xff1f;>>> 1、使类和成员的可访问性最小化 封装是软件设计的基本原则之一&#xff0c;它的好处就是解除组成系统的各个模块之间的耦合关系&#xff0c;使得这些模块可以独立地开发、测试、优化、使用、理解 修改&#xff0c;同…

java 圆的交点_java – 获取线条和形状的交点

理念您可以使用getPathIterator()方法将GenenralPath解构为其段(移动到,行到,四到,立方到,关闭).现在,您可以搜索每个线段与线的交叉点.public static Point[] getIntersections(Path path, Line line) {List intersections new ArrayList();PathIterator it path.getPathIte…

OpenGL运用辅佐库创立规矩几许目标

辅佐类分类&#xff1a; 1&#xff09;窗口初始化函数 2&#xff09;窗口处置和工作处置函数 3&#xff09;定义场景制造循环函数 4&#xff09;三围物体制造函数 5&#xff09;颜色索引表装入函数 6&#xff09;空闲工作处置函数 下面描写了一个程序&#xff0c;该程序尽可以包…

input子系统详解2——应用层代码实践

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、编程步骤总结 步骤1&#xff1a;确定设备文件名字 步骤2&#xff1a;使用标准接口打开与读取设备文件 步骤3&#xff1a;解析struct input_event 二、编程步骤分析 1、确定设备文件名 应用层操作…

构造函数初始化器

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 {class Program{static void Main(string[] args){cat c new cat("萌萌");//先执行cat(string s,int i)构造…

oracle中的视图详解

1.视图的概述 视图其实就是一条查询sql语句&#xff0c;用于显示一个或多个表或其他视图中的相关数据。视图将一个查询的结果作为一个表来使用&#xff0c;因此视图可以被看作是存储的查询或一个虚拟表。视图来源于表&#xff0c;所有对视图数据的修改最终都会被反映到视图的基…

input子系统详解3——input子系统框架核心层分析

以下内容源于朱有鹏嵌入式课程的学习&#xff0c;如有侵权请告知删除。 一、前言 由input子系统简介可知&#xff0c;input子系统分为三层&#xff1a; 1、上层输入事件驱动层 涉及的文件有x210_kernel\drivers\input\evdev.c、mousedev.c 和 joydev.c文件&#xff0c;分别对应…

java servlet 部署到tomcat_如何把spring boot项目部署到tomcat容器中

把spring-boot项目按照平常的web项目一样发布到tomcat容器下一、修改打包形式在pom.xml里设置 war二、移除嵌入式tomcat插件在pom.xml里找到spring-boot-starter-web依赖节点&#xff0c;在其中添加如下代码&#xff0c;org.springframework.bootspring-boot-starter-weborg.sp…

Gitlab Merge Request Builder Plugin 配置小记

2019独角兽企业重金招聘Python工程师标准>>> 以前在给一些开源项目贡献代码的时候&#xff0c;在github上一提交pull request或者提交的分支代码更新了的时候&#xff0c;jenkins就会自动把代码进行merge并且运行单元测试&#xff0c;当时看了心里就2个字&#xff1…

IOS:屏幕旋转与Transform

IOS&#xff1a;屏幕旋转与Transform iTouch&#xff0c;iPhone&#xff0c;iPad设置都是支持旋转的&#xff0c;如果我们的程序能够根据不同的方向做出不同的布局&#xff0c;体验会更好。 如何设置程序支持旋转呢&#xff0c;通常我们会在程序的info.plist中进行设置Supporte…

input子系统详解4——输入事件驱动层源码分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、前言 由input子系统简介可知&#xff0c;input子系统分为三层&#xff1a; ​ 1、上层输入事件驱动层 涉及的文件有x210_kernel\drivers\input\evdev.c、mousedev.c 和 joydev.c文件&#xff0…