linux驱动之i2c学习

  最近在研究linux的i2c驱动,从最底层i2c控制器初始化到应用层与i2c设备交互基本打通了。

  一、linux的i2c架构可以用下图表示:

   IIC适配器对应一条i2c总线,linux里面用i2c_adapter结构表示。总线下的i2c设备用i2c_client结构表示。algorithm是i2c的通信协议,IIC核心层负责注册/注销i2c_adapter、注册/注销i2c_client、注册i2c总线等操作。i2c-dev对应的是i2c-dev.c,它负责将总线实例化为一个i2c_client,应用层可以通过操作对应设备节点来与总线下的任意设备进行通信。IIC设备驱动是i2c总线下的具体设备的驱动方法。

  其中具体的IIC控制器操作与algorithm由IIC控制器驱动实现,常见的不同处理器的i2c总线驱动在内核源码/driver/i2c/buses/目录下。具体的i2c设备驱动内核源码并没有实现,需要自己提供。

   以下摘抄宋宝华老师写的书《linux设备驱动开发详解》中说作为一个工程师要实现的主要工作:

    I2C总线驱动:

    (1)提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。

    (2)提供I2C适配器的Algorithm,用具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。

    I2C设备驱动:

    (1):实现I2C设备驱动中的i2c_driver接口,用具体设备yyy的yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、和id_table指针。

    (2):实现I2C设备所对应类型的具体驱动,i2c_driver只是实现设备与总线的挂接,而挂接在总线上的设备千差万别。例如,如果是字符设备,就实现文件操作接口,即实现设备yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等;如果是声卡,就实现ALSA驱动。

 

  二、I2C核心

  (1)增加/删除i2c_adapter

    int i2c_add_adapter(struct i2c_adapter *adapter);

    int i2c_del_adapter(struct i2c_adapter *adap);

  (2)增加/删除i2c_driver

    int i2c_register_driver(struct module *owner, struct i2c_driver *driver);

    void i2c_del_driver(struct i2c_driver *driver);

    static inline int i2c_add_driver(struct i2c_driver *driver)
    {
      return i2c_register_driver(THIS_MODULE, driver);
    }

  (3)I2C传输、发送和接收

    int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);

    int i2c_master_send(const struct i2c_client *client, const char *buf, int count);

    int i2c_master_recv(const struct i2c_client *client, char *buf, int count);

 

 

 

 

 

 

 

 

 

 

posted @ 2016-02-21 23:13  zer-o  阅读(494)  评论(0编辑  收藏  举报