Linux下I2C驱动框架: I2C驱动框架与I2C总线驱动(即I2C控制器)

本文详细介绍了在Linux环境下开发I2C接口器件驱动,特别是关注I2C驱动框架和I2C总线驱动(控制器驱动),包括I2C总线驱动结构、注册注销方法以及I2C设备驱动的角色。着重指出I2C总线驱动通常由半导体厂商提供,用户主要关注I2C设备驱动的编写。
摘要由CSDN通过智能技术生成

一.  简介

现在,我们来学习一下如何在 Linux 下开发 I2C 接口器件 驱动,重点是学习 Linux 下的 I2C 驱动框架,按照指定的框架去编写 I2C 设备驱动。
本文来了解以下 Linux下 I2C 驱动框架,框架下的  i2C总线驱动(也就是I2C控制器驱动)。

二.  Linux下I2C驱动实验: I2C驱动框架与I2C总线驱动

1.  Linux I2C 驱动框架简介

回想一下我们在裸机篇中是怎么编写 AP3216C 驱动的,我们编写了四个文件: bsp_i2c.c
bsp_i2c.h bsp_ap3216c.c bsp_ap3216c.h 。其中前两个是 I.MX6U IIC 接口驱动,后两个文 件是 AP3216C 这个 I2C 设备驱动文件。相当于有两部分驱动:
(1)  I2C 主机驱动。
(2)  I2C 设备驱动。
对于 I2C 主机驱动,一旦编写完成就不需要再做修改,其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想,因此, Linux 内核也将 I2C 驱动分为两部分:
(1)  I2C 总线驱动, I2C 总线驱动就是 SOC I2C 控制器驱动,也叫做 I2C 适配器驱动。
(2)  I2C 设备驱动, I2C 设备驱动就是针对具体的 I2C 设备而编写的驱动。

2. I2C 总线驱动(I2C控制器驱动)

首先来看一下 I2C 总线,在讲 platform 的时候就说过, platform 是虚拟出来的一条总线,目的是为了实现总线、设备、驱动框架。
对于 I2C 而言,不需要虚拟出一条总线,直接使用 I2C 总线即可。 I2C 总线驱动重点是 I2C 适配器 ( 也就是 SOC I2C 接口控制器 ) 驱动。

(1)  I2C总线驱动的结构体

这里要用到两个重要的数据结构:i2c_adapter i2c_algorithmLinux 内核将 SOC I2C 适配器 ( 控制器 ) 抽象成 i2c_adapter i2c_adapter 结构体定义在 include/linux/i2c.h 文件中,结构体内容如下:
struct i2c_adapter {
	struct module *owner;
	unsigned int class;		  /* classes to allow probing for */
	const struct i2c_algorithm *algo; /* the algorithm to access the bus */
	void *algo_data;

	/* data fields that are valid for all devices	*/
	struct rt_mutex bus_lock;

	int timeout;			/* in jiffies */
	int retries;
	struct device dev;		/* the adapter device */

	int nr;
	char name[48];
	struct completion dev_released;

	struct mutex userspace_clients_lock;
	struct list_head userspace_clients;

	struct i2c_bus_recovery_info *bus_recovery_info;
	const struct i2c_adapter_quirks *quirks;
};

4 行, i2c_algorithm 类型的指针变量 algo ,对于一个 I2C 适配器,肯定要对外提供读 API 函数,设备驱动程序可以使用这些 API 函数来完成读写操作。 i2c_algorithm 就是 I2C 配器与 IIC 设备进行通信的方法。
i2c_algorithm 结构体定义在 include/linux/i2c.h 文件中,内容如下 ( 删除条件编译 )
 struct i2c_algorithm {
......
    int (*master_xfer)(struct i2c_adapter *adap,
    struct i2c_msg *msgs,
    int num);
    int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
    unsigned short flags, char read_write,
    u8 command, int size, union i2c_smbus_data *data);

 /* To determine what the adapter supports */
   u32 (*functionality) (struct i2c_adapter *);
......
};

3 行, master_xfer 就是 I2C 适配器的传输函数,可以通过此函数来完成与 IIC 设备之间的通信。
6 行, smbus_xfer 就是 SMBUS 总线的传输函数。
综上所述,I2C 总线驱动,或者说 I2C 适配器驱动的主要工作就是初始化 i2c_adapter 结构体变量,然后设置 i2c_algorithm 中的 master_xfer 函数。

(2)  I2C 总线驱动注册与注销

完成以后通过 i2c_add_numbered_adapter函数 或 i2c_add_adapter函, 这两个函数向系统注册设置好的 i2c_adapter ,这两个函数的原型如下:
int i2c_add_adapter(struct i2c_adapter *adapter)
int i2c_add_numbered_adapter(struct i2c_adapter *adap)

这两个函数的区别在于, i2c_add_adapter 函数使用动态的总线号,而 i2c_add_numbered_adapter 函数使用静态总线号。函数参数和返回值含义如下:

adapter adap :要添加到 Linux 内核中的 i2c_adapter ,也就是 I2C 适配器。
返回值: 0 ,成功;负值,失败。

如果要删除 I2C 适配器的话使用 i2c_del_adapter 函数即可,函数原型如下:
void i2c_del_adapter(struct i2c_adapter * adap)
函数参数和返回值含义如下:
adap :要删除的 I2C 适配器。
返回值: 无。

三.  总结

关于 I2C 的总线 ( 控制器或适配器 ) 驱动就讲解到这里,一般 SOC I2C 总线驱动都是由半导体厂商编写的,比如, I.MX6U I2C 适配器驱动 NXP 已经编写好了,这个不需要用户去编 写。
因此, I2C 总线驱动对我们这些 SOC 使用者来说是被屏蔽掉的,我们只要专注于 I2C 设备驱 动即可。除非你是在半导体公司上班,工作内容就是写 I2C 适配器驱动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值