已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于MTK65xx平台lcm和背光驱动的编写一、 与LCD驱动相关的主要文件路径mediatekplatformmt6573ubootmt6573_disp_drv.cmediatekplatformmt6573ubootmt6573_disp_drv_dpi.cmediatekplatformmt6573uboot mt6573_disp_drv_dbi.cmediatekplatformmt6573uboot mt6573_dpi_drv.cmediatekplatformmt6573uboot mt6573_dsi_drv.cmediatekplatformmt6573uboot mt6573_lcd_drv.cmediateksourcekerneldriversvideomtkfb.cmediateksourcekerneldriversvideodisp_drv.cmediateksourcekerneldriversvideodisp_drv_dpi.cmediateksourcekerneldriversvideodisp_drv_dbi.cmediatekplatformmt6573kerneldriversvideolcd_drv.cmediatekplatformmt6573kerneldriversvideodpi_drv.cmediatekplatformmt6573kerneldriversvideodsi_drv.cmediatekcustomcommonkernellcmLCM_NAMELCM_NAME.cmediatekplatformmt6573uboot mt6573_pwm.cmediatekplatformmt6573uboot mt65xx_leds.cmediateksourcekerneldriversledsleds.cmediatekcustomginwave73_gbkernelledsmt65xxcust_leds.c二、 怎样新建一个LCD驱动LCD模组主要包括LCD显示屏和驱动IC。比如LF040DNYB16a模组的驱动IC型号为NT35510。要在MTK6573平台上新建这个lcd的驱动,步骤如下:1、 在mediatekcustomcommonkernellcm目录下新建文件夹nt35510,在此文件夹中新建nt35510.c。这就是LCM硬件层驱动文件。2、 修改mediatekcustomcommonkernellcm mt65xx_lcm_list.c, 在 lcm_driver_list lcm_count 中增加nt35510_lcm_drv。3、 打开mediatekconfigginwave73_gbProjectConfig.mk,修改CUSTOM_UBOOT_LCM = nt35510, CUSTOM_KERNEL_LCM = nt35510;修改LCM_WIDTH、LCM_HEIGHT、BOOT_LOGO为正确的值。三、 驱动文件(nt35510.c) 主要任务是实现LCM_DRIVER nt35510_lcm_drv = .name = nt35510,.set_util_funcs = lcm_set_util_funcs,.get_params = lcm_get_params,.init = lcm_init,.suspend = lcm_suspend,.resume = lcm_resume,.compare_id = lcm_compare_id,;(1)lcm_get_params主要是设置LCM相关的参数,数据结构如下:typedef struct LCM_TYPE type;LCM_CTRL ctrl; /! how to control LCM registers unsigned int width; unsigned int height;unsigned int io_select_mode; /DBI or DPI should select IO mode according to chip spec/* particular parameters */ LCM_DBI_PARAMS dbi; LCM_DPI_PARAMS dpi; LCM_DSI_PARAMS dsi; LCM_PARAMS;LCM_TYPE 定义LCM与HOST间的接口,主要分为3种,DBI, DPI, DSI。其中DBI又分为parallel DBI 和serial DBI。parallel DBI(B型DBI)的命令和数据都在数据总线D17:0上传输。CSX为低时数据有效。WRX线控制D17:0为写时序,RDX控制D17:0为读时序。D/CX指示D17:0上传输的是命令还是数据。注:MT6573使用LPA0线作为D/CX线,LPCE线作为CSX线,LWRB线作为WRX线,LRDB线作为RDX线。serial DBI(C型DBI)的命令和数据都在SPI接口上传输。CSX为低时SDA有效。SCL提供时钟,DIN输入,DOUT输出。当SDA_EN=1时,DIN线成为双向的SDA线,即可输入又可输出,DOUT线不用。C型DBI分为3线(没有D/CX线)和4线(有D/CX线)两种。3线的使用一个D/CX bit来区分命令/数据,4线的使用D/CX线来区分命令/数据。注:MT6573使用LSA0线作为D/CX线,LSCE线作为CSX线。LSCK线作为SCL线,LSDA线作为SDA线。DPI的命令在SPI上传输,Pixel data(RGB data)在D17:0上传输。其命令传输方式与serial DBI相同。对于Pixel data(RGB data),需要自己的4条控制线:DPICK_PIN(RGB时钟) 、DPIDE_PIN(RGB数据有效)、 DPIVSYNC(场同步)、 DPIHSYNC(行同步) 。typedef enum LCM_CTRL_NONE = 0, LCM_CTRL_SERIAL_DBI, LCM_CTRL_PARALLEL_DBI, LCM_CTRL_GPIOLCM_CTRL定义LCM与HOST之间传递command的方式,有SERIAL_DBI、PARALLEL_DBI、GPIO几种控制方式。如果是DPI接口,其LCM_CTRL可以选择SERIAL_DBI或者GPIO。Width和height定义LCM的宽度和高度。io_select_mode有这些选项:0(LCD_IO_SEL_16CPU_24RGB),1(LCD_IO_SEL_18CPU_18RGB),2(LCD_IO_SEL_24CPU_8RGB),3(LCD_IO_SEL_24CPU_ONLY)。根据driver IC 的定义填写。LCM_PARAMS根据不同的LCM_TYPE取值,这是针对DBI/DPI/DSI接口类型的详细参数定义。比如LCM_DPI_PARAMS定义如下:typedef struct unsigned int mipi_pll_clk_ref; / 0.1 unsigned int mipi_pll_clk_div1; / 0.63 unsigned int mipi_pll_clk_div2; / 0.15 unsigned int dpi_clk_div; / 2.32 unsigned int dpi_clk_duty; / (dpi_clk_div - 1) . 31 /* polarity parameters */ LCM_POLARITY clk_pol; LCM_POLARITY de_pol; LCM_POLARITY vsync_pol; LCM_POLARITY hsync_pol; /* timing parameters */ unsigned int hsync_pulse_width; unsigned int hsync_back_porch; unsigned int hsync_front_porch; unsigned int vsync_pulse_width; unsigned int vsync_back_porch; unsigned int vsync_front_porch; /* output format parameters */ LCM_DPI_FORMAT format; LCM_COLOR_ORDER rgb_order; unsigned int is_serial_output; /* intermediate buffers parameters */ unsigned int intermediat_buffer_num; / 2.3 /* iopad parameters */ LCM_DRIVING_CURRENT io_driving_current; LCM_DPI_PARAMS;其中,第一段前4项用于控制DPI时钟,计算公式如下:Pixel Clock Frequency = 26MHz * mipi_pll_clk_div1 / (mipi_pll_clk_ref + 1)/ (2 * mipi_pll_clk_div2)/ dpi_clk_div第二段4个参数设置DPICK_PIN(RGB时钟) 、DPIDE_PIN(RGB数据有效)、 DPIVSYNC(场同步)、 DPIHSYNC(行同步)线是上升沿还是下降沿有效。行同步脉冲开始前和开始后的几个时钟周期,是行信号消隐期;场同步开始前和开始后的几个行周期,是场信号消隐期。消隐期不传递图像信号。消隐期特性由第三段六个参数定义:hsync_pulse_width; hsync_back_porch; hsync_front_porch; vsync_pulse_width; vsync_back_porch; vsync_front_porch;LCM_DPI_FORMAT指定每个像素中RGB各占几个bit.LCM_COLOR_ORDER指定RGB的顺序。上述参数的值,均依照LCM spec及驱动IC datasheet中的定义。这里要说说一个特别之处。NT35510使用DPI接口,SERIAL_DBI ctrl 方式时,没有D/CX线,datasheet上定义的传输方式是9 bits,即在数据byte前加个D/CX bit。但使用了NT35510的LCMLF040DNYB16a,其spec中却另外定义了其串口使用16 bits 模式传输。Byte1 是标志byte, 前3位分别为 R/W bit, D/CX bit, High/Low bit;Byte2 则是命令或数据。NT35510的每个command长度为2byte,还可能带有若干bytes的参数,比如命令F001,参数AA,应该这样传输:0x20 0xF0 0x00 0x01 0x40 0xAA。(2)lcm_init主要实现LCM的初始化,包括如下步骤:config_gpio配置GPIO。发送reset信号。RESET pin low和RESET pin high需要持续的时间一般为若干ms, 以datasheet 为准。init_lcm_registers初始化LCM的寄存器。具体可以厂家提供的初始代码为参考。一般在此函数末尾,都会使用唤醒命令组(见后文),使LCM进入工作状态。(3)lcm_suspend 使LCM休眠,使用特定的命令,并遵守datasheet定义的时间特性。常用命令组如下:0X2800 (or 0X28) set display off0X1000 (or 0X10) enter sleep mode对nt35510而言,还有一种更深睡眠的状态deep standby mode,使用如下命令进入:0X4F00 0X01(4)lcm_resume使LCM苏醒,使用特定的命令,并遵守datasheet定义的时间特性。唤醒命令组:0X1100 (or 0X11) exit sleep mode0X2900 (or 0X29) set display on对nt35510而言,如果在lcm_suspend中使LCM enter deep standby mode,则不能使用唤醒命令组,需要使用reset信号并要重新init_lcm_registers。四、 驱动 nt35510_lcm_drv怎样被上层使用Mtkfb.c中实现了LCM的platform driver:static struct platform_driver mtkfb_driver = .driver = .name = “mtk-fb”, .bus = &platform_bus_type, .probe = mtkfb_probe, .remove = mtkfb_remove, .suspend = mtkfb_suspend, .resume = mtkfb_resume, ,;mtkfb_probe会调用函数mtkfb_find_lcm_driver来发现LCM的硬件层驱动。mtkfb_find_lcm_driverDISP_SelectDevicedisp_drv_get_lcm_driver,检查lcm_driver_list, 得到当前使用的LCM及其驱动名称。Mt6573_devs.c中,定义了framebuffer型的platform device,这个设备在mt6573_board_init()调用时被注册。它所对应的驱动就是上文提到的mtkfb_driverstatic struct platform_device mt6573_device_fb = .name = mtkfb, .id = 0, .num_resources = ARRAY_SIZE(resource_fb), .resource = resource_fb, .dev = .dma_mask = &mtkfb_dmamask, .coherent_dma_mask = 0xffffffff, ,;在linux 内核中lcd 设备驱动所使用的是framebuffer设备类型,framebuffer设备驱动程序的核心数据结构是fb_ops;用户空间就是通过此结构体,调用其中的函数来对LCD实现控制。Mtkfb.c中定义并实现了fb_ops类型的mtkfb_ops。一个使用mtkfb_ops的例子见mediateksourcekerneldriversgpupvrservices43rdpartymtklfb mtklfb_displayclass.c。static struct fb_ops mtkfb_ops = .owner = THIS_MODULE, .fb_open = mtkfb_open, .fb_release = mtkfb_release, .fb_setcolreg = mtkfb_setcolreg, /批量配置颜色参数 .fb_pan_display = mtkfb_pan_display_proxy, /虚拟屏幕内容显示 .fb_fillrect = cfb_fillrect, /填充区域显示 .fb_copyarea = cfb_copyarea, /复制区域显示 .fb_imageblit = cfb_imageblit, /显示图象 .fb_cursor = mtkfb_soft_cursor, /光标显示 .fb_check_var = mtkfb_check_var, /检查并配置fb_var_screeninfo参数 .fb_set_par = mtkfb_set_par, /change display mode and set parameter .fb_ioctl = mtkfb_ioctl, /特定ioctl配置LCD屏幕特性;五、 Frame Buffer 设备驱动mtkfb_driver中的各个函数会调用到DISP_xxx函数(DISP_drv.c),而DISP_xxx会调用到LCD_xxx函数(lcd_drv.c)以及LCM硬件层驱动。mtkfb_probe的主要工作如下:* find lcm driver* Register interrupt handler (call back function), Init screen update wait queue, create screen update kThread* Allocate and initialize frame buffer device (fb_info , mtkfb_device), select panel type according to machine type* Initialize Display Driver PDD Layer (DISP_init)* Initialize fb_info struct (mtkfb_fbinfo_init)* Register mtkfb_device fs to system (mtkfb_register_sysfs)* Register fb_info to system (register_framebuffer)fb_info结构定义如下:struct fb_info int node;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 */struct fb_fix_screeninfo fix; /* Current fix */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_BACKLIGHTstruct backlight_device *bl_dev;struct mutex bl_curve_mutex;u8 bl_curveFB_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 */struct device *dev; /* This is this fb device */int class_flag; /* private sysfs flags */#ifdef CONFIG_FB_TILEBLITTINGstruct fb_tile_ops *tileops; /* Tile Blitting */#endifchar _iomem *screen_base; /* Virtual address */unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */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;struct apertures_struct unsigned int count;struct aperture resource_size_t base;resource_size_t size; ranges0; *apertures;1)fb_var_screeninfo这个结构描述了显示卡的特性:NOTE: _u32 是表示 unsigned 不带符号的 32 bits 的数据类型,其余类推。这是 Linux 内核中所用到的数据类型,如果是开发用户空间(user-space)的程序,可以根据具体计算机平台的情况,用 unsigned long 等等来代替struct fb_var_screeninfo_u32 xres; /* visible resolution */ /可视区域_u32 yres;_u32 xres_virtual; /* virtual resolution */ /可视区域_u32 yres_virtual;_u32 xoffset; /* offset from virtual to visible resolution */ /可视区域的偏移_u32 yoffset;_u32 bits_per_pixel; /* guess what */ /每一象素的bit数_u32 grayscale; /* != 0 Gray levels instead of colors */等于零就成黑白struct fb_bitfield red; /* bitfield in fb mem if true color, */真彩的bit机构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; /* height of picture in mm */ 内存中的图像高度_u32 width; /* width of picture in mm */ 内存中的图像宽度_u32 accel_flags; /* acceleration flags (hints) */ 加速标志/* Timing: All values in pixclocks, except pixclock (of course) */时序-_-这些部分就是显示器的显示方法了,可以找相关的资料看看_u32 pixclock; /* pixel clock in ps (pico seconds) */_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 reserved6; /* Reserved for future compatibility */ 备用以后开发;2) fb_fix_screeninfon这个结构在显卡被设定模式后创建,它描述显示卡的属性,并且系统运行时不能被修改;比如FrameBuffer内存的起始地址。它依赖于被设定的模式,当一个模式被设定后,内存信息由显示卡硬件给出,内存的位置等信息就不可以修改。struct fb_fix_screeninfo char id16; /* identification string eg TT Builtin */IDunsigned long smem_start; /* Start of frame buffer mem */ 内存起始/* (physical address) */ 物理地址_u32 smem_len; /* Length of frame buffer mem */ 内存大小_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 */ 一行的字节表示unsigned long mmio_start; /* Start of Memory Mapped I/O */内存映射的I/O起始/* (physical address) */_u32 mmio_len; /* Length of Memory Mapped I/O */ I/O的大小_u32 accel; /* Type of acceleration available */ 可用的加速类型_u16 reserved3; /* Reserved for future compatibility */;Mtkfb_device结构定义如下:struct mtkfb_device int state; void *fb_va_base; /* MPU virtual address */ dma_addr_t fb_pa_base; /* Bus physical address */ unsigned long fb_size_in_byte; unsigned long layer_enable; MTK_FB_FORMAT layer_formatHW_OVERLAY_COUNT; unsigned int layer_config_dirty; int xscale, yscale, mirror; /* transformations. rotate is stored in fb_info-var */ u32 pseudo_palette17; struct fb_info *fb_info; /* Linux fbdev framework data */ struct device *dev;六、 uBoot阶段Mt6573_board.c中,board_init函数执行硬件先期初始化工作,它调用mt65xx_disp_init函数(Mt6573_disp_drv.c)。board_initmt65xx_disp_initDISP_Initdisp_drv_init_contextDISP_DetectDevicedisp_drv_get_lcm_driverlcm_driver_list disp_drv_init_contextDISP_GetDriverDPI / DISP_GetDriverDBI / DISP_GetDriverDSIDISP_GetDriverDPI (mt6573_disp_drv_dpi.c)DPI_DISP_DRV. dpi_initinit_dpiDPI_Init (Mt6573_dpi_drv.c)DISP_GetDriverDBI (mt6573_disp_drv_dbi.c)DBI_DISP_DRV. dbi_initinit_lcdLCD_xxx(Mt6573_lcd_drv.c)DISP_GetDriverDSI (mt6573_disp_drv_dsi.c)DSI_DISP_DRV. dsi_initinit_lcd,init_dsiDSI_Init(Mt6573_dsi_drv.c)DISP_InitLCD_Init (Mt6573_lcd_drv.c)DISP_UpdateScreenLCD_StartTransfer (Mt6573_lcd_drv.c)七、 背光控制Cust_leds.c中定义了cust_mt65xx_led类型的数组cust_led_list,列出了平台的所有led设备,包括不同颜色的led灯,轨迹球、键盘、按键、LCD等的背光灯。不同led设备可以有各自不同的背光控制方式,比如PWM(脉冲宽度调制)方式,GPIO方式,PMIC方式,用户自定义方式等。如下所示:static struct cust_mt65xx_led cust_led_listMT65XX_LED_TYPE_TOTAL = red, MT65XX_LED_MODE_PWM, PWM3,green, MT65XX_LED_MODE_PWM, PWM2,blue, MT65XX_LED_MODE_PWM, PWM1,jogball-backlight, MT65XX_LED_MODE_NONE, -1,keyboard-backlight, MT65XX_LED_MODE_NONE, -1,button-backlight, MT65XX_LED_MODE_PWM, PWM7,lcd-backlight, MT65XX_LED_MODE_CUST, (int)Cust_SetBacklight,;这个数组通过get_cust_led_list函数被mt65xx_leds_probe调用,传递给mt65xx_leds_driver,并且mt65xx_leds_probe 将数组中的设
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2027年电厂安装合同二篇
- 2027年施工及质保合同二篇
- 合规转利润:降本增效全指南(2026)《GBT 36343-2018信息技术 数据交易服务平台 交易数据描述》
- 儿科护理科研进展与临床应用
- 人教版一年级上册《 1~5的认识》教学设计
- 生物质化工产品生产工操作水平竞赛考核试卷含答案
- 模锻工变更管理强化考核试卷含答案
- 《解决问题》的教学实录
- 冷冻食品制作工创新实践竞赛考核试卷含答案
- 中药药剂员成果转化考核试卷含答案
- 应急物流管理 课件 第1、2章 应急物流概述;应急物流管理系统
- 房产公证模板范文
- 如果历史是一群喵课件
- 落叶清扫机设计
- 物料搬运安全培训
- 短路电流查表
- 新概念英语第二册+Lesson+4+An+exciting+trip+讲义
- 天使eric carle33本绘本mp3音频
- 手工焊接技术及要点介绍
- LY/T 2083-2013全国营造林综合核查技术规程
- GB/T 4457.4-2002机械制图图样画法图线
评论
0/150
提交评论