LINUX I2C设备驱动模型分析之三 I2C ADAPTER实现分析

       前两篇我们分析了I2C总体框架、I2C总线,本节主要分析下I2C ADAPTER部分,其实也就是

I2C控制器部分。在I2C模块中,有两个设备类型:i2c adapter、i2c client,其中i2c client可以理解为设备驱动模型中的设备,与注册到总线上的i2c驱动绑定,而i2c adapter也属于注册到i2c总线上的设备,但其不需要与i2c驱动绑定。其主要为i2c驱动提供访问i2c设备的方法,同时一个i2c设备需要依附于i2c adapter(在设备模型中,i2c adapter是依附于其上的i2c client的父device)。

 

     本章我们主要说明i2c adapter的注册、注销、i2c adapter提供的方法等。I2c adapter相关的

结构体之前已经介绍,此处不再赘述。

 

I2c adapter的方法(或i2c adapter的算法)

        I2c adapter的方法用于设置该adapter的传输方法、支持的传输模式选择等,对应的结构体为i2c_algorithm,该结构体的定义如下,主要内容如下:

  1. 若该adapter支持i2c传输方式,则该adapter需要实现master_xfer接口,用以支持通过i2c时序传输数据(读写),
  2. 若该adapter支持smbus传输方式,则该adapter需要实现smbus_xfer接口,用以支持通过smbus时序传输数据,若不支持smbus传输方式,则通过master_xfer模拟smbus时序实现数据通信。
  3. functionality接口主要用于返回该adapter支持的方法,如支持I2C_FUNC_I2C、I2C_FUNC_10BIT_ADDR、I2C_FUNC_SMBUS_EMUL等,当调用某一个adapter的通信方法前,需先调用该functionality接口,获取该adapter支持的通信方式等。
/*
 * The following structs are for those who like to implement new bus drivers:
 * i2c_algorithm is the interface to a class of hardware solutions which can
 * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584
 * to name two of the most common.
 */
struct i2c_algorithm {
	/* If an adapter algorithm can't do I2C-level access, set master_xfer
	   to NULL. If an adapter algorithm can do SMBus access, set
	   smbus_xfer. If set to NULL, the SMBus protocol is simulated
	   using common I2C messages */
	/* master_xfer should return the number of messages successfully
	   processed, or a negative value on error */
	int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
			   int num);
	int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
			   unsigned short flags, char read_write,
			   u8 command, int size, union i2c_smbus_data *data);

	/* To determine what the adapter supports */
	u32 (*functionality) (struct i2c_adapter *);
};

如下为i2c imx adapter的方法定义,该i2c adpater支持i2c的通信方法,且支持smbus时序的通信方式,但是使用i2c的通信方法模拟smbus时序通信。

static u32 i2c_imx_func(struct i2c_adapter *adapter)

{

        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;

}



static struct i2c_algorithm i2c_imx_algo = {

        .master_xfer    = i2c_imx_xfer,

        .functionality  = i2c_imx_func,

};

i2c_adapter注册

I2c adapter的注册主要实现的功能也比较明晰,主要实现如下几个方面的内容:

  1. 首先判断i2c adapter的各成员是否设置合理(如是否设置成员变量)
  2. 设置i2c_adapter的device类型的成员变量dev,设置dev的type为i2c_adapter_type,此处设置i2c_adapter_type的目的用于与i2c client进行区分,因i2c client、i2c adaper均需要注册到i2c_bus上,而在i2c_bus模块仅i2c_client、i2c_driver才能进行绑定操作,此处设置dev的type就是防止将i2c adapter与i2c_driver进行匹配。

i2c_adapter_type中定义了一个adpater所支持的默认属性(对应于sysfs下对应adapter目录下的属性文件)以及定义的release方法

  1. 设置的i2c_adapter所属的bus为i2c_bus;
  2. 针对每一个注册到i2c总线上的驱动,在该adapter上进行i2c设备的探测,并对探测到的i2c设备进行绑定操作。

此处涉及i2c设备注册的一种方式:针对spd(存储内存模型相关信息的eeprom设备)、hwmon等类的设备,可以在内核初始化时进行i2c设备的注册操作,而在i2c

扫描二维码关注公众号,回复: 9646593 查看本文章

adapter注册或者相应i2c driver注册时,通过i2c driver的detect函数指针以及i2c driver支持的i2c地址列表信息,自动完成i2c client的探测,并将探测到的i2c client注册到i2c总线上。

但针对这一种i2c设备的注册方式有几个前提条件:

  1. I2c driver需要支持detect函数;
  2. I2c adapter与i2c driver均需要标注其支持自动探测i2c设备的类,且它们支持的类型存在交集时方可支持探测(如均标注支持hwmon、spd的探测等)

                  仅在满足上述两个条件的情况下,才能够支持此类i2c设备的注册。

 

i2c_adapter的流程图如下所示

i2c_verify_adapter

该接口用于判断注册到i2c总线上的一个设备是否为adapter设备,主要是判断该adpater对应device类型的成员变量dev的type成员是否为i2c_adapter_type。

struct i2c_adapter *i2c_verify_adapter(struct device *dev)

{

    return (dev->type == &i2c_adapter_type)

        ? to_i2c_adapter(dev): NULL;

}

i2c_del_adapter

该接口用于从i2c总线上删除一个adpater,该接口实现的功能大致如下:

  1. 遍历注册到i2c总线上的所有驱动,针对驱动上已绑定的所有i2c client,完成i2c client的注销操作(包括调用设备驱动模型中的device_unregister进行注销等);
  2. 针对所有通过应用层sysfs中的接口创建的client设备,也完成i2c client的注销操作
  3. 调用device_unregister操作,完成该adapter的注销操作。针对i2c部分的注销操作,也就是去除下图中的关联,并将所有依附至该adapter上的i2c client,均进行注销操作。

以上便是i2c adpater相关的注册与注销部分的介绍。下一篇分析i2c client、i2c driver的注销。

发布了140 篇原创文章 · 获赞 30 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/lickylin/article/details/103058450
今日推荐