一、Regmap简介
基于代码复用的原则,Linux 内核引入了 regmap 模型, regmap 将寄存器访问的共同逻辑抽 象出来,驱动开发人员不需要再去纠结使用 SPI 或者 I2C 接口 API 函数,统一使用 regmapAPI函数。这样的好处就是统一使用 regmap,降低了代码冗余,提高了驱动的可以移植性。
regmap 模型的重点在于:
通过
regmap
模型提供的统一接口函数来访问器件的寄存器,
SOC
内部的寄存器也可以使
用
regmap
接口函数来访问。
regmap
是
Linux
内核为了减少慢速
I/O
在驱动上的冗余开销,提供了一种通用的接口来操作硬件寄存器。另外,regmap
在驱动和硬件之间添加了
cache
,降低了低速
I/O
的操作次数,提高了访问效率,缺点是实时性会降低。
以下情况会使用regmap
以下情况会使用regmap
①、硬件寄存器操作,比如选用通过
I2C/SPI
接口来读写设备的内部寄存器,或者需要读写 SOC
内部的硬件寄存器。
②、提高代码复用性和驱动一致性,简化驱动开发过程。
③、减少底层
I/O
操作次数,提高访问效率。
二、Regmap
驱动框架
regmap 框架分为三层:
①、底层物理总线:
regmap
就是对不同的物理总线进行封装,目前
regmap
支持的物理总线有 i2c
、
i3c
、
spi
、
mmio
、
sccb
、
sdw
、
slimbus
、
irq
、
spmi
和
w1
。
②、
regmap
核心层,用于实现
regmap
,我们不用关心具体实现。
③、regmapAPI 抽象层,regmap 向驱动编写人员提供的 API 接口,驱动编写人员使用这些API 接口来操作具体的芯片设备,也是驱动编写人员重点要掌握的。
三、regmap
结构体
Linux
内 核 将
regmap
框 架 抽 象 为
regmap 结 构 体 , 这 个 结 构 体 定 义 在 文 件 drivers/base/regmap/internal.h 中
四、regmap_config 结构体
四、regmap_config 结构体
顾名思义,
regmap_config
结构体就是用来初始化
regmap
的,这个结构体也定义在 include/linux/regmap.h 文件中
五、Regmap
操作函数
1、Regmap 申请与初始化
SPI
接口初始化函数为 regmap_init_spi
struct regmap * regmap_init_spi(struct spi_device *spi,const struct regmap_config *config)
I2C
接口的
regmap
初始化函数为
regmap_init_i2c
struct regmap * regmap_init_i2c(struct i2c_client *i2c,const struct regmap_config *config)
退出驱动的时候需要释放掉申请到的
regmap
,不管是什么接口,全部使用
regmap_exit
这 个函数来释放 regmap
void regmap_exit(struct regmap *map)
2
、
regmap
设备访问
API 函数
regmap 提供了最核心的两个读写寄存器操作函数: regmap_read 和 regmap_write 。
regmap 提供了最核心的两个读写寄存器操作函数: regmap_read 和 regmap_write 。
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
修改寄存器指定的bit函数:regmap_update_bits
int regmap_update_bits (struct regmap *map,unsigned int reg,unsigned int mask,unsigned int val)
读取多个寄存器的值函数:regmap_bulk_read
int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,size_t val_count)
六、regmap_config 掩码设置
需重点关注结构体 regmap_config中的两个关于掩码的成员变量:read_flag_mask 和 write_flag_mask