i2c适配器驱动程序

我们先来参考一下内核中自带的驱动程序,看看别人怎么写的

我们可以对内核进行make menuconfIg 看看它对应于哪一个文件


这里有个S3C2410 I2C Driver

然后按下H可以看到它依赖于那个配置


这里是依赖于我们的CONFIG_I2C_S3C2410这个配置的

我们在driver/i2c目录下搜索,CONFIG_I2C_S3C2410,看看它对应哪个文件


对应于我们的i2c-s3c2410.c这个文件,于是我们去内核源码中看这个文件是怎么实现的,从入口函数开始看起


注册一个平台driver,调用probe函数


i2c_adap,分配设置构造这个i2c_adap,

然后通过上面这个函数注册adapter,先不管,这个驱动复杂主要复杂在下面这个成员

algo算法,进去看一下有什么算法


算法里面有个功能,看看这个函数


返回我们适配器支持的功能,还有一个主的传输函数


里面主要是调用doxfer,应该就是去实现I2C最底层的那些操作,比如说发出start信号,发出设备地址,读写数据等等等等这些操作。重点就在这个函数

现在我们反过来,我们以前写的驱动程序,

我们驱动里面调用i2c_smbus_wrire_byte_data等类似于这样的接口的,是怎么找到适配器,调用你适配器里面的传输函数

进入i2c_smbus_wrire_byte_data这个函数里面看一下


调用了i2c_smbus_xfer,进去看一眼


里面调用了adapter里面的算法里面的传输函数,我们的是master_xfer,我们没有设置smbus_xfer这个函数,他会调用这个函数,这个函数应该最终会调用到master_xfer这个函数,

我们现在开始写代码,记得三要素,分配,设置注册,三要素

我们肯定也是仿照内核中的代码来实现这个功能,在内核中搜索i2c_add_adapter函数来注册i2c_adapter,我们在内核中收索这个函数,这里说明一下

2440里面用的i2c_add_numbered_adapater,这个只是编号的然后在再注册,这里我们用i2c_add_adapter让系统自己帮我们编号


一大堆,我们就参考最后一个把


人家是这么定义的,我们把它拿过来

框架如下

static int s3c_xfer(struct i2c_adapter *adap,struct i2c_msg *msgs, int num)
{
	
}
static u32 s3c_func(struct i2c_adapter *adap)
{
	//I2C_FUNC_I2C什么意思,我也不知道
	//I2C_FUNC_SMBUS_EMUL 是什么意思呢,你不是说smbus不是i2c里面的一个
	//小子集吗,smbus应该是在algo里面的smbus_xfer来做的,你可以看内核中
	//i2c_algorithm这个结构体,其中就有一个成员变量是smbus_xfer
	//如果你适配器直接支持smbus_xfer的话,你下面那个i2c_algorithm里面写一个
	//函数,如果不支持的话,没关系,你也可以用master_xfer来支持它,来模拟它
	//I2C_FUNC_PROTOCOL_MANGLING 这个暂时也不知道是什么意思

	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
}
static const struct i2c_algorithm s3c_algo = {
	//主要的传输函数,怎么写,我们也是仿照
	.master_xfer	= s3c_xfer,
	//功能,这里我们可以仿照2410的
	.functionality	= s3c_func,
};


/*
   1.分配/设置i2c_adapter结构体
   2.注册i2c_adapter结构体
*/

static struct i2c_adapter s3c_i2c_adapter = {
	//名字不重要
	.name = "S3c I2C bus",
	//算法才是最重要的,这个我们也参考被人的代码
    .algo			= &s3c_algo,
	//这个不需要
	//.algo_data		= &i2c_sgi_vino_data,
    .owner 			= THIS_MODULE,
};


static int i2c_bus_s5pv210_init(void)
{
	i2c_add_adapter(s3c_i2c_adapter);
	return 0;
}

static void i2c_bus_s5pv210_exit(void)
{
	i2c_del_adapter(s3c_i2c_adapter);
}

module_init(i2c_bus_s5pv210_init);
module_exit(i2c_bus_s5pv210_exit);

.master_xfer = s3c_xfer,这个才是难点中的难点,框架已经出来了,重要的,你这个框架你可以拿过去用到任何地方,主要是.master_xfer = s3c_xfer,这个文件

怎么发出I2C数据,这个才是单板相关的,

我们来看i2c_msg里面有什么东西,





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值