[问题] 请教linux i2c newstyle驱动的问题

楼主: cutem (大少爷)   2016-07-27 14:59:15
在下最近在研究newstyle i2c驱动,网络文章看了一些,
有一点心得,但由于身边朋友同学并没有做embedded system
的人,所以想跟各位先进请益一下,我先上一个google 到的sample
,我是把它编译成module,也就是ko档。
这个程式稍微改一下就真的可以用insmod挂起来了,本身是属于动
态侦测i2c device的做法,不过我有一些问题如下:
希望各位大大可以给我一些方向。感谢。
1.挂起来之后,我要怎么在application层透过这个驱动程式对i2c
装置进行读写动作?因为我看这个例子里面完全没有实作跟application
沟通的程式码?
后来有google到一些思路如下:
a.先将这个struct定义出来,并且把最基本的open,read,write完成
static const struct file_operations i2c_fops = {
.owner = THIS_MODULE,
.open = i2c_open,
.read = i2c_read,
.write = i2c_write,
.unlocked_ioctl = i2c_ioctl,
.release = i2c_release,
};
b.注册成char device,那么理论上就可以在application去对driver做读写。
register_chrdev(I2C_MAJOR,DEVICE_NAME,&i2c_fops)
2.因为我没有真的在application进行读写device的动作,所以我也不确
定这个程式码是不是真的ok呢?
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
Static int i2c_driver_demo_probe(struct i2c_client *client, const struct
i2c_device_id *id)
{
Return 0;
}
static int __devexit i2c_driver_demo_remove(struct i2c_client *client)
{
return 0;
}
static const truct i2c_device_id i2c_driver_demo_id[] = {
{“XXXX”,0},
{}
} ;
MODULE_DEVICE_TABLE(i2c, i2c_driver_demo_id);
int i2c_driver_demo_detect(struct i2c_client *client, struct i2c_board_info
*info)
{
struct i2c_adapter *adapter = client->adapter;
int vendor,device,revision;
if(!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
Return -ENODEV;
/*方法1:获取设备特定寄存器的值,该值要能反映出设备的信息,判断设
备,例如如下代码段
*/
vendor=i2c_smbus_read_byte_data(client,XXXX_REG_VENDOR);
if(vendor!=XXXX_VENDOR)
return-ENODEV;
device=i2c_smbus_read_byte_data(client,XXXX_REG_DEVICE);
if(device!=XXXX_DEVICE)
return -ENODEV;
revision = i2c_smbus_read_byte_data(client, XXXX_REG_REVISION);
if(revision != XXXX_REVISION)
return -ENODEV;
/*方法二:获取设备的CHIP_ID,判断设备,例如以下代码*/
}
/*0x60为I2C设备位址*/
static const unsigned short normal_i2c[] = {0x60 , I2C_CLIENT_END};
static struct i2c_driver i2c_driver_demo = {
.class = I2C_CLASS_HWMON,
.probe = i2c_driver_demo_probe,
.remove = __devexit_p(i2c_driver_demo_remove),
.ip_table = i2c_driver_demo_id,
.driver = {
.name = “XXXX”
.owner = THIS_MODULE,
},
.detect = i2c_driver_demo_detect,
.address_list = normal_i2c,
};
static int __init i2c_driver_demo_init(void)
{
return i2c_add_driver(&i2c_driver_demo);
}
module_init(i2c_driver_demo_init);
module_exit(i2c_driver_demo_exit);
MODULE_AUTHOR("anchor");
MODULE_DESCRIPTION("I2Cdevicedriverdemo");
MODULE_LICENSE("GPL");
补充说明:若I2C设备驱动不能在detect回调函数里访问硬件,可采用如下形式解决,例
如:
inti2c_driver_demo_detect(structi2c_client*client,structi2c_board_info*info){
structi2c_adapter*adapter=client->adapter;
if(2 == adapter->nr)
{ constchar*type_name="XXXX";
strlcpy(info->type,type_name,I2C_NAME_SIZE);
return0;
}else{
return-ENODEV;
}
}
作者: leolarrel (真.粽子无双)   2016-07-29 18:56:00
大大,您贴的code是示范如何在kernel里面使用i2c driver不是在app层app层读写i2c的范例http://goo.gl/Q7csfR .请注意,这只是范例,不保证会动但是他给了你一些方向去找资料研究
楼主: cutem (大少爷)   2016-07-29 23:18:00
其实您说的正是我疑惑的,newstyle i2c driver好像都不用写跟user space沟通的code,然后您给的例子就可以有作用。
作者: yvb   2016-07-30 00:33:00
没实际使用和追踪 i2c 的部分, 但简单看了一下, 猜测大概是被kernel下 drivers/i2c/i2c-dev.c 及该层相关程式包装好了,所以就只需要写 对硬件的操作 部分即可.没实际对照kernel code,这篇不知如何? http://goo.gl/2qVEUA
作者: fightforlive (学历无用论是屁)   2016-07-30 13:41:00
这是driver = =
楼主: cutem (大少爷)   2016-07-30 20:39:00
谢谢yvb大的指点、其实我想的和您差不多,只是手中没有设备只有桌机可以试一下程式片段,不然拿颗mcu挂上去,直接写code从user space去读取看看就知道了。new style i2c的网上的介绍其实看起来很简单,只是都没人提到和user space沟通部份的程式,一副好像注册完就ok的样子所以才会觉得疑惑。
作者: yvb   2016-07-30 23:12:00
不管 driver 是不是 new style, userspace 写法应该都一样吧?
楼主: cutem (大少爷)   2016-07-30 23:20:00
user spce都一样,但是driver内只要注册写完就能用这点我目前无法验证,所以才会满脑子疑惑。
作者: openeyes222 (睁大眼看)   2016-07-31 06:44:00
你必须要知道如何与i2c device沟通,这才是能用的内容。

Links booklink

Contact Us: admin [ a t ] ucptt.com