Linux驱动学习--I2C_Adapter驱动框架(三)

1、I2C_Adapter驱动框架

1)i2c_adapter结构体:

结构体中的i2c_algorithm是指进入这个总线的算法。

  • master_xfer:这是最重要的函数,它实现了一般的I2C传输,用来传输一个或者多个i2c_msg
  • master_xfer_atomic:
    • 可选的函数,功能跟master_xfer一样,在atomic context环境下使用
    • 比如关机之前。所有中断都关闭的情况下,用来访问电源管理芯片
  • smbus__xfer:实现SMBus传输,如果不提供这个函数,SMBus传输会使用master_xfer来模拟
  • smbus_xfer_atomic:
    • 可选函数,功能跟smbus_xfer一样,在atomic context 环境下使用
    • 比如在关机之前、所有中断都关闭的情况下,用来访问电源管理芯片
  • functionality:返回值所支持的flags:各类I2C_FUNC_*
  • reg_slave/unreg_slave:
    • 有些I2C Adapter也可以工作于Slave模式,用来实现或模拟一个i2c设备
  • reg_slave就是把一个i2c_client注册到I2C Adapter,换句话说就是让这个I2C Adapter模拟该I2C_client
    • unreg_slave:反注册

2、驱动程序框架

分配、设置、注册一个i2c_adapter结构体:

i2c_adapter的核心是i2c_algorithm

i2c_algorithm的核心是master_xfer函数

分配函数:

struct i2c_adapter *adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);

设置:

adap->owner = THIS_MODULE;
adap->algp = i2c_imx_algo;

注册:

ret = i2c_add_adapter(adap);    //不管adap->nr原来是什么,都动态设置adap->nr
ret = i2c_add_numbered_adapter(adap);    //如果adap->nr == -1则动态分配nr;否则使用该nr

反注册:

i2c_del_adapter(adap);

3、i2c_algorithm示例

Linux-5.4中使用GPIO模拟I2C

Linux-4.9.88中IMX6ULL的I2C驱动

4、编写一个驱动框架

1、设备数

在设备树里构造I2C Bus节点:

i2c_bus_virtual{
    compatible = “imx6ull,i2c-bus-virtual”;
};

2、platform_driver

分配、设置、注册platform_driver结构体。

核心是probe函数

  • 根据设备树信息设置硬件(引脚、时钟等)
  • 分配、设置、注册i2c_adapter

3、i2c_adapter

i2c_adapter的核心是master_xfer函数。它的实现取决于硬件,大概代码如下:

static int xxx_master_xfer(struct i2c_adapter *adapter,
						struct i2c_msg *msgs, int num)
{
    for (i = 0; i < num; i++) {
        struct i2c_msg *msg = msgs[i];
        {
        	// 1. 发出S信号: 设置寄存器发出S信号
            CTLREG = S;
            
            // 2. 根据Flag发出设备地址和R/W位: 把这8位数据写入某个DATAREG即可发出信号
            //    判断是否有ACK
            
            if (!ACK)
                return ERROR;
            else {
	            // 3. read / write
	            if (read) {
                    STATUS = XXX; // 这决定读到一个数据后是否发出ACK给对方
                    val = DATAREG; // 这会发起I2C读操作
                } else if(write) {
                    DATAREG = val; // 这会发起I2C写操作
                    val = STATUS;  // 判断是否收到ACK
                    if (!ACK)
                        return ERROR;
                }                
            }
            // 4. 发出P信号
            CTLREG = P;
        }
    }
    
    return i;
}

至此,I2C_Adapter驱动框架的学习就到此为止了。如果对大家有收获的话,希望大家多多点赞,收藏,关注。

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值