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驱动架构全面分析

I2C 概述   I2C是philips提出的外设总线.   I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程...
  • wangpengqi
  • wangpengqi
  • 2013年12月31日 11:04
  • 19628

I2C子系统驱动架构 - 驱动框架

文章系列I2C子系统驱动架构 - 简介I2C子系统驱动架构 - 驱动框架I2C子系统驱动架构 - 具体实现 基于linux内核4.6.3版本介绍 I2C驱动框架I2C驱动框架图如下所示,用户空间上...
  • l289123557
  • l289123557
  • 2016年07月03日 18:15
  • 4982

linux IO子系统和文件系统读写流程分析

以下内容的分析是基于2.6.32及其后的内核.我们在linux上总是要保存数据,数据要么保存在文件系统里(如ext3),要么就保存在裸设备里。我们在使用这些数据的时候都是通过文件这个抽象来访问的,操作...
  • lwj103862095
  • lwj103862095
  • 2014年07月29日 14:36
  • 5273

linux内核的I2C子系统详解2——关键结构体、关键文件

以下内容源于朱有鹏《物联网大讲堂》课程的学习,如有侵权,请告知删除。 3、I2C子系统的4个关键结构体 (1)struct i2c_adapter :I2C适配器 用来描述I2C...
  • oqqHuTu12345678
  • oqqHuTu12345678
  • 2017年12月17日 17:46
  • 53

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

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

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

转自http://www.embeddedlinux.org.cn/html/yingjianqudong/201303/17-2502.html 1.1 I2C总线知识 1.1.1  I...
  • yuzeze
  • yuzeze
  • 2016年07月08日 09:59
  • 211

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

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

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

——转自  http://www.embeddedlinux.org.cn/html/yingjianqudong/201303/17-2502.html 1.1 I2C总线知识 1.1....
  • hlzs_01
  • hlzs_01
  • 2014年06月11日 11:59
  • 397

Linux内核I2C子系统详解

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

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

1.1 I2C总线知识 1.1.1  I2C总线物理拓扑结构      I2C总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。 通信原理...
  • tianshiyalin
  • tianshiyalin
  • 2014年05月15日 00:20
  • 480
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux中i2c子系统代码结构详解
举报原因:
原因补充:

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