当前位置: 代码迷 >> 移动开发 >> s3c6410(arm11核)的LCD驱动了解一(probe)
  详细解决方案

s3c6410(arm11核)的LCD驱动了解一(probe)

热度:7933   发布时间:2013-02-26 00:00:00.0
s3c6410(arm11核)的LCD驱动理解一(probe)
static int __devinit s3c_fb_probe(struct platform_device *pdev){	struct device *dev = &pdev->dev;	//私有数据结构体	struct s3c_fb_platdata *pd;	struct s3c_fb *sfb;	struct resource *res;	int win;	int ret = 0;	pd = pdev->dev.platform_data;	if (!pd) {		dev_err(dev, "no platform data specified\n");		return -EINVAL;	}	//申请一段struct s3c_fb内存	sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);	if (!sfb) {		dev_err(dev, "no memory for framebuffers\n");		return -ENOMEM;	}	//下面一大段程序就是初始化struct s3c_fb类型结构体sfb	sfb->dev = dev;	sfb->pdata = pd;	//获取时钟结构体bus_clk	sfb->bus_clk = clk_get(dev, "lcd");	//判断该指针是否有效	if (IS_ERR(sfb->bus_clk)) {		dev_err(dev, "failed to get bus clock\n");		goto err_sfb;	}	//使能LCD时钟	clk_enable(sfb->bus_clk);	//IO映射	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	if (!res) {		dev_err(dev, "failed to find registers\n");		ret = -ENOENT;		goto err_clk;	}	sfb->regs_res = request_mem_region(res->start, resource_size(res),					   dev_name(dev));	if (!sfb->regs_res) {		dev_err(dev, "failed to claim register region\n");		ret = -ENOENT;		goto err_clk;	}	sfb->regs = ioremap(res->start, resource_size(res));	if (!sfb->regs) {		dev_err(dev, "failed to map registers\n");		ret = -ENXIO;		goto err_req_region;	}	dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);	/* setup gpio and output polarity controls */	//setup_gpio,这个函数需要在板级配置文件(smdk6410.c)中实现	pd->setup_gpio();	//vidcon1也是要在板级配置文件中配置,看数据手册可知,VIDCON1是LCD控制寄存器	writel(pd->vidcon1, sfb->regs + VIDCON1);	/* zero all windows before we do anything */	//初始化s3c6410的window寄存器	for (win = 0; win < S3C_FB_MAX_WIN; win++)		s3c_fb_clear_win(sfb, win);	/* we have the register setup, start allocating framebuffers */	for (win = 0; win < S3C_FB_MAX_WIN; win++) {		//判断这个win在板级配置文件中是否被配置,若未被配置,跳过此操作		//在我的板级配置文件中是配置成win[0]		if (!pd->win[win])			continue;		//probe最重要的函数,是关于framebuffer的操作		ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]);		if (ret < 0) {			dev_err(dev, "failed to create window %d\n", win);			for (; win >= 0; win--)				s3c_fb_release_win(sfb, sfb->windows[win]);			goto err_ioremap;		}	} 	//把sfb保存为平台设备私有数据,在后面就可以调用platform_get_drvdata获取sfb	platform_set_drvdata(pdev, sfb);	return 0;err_ioremap:	iounmap(sfb->regs);err_req_region:	release_resource(sfb->regs_res);	kfree(sfb->regs_res);err_clk:	clk_disable(sfb->bus_clk);	clk_put(sfb->bus_clk);err_sfb:	kfree(sfb);	return ret;}

  相关解决方案