十九、(正点原子)Linux I2C驱动

一、Linux I2C驱动框架

        以前使用I2C时候,会建立一个i2c的文件和i2c通信设备的文件,也叫做驱动。I2C驱动主要分为两个驱动:

                ①、I2C主机驱动(i2c文件)

                ②、I2C设备驱动(i2c通信设备)

        对于主机驱动,主要就是I2C控制器驱动,一旦编写好就不需要修改,这个驱动提供I2C传输接口,I2C设备直接调用这个接口就可以完成通信。对于Linux的分离分层也正好符合。因此Linux内核也将I2C驱动分为两部分:

        ①、I2C总线驱动,I2C 总线驱动就是 SOC 的 I2C 控制器驱动,也叫做 I2C 适配器驱动。对于I2C的主机驱动。

        ②、I2C设备驱动,主要是I2C通信的设备,要根据具体的设备来编写驱动。

        1、I2C总线驱动

        I2C有自己的总线,不需要使用platform总线。I2C 总线驱动重点是 I2C 适配器(也就是 SOC的 I2C 接口控制器)驱动,这里要用到两个重要的数据结构:i2c_adapter和 i2c_algorithm, Linux 内核将 SOC 的 I2C 适配器抽象成i2c_adapter,i2c_adapter 结构体定义在 include/linux/i2c.h 文件中,结构体内容如下:

498 struct i2c_adapter {
499     struct module *owner;
500     unsigned int class; /* classes to allow probing for */
501     const struct i2c_algorithm *algo; /* 总线访问算法 */
502     void *algo_data;
503
504     /* data fields that are valid for all devices */
505     struct rt_mutex bus_lock;
506
507     int timeout; /* in jiffies */
508     int retries;
509     struct device dev; /* the adapter device */
510
511     int nr;
512     char name[48];
513     struct completion dev_released;
514
515     struct mutex userspace_clients_lock;
516     struct list_head userspace_clients;
517
518     struct i2c_bus_recovery_info *bus_recovery_info;
519     const struct i2c_adapter_quirks *quirks;
520 };

        第 501 行, i2c_algorithm 类型的指针变量 algo,对于一个 I2C 适配器,肯定要对外提供读写 API 函数,设备驱动程序可以使用这些 API 函数来完成读写操作。 i2c_algorithm 就是 I2C 适配器与 IIC 设备进行通信的方法。
        i2c_algorithm 结构体定义在 include/linux/i2c.h 文件中,内容如下(删除条件编译):

391 struct i2c_algorithm {
......
398     int (*master_xfer)(struct i2c_adapter *adap,
                            struct i2c_msg *msgs,
399                         int num);
400     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
401                     unsigned short flags, char read_write,
402                     u8 command, int size, union i2c_smbus_data *data);
403
404     /* To determine what the adapter supports */
405     u32 (*functionality) (struct i2c_adapter *);
......
411 };

        第 398 行, master_xfer 就是 I2C 适配器的传输函数,可以通过此函数来完成与 IIC 设备之间的通信。

        第 400 行, smbus_xfer 就是 SMBUS 总线的传输函数。

        综上所述, I2C 总线驱动,或者说 I2C 适配器驱动的主要工作就是初始化 i2c_adapter 结构体变量,然后设置 i2c_algorithm 中的 master_xfer 函数。完成以后通过i2c_add_adapter 或i2c_add_numbered_adapter这两个函数向系统注册设置好的 i2c_adapter,这两个函数的原型如下:

定义在include/linux/i2c.h

int i2c_add_adapter(struct i2c_adapter *adapter)
int i2c_add_numbered_adapter(struct i2c_adapter *adap)

        adapter或adap:要添加到Linux内核中的i2c_adapter,也就是I2C控制器。

        返回值:0:成功,负值,失败。

        这两个函数的区别在于 i2c_add_adapter 使用动态的总线号,而 i2c_add_numbered_adapter使用静态总线号。如果要删除 I2C 适配器的话使用 i2c_del_adapter 函数即可,函数原型如下:

定义在include/linux/i2c.h

void i2c_del_adapter(struct i2c_adapter * adap)

        adap:要删除的I2C控制器。 

        一般I2C总线驱动有SOC厂家编写,因为不同的 SOC厂家I2C在硬件上可能不一样。所以SOC厂家会将他们自己的I2C控制器的驱动编写好。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tofu_Cabbage

你的打赏是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值