s3c2410fb.c解析

一下是个人注释,有错误的望指正,谢谢。

 

static int __init s3c24xxfb_probe(struct platform_device *pdev,
      enum s3c_drv_type drv_type)
{
 struct s3c2410fb_info *info;
 struct s3c2410fb_display *display;
 struct fb_info *fbinfo;
 struct s3c2410fb_mach_info *mach_info;
 struct resource *res;
 int ret;
 int irq;
 int i;
 int size;
 u32 lcdcon1;

 mach_info = pdev->dev.platform_data;/*获取之前单板设定的平台数据*/
 if (mach_info == NULL) {
  dev_err(&pdev->dev,
   "no platform data for lcd, cannot attach/n");
  return -EINVAL;
 }

 if (mach_info->default_display >= mach_info->num_displays) {
  dev_err(&pdev->dev, "default is %d but only %d displays/n",
   mach_info->default_display, mach_info->num_displays);
  return -EINVAL;
 }

 display = mach_info->displays + mach_info->default_display;

 irq = platform_get_irq(pdev, 0);?*获取之前设定的中断资源*/
 if (irq < 0) {
  dev_err(&pdev->dev, "no irq for device/n");
  return -ENOENT;
 }

 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);/**/
 if (!fbinfo)
  return -ENOMEM;

 platform_set_drvdata(pdev, fbinfo);    /*   篸pdev->dev.driver_data = fbinfo,device结构的driver_data域指向驱动程序的私有数据空间。*/

?
 info = fbinfo->par;
 info->dev = &pdev->dev;
 info->drv_type = drv_type;

 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);/*获取之前单板平台物理内存资源*/
 if (res == NULL) {
  dev_err(&pdev->dev, "failed to get memory registers/n");
  ret = -ENXIO;
  goto dealloc_fb;
 }

 size = (res->end - res->start) + 1;
 info->mem = request_mem_region(res->start, size, pdev->name);// request_mem_region申请I/O内存
 if (info->mem == NULL) {
  dev_err(&pdev->dev, "failed to get memory region/n");
  ret = -ENOENT;
  goto dealloc_fb;
 }

 info->io = ioremap(res->start, size);//I/O内存
转化为虚拟地址
 if (info->io == NULL) {
  dev_err(&pdev->dev, "ioremap() of registers failed/n");
  ret = -ENXIO;
  goto release_mem;
 }

 info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);

 dprintk("devinit/n");

 strcpy(fbinfo->fix.id, driver_name);

 /* Stop the video */
 lcdcon1 = readl(info->io + S3C2410_LCDCON1);
 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);

 fbinfo->fix.type     = FB_TYPE_PACKED_PIXELS;
 fbinfo->fix.type_aux     = 0;
 fbinfo->fix.xpanstep     = 0;
 fbinfo->fix.ypanstep     = 0;
 fbinfo->fix.ywrapstep     = 0;
 fbinfo->fix.accel     = FB_ACCEL_NONE;

 fbinfo->var.nonstd     = 0;
 fbinfo->var.activate     = FB_ACTIVATE_NOW;
 fbinfo->var.accel_flags     = 0;
 fbinfo->var.vmode     = FB_VMODE_NONINTERLACED;

 fbinfo->fbops      = &s3c2410fb_ops;
 fbinfo->flags      = FBINFO_FLAG_DEFAULT;
 fbinfo->pseudo_palette      = &info->pseudo_pal;

 for (i = 0; i < 256; i++)
  info->palette_buffer[i] = PALETTE_BUFF_CLEAR;

 ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);//申请中断号 返回0则成功 1则失败

 if (ret) {
  dev_err(&pdev->dev, "cannot get irq %d - err %d/n", irq, ret);
  ret = -EBUSY;
  goto release_regs;
 }

 info->clk = clk_get(NULL, "lcd");/*获取时钟*/
 if (!info->clk || IS_ERR(info->clk)) {
  printk(KERN_ERR "failed to get lcd clock source/n");
  ret = -ENOENT;
  goto release_irq;
 }

 clk_enable(info->clk);/*使能时钟*/
 dprintk("got and enabled clock/n");

 msleep(1);

 /* 为显示获取最大内存 */
 for (i = 0; i < mach_info->num_displays; i++) {
  unsigned long smem_len = mach_info->displays[i].xres;

  smem_len *= mach_info->displays[i].yres;
  smem_len *= mach_info->displays[i].bpp;
  smem_len >>= 3;
  if (fbinfo->fix.smem_len < smem_len)
   fbinfo->fix.smem_len = smem_len;
 }

 /* 初始化祯缓冲 */
 ret = s3c2410fb_map_video_memory(fbinfo);
 if (ret) {
  printk(KERN_ERR "Failed to allocate video RAM: %d/n", ret);
  ret = -ENOMEM;
  goto release_clock;
 }

 dprintk("got video memory/n");

 fbinfo->var.xres = display->xres;
 fbinfo->var.yres = display->yres;
 fbinfo->var.bits_per_pixel = display->bpp;

 s3c2410fb_init_registers(fbinfo);

 s3c2410fb_check_var(&fbinfo->var, fbinfo);

 ret = register_framebuffer(fbinfo);
 if (ret < 0) {
  printk(KERN_ERR "Failed to register framebuffer device: %d/n",
   ret);
  goto free_video_memory;
 }

 /* create device files */
 ret = device_create_file(&pdev->dev, &dev_attr_debug);
 if (ret) {
  printk(KERN_ERR "failed to add debug attribute/n");
 }

 printk(KERN_INFO "fb%d: %s frame buffer device/n",
  fbinfo->node, fbinfo->fix.id);

/*在电源管理中挂起 就要中断时钟信号*/

 return 0;static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
{
 struct fb_info    *fbinfo = platform_get_drvdata(dev);
 struct s3c2410fb_info *info = fbinfo->par;

 s3c2410fb_lcd_enable(info, 0);

 /* sleep before disabling the clock, we need to ensure
  * the LCD DMA engine is not going to get back on the bus
  * before the clock goes off again (bjd) */

 msleep(1);
 clk_disable(info->clk);

 return 0;
}

/*在电源管理中重启 就要使能时钟信号*/

 

 

static int s3c2410fb_resume(struct platform_device *dev)
{
 struct fb_info    *fbinfo = platform_get_drvdata(dev);
 struct s3c2410fb_info *info = fbinfo->par;

 clk_enable(info->clk);
 msleep(1);

 s3c2410fb_init_registers(fbinfo);

 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值