1、 /fb特定的ioctl;/上面这些操作函数指针需要驱动开发人员自己编写的,如果没赋值则默认调用系统中的static struct platform_driver s3cfb_driver = .probe= s3cfb_probe,.remove= s3cfb_remove,.suspend= s3cfb_suspend,.resume= s3cfb_resume, .driver= .name= s3c-fb,int _devinit s3cfb_init(void) /*模块加载函数实现平台驱动的注册*/return platform_driver_register(&s3cfb_dri
2、ver);static void _exit s3cfb_cleanup(void)platform_driver_unregister(&module_init(s3cfb_init);module_exit(s3cfb_cleanup);/s3cfb_probe平台驱动的探测函数,主要初始化fb_info结构体中的可变参数和不可变参数结构体,LCD硬件控制器的初始化,获取时钟来源,显示缓存空间的申请,注册帧缓冲设备等工作。static int _init s3cfb_probe(struct platform_device *pdev) /定义局部变量 struct resource *r
3、es; /保存平台资源的局部变量struct fb_info *fbinfo;/帧缓冲结构s3cfb_info_t *info;/对于特定的bsp封装了驱动中所需要的一些信息char driver_name = s3cfb;/*驱动名称*/int index = 0, ret, size;/用来临时保存信息 /*分配fb_info结构体*/fbinfo = framebuffer_alloc(sizeof(s3cfb_info_t), &pdev-dev);if (!fbinfo)return -ENOMEM; /*将fbinfo传递给内核中总线设备结构所对应的驱动数据信息*/platform
4、_set_drvdata(pdev, fbinfo);/方便后面用到/*platform_set_drvdata(pdev, fbinfo)的具体实现函数:*void dev_set_drvdata(struct device *dev, void *data)* int error; if (!dev) return;dev-p) error = device_private_init(dev); if (error) dev-p-driver_data = data;*/ /*fb_info中似有成员赋值给s3cfb_info_t*/info = fbinfo-par;info-dev =
5、 &dev; /*获取LCD平台设备所使用的IO端口资源*/res = platform_get_resource(pdev, IORESOURCE_MEM, 0);if (res = NULL) dev_err(&dev, failed to get memory registersn);ret = -ENXIO;goto dealloc_fb;size = (res-end - res-start) + 1;/计算IO端口所需要的空间 /*为上面LCDIO端口申请IO内存*/mem = request_mem_region(res-start, size, pdev-name);if (i
6、nfo-mem = NULL) failed to get memory regionnret = -ENOENT; /*将LCD的此段IO地址空间映射成虚拟地址空间,这样才能操作*/io = ioremap(res-start, size);io = NULL) ioremap() of registers failedngoto release_mem; /*初始化LCD视频中断控制寄存器0*/s3cfb_pre_init(); /*TFT背光设置*/s3cfb_set_backlight_power(1); /*电源设置*/s3cfb_set_lcd_power(1);s3cfb_set
7、_backlight_level(S3CFB_DEFAULT_BACKLIGHT_LEVEL); /*获取LCD时钟*/clk = clk_get(NULL, lcdclk | IS_ERR(info-clk) printk(KERN_INFO failed to get lcd clock sourcenret = -ENOENT;goto release_io; /*使能时钟*/clk_enable(info-clk);printk(S3C_LCD clock got enabled : %ld.%03ld Mhzn, PRINT_MHZ(clk_get_rate(info-clk);s3
8、cfb_fimd.vsync_info.count = 0; /*初始化帧同步信号的等待队列头*/init_waitqueue_head(&s3cfb_fimd.vsync_info.wait_queue); /*获取LCD平台设备所使用的中断号*/res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);failed to get irqngoto release_clock; /申请中断,中断处理函数为s3cfb_irqret = request_irq(res-start, s3cfb_irq, 0, s3c-lcd, pdev);if (
9、ret != 0) Failed to install irq (%d)n, ret);msleep(5); /*6410支持多种屏幕*/for (index = 0; index mem;s3cfb_infoindex.io = info-io;s3cfb_infoindex.clk = info-clk; /*填充各种结构体中的参数,比如填充fb_info中的可变参数结构的成员和不可变参数结构的成员等*/s3cfb_init_fbinfo(&s3cfb_infoindex, driver_name, index);/* Initialize video memory */帧缓冲设备显示缓冲
10、区的内存分配*/ret = s3cfb_map_video_memory(&s3cfb_infoindex);if (ret) Failed to allocate video RAM: %dnret = -ENOMEM;goto release_irq; /*初始化完fb_info后,开始对LCD各寄存器进行初始化,这个寄存器的配置还真没怎么搞懂啊。感觉好难。*/ret = s3cfb_init_registers(& /*检查可变参数*/ret = s3cfb_check_var(&s3cfb_infoindex.fb.var, &s3cfb_infoindex.fb);if (index
11、 2)if (fb_alloc_cmap(&s3cfb_infoindex.fb.cmap, 256, 0) 0) else s3cfb_infoindex.fb.cmap, 16, 0) /*注册帧缓冲设备(FrameBuffer)fb_info到系统当中*/ret = register_framebuffer(&if (ret dev), &dev_attr_backlight_power);printk(KERN_WARNING s3cfb: failed to add entriesnret = device_create_file(&dev_attr_backlight_level)
12、;dev_attr_lcd_power);jkq debug VIDCON0 is %xn,readl(S3C_VIDCON0);return 0;/*下面这些是各错误函数*/free_video_memory:s3cfb_unmap_video_memory(&release_irq:free_irq(res-start, &info);release_clock:clk_disable(info-clk_put(info-release_io:iounmap(info-io);release_mem:release_resource(info-mem);kfree(info-dealloc
13、_fb:framebuffer_release(fbinfo);return ret;/*初始化LCD视频中断控制寄存器0*/void s3cfb_pre_init(void)/* initialize the fimd specific */s3cfb_fimd.vidintcon0 &= S3C_VIDINTCON0_FRAMESEL0_MASK;s3cfb_fimd.vidintcon0 |= S3C_VIDINTCON0_FRAMESEL0_VSYNC;s3cfb_fimd.vidintcon0 |= S3C_VIDINTCON0_INTFRMEN_ENABLE; /*详情请看S3C6
14、410数据手册第14章482页。初始化视频中断以VSYNS开始并使能该寄存器*/writel(s3cfb_fimd.vidintcon0, S3C_VIDINTCON0);/*下面这三个是控制LCD电源以及背光控制的*/static void s3cfb_set_lcd_power(int to)s3cfb_fimd.lcd_power = to;if (s3cfb_fimd.set_lcd_power)(s3cfb_fimd.set_lcd_power)(to);static void s3cfb_set_backlight_power(int to)s3cfb_fimd.backlight
15、_power = to;if (s3cfb_fimd.set_backlight_power)(s3cfb_fimd.set_backlight_power)(to);static void s3cfb_set_backlight_level(int to)s3cfb_fimd.backlight_level = to;if (s3cfb_fimd.set_brightness)(s3cfb_fimd.set_brightness)(to);/*/*该函数在probe中被调用(初始化s3cfb_info_t结构体,其中每一个fb_info结构都会对应一个s3cfb_info_t结构体)*/初始
16、化就是填充s3cfb_info_t结构中的成员变量和成员函数static void s3cfb_init_fbinfo(s3cfb_info_t *finfo, char *drv_name, int index)int i = 0;if (index = 0)/lcdsize是一全局变量用来标记LCD所使用的尺寸。if(lcdsize = 0)s3cfb_init_hw_35();else if(lcdsize = 1)s3cfb_init_hw_43();/本开发板所使用的else if(lcdsize = 2)s3cfb_init_hw_56();else if(lcdsize = 3)
17、s3cfb_init_hw_70();else if(lcdsize = 4)s3cfb_init_hw_vga800();elsestrcpy(finfo-fb.fix.id, drv_name);/初始化不可变参数结构中的char id16数组/填充不可变参数结构finfo-win_id = index;fb.fix.type = FB_TYPE_PACKED_PIXELS;fb.fix.type_aux = 0;fb.fix.xpanstep = 0;fb.fix.ypanstep = 1;fb.fix.ywrapstep = 0;fb.fix.accel = FB_ACCEL_NONE
18、;/无硬件加速fb.fbops = &s3cfb_ops;/指向frambuffer函数操作集fb.flags= FBINFO_FLAG_DEFAULT;fb.pseudo_palette = &pseudo_pal;/填充可变参数结构fb.var.nonstd = 0;fb.var.activate = FB_ACTIVATE_NOW;fb.var.accel_flags = 0;fb.var.vmode = FB_VMODE_NONINTERLACED;fb.var.xoffset = s3cfb_fimd.xoffset;/水平方向虚拟到可见之间的偏移fb.var.yoffset = s
19、3cfb_fimd.yoffset;/垂直方向虚拟到可见之间的偏移if (index = 0) fb.var.height = s3cfb_fimd.height;fb.var.width = s3cfb_fimd.width;fb.var.xres = s3cfb_fimd.xres;fb.var.yres = s3cfb_fimd.yres;fb.var.xres_virtual = s3cfb_fimd.xres_virtual;fb.var.yres_virtual = s3cfb_fimd.yres_virtual;fb.var.height = s3cfb_fimd.osd_height;/图像高度fb.var.width = s3cfb_fimd.osd_width;/图像宽度fb.var.xres = s3cfb_fimd.osd_xres;/水平方向真实可见的解析度fb.var
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1