[资料分享与下载] i.mx536(cotex-a8核)的I2C驱动理解一(probe)

[复制链接]
918|0
 楼主| ccw1986 发表于 2015-7-3 10:50 | 显示全部楼层 |阅读模式
  1.     //总得来说三个主要步骤  
  2.     //(1)映射虚拟内存,注册中断等  
  3.     //(2)填充结构体struct imx_i2c_struct  
  4.     //(3)调用i2c_register_adapter注册I2C设备  
  5.     static int __init i2c_imx_probe(struct platform_device *pdev)  
  6.     {  
  7.         //分析了几个驱动发现,平台驱动有很多相似的地方,比如说在prode里一般都会定义  
  8.         //一个platform_data结构体,一个对应设备的结构体比如struct imx_i2c_struct  
  9.         struct imx_i2c_struct *i2c_imx;  
  10.         struct resource *res;  
  11.         struct imxi2c_platform_data *pdata;  
  12.         //__iomem表示指针是指向一个I/O的内存空间  
  13.         void __iomem *base;  
  14.         //resource_size_t = u32  
  15.         resource_size_t res_size;  
  16.         int irq;  
  17.         int ret;  
  18.       
  19.         dev_dbg(&pdev->dev, "<%s>\n", __func__);  
  20.         //获取IO资源和中断资源  
  21.         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
  22.         if (!res) {  
  23.             dev_err(&pdev->dev, "can't get device resources\n");  
  24.             return -ENOENT;  
  25.         }  
  26.         //获取中断资源  
  27.         irq = platform_get_irq(pdev, 0);  
  28.         if (irq < 0) {  
  29.             dev_err(&pdev->dev, "can't get irq number\n");  
  30.             return -ENOENT;  
  31.         }  
  32.       
  33.         pdata = pdev->dev.platform_data;  
  34.       
  35.         if (pdata && pdata->init) {  
  36.             ret = pdata->init(&pdev->dev);  
  37.             if (ret)  
  38.                 return ret;  
  39.         }  
  40.       
  41.         res_size = resource_size(res);  
  42.         //检测该IO资源是否可用,若可用,并标志为已用  
  43.         if (!request_mem_region(res->start, res_size, DRIVER_NAME)) {  
  44.             ret = -EBUSY;  
  45.             goto fail0;  
  46.         }  
  47.         //映射物理地址到虚拟内存  
  48.         base = ioremap(res->start, res_size);  
  49.         if (!base) {  
  50.             dev_err(&pdev->dev, "ioremap failed\n");  
  51.             ret = -EIO;  
  52.             goto fail1;  
  53.         }  
  54.         //给i2c_imx分配内存,并初始化为0  
  55.         i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL);  
  56.         if (!i2c_imx) {  
  57.             dev_err(&pdev->dev, "can't allocate interface\n");  
  58.             ret = -ENOMEM;  
  59.             goto fail2;  
  60.         }  
  61.       
  62.          
  63.         //填充结构体i2c_imx  
  64.         strcpy(i2c_imx->adapter.name, pdev->name);  
  65.         //i2c_adapter,Linux的I2C驱动框架中的主要数据结构(i2c_driver、i2c_client、i2c_adapter和i2c_algorithm)之一出现了  
  66.         //对应于物理上的一个适配器  
  67.         i2c_imx->adapter.owner       = THIS_MODULE;  
  68.         //i2c_algorithm也出现了  
  69.         //i2c_algorithm主要提供通信的函数  
  70.         i2c_imx->adapter.algo        = &i2c_imx_algo;  
  71.         i2c_imx->adapter.dev.parent  = &pdev->dev;  
  72.         i2c_imx->adapter.nr      = pdev->id;  
  73.         i2c_imx->irq         = irq;  
  74.         i2c_imx->base            = base;  
  75.         i2c_imx->res         = res;  
  76.       
  77.         /* Get I2C clock */  
  78.         //开启I2C时钟源  
  79.         i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk");  
  80.         if (IS_ERR(i2c_imx->clk)) {  
  81.             ret = PTR_ERR(i2c_imx->clk);  
  82.             dev_err(&pdev->dev, "can't get I2C clock\n");  
  83.             goto fail3;  
  84.         }  
  85.       
  86.         /* Request IRQ */  
  87.         //注册中断函数i2c_imx_isr  
  88.         ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx);  
  89.         if (ret) {  
  90.             dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq);  
  91.             goto fail4;  
  92.         }  
  93.       
  94.         /* Init queue */  
  95.         //初始化queue  
  96.         init_waitqueue_head(&i2c_imx->queue);  
  97.       
  98.         /* Set up adapter data */  
  99.         //把I2C_imx保存到adapter中,最终可以调用i2c_get_adapdata获取  
  100.         i2c_set_adapdata(&i2c_imx->adapter, i2c_imx);  
  101.       
  102.         /* Set up clock divider */  
  103.         //这个pdata->bitrate在板级配置文件中设置  
  104.         if (pdata && pdata->bitrate)  
  105.             i2c_imx_set_clk(i2c_imx, pdata->bitrate);  
  106.         else  
  107.             i2c_imx_set_clk(i2c_imx, IMX_I2C_BIT_RATE);  
  108.       
  109.         /* Set up chip registers to defaults */  
  110.         writeb(0, i2c_imx->base + IMX_I2C_I2CR);  
  111.         writeb(0, i2c_imx->base + IMX_I2C_I2SR);  
  112.       
  113.         /* Add I2C adapter */  
  114.         //重要的函数来了,  
  115.         //i2c_add_numbered_adapter最终调用i2c_register_adapter添加I2C控制器  
  116.         ret = i2c_add_numbered_adapter(&i2c_imx->adapter);  
  117.         if (ret < 0) {  
  118.             dev_err(&pdev->dev, "registration failed\n");  
  119.             goto fail5;  
  120.         }  
  121.       
  122.         /* Set up platform driver data */  
  123.         platform_set_drvdata(pdev, i2c_imx);  
  124.         //打印调试信息  
  125.         dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq);  
  126.         dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n",  
  127.             i2c_imx->res->start, i2c_imx->res->end);  
  128.         dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n",  
  129.             res_size, i2c_imx->res->start);  
  130.         dev_dbg(&i2c_imx->adapter.dev, "adapter name: "%s"\n",  
  131.             i2c_imx->adapter.name);  
  132.         dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");  
  133.       
  134.         return 0;   /* Return OK */  
  135.       
  136.     fail5:  
  137.         free_irq(i2c_imx->irq, i2c_imx);  
  138.     fail4:  
  139.         clk_put(i2c_imx->clk);  
  140.     fail3:  
  141.         kfree(i2c_imx);  
  142.     fail2:  
  143.         iounmap(base);  
  144.     fail1:  
  145.         release_mem_region(res->start, resource_size(res));  
  146.     fail0:  
  147.         if (pdata && pdata->exit)  
  148.             pdata->exit(&pdev->dev);  
  149.         return ret; /* Return error number */  
  150.     }  


您需要登录后才可以回帖 登录 | 注册

本版积分规则

84

主题

925

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部