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

I2C驅動情景分析——怎樣控制I2C時序

內核版本:linux-3.4.2

源程序:    linux-3.4.2\drivers\i2c\busses\I2c-s3c2410.c

這次要解決的問題是:如何配置soc的I2C模塊,輸出想要的時序波形?

關於Linux裡I2C驅動的架構,在轉載的文章講得相當透徹(《linux下I2C驅動架構全面分析》http://www.linuxidc.com/Linux/2014-05/101648.htm )。I2C驅動的框架如下圖,主要包括:

總線驅動層: 驅動Soc內部的I2c模塊,也稱之為適配器(adapter)驅動。覆蓋圖中硬件驅動層。

設備驅動層:實現i2c設備的device驅動(如Eeprom的驅動),使用I2C驅動的接口,編寫字符設備(多數是字符設備)。覆蓋圖中的driver驅動層。

核心層:是連接“總線驅動層”和“設備驅動層”的接口。如總線驅動層向核心層注冊一個使用總線的驅動,設備驅動調用這個總線驅動,控制對應的函數。由於

Linux能夠支持多種I2C總線和多種I2C設備,因此采用了總線平台驅動。采用了分層和分離的思想,使一個I2C設備可以使用任意一條I2C總線。

圖1. Linux的I2C驅動框架圖

簡要地回顧完I2C驅動的架構,回到主題——怎樣產生I2C時序?

在總線驅動層裡實現了產生I2C時序,注冊一個master_xfer()方法,使用soc的內部I2C模塊收發數據。我找了一個i2c總線的實例

進行說明:linux-3.4.2\drivers\i2c\busses\I2c-s3c2410.c

static int __init i2c_adap_s3c_init(void)
{
 return platform_driver_register(&s3c24xx_i2c_driver);//注冊一個平台驅動<span > platform_driver</span>
}

static struct platform_driver s3c24xx_i2c_driver = {
 .probe  = s3c24xx_i2c_probe,  //設置probe函數,初始化soc內的i2c模塊,設置收發函數
 .remove  = s3c24xx_i2c_remove,
 .id_table = s3c24xx_driver_ids,  //當一個設備的id與.id_table中的一項匹配時(相等),調用probe函數
 .driver  = {
  .owner = THIS_MODULE,
  .name = "s3c-i2c",
  .pm = S3C24XX_DEV_PM_OPS,
  .of_match_table = s3c24xx_i2c_match,
 },
};

static int s3c24xx_i2c_probe(struct platform_device *pdev)
{
 i2c->adap.algo    = &s3c24xx_i2c_algorithm;  //設置具體的收發算法
 ret = i2c_add_numbered_adapter(&i2c->adap);  //把適配器的驅動注冊進內核,以後這個適配器由core層進行管理
}

/* i2c bus registration info */
static const struct i2c_algorithm s3c24xx_i2c_algorithm = {
 .master_xfer  = s3c24xx_i2c_xfer, //設置<span >master_xfer函數,由這個函數產生I2C時序</span>
 .functionality  = s3c24xx_i2c_func,
};

當程序來到了master_xfer這一步,接下來就是硬件相關的部分了(和soc內部的i2c模塊相關的部分)。master_xfer會根據函數的參數,找到
 
對應的適配器,發送數據。看看master_xfer的參數:

static int s3c24xx_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)

adap:指定需要用到的適配器(Linux驅動能夠同時管理多個適配器)
 
msgs:需要發送的消息
num: 消息的長度


至此,已經用程序解了“怎樣產生I2C時序”:在master_xfer函數裡設置好如何發送一個I2C時序。當需要發送I2C時序時,調用core層的接口,指定使用哪一條總線、發送什麼數據,即可產生想要的I2C時序。

更多 I2C驅動情景分析 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=29201

Copyright © Linux教程網 All Rights Reserved