在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            ARM-Linux s3c2440 之I2C分析

            作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
            內(nèi)核版本linux-2.6.30.4
            I2C在Linux中是Bus下的一個(gè)子系統(tǒng). 它由客戶驅(qū)動(dòng)(client driver),i2c-core核心,i2c適配器驅(qū)動(dòng)(adapter driver) ,算法aglorithm組成。s3c2440中有兩個(gè)i2c現(xiàn)適配器.作為platform_device設(shè)備在系統(tǒng)啟動(dòng)先時(shí)被注冊(cè)和添加。下面我們分析i2c(設(shè)備,驅(qū)動(dòng),總線)的實(shí)現(xiàn)過(guò)程.
            //填充設(shè)備資源
            //struct resource結(jié)構(gòu)體描述了掛接在cpu總線上的設(shè)備實(shí)體資源
            //.start:i2c寄存器起始地址; .end:i2c寄存器結(jié)束地址; .flag:描述設(shè)備實(shí)體的共性和特性標(biāo)志
            1. staticstructresources3c_i2c_resource[]={
            2. [0]={//i2c-0
            3. .start=S3C_PA_IIC,
            4. .end=S3C_PA_IIC+SZ_4K-1,
            5. .flags=IORESOURCE_MEM,
            6. },
            7. [1]={//i2c-1
            8. .start=IRQ_IIC,
            9. .end=IRQ_IIC,
            10. .flags=IORESOURCE_IRQ,
            11. },
            12. };
            /i2c適配器初始化時(shí)數(shù)據(jù)
            1. staticstructs3c2410_platform_i2cdefault_i2c_data0__initdata={
            2. .flags=0,
            3. .slave_addr=0x10,
            4. .frequency=100*1000,
            5. .sda_delay=100,
            6. };

            //聲明i2c適配器為platform_device

            本文引用地址:http://www.biyoush.com/article/201611/318136.htm

            1. structplatform_devices3c_device_i2c0={
            2. .name="s3c2410-i2c",
            3. #ifdefCONFIG_S3C_DEV_I2C1
            4. .id=0,
            5. #else
            6. .id=-1,
            7. #endif
            8. .num_resources=ARRAY_SIZE(s3c_i2c_resource),
            9. .resource=s3c_i2c_resource,
            10. };
            11. staticstructs3c2410_platform_i2cdefault_i2c_data0__initdata={
            12. .flags=0,
            13. .slave_addr=0x10,
            14. .frequency=100*1000,
            15. .sda_delay=100,
            16. };

            //添加i2c適配器:
            1. staticstructplatform_device*smdk2440_devices[]__initdata={
            2. ...
            3. &s3c_device_i2c0,
            4. ...
            5. };
            //添加plat_from_data
            1. void__inits3c_i2c0_set_platdata(structs3c2410_platform_i2c*pd)
            2. {
            3. structs3c2410_platform_i2c*npd;
            4. if(!pd)
            5. pd=&default_i2c_data0;
            6. npd=kmemdup(pd,sizeof(structs3c2410_platform_i2c),GFP_KERNEL);
            7. if(!npd)
            8. printk(KERN_ERR"%s:nomemoryforplatformdatan",__func__);
            9. elseif(!npd->cfg_gpio)
            10. npd->cfg_gpio=s3c_i2c0_cfg_gpio;//i2c引腳配置
            11. s3c_device_i2c0.dev.platform_data=npd;//掛接plat_form_data數(shù)據(jù)
            12. }
            //定義好上面相關(guān)結(jié)構(gòu)后,在smdk2440_machine_init()中被注冊(cè)和添加成platform_device
            1. staticvoid__initsmdk2440_machine_init(void)
            2. {
            3. s3c24xx_fb_set_platdata(&smdk2440_fb_info);
            4. s3c_i2c0_set_platdata(NULL);
            5. ...
            6. //注冊(cè)和添加platform_device
            7. platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
            8. ...
            9. }
            其中 smdk2440_machine_init在被賦值在MACHINE_START中
            在start_kernel()-->setup_arch()時(shí)被調(diào)用,但值得注意的是i2c適配器并沒有被初始化,因?yàn)檫€沒有驅(qū)動(dòng)!
            通過(guò)下面可以知道platform_device_register()和device_register()的區(qū)別:
            1. platform_add_devices()-->platform_device_register()-->
            2. platform_device_add()-->device-->add()
            platfrom_bus_init()時(shí)也將添加一個(gè)名叫platform的設(shè)備(struct device platform_bus):
            1. plat_form_bus_init()-->device_register()-->device_register()
            2. -->device-->add()
            但這個(gè)設(shè)備是虛擬的,所有platform_device_add()后的設(shè)備都是在/devices/platform/下
            因?yàn)樗衟laform_device 的父母親都是platform_bus,是在platform_device_add()中
            1. if(!pdev->dev.parent)
            2. pdev->dev.parent=&platform_bus;
            我想這也就是platform_device_register()和device_register()區(qū)別吧
            在reset_init()-->kernel_init()-->do_basic_setup()
            -->driver_init()-->platform_bus_init()完成platform_bus總線的注冊(cè)
            但是現(xiàn)在i2c適配器并沒有和驅(qū)動(dòng)綁上,因?yàn)榈较惮F(xiàn)在為止驅(qū)動(dòng)還沒有出現(xiàn)呢(初始化)
            只有做好前面一些的準(zhǔn)備功夫,i2c適配器驅(qū)動(dòng)才能初始化,這個(gè)是需要按照順序來(lái)的。
            s3c2440-i2c適配器驅(qū)動(dòng)的初始化在drivers/i2c/bus/i2c-s3c2410.c中實(shí)現(xiàn)
            并且作為platform_driver注冊(cè)。
            //填充driver結(jié)構(gòu)并完成相應(yīng)probe,remove等函數(shù)
            1. staticstructplatform_drivers3c2440_i2c_driver={
            2. .probe=s3c24xx_i2c_probe,
            3. .remove=s3c24xx_i2c_remove,
            4. .suspend_late=s3c24xx_i2c_suspend_late,
            5. .resume=s3c24xx_i2c_resume,
            6. .driver={
            7. .owner=THIS_MODULE,
            8. .name="s3c2440-i2c",//
            9. },
            10. };

            //初始化并注冊(cè)platform_driver

            1. staticint__initi2c_adap_s3c_init(void)
            2. {
            3. intret;
            4. ret=platform_driver_register(&s3c2410_i2c_driver);//
            5. if(ret==0){
            6. printk("registers3c2440_i2c_driver.....n");
            7. ret=platform_driver_register(&s3c2440_i2c_driver);
            8. if(ret)
            9. {
            10. printk("registers3c2410_i2c_driver.....n");
            11. platform_driver_unregister(&s3c2410_i2c_driver);
            12. }
            13. }
            14. returnret;
            15. }
            16. subsys_initcall(i2c_adap_s3c_init);

            這樣適配器就和驅(qū)動(dòng)綁定上了,過(guò)程是這樣的:
            1. platform_driver_register()-->driver_register()-->bus_add_driver()-->driver_attach()
            2. __driver_attach()-->driver_probe_device()-->s3c24xx_i2c_probe()
            并且在s3c24xx_i2c_probe()的時(shí)候調(diào)用
            1. i2c_add_numbered_adapter(&i2c->adap);
            最后添加自己為i2c總線的適配器。這樣分析過(guò)程也就結(jié)束了。


            關(guān)鍵詞: ARMLinuxs3c2440I2C分

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉