歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> I2C子系統之I2C bus初始化——I2C_init()

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

日期:2017/3/1 10:12:44   编辑:Linux編程

根據前文的分析(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. if (!client) //判斷當前的dev是否是client類型,假如不是立即返回
  6. return 0;
  7. /* Attempt an OF style match */
  8. if (of_driver_match_device(dev, drv)) //條件drv->of_match_table,對at24來說是at24_driver->drv->of_match_table
  9. return 1;
  10. driver = to_i2c_driver(drv);
  11. /* match on an id table if there is one */
  12. if (driver->id_table)
  13. return i2c_match_id(driver->id_table, client) != NULL;
  14. return 0;
  15. }

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. if (!client)
  7. return 0;
  8. driver = to_i2c_driver(dev->driver);
  9. if (!driver->probe || !driver->id_table)
  10. return -ENODEV;
  11. client->driver = driver;
  12. if (!device_can_wakeup(&client->dev))
  13. device_init_wakeup(&client->dev,
  14. client->flags & I2C_CLIENT_WAKE);
  15. dev_dbg(dev, "probe\n");
  16. status = driver->probe(client, i2c_match_id(driver->id_table, client));
  17. if (status) {
  18. client->driver = NULL;
  19. i2c_set_clientdata(client, NULL);
  20. }
  21. return status;
  22. }

相關閱讀:

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