31 IIC(九)iic adapter

发布时间 2023-06-24 15:38:16作者: 人民广场的二道贩子

代码

1 iic adapter驱动架构

i2c adapter设备是挂载于platform bus

整体重点架构如下

  • 分配

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

    adapter->owner = THIS_MODULE;
    adapter->algo = &i2c_algo;
    
  • 注册

    ret = i2c_add_adapter(adapter);           // 动态分配nr
    ret = i2c_add_numbered_adapter(adapter);  // nr = -1则动态分配nr,否则则指定nr
    
  • 卸载

    i2c_del_adapter(adapter);
    

2 常用数据结构解析

2.1 i2c_adapter

struct i2c_adapter {
        struct module *owner;
        unsigned int class;               /* classes to allow probing for */
        const struct i2c_algorithm *algo; /* the algorithm to access the bus */
        void *algo_data;

        /* data fields that are valid for all devices   */
        const struct i2c_lock_operations *lock_ops;
        struct rt_mutex bus_lock;
        struct rt_mutex mux_lock;

        int timeout;                    /* in jiffies */
        int retries;
        struct device dev;              /* the adapter device */
        unsigned long locked_flags;     /* owned by the I2C core */
#define I2C_ALF_IS_SUSPENDED            0
#define I2C_ALF_SUSPEND_REPORTED        1

        int nr;
        char name[48];
        struct completion dev_released;

        struct mutex userspace_clients_lock;
        struct list_head userspace_clients;

        struct i2c_bus_recovery_info *bus_recovery_info;
        const struct i2c_adapter_quirks *quirks;

        struct irq_domain *host_notify_domain;
};

2.2 i2c_algorithm

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 (*master_xfer_atomic)(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);
        int (*smbus_xfer_atomic)(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 *adap);

#if IS_ENABLED(CONFIG_I2C_SLAVE)
        int (*reg_slave)(struct i2c_client *client);
        int (*unreg_slave)(struct i2c_client *client);
#endif
};
  • master_xfer

    i2c传输

  • mas_terxfer_atomic

    原子传输

  • smbus_xfer

    smbus传输,如果没有提供此函数。则回使用master_xfer来进行模拟

  • smbus_xfer_atomic

    smbus的原子传输

  • functionality

    返回此algo支持的功能

  • reg_slave/unreg_slave

    reg_slave将一个i2c client注册到i2c adapter。即让i2c adapter模拟i2c client

    unreg_slave卸载i2c adapter模拟的i2c client

3. 示例