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协议和驱动框架分析的主要内容,如果未能解决你的问题,请参考以下文章

I2C协议和驱动框架分析

I2C协议和驱动框架分析

I2C通信协议和流程分析

IIC总线协议和时序

Thrift源码分析-- 协议和编解码

linux驱动之i2c总线驱动调用分析基于linux4.4