歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

I2C子系統之I2C bus初始化——I2C_init()

根據前文的分析(http://www.linuxidc.com/Linux/2012-08/68260.htm
),在linux內核啟動的時候最先執行的和I2C子系統相關的函數應該是driver/i2c/i2c-core.c文件中的

i2c_init()函數。下面具體此函數具體做了那些預備工作。

1.i2c總線的注冊

i2c_init()的函數實現如下:

  1. static int __init i2c_init(void)    
  2. {    
  3.         ... ...    
  4.     retval = bus_register(&i2c_bus_type);    
  5.         ... ...    
  6. }    
可以發現i2c_inti的函數主要功能就是注冊i2c總線。下面重點分析下這個i2c_bus_type這個表示總線的結構體。

2.i2c_bus_type總線

  1. struct bus_type i2c_bus_type = {  
  2.     .name       = "i2c",  
  3.     .match      = i2c_device_match,  
  4.     .probe      = i2c_device_probe,  
  5.     .remove     = i2c_device_remove,  
  6.     .shutdown   = i2c_device_shutdown,  
  7.     .pm     = &i2c_device_pm_ops,  
  8. };  

總線提供了match和probe方法:match方法的用來進行client device和client driver的配對。

在向總線i2c_bus_type注冊設備或者驅動時會調用此方法。

2.6.37.1中的at24c02采用的是i2c_match_id這種方法,本質上還是通過name來配對。

  1. static int i2c_device_match(struct device *dev, struct device_driver *drv)  
  2. {  
  3.     struct i2c_client   *client = i2c_verify_client(dev);  
  4.     struct i2c_driver   *driver;  
  5.   
  6.     if (!client)                              //判斷當前的dev是否是client類型,假如不是立即返回   
  7.         return 0;  
  8.   
  9.     /* Attempt an OF style match */  
  10.     if (of_driver_match_device(dev, drv))    //條件drv->of_match_table,對at24來說是at24_driver->drv->of_match_table   
  11.         return 1;  
  12.   
  13.     driver = to_i2c_driver(drv);  
  14.     /* match on an id table if there is one */  
  15.     if (driver->id_table)  
  16.         return i2c_match_id(driver->id_table, client) != NULL;  
  17.   
  18.     return 0;  
  19. }  

probe方法在完成設備和驅動的配對後調用執行,i2c_bus_type的probe方法是通過傳遞進來的drv找到

包含此drv的i2c_driver驅動,然後再去調用i2c_driver的probe方法,此處就是at24_probe。為什麼要這

樣呢?因為driver_register後,注冊的是i2_driver->drv,而drv中的probe未初始化,我們需要調用的是

i2c-driver的probe方法。

  1. static int i2c_device_probe(struct device *dev)  
  2. {  
  3.     struct i2c_client   *client = i2c_verify_client(dev);  
  4.     struct i2c_driver   *driver;  
  5.     int status;  
  6.   
  7.     if (!client)  
  8.         return 0;  
  9.   
  10.     driver = to_i2c_driver(dev->driver);  
  11.     if (!driver->probe || !driver->id_table)  
  12.         return -ENODEV;  
  13.     client->driver = driver;  
  14.     if (!device_can_wakeup(&client->dev))  
  15.         device_init_wakeup(&client->dev,  
  16.                     client->flags & I2C_CLIENT_WAKE);  
  17.     dev_dbg(dev, "probe\n");  
  18.   
  19.     status = driver->probe(client, i2c_match_id(driver->id_table, client));  
  20.     if (status) {  
  21.         client->driver = NULL;  
  22.         i2c_set_clientdata(client, NULL);  
  23.     }  
  24.     return status;  
  25. }  

相關閱讀:

I2C子系統之at24c02讀寫測試 http://www.linuxidc.com/Linux/2012-08/68256.htm
I2C子系統之ioctl()  http://www.linuxidc.com/Linux/2012-08/68257.htm
I2C子系統之at24c02簡介 http://www.linuxidc.com/Linux/2012-08/68258.htm
I2C子系統之總結 http://www.linuxidc.com/Linux/2012-08/68259.htm
I2C子系統之內核中I2C子系統的結構 http://www.linuxidc.com/Linux/2012-08/68260.htm
I2C子系統之I2C bus初始化——I2C_init() http://www.linuxidc.com/Linux/2012-08/68261.htm
I2C子系統之platfor_device初始化——smdk2440_machine_init() http://www.linuxidc.com/Linux/2012-08/68262.htm
I2C子系統之platform_driver初始化——I2C_adap_s3c_init() http://www.linuxidc.com/Linux/2012-08/68263.htm
I2C子系統之I2C總線時鐘頻率設置 http://www.linuxidc.com/Linux/2012-08/68264.htm
I2C子系統之adapter device和client device注冊——I2C_add_number_adapter() http://www.linuxidc.com/Linux/2012-08/68265.htm
I2C子系統之__I2C_first_dynamic_bus_num變量的相關分析 http://www.linuxidc.com/Linux/2012-08/68266.htm
I2C子系統之 adapter driver注冊——I2C_dev_init() http://www.linuxidc.com/Linux/2012-08/68267.htm
I2C子系統之write() http://www.linuxidc.com/Linux/2012-08/68268.htm

Copyright © Linux教程網 All Rights Reserved