- linux4.1.15 i2c_driver probe被呼叫流程
**/*linux4.1.15 i2c_driver probe被呼叫的流程分析*/**
i2c_add_driver(&ap3216c_driver); //ap3216c.c中呼叫
i2c_register_driver(THIS_MODULE, driver) //drivers\i2c\i2c-core.c
driver_register(&driver->driver); //drivers\base\driver.c
bus_add_driver(drv); //drivers\base\bus.c
if (drv->bus->p->drivers_autoprobe)
driver_attach(drv); //drivers\base\dd.c
driver_attach(struct device_driver *drv) //drivers\base\dd.c
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); //drivers\base\bus.c
int bus_for_each_dev(struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
error = fn(dev, data);
fn 既:__driver_attach(struct device *dev, void *data) //drivers\base\dd.c
driver_match_device(drv, dev) //drivers\base\dd.c
| // 呼叫i2c核心i2c-core.c中的總線的match匹配函式
| return drv->bus->match ? drv->bus->match(dev, drv) : 1; //drivers\base\base.h
| .match = i2c_device_match //drivers\i2c\i2c-core.c
| if (of_driver_match_device(dev, drv)) //drivers\i2c\i2c-core.c
| of_match_device(drv->of_match_table, dev) //drivers\of\device.c
| of_match_node(matches, dev->of_node); //drivers\of\base.c
| __of_match_node(matches, node); //drivers\of\base.c
| __of_device_is_compatible(node, matches->compatible,
| matches->type, matches->name); //drivers\of\base.c
| __of_find_property(device, "compatible", NULL);
|
if (!dev->driver)
driver_probe_device(drv, dev); //drivers\base\dd.c
really_probe(dev, drv); //drivers\base\dd.c
if (dev->bus->probe) {
ret = dev->bus->probe(dev); //設備的probe,在i2c核心層drivers\i2c\i2c-core.c
}
即:.probe = i2c_device_probe //drivers\i2c\i2c-core.c
//呼叫用戶設備驅動中的probe
status = driver->probe(client, i2c_match_id(driver->id_table, client));
static int ap3216c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
...
}
- 涉及到的檔案說明
I2C-core.c 核心以及/proc/bus/i2c 介面
i2c_register_driver(THIS_MODULE, driver)
呼叫 of_driver_match_device(dev, drv)
struct bus_type i2c_bus_type = {
.name = "i2c",
.match = i2c_device_match,
.probe = i2c_device_probe,
};
drivers\base\driver.c 常規驅動 API,負責驅動的操作
driver_register(&driver->driver);
/* 主要實作的是驅動和設備的系結,解除,以及驅動的自動探測等功能 */
/* 系統一啟動就會自動執行 buses_init 來注冊總線子系統(bus_subsys)*/
drivers\base\bus.c
bus_add_driver(drv); //將驅動關聯到總線上
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
/* 負責實作驅動與設備的關聯與釋放操作的 */
drivers\base\dd.c
driver_attach(struct device_driver *drv) //同device_attach,區別是遍歷的是drv->bus,即查找驅動
//所在的總線,將總線上的設備嘗試關聯成drv驅動
__driver_attach(struct device *dev, void *data)
driver_match_device(drv, dev)
driver_probe_device(drv, dev); //驅動的系結
really_probe(dev, drv); //呼叫really_probe函式進行系結, 對dev創建link,實作dev和drive檔案夾的鏈接,
//呼叫dev->bus->probe或drv->probe進行探測
//探測成功則driver_bound(dev)完成系結
drivers\of\device.c 設備樹相關,匹配設備
of_match_device(drv->of_match_table, dev)
drivers\of\base.c 設備樹相關,匹配DTS節點
of_match_node(matches, dev->of_node);
__of_match_node(matches, node);
- 架構(參考自網路)
Linux的I2C構架分為三個部分:
1)I2C core框架
提供了核心資料結構的定義和相關介面函式,用來實作I2C配接器驅動和設備驅動的注冊、注銷管理,以及I2C通信方法上層的、與具體
配接器無關的代碼,為系統中每個I2C總線增加相應的讀寫方法,具體實作在/drivers/i2c目錄下的i2c-core.c和i2c-dev.c,
2) I2C總線驅動
定義描述具體I2C總線配接器的i2c_adapter資料結構、實作在具體I2C配接器上的I2C總線通信方法,并由i2c_algorithm資料結構進行
描述,經過I2C總線驅動的的代碼,可以為我們控制I2C產生開始位、停止位、讀寫周期以及從設備的讀寫、產生ACK等,總線驅動具體實
現在/drivers/i2c目錄下busses檔案夾中,例如Linux I2C GPIO總線驅動為i2c_gpio.c,總線演算法在/drivers/i2c目錄下algos文
件夾中, 例如Linux I2C GPIO總線驅動演算法實作為i2c_algo_bit.c,
3) I2C 設備驅動
是對具體I2C硬體驅動的實作,I2C 設備驅動通過I2C配接器與CPU通信,其中主要包含i2c_driver和 i2c_client資料結構,
i2c_driver結構對應一套具體的驅動方法,例如:probe、remove、suspend等,需要自己申明, i2c_client資料結構由內核根據具
體的設備注冊資訊自動生成,設備驅動根據硬體具體情況填充,設備驅動具體實作放在/drivers/i2c目錄下chips檔案夾中,
- 驅動的撰寫
如何撰寫自己的i2c相關的驅動,參考方案:
(1)提供 I2C 配接器的硬體驅動,探測、初始化 I2C 配接器(如申請 I2C 的 I/O 地址和中斷號)、驅動 CPU 控制的 I2C 配接器從硬
件上產生各種信號以及處理 I2C 中斷等,
(2)提供 I2C 配接器的 algorithm ,用具體配接器的 xxx_xfer() 函式填充 i2c_algorithm 的 master_xfer 指標,并把
i2c_algorithm 指標賦值給 i2c_adapter 的 algo 指標,
(3)實作 I2C 設備驅動與 i2c_driver 介面,用具體設備 yyy 的 yyy_attach_adapter() 函式指標、 yyy_detach_client() 函式指
針和 yyy_command() 函式指標的賦值給 i2c_driver 的 attach_adapter 、 detach_adapter 和 detach_client 指標,
(4)實作 I2C 設備驅動的檔案操作介面,即實作具體設備 yyy 的 yyy_read() 、 yyy_write() 和 yyy_ioctl() 函式等,
上述作業中 1、2 屬于I2C總線驅動,3、4 屬于I2C設備驅動,做完這些作業,系統會增加兩個內核模塊,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/71223.html
標籤:其他
上一篇:2020-09-16
