在这里先和大家说一句对不起,上周家里出了点事(舅舅去世了),真的没有时间来发帖子,希望大家多见谅吧。
这里把上次欠下的东西补上,耽误了很久,好心酸。。不墨迹了 ,直接开始上程序,这次是在3.4.2的内核版本下开始写的,先写个大框,之后再慢慢补充内容。
这里我们用的是内核文档里给的第二种方法,大家可以在linux-3.4.y-nanopi2-lollipop-mr1Documentationi2c这个文件夹里找到instantiating-devices,打开之后,用这里面的第二种方法
Method 2: Instantiate the devices explicitly
--------------------------------------------
This method is appropriate when a larger device uses an I2C bus for
internal communication. A typical case is TV adapters. These can have a
tuner, a video decoder, an audio decoder, etc. usually connected to the
main chip by the means of an I2C bus. You won't know the number of the I2C
bus in advance, so the method 1 described above can't be used. Instead,
you can instantiate your I2C devices explicitly. This is done by filling
a struct i2c_board_info and calling i2c_new_device().
Example (from the sfe4001 network driver):
static struct i2c_board_info sfe4001_hwmon_info = {
I2C_BOARD_INFO("max6647", 0x4e),
};
int sfe4001_init(struct efx_nic *efx)
{
(...)
efx->board_info.hwmon_client =
i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
(...)
}
The above code instantiates 1 I2C device on the I2C bus which is on the
network adapter in question.
A variant of this is when you don't know for sure if an I2C device is
present or not (for example for an optional feature which is not present
on cheap variants of a board but you have no way to tell them apart), or
it may have different addresses from one board to the next (manufacturer
changing its design without notice). In this case, you can call
i2c_new_probed_device() instead of i2c_new_device().
Example (from the nxp OHCI driver):
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
static int __devinit u***_hcd_nxp_probe(struct platform_device *pdev)
{
(...)
struct i2c_adapter *i2c_adap;
struct i2c_board_info i2c_info;
(...)
i2c_adap = i2c_get_adapter(2);
memset(&i2c_info, 0, sizeof(struct i2c_board_info));
strlcpy(i2c_info.type, "isp1301_nxp", I2C_NAME_SIZE);
isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
normal_i2c, NULL);
i2c_put_adapter(i2c_adap);
(...)
}
The above code instantiates up to 1 I2C device on the I2C bus which is on
the OHCI adapter in question. It first tries at address 0x2c, if nothing
is found there it tries address 0x2d, and if still nothing is found, it
simply gives up.
The driver which instantiated the I2C device is responsible for destroying
it on cleanup. This is done by calling i2c_unregister_device() on the
pointer that was earlier returned by i2c_new_device() or
i2c_new_probed_device().
英文不好,各位还是自己去翻译吧,下面开始写程序
第一,还是老样子,把协议啊,头文件啊整进来。
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
module_init(i2c_1_init);
module_init(i2c_1_exit);
MODULE_LICENSE("GPL");
头文件写完之后,把协议加上,告诉一下内核我们的入口函数和出口函数。之后把入口函数和出口函数完善一下,我也不细说了,有问题各位可以私聊我哈。
static const struct i2c_device_id i2c_1_id_table[] ={
{ "i2c_1", 0 },
{}
};
static int __devinit i2c_1_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
printk("%s %s %dn", __FILE__, __FUNCTION__,__LINE__);
return 0;
}
static int __devinit i2c_1_remove(struct i2c_client *client)
{
printk("%s $s %dn", __FILE__, __FUNCTION__,__LINE__);
return 0;
}
static struct i2c_driver i2c_1_i2c_driver = {
.driver = {
.name = "kidsure",
.owner= THIS_MODULE,
},
.probe = i2c_1_probe,//匹配成功后调用这个函数
.remove = __devexit_p(i2c_1_remove),//删除时调用
.id_table = i2c_1_id_table,//匹配时校验该名称
};
static int i2c_1_init(void)
{
/*注册i2c 设备*/
int i2c_vel;
i2c_vel = i2c_add_driver(&i2c_1_i2c_driver);//判断返回值
if(i2c_vel == -1)
{
printf{"err1"};
}
return 0;
}
static void i2c_1_exit(void)
{
i2c_del_driver(&i2c_1_i2c_driver);
return 0;
}
这样吧i2c总线的驱动框架写好了,之后我们重建一个文件叫****_drv.c神马的都行。来开始写设备驱动。
同样的先把头文件和协议复制一下子。
static struct i2c_board_info i2c_1_info ={
I2C_BOARD_INFO{"i2c_1",0x48}//与总线驱动中i2c_1_id_table一致,后面是地址
}
static struct i2c_client *i2c_1_client;
static int i2c_1_dev_init(void)
{
struct i2c_adapter *i2c_adap;
i2c_adap = i2c_get_adapter(0);//第0个适配器
i2c_1_client = i2c_new_device(i2c_adap, &i2c_1_info);
i2c_put_adapter(i2c_adap);//释放适配器
return 0;
}
static void i2c_1_dev_exit(void)
{
i2c_unregister_device(i2c_1_client);
return 0;
}
总结起来最后就是入口函数里那个i2c_new_device,把它配置好,其他都万事大吉。
然后说一下它I2C_BOARD_INFO{"i2c_1",0x48},这个是用来和前一个文件比较的,如果名字相同就会调用之前的probe函数,后面是地址。我用的51单片机开发板上面的AD转换,PCF8591.。
查了一下芯片手册,其中A2,A1,A0控制地址的后三位,在看一下原理图。
这三个引脚都接地了,所以它的地址应该是1001000,所以后面地址写的是0x48.
这样大体的框架写好了,之后就是如何读取和利用数据了。。结项路漫漫,我可不立Flag了,不定期更新。。最近有点忙啊。。望各位见谅,今天到这里啦
|