Chinaunix首页 | 论坛 | 博客
  • 博客访问: 362943
  • 博文数量: 135
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 599
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-19 21:10
文章分类
文章存档

2014年(3)

2013年(79)

2012年(53)

分类: 嵌入式

2013-10-24 11:35:12

原文地址:linux下I2C驱动分析2-(2) 作者:zjh_larm

用法总结

上面我们总结了i2c_algorithmmaster_xfer成员函数的实现,我们正是调用该函数来实现i2c设备的访问的。一般我们在设备驱动中找到设备所接的适配器以后,同时也找到了该适配器的通信方法,然后我们会根据芯片的datasheet组织i2c消息,然后调用i2c核心提供的函数i2c_transfer来访问芯片。下面我们来跟踪下i2c_transfer函数,其实就是对i2c_algorithm->master_xfer的封装。

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

{

       int ret;

 

       if (adap->algo->master_xfer) {

#ifdef DEBUG

              for (ret = 0; ret < num; ret++) {

                     dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "

                            "len=%d\n", ret, msgs[ret].flags & I2C_M_RD ?

                            'R' : 'W', msgs[ret].addr, msgs[ret].len);

              }

#endif

 

              mutex_lock(&adap->bus_lock);

//可以看到就是直接调用master_xfer函数。

              ret = adap->algo->master_xfer(adap,msgs,num);

              mutex_unlock(&adap->bus_lock);

 

              return ret;

       } else {

              dev_dbg(&adap->dev, "I2C level transfers not supported\n");

              return -ENOSYS;

       }

}

 

 

下面再来讨论下前面一章中i2c_probe函数中调用的i2c_check_functionality函数的实现。

I2c_probe函数中有这样一段:

       /* Stop here if we can't use SMBUS_QUICK */

       if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {

              if (address_data->probe[0] == I2C_CLIENT_END

               && address_data->normal_i2c[0] == I2C_CLIENT_END)

                    return 0;

 

              dev_warn(&adapter->dev, "SMBus Quick command not supported, "

                      "can't probe for chips\n");

              return -1;

       }

追踪i2c_check_functionality

static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func)

{

       return (func & i2c_get_functionality(adap)) == func;

}

static inline u32 i2c_get_functionality(struct i2c_adapter *adap)

{

       return adap->algo->functionality(adap);

}

可见还是调用了algothmfunctionlity函数。

我们来看看该驱动中这个函数的实现:

static struct i2c_algorithm mxc_i2c_algorithm = {

       .master_xfer = mxc_i2c_xfer,

       .functionality = mxc_i2c_func

};

static u32 mxc_i2c_func(struct i2c_adapter *adap)

{

       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;

}

 

可见就是要该适配器支持I2C_FUNC_SMBUS_QUICK的功能。

 

阅读(1462) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~