Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10826
  • 博文数量: 8
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 17
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-04 10:11
文章分类
文章存档

2013年(8)

我的朋友

分类: LINUX

2013-12-04 20:13:47

这里最好牵涉到几个文件S3cfb.c、S3cfb_fimd6x.c setuo-fb.c fb_mem.c
在这里之前最好知道pci,和memio一些术语的意思

S3cfb.c中的s3cfb_probe设备探测,是驱动注册的主要函数


 

点击(此处)折叠或打开

  1. /*定义一个结构体用来维护驱动程序中各函数中用到的变量
  2.   先别看结构体要定义这些成员,到各函数使用的地方就明白了*/
  3. static int __devinit s3cfb_probe(struct platform_device *pdev)
  4. {
  5.     struct s3c_platform_fb *pdata;/*LCD屏配置信息结构体*/
  6.     struct s3cfb_global *fbdev;/*驱动程序全局变量结构体*/
  7.     struct resource *res; /*用来保存从LCD平台设备中获取的LCD资源*/
  8.     int i, j, ret = 0;

  9.     printk("%s\n",__func__);
  10.     fbdev = kzalloc(sizeof(struct s3cfb_global), GFP_KERNEL);
  11.     if (!fbdev) {
  12.         dev_err(&pdev->dev, "failed to allocate for "
  13.             "global fb structure\n");
  14.         ret = -ENOMEM;
  15.         goto err_global;
  16.     }
  17.     fbdev->dev = &pdev->dev;

  18.     fbdev->regulator = regulator_get(&pdev->dev, "pd");
  19.     if (!fbdev->regulator) {
  20.         dev_err(fbdev->dev, "failed to get regulator\n");
  21.         ret = -EINVAL;
  22.         goto err_regulator;
  23.     }
  24.     ret = regulator_enable(fbdev->regulator);
  25.     if (ret < 0) {
  26.         dev_err(fbdev->dev, "failed to enable regulator\n");
  27.         ret = -EINVAL;
  28.         goto err_regulator;
  29.     }

  30.     /*获取LCD参数信息*/
  31.     pdata = to_fb_plat(&pdev->dev);
  32.     if (!pdata) {
  33.         dev_err(fbdev->dev, "failed to get platform data\n");
  34.         ret = -EINVAL;
  35.         goto err_pdata;
  36.     }

  37.     fbdev->lcd = (struct s3cfb_lcd *)pdata->lcd;

  38.     /*配置GPIO端口*/
  39.     if (pdata->cfg_gpio)
  40.         pdata->cfg_gpio(pdev);

  41.     /*设置时钟参数*/
  42.     if (pdata->clk_on)
  43.         pdata->clk_on(pdev, &fbdev->clock);

  44.     /*获取LCD平台设备所使用的IO端口资源,注意这个IORESOURCE_MEM标志和LCD平台设备定义中的一致*/
  45.     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  46.     if (!res) {
  47.         dev_err(fbdev->dev, "failed to get io memory region\n");
  48.         ret = -EINVAL;
  49.         goto err_io;
  50.     }

  51.     /*申请LCD IO端口所占用的IO空间(注意理解IO空间和内存空间的区别),request_mem_region定义在ioport.h中*/
  52.     res = request_mem_region(res->start,
  53.                  res->end - res->start + 1, pdev->name);
  54.     if (!res) {
  55.         dev_err(fbdev->dev, "failed to request io memory region\n");
  56.         ret = -EINVAL;
  57.         goto err_io;
  58.     }

  59.     /*将LCD的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中
  60.          注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作*/
  61.     fbdev->regs = ioremap(res->start, res->end - res->start + 1);
  62.     if (!fbdev->regs) {
  63.         dev_err(fbdev->dev, "failed to remap io region\n");
  64.         ret = -EINVAL;
  65.         goto err_mem;
  66.     }
  67. #ifdef CONFIG_FB_S3C_LTE480WV
  68.     /*设置寄存器初始状态*/
  69.     s3cfb_pre_init_para(fbdev);
  70. #endif

  71.     /*设置gamma 值*/
  72.     s3cfb_set_gamma(fbdev);
  73.     /*设置VSYNC中断*/
  74.     s3cfb_set_vsync_interrupt(fbdev, 1);
  75.     /*设置全局中断*/
  76.     s3cfb_set_global_interrupt(fbdev, 1);
  77.     /*fb设备参数信息初始化*/
  78.     s3cfb_init_global(fbdev);

  79.     /*为framebuffer分配空间,进行内存映射,填充fb_info*/
  80.     if (s3cfb_alloc_framebuffer(fbdev)) {
  81.         ret = -ENOMEM;
  82.         goto err_alloc;
  83.     }

  84.     /*注册fb设备到系统中*/
  85.     if (s3cfb_register_framebuffer(fbdev)) {
  86.         ret = -EINVAL;
  87.         goto err_register;
  88.     }

  89.     s3cfb_set_clock(fbdev);
  90.     s3cfb_set_window(fbdev, pdata->default_win, 1);

  91.     s3cfb_display_on(fbdev);

  92.     fbdev->irq = platform_get_irq(pdev, 0);
  93.     if (request_irq(fbdev->irq, s3cfb_irq_frame, IRQF_SHARED,
  94.             pdev->name, fbdev)) {
  95.         dev_err(fbdev->dev, "request_irq failed\n");
  96.         ret = -EINVAL;
  97.         goto err_irq;
  98.     }

  99. #ifdef CONFIG_FB_S3C_LCD_INIT
  100.     if (pdata->backlight_on)
  101.         pdata->backlight_on(pdev);

  102.     if (!bootloaderfb && pdata->reset_lcd)
  103.         pdata->reset_lcd(pdev);

  104.     if (pdata->lcd_on)
  105.         pdata->lcd_on(pdev);
  106. #endif

  107. #ifdef CONFIG_HAS_EARLYSUSPEND
  108.     fbdev->early_suspend.suspend = s3cfb_early_suspend;
  109.     fbdev->early_suspend.resume = s3cfb_late_resume;
  110.     fbdev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
  111.     register_early_suspend(&fbdev->early_suspend);
  112. #endif

  113.     /*对设备文件系统的支持,创建fb设备文件*/
  114.     ret = device_create_file(&(pdev->dev), &dev_attr_win_power);
  115.     if (ret < 0)
  116.         dev_err(fbdev->dev, "failed to add sysfs entries\n");

  117.     dev_info(fbdev->dev, "registered successfully\n");

  118.     /*显示开机logo*/
  119. #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
  120.     if (fb_prepare_logo( fbdev->fb[pdata->default_win], FB_ROTATE_UR)) {
  121.         printk("Start display and show logo\n");
  122.         /* Start display and show logo on boot */
  123.         fb_set_cmap(&fbdev->fb[pdata->default_win]->cmap, fbdev->fb[pdata->default_win]);
  124.         fb_show_logo(fbdev->fb[pdata->default_win], FB_ROTATE_UR);
  125.     }
  126. #endif

  127.     return 0;
  128. }


 

阅读(393) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~