一. 简介
I2C
适配器驱动
SOC
厂商已经替我们编写好了。
我们需要做的就是编写具体的设备驱动。
接下来,我们就来学习一下
I2C
设备驱动的详细编写流程。
本文来学习I2C设备驱动开发中,设备节点信息如何描述。分为两种情况:
(1) 无设备树,如何描述设备节点信息。
(2) 有设备树文件时,如何描述设备节点信息。
二. I2C 设备驱动编写流程:设备节点信息描述
本文分别学习一下,无设备树文件的情况与有设备树文件支持的情况下,I2C设备节点信息分别是如何描述。
1. 未使用设备树的时候
首先肯定要描述
I2C
设备节点信息,先来看一下没有使用设备树的时候是如何在
BSP
里面描述
I2C
设备信息的。
在未使用设备树的时候,需要在
BSP
里面使用
i2c_board_info
结构体来描
述一个具体的
I2C
设备。
i2c_board_info
结构体如下:
struct i2c_board_info {
char type[I2C_NAME_SIZE];
unsigned short flags;
unsigned short addr;
void *platform_data;
struct dev_archdata *archdata;
struct device_node *of_node;
struct fwnode_handle *fwnode;
int irq;
};
type 和 addr 这两个成员变量是必须要设置的,一个是 I2C 设备的名字,一个是 I2C 设备的器件地址。
打开
arch/arm/mach-imx/mach-mx27_3ds.c
文件,此文件中关于
OV2640
的
I2C
设备信息描述如下:
static struct i2c_board_info mx27_3ds_i2c_camera = {
I2C_BOARD_INFO("ov2640", 0x30),
};
上面的OV2640
的
I2C
设备信息 中使用 I2C_BOARD_INFO
来完成
mx27_3ds_i2c_camera
的初始化工作,
I2C_BOARD_INFO
是一个宏,定义如下:
#define I2C_BOARD_INFO(dev_type, dev_addr) \
.type = dev_type, .addr = (dev_addr)
可以看出,
I2C_BOARD_INFO
宏其实就是设置
i2c_board_info
的
type
和
addr
这两个成员
变量,因此,上面的代码
的主要工作就是设置
I2C
设备名字为
ov2640
,
ov2640
的器件地
址为
0X30
。
我们可以在 Linux 源码里面全局搜索 i2c_board_info,会找到大量以 i2c_board_info 定义的
I2C 设备信息,这些就是未使用设备树的时候 I2C 设备的描述方式,当采用了设备树以后,就不
会再使用 i2c_board_info 来描述 I2C 设备了。
2. 使用设备树的时候
使用设备树的时候,
I2C
设备信息只要(在设备树文件下)创建相应的I2C设备节点就行了。
比如,
NXP
官方的
EVK
开发
板在
I2C1
上接了
mag3110
这个磁力计芯片,因此,必须在
i2c1
节点下创建
mag3110
子节点,然
后,在这个子节点内描述
mag3110
这个芯片的相关信息。
打开
imx6ull-14x14-evk.dts
这个设备树
文件,然后找到如下内容:
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
mag3110@0e {
compatible = "fsl,mag3110";
reg = <0x0e>;
position = <2>;
};
...................
};
第
7~11
行,向
i2c1
添加
mag3110
子节点。
第 7 行 “mag3110@0e” 是子节点名字,“@” 后面的 “0e” 就是 mag3110 的 I2C 器件地址。
第 8 行设置 compatible 属性值为“fsl,mag3110”。
第 9 行的 reg 属性也是设置 mag3110 的器件地址的,因此,值为 0x0e。I2C 设备节点的创建重点 是 compatible 属性和 reg 属性的设置,一个用于匹配驱动,一个用于设置器件地址。