linux中i2c子系统代码结构详解

原创 2017年09月13日 15:17:39
本文介绍一下linux驱动代码中i2c子系统的驱动代码结构和使用方法,示例平台文件为高通msmXXXX平台
一,i2c子系统代码结构

i2c-core.c

1,使用bus_register进行总线注册

2,提供与具体硬件无关的操作逻辑供i2c-dev.c中使用
3,将操作逻辑通过EXPORT_SYMBOL导出到整个内核,供其他基于i2c的设备驱动调用
i2c-dev.c
实现i2c基本read、write功能,创建/dev/i2c-x节点
bus文件夹中的i2c-msm-v2.c
对i2c_core中物理层相关的操作进行实现,如clk配置、收发函数等等
二,i2c-dev中对i2c-croe的使用
i2c-dev.c中没有probe函数,在初始化函数中注册了各个设备对应的/dev/i2c-X节点。
static int __init i2c_dev_init(void)
{
	int res;

	res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);
	i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
	i2c_dev_class->dev_groups = i2c_groups;

	/* Keep track of adapters which will be added or removed later */
	res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);
	i2c_for_each_dev(NULL, i2cdev_attach_adapter);

	return 0;
}
i2cdev_attach_adapter函数中的get_free_i2c_dev会向i2c设备list添加一个新项。device_create会在/dev下创建节点。
static int i2cdev_attach_adapter(struct device *dev, void *dummy)
{
	struct i2c_adapter *adap;
	struct i2c_dev *i2c_dev;
	int res;


	adap = to_i2c_adapter(dev);


	i2c_dev = get_free_i2c_dev(adap);
	/* register this i2c device with the driver core */
	i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
				     MKDEV(I2C_MAJOR, adap->nr), NULL,
				     "i2c-%d", adap->nr);
	return 0;
}

之后可以在open函数中由次设备号获取相应i2c adapter
static int i2cdev_open(struct inode *inode, struct file *file)
{
	unsigned int minor = iminor(inode);
	struct i2c_client *client;
	struct i2c_adapter *adap;
	struct i2c_dev *i2c_dev;

	i2c_dev = i2c_dev_get_by_minor(minor);
	adap = i2c_get_adapter(i2c_dev->adap->nr);
	client = kzalloc(sizeof(*client), GFP_KERNEL);
	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
	client->adapter = adap;
	file->private_data = client;
	return 0;
}
读写函数可以有open时获取的i2c adapter去调用i2c-core中的传输函数完成通信。
static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
		loff_t *offset)
{
	char *tmp;
	int ret;
	struct i2c_client *client = file->private_data;
	tmp = kmalloc(count, GFP_KERNEL);
	ret = i2c_master_recv(client, tmp, count);
	kfree(tmp);
	return ret;
}
三,基于i2c子系统的的驱动对i2c-core 的使用
对于其它基于i2c协议的设备驱动,可以使用i2c_register_driver()函数即可将本驱动注册为i2c子系统中。
static int __init aw2013_init(void)
{
	return i2c_add_driver(&aw2013_driver);
}
module_init(aw2013_init);
i2c_add_driver函数最终会调用i2c_register_driver,其中会在i2c_client设备的list中增加一个新项,并完成设备注册。
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
	int res;
	driver->driver.owner = owner;
	driver->driver.bus = &i2c_bus_type;
	res = driver_register(&driver->driver);
	INIT_LIST_HEAD(&driver->clients);
	i2c_for_each_dev(driver, __process_new_driver);
	return 0;
}
可以使用probe返回的的i2c_client结构体调用i2c-core.c中EXPORT_SYMBOL得到的函数进行读写操作。
static int aw2013_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	psx93XX_t this = 0;
	int ret;
	if (this) {
		/* setup i2c communication */
		this->bus = client;
		i2c_set_clientdata(client, this);

		/* record device struct */
		this->pdev = &client->dev;
	....
	
	return ret;
}
static int write_register(psx93XX_t this, u8 address, u8 value)
{
	struct i2c_client *i2c = 0;
	char buffer[2];
	int returnValue = 0;

	buffer[0] = address;
	buffer[1] = value;
	returnValue = -ENOMEM;
	if (this && this->bus) {
		i2c = this->bus;

		returnValue = i2c_master_send(i2c, buffer, 2);
	}
	return returnValue;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。如本文对您有帮助,欢迎点赞评论。 举报

相关文章推荐

嵌入式Linux内核I2C子系统详解

1.1 I2C总线知识 1.1.1  I2C总线物理拓扑结构       I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SD...

Linux内核I2C子系统详解

1 I2C总线知识1.1 I2C总线物理拓扑结构 I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

嵌入式Linux之我行--内核I2C子系统详解

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。 共享资源,欢迎转载:h...

嵌入式Linux之我行--内核I2C子系统详解

嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux的朋友提供方便。如有错误之处,谢请指正。 共享资源,欢迎转载:h...

Linux内核I2C子系统驱动(三)

I2C子系统驱动(三)               当适配器加载到内核后,就针对具体设备编写I2C设备驱动。编写设备驱动有两种方法,一种是利用系统提供的i2c-d...

linux设备模型之I2C子系统

=============================== 本文系本站原创,欢迎转载! 转载请注明出处:http://blog.csdn.net/gdt_a20 ========...

linux内核I2C子系统学习

因为I2C的通信肯定至少要有2个芯片完成,所以它的驱动是由2大部分组成: 主芯片的i2c的驱动从芯片的i2c的驱动     注:万一选的都不支持咋办???(惨了,只能2个芯片的驱动...

Linux2.6 I2C子系统分析

在linux中iic是以子系统的方式存在,我们查看2.6.32.2的内核源代码结构: 在/drivers/iic目录下有algos busses chips文件夹,有i2c-core...

linux驱动之--I2C子系统

I2C编程框架 1. 入口,出口函数 module_init(at24c02_init) module_exit(at24c02_exit); MODULE_LICENSE(“GPL”); ...

Linux驱动子系统之I2C

转自:http://www.linuxidc.com/Linux/2011-11/47651.htm [概述] I2C总线是由Philips公司开发的两线式串行总线,这两根线为时钟线(SCL)和...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)