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

本文详细介绍了如何使用s3c_fb探针函数初始化s3c_fb类型的结构体,实现对LCD的控制和显示。通过获取资源、设置时钟、配置GPIO和输出极性控制等步骤,成功地将结构体与实际硬件连接,从而在LCD上显示内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值