I2C协议和驱动框架分析
Posted bobuddy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I2C协议和驱动框架分析相关的知识,希望对你有一定的参考价值。
3、从设备驱动分析
总线驱动一般由主控芯片厂商(高通海思MTK展讯全志瑞芯微等等)已经做好了,驱动工程师就需要完成 I2C 设备驱动。I2C的设备驱动框架只是一款芯片(I2C接口)驱动的基础,通常还会和其他子系统(比如 camera 的 V4L2、Audio codec 的 ASoc 以及各类 sensor 的 input 子系统等)糅合在一起。所以,不管是实现一款芯片的驱动还是去分析别人的驱动代码,都需要有相关的子系统知识。这里我们以 goodix 的 TP 驱动为例,主要分析 I2C 的设备驱动部分。驱动入口如下:
static const struct i2c_device_id goodix_ts_id[] =
GTP_I2C_NAME, 0 ,
;
static struct of_device_id goodix_ts_dt_ids[] =
.compatible = "goodix,gt9xx" ,
;
static struct i2c_driver goodix_ts_driver =
.probe = goodix_ts_probe,
.remove = goodix_ts_remove,
.id_table = goodix_ts_id,
.driver =
.name = GTP_I2C_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(goodix_ts_dt_ids),
,
;
static int goodix_ts_init(void)
/*
* 工作队列机制,任务推后执行
* 创建单内核线程,并返回一个工作队列
* 中断里调用queue_work()内核会调度执行该工作队列里的任务
*/
goodix_wq = create_singlethread_workqueue("goodix_wq");
if (!goodix_wq)
GTP_ERROR("Failed to create workqueue goodix_wq");
return -ENOMEM;
return i2c_add_driver(&goodix_ts_driver);
static void goodix_ts_exit(void)
i2c_del_driver(&goodix_ts_driver);
if (goodix_wq)
destroy_workqueue(goodix_wq);
module_init(goodix_ts_init);
module_exit(goodix_ts_exit);
关于工作队列,以后有机会单独拿出来分析一波。任何一个 i2c 设备驱动都会调用 i2c_add_driver,我们的分析就从这个函数开始:
#define i2c_add_driver(driver) \\
i2c_register_driver(THIS_MODULE, driver)
i2c_add_driver 是个宏函数,i2c_register_driver(i2c-core.c) 的函数体如下:
/*
* An i2c_driver is used with one or more i2c_client (device) nodes to access
* i2c slave chips, on a bus instance associated with some i2c_adapter.
*/
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
int res;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p)))
return -EAGAIN;
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
/* 设备驱动挂在i2c_bus_type下 */
driver->driver.bus = &i2c_bus_type;
INIT_LIST_HEAD(&driver->clients);
/* When registration returns, the driver core
* will have called probe() for all matching-but-unbound devices.
*/
res = driver_register(&driver->driver);
if (res)
return res;
pr_debug("i2c-core: driver [%s] registered\\n", driver->driver.name);
/* Walk the adapters that are already present */
/* 并没有做什么实质性的工作,由于device_type不匹配就返回了 */
i2c_for_each_dev(driver, __process_new_driver);
return 0;
EXPORT_SYMBOL(i2c_register_driver);
以上是关于I2C协议和驱动框架分析的主要内容,如果未能解决你的问题,请参考以下文章