基于S3C2440的Linux-3.6.6移植——ADC的移植

本文详细介绍了如何在Linux-3.6.6内核中移植S3C2440的ADC驱动。首先,文章分析了adc.c文件中的关键函数,如adc_init、s3c_adc_probe等,解释了如何注册和初始化ADC驱动。接着,讨论了如何使用s3c_adc_register和s3c_adc_read函数读取ADC转换数据。最后,展示了如何编写一个通用的ADC应用层文件,并将其集成到系统中。通过这个过程,读者可以了解如何利用系统自带的驱动文件实现ADC功能。
摘要由CSDN通过智能技术生成

在linux-3.6.6中,系统已经有了关于s3c2440的ADC通用驱动程序文件——arch/arm/plat-samsung/adc.c,但还没有应用层文件,如果要想使ADC工作,并利用系统已有的驱动文件,那么就必须自己动手写一个应用层文件。

 

本文先介绍adc.c,然后给出一个通用的ADC应用层文件,并移植到开发板上。

 

先看adc.c文件中的初始化函数adc_init:

static int __init adc_init(void)

{

       int ret;

       //注册ADC驱动

       ret = platform_driver_register(&s3c_adc_driver);

       if (ret)

                printk(KERN_ERR "%s:failed to add adc driver\n", __func__);

 

       return ret;

}

 

s3c_adc_driver的定义为:

static struct platform_driver s3c_adc_driver = {

       .id_table       = s3c_adc_driver_ids,

       .driver         = {

                .name   = "s3c-adc",

                .owner  = THIS_MODULE,

                .pm     = &adc_pm_ops,

       },

       .probe          = s3c_adc_probe,

       .remove         = __devexit_p(s3c_adc_remove),

};

 

s3c_adc_driver_ids的定义为:

static struct platform_device_id s3c_adc_driver_ids[] = {

       {

                .name           = "s3c24xx-adc",

                .driver_data    = TYPE_ADCV1,

       }, {

                .name           = "s3c2443-adc",

                .driver_data    = TYPE_ADCV11,

       }, {

                .name           = "s3c2416-adc",

                .driver_data    = TYPE_ADCV12,

       }, {

                .name           = "s3c64xx-adc",

                .driver_data    = TYPE_ADCV2,

       }, {

                .name           = "samsung-adc-v3",

                .driver_data    = TYPE_ADCV3,

       },

       { }

};

 

下面重点介绍probe函数s3c_adc_probe

static int s3c_adc_probe(struct platform_device *pdev)

{

       struct device *dev = &pdev->dev;

       struct adc_device *adc;

       struct resource *regs;

       enum s3c_cpu_typecpu = platform_get_device_id(pdev)->driver_data;

       int ret;

       unsigned tmp;

 

       //在内存中开辟一段空间给ADC设备——adc_device

       adc = kzalloc(sizeof(struct adc_device), GFP_KERNEL);

       if (adc == NULL) {

                dev_err(dev, "failed toallocate adc_device\n");

                return -ENOMEM;

       }

 

       spin_lock_init(&adc->lock);

 

       adc->pdev = pdev;

       //为ADC设置预分频

       adc->prescale = S3C2410_ADCCON_PRSCVL(49);

 

       //得到ADC的调整器

       adc->vdd = regulator_get(dev, "vdd");

       if (IS_ERR(adc->vdd)) {

                dev_err(dev, "operatingwithout regulator \"vdd\" .\n");

                ret = PTR_ERR(adc->vdd);

                goto err_alloc;

       }

 

       //得到ADC的中断号

       adc->irq = platform_get_irq(pdev, 1);

       if (adc->irq <= 0) {

                dev_err(dev, "failed toget adc irq\n");

                ret = -ENOENT;

                goto err_reg;

       }

 

       //申请中断,中断处理函数为s3c_adc_irq

       ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc);

       if (ret < 0) {

                dev_err(dev, "failed toattach adc irq\n");

                goto err_reg;

       }

 

       //得到ADC时钟

       adc->clk = clk_get(dev, "adc");

       if (IS_ERR(adc->clk)) {

                dev_err(dev, "failed toget adc clock\n");

                ret = PTR_ERR(adc->clk);

                goto err_irq;

       }

 

       //得到ADC的IO内存资源

       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);

       if (!regs) {

                dev_err(dev, "failed tofind registers\n");

               ret = -ENXIO;

                goto err_clk;

       }

 

       //得到虚拟地址

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值