linux下I2c框架分析之通信(五)

linux下I2c框架分析之通信(五)
平台:君正x1000
内核:Linux3.5
在linux的i2c框架中,设备和主机的通信数据都是经过适配器处理的,所以通信的协议的实现也是依靠适配器驱动实现的。
在通信结构i2c_algorithm中主要实现两个成员.master_xfer和.functionality ,i2c通信协议的实现主要是master_xfer完成,functionality主要是返回支出的功能。

/*  \drivers\i2c\busses\i2c-v12-jz.c  */
static const struct i2c_algorithm i2c_jz_algorithm = {
	.master_xfer = i2c_jz_xfer,
	.functionality = i2c_jz_functionality,
};
static int i2c_jz_probe(struct platform_device *dev)
{
	int ret = 0;
	struct i2c_jz *i2c;
	struct resource *res;
	unsigned int reg_tmp;
	
	i2c = kzalloc(sizeof(struct i2c_jz), GFP_KERNEL);
	i2c->adap.owner = THIS_MODULE;
	i2c->adap.algo = &i2c_jz_algorithm;  //适配器指向这个通信结构
	i2c->adap.retries = 5;
	i2c->adap.timeout = 5;
	i2c->adap.algo_data = i2c;
	i2c->adap.dev.parent = &dev->dev;
	i2c->adap.nr = dev->id;
	sprintf(i2c->adap.name, "i2c%u", dev->id);
}

因为在i2c协议中,cpu作为主控,是主动读写终端设备的数据,终端总是作为被动方,下面咱们看看适配器是怎么访问终端设备的。
终极接口
此接口对设备可读可写,无论你在驱动程序中见到的任何封装的读写函数都会调用到此接口。

  /*  \drivers\i2c\i2c-core.c  */
 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
 /* 上面适配器驱动中已经实现此函数  */
	if (adap->algo->master_xfer) 
	    ret = __i2c_transfer(adap, msgs, num);
}
 /*  \drivers\i2c\i2c-core.c  */
int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{    
	for (ret = 0, try = 0; try <= adap->retries; try++) {
		ret = adap->algo->master_xfer(adap, msgs, num);
	}
}

这样就把数据传进去了,是不是很奇怪,到底怎么读怎么写呢,接下来再看一个结构

struct i2c_msg {
	__u16 addr;	/* slave address			*/
	__u16 flags;       /* 可以是以下宏定义的组合  */
#define I2C_M_TEN		0x0010	/* this is a ten bit chip address */
#define I2C_M_RD		0x0001	/* read data, from slave to master */
#define I2C_M_STOP		0x8000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_NOSTART */
#define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_IGNORE_NAK	0x1000	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_NO_RD_ACK		0x0800	/* if I2C_FUNC_PROTOCOL_MANGLING */
#define I2C_M_RECV_LEN		0x0400	/* length will be first received byte */
	__u16 len;		/* msg length				*/
	__u8 *buf;		/* pointer to msg data			*/
};

了解了这个结构,咱们看看适配器是怎么解析消息的。此时咱们就要研究刚才 i2c_algorithm中的.master_xfer = i2c_jz_xfer的实现了。

static int i2c_jz_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int count)
{
	/*  进行读写判断 */
	if (msg->flags & I2C_M_RD) {
			ret = xfer_read(i2c, msg->buf, msg->len, end_type);
		} else {
			ret = xfer_write(i2c, msg->buf, msg->len, end_type);
		}
}

最关键的就是这两个函数,其对适配器寄存器的设置需配合cpu数据手册暂且不做研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值