【Linux 驱动】IMX6ULL eLCDIF驱动

1. eLCDIF设备树

lcdif: lcdif@021c8000 {compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";    //属性reg = <0x021c8000 0x4000>;                             //起始地址 地址大小interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;          //中断clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,                 //时钟子系统<&clks IMX6UL_CLK_LCDIF_APB>,<&clks IMX6UL_CLK_DUMMY>;clock-names = "pix", "axi", "disp_axi";                //系统名称status = "disabled";                                   //状态};
* Freescale MXS LCD Interface (LCDIF)Required properties:
- compatible: Should be "fsl,<chip>-lcdif".  Supported chips includeimx23 and imx28.
- reg: Address and length of the register set for lcdif
- interrupts: Should contain lcdif interrupts
- display : phandle to display node (see below for details)* display nodeRequired properties:
- bits-per-pixel : <16> for RGB565, <32> for RGB888/666.
- bus-width : number of data lines.  Could be <8>, <16>, <18> or <24>.Required sub-node:
- display-timings : Refer to binding doc display-timing.txt for details.+----------+-------------------------------------+----------+-------+|          |        ↑                            |          |       ||          |        |vback_porch                 |          |       ||          |        ↓                            |          |       |+----------#######################################----------+-------+|          #        ↑                            #          |       ||          #        |                            #          |       ||  hback   #        |                            #  hfront  | hsync ||   porch  #        |       hactive              #  porch   |  len  ||<-------->#<-------+--------------------------->#<-------->|<----->||          #        |                            #          |       ||          #        |vactive                     #          |       ||          #        |                            #          |       ||          #        ↓                            #          |       |+----------#######################################----------+-------+|          |        ↑                            |          |       ||          |        |vfront_porch                |          |       ||          |        ↓                            |          |       |+----------+-------------------------------------+----------+-------+|          |        ↑                            |          |       ||          |        |vsync_len                   |          |       ||          |        ↓                            |          |       |+----------+-------------------------------------+----------+-------+Examples:&lcdif@80030000 {pinctrl-names = "default";                    //pinctrl 名字pinctrl-0 = <&pinctrl_lcdif_dat               //pinctrl 子系统&pinctrl_lcdif_ctrl&pinctrl_lcdif_reset>;display = <&display0>;                        status = "okay";                               //状态display: display {                             //子节点bits-per-pixel = <32>;                     //每个像素点大小bus-width = <24>;                          //总线宽度display-timings {                          //display-timing子节点native-mode = <&timing0>;timing0: timing0 {clock-frequency = <33500000>;      //时钟频率hactive = <800>;                   //水平显示分别率vactive = <480>;                   //垂直显示分别率hfront-porch = <164>;              //水平方向前肩hback-porch = <89>;                //水平方向后肩hsync-len = <10>;                  //水平脉冲宽度vback-porch = <23>;                //垂直方向后肩vfront-porch = <10>;               //垂直方向前肩 vsync-len = <10>;                  //垂直脉冲宽度hsync-active = <0>;                //水平方向有效脉冲极性vsync-active = <0>;                //垂直方向有效脉冲极性de-active = <1>;                   //使能有效极性pixelclk-active = <0>;             //像素时钟边沿采样有效性};};};
};

2. 相关数据结构

(1)struct  fb_info

Linux内核中使用fb_info结构体变量来描述一个framebuffer,在调用register_framebuffer接口注册framebuffer之前,必须要初始化其中的重要数据成员。

        struct  fb_info中成员众多,我们需要着重关注以下成员:

        fb_var_screeninfo:代表可修改的LCD显示参数,如分辨率和像素比特数等;

        fb_fix_screeninfo:代表不可修改的LCD属性参数,如显示内存的物理地址和长度等;

        fb_ops:LCD底层硬件操作接口集。

struct fb_info 
{int node;                       //用来表示该fb设备的次设备号int flags;                      //一个标志位struct mutex lock;              /* Lock for open/release/ioctl funcs */struct mutex mm_lock;           /* Lock for fb_mmap and smem_* fields */struct fb_var_screeninfo var;   /* Current var */        //  fb的可变参数struct fb_fix_screeninfo fix;   /* Current fix */        //  fb的不可变参数struct fb_monspecs monspecs;    /* Current Monitor specs */struct work_struct queue;       /* Framebuffer event queue */struct fb_pixmap pixmap;        /* Image hardware mapper */struct fb_pixmap sprite;        /* Cursor hardware mapper */     struct fb_cmap cmap;            /* Current cmap */struct list_head modelist;      /* mode list */struct fb_videomode *mode;      /* current mode */#ifdef CONFIG_FB_BACKLIGHT/* assigned backlight device *//* set before framebuffer registration, remove after unregister */struct backlight_device *bl_dev;/* Backlight level curve */struct mutex bl_curve_mutex;    u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IOstruct delayed_work deferred_work;struct fb_deferred_io *fbdefio;
#endifstruct fb_ops *fbops;          //  该设备对应的操作方法struct device *device;         /* This is the parent */     //fb设备的父设备struct device *dev;            /* This is this fb device */ //本设备的deviceint class_flag;                /* private sysfs flags */
#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops;   /* Tile Blitting */
#endifchar __iomem *screen_base;     /* Virtual address */        //LCD的显存地址(虚拟地址) unsigned long screen_size;     /* Amount of ioremapped VRAM or 0 *///  LCD显存的字节大小void *pseudo_palette;          /* Fake palette of 16 colors */ 
#define FBINFO_STATE_RUNNING    0
#define FBINFO_STATE_SUSPENDED    1u32 state;                     /* Hardware state i.e suspend */void *fbcon_par;               /* fbcon use-only private area *//* From here on everything is device dependent */void *par;/* we need the PCI or similiar aperture base/size notsmem_start/size as smem_start may just be an objectallocated inside the aperture so may not actually overlap */struct apertures_struct {unsigned int count;struct aperture {resource_size_t base;resource_size_t size;} ranges[0];} *apertures;
};struct fb_info

 (2)struct fb_var_screeninfo

Linux内核中使用struct fb_var_screeninfo来描述可修改的LCD显示参数,如分辨率和像素比特数等。

struct fb_var_screeninfo 
{__u32 xres;                  //   水平分辨率 __u32 yres;                  //   垂直分辨率__u32 xres_virtual;          //   虚拟水平分辨率__u32 yres_virtual;          //   虚拟垂直分辨率__u32 xoffset;               //  当前显存水平偏移量__u32 yoffset;               //  当前显存垂直偏移量__u32 bits_per_pixel;        //  像素深度__u32 grayscale;             /* != 0 Graylevels instead of colors */struct fb_bitfield red;      /* bitfield in fb mem if true color, */struct fb_bitfield green;    /* else only length is significant */struct fb_bitfield blue;struct fb_bitfield transp;   /* transparency*/    __u32 nonstd;           /* != 0 Non standard pixel format */__u32 activate;         /* see FB_ACTIVATE_* */__u32 height;           //  LCD的物理高度mm__u32 width;            // LCD的物理宽度mm__u32 accel_flags;      /* (OBSOLETE) see fb_info.flags *//* Timing: All values in pixclocks, except pixclock (of course) */__u32 pixclock;            /* pixel clock in ps (pico seconds)  */  //  像素时钟//下面这六个就是LCD的时序参数__u32 left_margin;        /* time from sync to picture   */__u32 right_margin;        /* time from picture to sync  */__u32 upper_margin;        /* time from sync to picture  */__u32 lower_margin;__u32 hsync_len;        /* length of horizontal sync     */__u32 vsync_len;        /* length of vertical sync       */__u32 sync;            /* see FB_SYNC_*        */__u32 vmode;            /* see FB_VMODE_*        */__u32 rotate;            /* angle we rotate counter clockwise */__u32 reserved[5];        /* Reserved for future compatibility */
};struct fb_var_screeninfo

(3)struct fb_fix_screeninfo

Linux内核中使用struct fb_fix_screeninfo来描述不可修改的LCD属性参数,如显示内存的物理地址和长度等。

struct fb_fix_screeninfo 
{char id[16];                /* identification string eg "TT Builtin" */unsigned long smem_start;   // LCD显存的起始地址(物理地址)/* (physical address) */__u32 smem_len;            /* Length of frame buffer mem *///  LCD显存的字节大小__u32 type;               /* see FB_TYPE_**/__u32 type_aux;           /* Interleave for interleaved Planes */__u32 visual;             /* see FB_VISUAL_*              */ __u16 xpanstep;           /* zero if no hardware panning  */__u16 ypanstep;           /* zero if no hardware panning  */__u16 ywrapstep;          /* zero if no hardware ywrap    */__u32 line_length;        /* length of a line in bytes    *///  LCD一行的长度 (以字节为单位)unsigned long mmio_start; /* Start of Memory Mapped I/O   *//* (physical address) */__u32 mmio_len;            /* Length of Memory Mapped I/O  */__u32 accel;            /* Indicate to driver which    *//*  specific chip/card we have    */__u16 reserved[3];        /* Reserved for future compatibility */
};struct fb_fix_screeninfo

3. fbmem.c

3.1 入口函数

        FrameBuffer驱动是以模块的形式注册到系统中,在模块初始化时,创建FrameBuffer对应的设备文件及proc文件,并注册FrameBuffer设备操作接口函数fb_fops。

static int __init
fbmem_init(void)
{proc_create("fb", 0, NULL, &fb_proc_fops);    //向 proc 文件系统报告驱动状态和参数if (register_chrdev(FB_MAJOR,"fb",&fb_fops))    //注册字符设备驱动,主设备号是29 名称为fbprintk("unable to get major %d for fb devs\n", FB_MAJOR);fb_class = class_create(THIS_MODULE, "graphics");    //创建 /sys/class/graphics 设备类,配合 mdev生成设备文件if (IS_ERR(fb_class)) {printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));fb_class = NULL;}return 0;
}

3.2 fb_fops

        在linux设备驱动中,所有的显示缓存设备均由framebuffer子系统内部管理,即linux设备驱动框架只认识一个主设备号为29的framebuffer设备。应用层所有针对显示缓存(最多32个)的访问均会推送给fb_fops进行进一步分发操作。

static const struct file_operations fb_fops = {.owner =	THIS_MODULE,.read =		fb_read,.write =	fb_write,.unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT.compat_ioctl = fb_compat_ioctl,
#endif.mmap =		fb_mmap,.open =		fb_open,.release =	fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO.fsync =	fb_deferred_io_fsync,
#endif.llseek =	default_llseek,
};

3.2.1 fb_open

      

3.2.2 fb_mmap

3.2.3 fb_ioctl 

static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,unsigned long arg)
{struct fb_ops *fb;struct fb_var_screeninfo var;struct fb_fix_screeninfo fix;struct fb_con2fbmap con2fb;struct fb_cmap cmap_from;struct fb_cmap_user cmap;struct fb_event event;void __user *argp = (void __user *)arg;long ret = 0;switch (cmd) {case FBIOGET_VSCREENINFO:        // 获取可变屏幕参数if (!lock_fb_info(info))return -ENODEV;var = info->var;unlock_fb_info(info);ret = copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;break;case FBIOPUT_VSCREENINFO:        // 设置可变屏幕参数if (copy_from_user(&var, argp, sizeof(var)))return -EFAULT;console_lock();if (!lock_fb_info(info)) {console_unlock();return -ENODEV;}info->flags |= FBINFO_MISC_USEREVENT;ret = fb_set_var(info, &var);info->flags &= ~FBINFO_MISC_USEREVENT;unlock_fb_info(info);console_unlock();if (!ret && copy_to_user(argp, &var, sizeof(var)))ret = -EFAULT;break;case FBIOGET_FSCREENINFO:        //获得固定的屏幕参数设置if (!lock_fb_info(info))return -ENODEV;fix = info->fix;unlock_fb_info(info);ret = copy_to_user(argp, &fix, sizeof(fix)) ? -EFAULT : 0;break;case FBIOPUTCMAP:                // 获得固定的屏幕参数设置if (copy_from_user(&cmap, argp, sizeof(cmap)))return -EFAULT;ret = fb_set_user_cmap(&cmap, info);break;case FBIOGETCMAP:                // 获得颜色表if (copy_from_user(&cmap, argp, sizeof(cmap)))return -EFAULT;if (!lock_fb_info(info))return -ENODEV;cmap_from = info->cmap;unlock_fb_info(info);ret = fb_cmap_to_user(&cmap_from, &cmap);break;case FBIOPAN_DISPLAY:            // 平移显示if (copy_from_user(&var, argp, sizeof(var)))return -EFAULT;console_lock();if (!lock_fb_info(info)) {console_unlock();return -ENODEV;}ret = fb_pan_display(info, &var);unlock_fb_info(info);console_unlock();if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))return -EFAULT;break;case FBIO_CURSOR:ret = -EINVAL;break;case FBIOGET_CON2FBMAP:if (copy_from_user(&con2fb, argp, sizeof(con2fb)))return -EFAULT;if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)return -EINVAL;con2fb.framebuffer = -1;event.data = &con2fb;if (!lock_fb_info(info))return -ENODEV;event.info = info;fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);unlock_fb_info(info);ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;break;case FBIOPUT_CON2FBMAP:if (copy_from_user(&con2fb, argp, sizeof(con2fb)))return -EFAULT;if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)return -EINVAL;if (con2fb.framebuffer >= FB_MAX)return -EINVAL;if (!registered_fb[con2fb.framebuffer])request_module("fb%d", con2fb.framebuffer);if (!registered_fb[con2fb.framebuffer]) {ret = -EINVAL;break;}event.data = &con2fb;console_lock();if (!lock_fb_info(info)) {console_unlock();return -ENODEV;}event.info = info;ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);unlock_fb_info(info);console_unlock();break;case FBIOBLANK:console_lock();if (!lock_fb_info(info)) {console_unlock();return -ENODEV;}info->flags |= FBINFO_MISC_USEREVENT;ret = fb_blank(info, arg);info->flags &= ~FBINFO_MISC_USEREVENT;unlock_fb_info(info);console_unlock();break;default:if (!lock_fb_info(info))return -ENODEV;fb = info->fbops;if (fb->fb_ioctl)ret = fb->fb_ioctl(info, cmd, arg);elseret = -ENOTTY;unlock_fb_info(info);}return ret;
}

4. mxsfb.c

        一个标准的platform平台设备驱动

4.1 mxsfb_probe

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

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

相关文章

Linux存储管理-逻辑卷管理(LVM)

逻辑卷管理&#xff08;LVM&#xff09;流程 物理磁盘/分区 -> 物理卷&#xff08;PV&#xff09;-> 加入卷组&#xff08;VG&#xff09;-> 卷组调配空间&#xff0c;制作逻辑卷&#xff08;LV&#xff09;-> 格式化 -> 挂载 -> 使用 为什么需要逻辑卷管理…

Web 性能入门指南-3.5 优化单页应用程序 (SPA)

&#x1f338; 欢迎来到前端后花园&#xff01;这里是一个温馨的小角落&#xff0c;专为热爱前端技术的你打造。没有华丽的辞藻&#xff0c;只有真诚的分享。希望你能在这里找到实用的内容&#xff0c;学到新知识&#xff0c;同时也欢迎你畅所欲言&#xff0c;分享你的思考和见…

【Linux 13】文件系统

文章目录 &#x1f308; 一、前言&#x1f308; 二、文件操作的系统接口⭐ 1. 打开文件 open⭐ 2. 关闭文件 close⭐ 3. 写入文件 write⭐ 4. 读取文件 read &#x1f308; 三、文件描述符⭐ 1. 文件描述符介绍⭐ 2. 提前被分配的文件描述符 0 1 2⭐ 3. 文件描述符的分配规则 &…

浏览器插件利器--allWebPluginV2.0.0.16-beta版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

minio安装小计一则

安装minio并且使用api方式对文件进行操作 本文使用docker安装 docker pull minio/minio docker pull minio/mc &#xff08;mc为minio文件运行命令行工具&#xff09; 使用如下命令运行Minio服务器容器&#xff1a; docker run -p 9000:9000 -p 9001:9001 --name minio-…

【深度学习】大模型GLM-4-9B Chat ,微调与部署

下载好东西&#xff1a; 启动容器环境: docker run -it --gpus all --net host --shm-size8g -v /ssd/xiedong/glm-4-9b-xd:/ssd/xiedong/glm-4-9b-xd kevinchina/deeplearning:pytorch2.3.0-cuda12.1-cudnn8-devel-yolov8train bashpip install typer tiktoken numpy1.2…

Web开发:ASP.NET CORE使用Ajax定时获取后端数据

一、低难度&#xff08;刷新a标签&#xff09; 1、需求 给a标签每15s刷新一次&#xff0c;显示最新的时间&#xff08;时间必须由后端获取&#xff09; 应该如何操作呢 2、代码 后端 using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Mi…

解决mysql5.0,Navicat for MySQL,IntelliJ IDEA之间中文乱码

使用软件版本 jdk-8u171-windows-x64 ideaIU-2021.1.3 mysql-essential-5.0.87-win32 navicat8_mysql_cs 这个问题我调试了好久&#xff0c;网上的方法基本上都试过了&#xff0c;终于是解决了。 三个地方结果都不一样。 方法一 首先大家可以尝试下面这种方法&#xff1a…

记录 cocos 开发问题 ,微信 wx.xxx函数 报找不到名称“wx”

今天写微信排行榜遇到 问题分享一下。 目前&#xff0c;微信、百度 和 抖音 小游戏这些平台为了保护其社交关系链数据&#xff0c;增加了 开放数据域 的概念&#xff0c;这是一个单独的游戏执行环境。开放数据域中的资源、引擎、程序&#xff0c;都和主游戏&#xff08;主域&a…

(秋招复习)自动驾驶与机器人中的SLAM技术(二)

秋招复习之--自动驾驶与机器人中的SLAM技术2 第五章 基础点云处理激光传感器与点云的数学模型最近邻问题准确率和召回率暴力最近邻栅格和体素方法二分树与K-d树四叉树和八叉树 拟合问题平面拟合直线拟合 第六章 2D激光定位与建图扫描匹配算法点到点的scan matching点到线的scan…

mybatis-plus模板引擎代码生成

网盘代码&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1jwuVGiA97dc1KVnGKc0c4g?pwd6666 提取码&#xff1a;6666 Gradle依赖&#xff1a; dependencies {// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starterimplementation org.…

linux系统设置开机启动的两种方法systemd及rc.local(手工写sh脚本,手工写service服务)

文章目录 知识点实验一、systemd&#xff08;一&#xff09;自写一个sh脚本并加入开机启动&#xff08;二&#xff09;源码安装的nginx加入开机启动 rc.local 知识点 在Linux系统中&#xff0c;有多种方法可以设置开机启动。以下是其中的一些主要方法&#xff1a; systemd 在较…

基于SSM的网上选课系统

系统背景 在当今信息化高速发展的时代&#xff0c;随着Internet的普及和高等教育规模的不断扩大&#xff0c;传统的手工选课方式已难以满足高校日益增长的管理需求。传统的选课方式不仅效率低下&#xff0c;还容易出现人为错误&#xff0c;导致资源浪费和管理成本上升。因此&am…

2959.力扣每日一题7/17 Java(暴力枚举+Floyd算法)

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;算法练习关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 Floyd算法 解题思路 解题过程 时间复杂度 空间复杂度 Floyd算法 …

Linux系统快速搭建轻量化网站Halo并实现无公网IP远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

AWE2025正式启动,AWE×AI 推动智慧生活的普及

7月18日&#xff0c;2025年中国家电及消费电子博览会&#xff08;AWE2025&#xff09;正式启动。主办方宣布&#xff0c;AWE2025的主题为“AI科技、AI生活”&#xff0c;展会将于2025年3月20-23日在上海新国际博览中心举办。 作为全球三大家电和消费电子领域展会之一&#xff…

一个非常好的美图展示网站整站打包源码,集成了wordpress和开源版ripro主题,可以完美运营。

一个非常好的美图展示网站整站打包源码&#xff0c;集成了wordpress和开源版ripro主题&#xff0c;可以完美运营。 自带了5个多g的美图资源&#xff0c;让网站内容看起来非常大气丰富&#xff0c;可以快速投入运营。 这个代码包&#xff0c;原网站已经稳定运营多年&#xff0…

Linux_生产消费者模型

目录 1、生产消费者模型示意图 2、生产者消费者之间的关系 3、定义交易场所 4、实现生产消费者模型 5、伪唤醒 6、多生产多消费者的实际运用 7、POSIX信号量 7.1 初始化信号量 7.2 销毁信号量 7.3 等待信号量 7.4 发布信号量 8、生产消费的环形队列模型 8.1…

Codeforces Round 942 (Div. 2)

比赛链接&#xff1a;Dashboard - Codeforces Round 942 (Div. 2) - Codeforces A题 翻译中文题面&#xff1a; 一场比赛包含 n 个问题&#xff0c;第 i 个问题的难度预期最多为 bi。已经有 n 个问题的提议&#xff0c;第 i 个问题的难度是 ai。最初&#xff0c;数组 a1,a2,……

安全与便捷并行,打造高效易用的用户支付体验

在当今数字时代&#xff0c;快捷、安全的支付方式已经成为用户日常生活中不可或缺的一部分。不论是在线购物、订阅服务&#xff0c;还是线下消费&#xff0c;用户都期望享受流畅且安全的支付体验。作为开发者&#xff0c;选择适合的支付服务不仅关乎用户体验&#xff0c;更直接…