在 Linux 内核中,regmap 是一个通用的寄存器映射抽象层,用于简化对硬件寄存器(尤其是 I2C、SPI、MMIO 等设备)的访问。其核心思想是通过统一的 API 屏蔽底层总线差异,提供安全高效的寄存器操作。以下是 regmap 相关函数的实现原理和调用方法详解:
- Regmap 的核心设计
(1) 数据结构
struct regmap
核心结构体,包含寄存器位宽、缓存策略、总线操作等配置。
struct regmap_bus
定义底层总线操作(如 read/write),由具体总线驱动(如 I2C、SPI)实现。
struct regmap_config
配置参数(如寄存器位宽、缓存类型、读写回调等)。
(2) 核心功能
寄存器读写:regmap_read/regmap_write/regmap_bulk_read 等。
缓存机制:透明管理寄存器缓存(可选)。
并发控制:内置锁机制保证线程安全。
- 常用 Regmap 函数及调用方法
(1) 初始化 Regmap
I2C 设备示例
#include <linux/regmap.h>
#include <linux/i2c.h>
static const struct regmap_config my_regmap_config = {
.reg_bits = 8, // 寄存器地址位数(如 8 或 16)
.val_bits = 8, // 寄存器值位数
.max_register = 0xFF, // 最大寄存器地址
.cache_type = REGCACHE_RBTREE, // 缓存类型(可选)
};
static int my_probe(struct i2c_client *client) {
struct regmap *regmap;
regmap = devm_regmap_init_i2c(client, &my_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Regmap init failed\n");
return PTR_ERR(regmap);
}
// 将 regmap 存储到设备私有数据中
dev_set_drvdata(&client->dev, regmap);
return 0;
}
SPI 设备示例
regmap = devm_regmap_init_spi(spi_device, &my_regmap_config);
MMIO(内存映射 I/O)示例
SOC x模块寄存器访问:
regmap = devm_regmap_init_mmio(dev, mmio_base, &my_regmap_config);
(2) 寄存器读写操作
单寄存器读写
unsigned int reg_val;
int ret;
// 读取寄存器 0x10 的值
ret = regmap_read(regmap, 0x10, ®_val);
if (ret < 0) {
dev_err(dev,


被折叠的 条评论
为什么被折叠?



