Regmap子系统之Regmap使用

一、regmap_config用来配置regmap对象

常见的结构体成员如下:

int reg_bits;// 寄存器地址的位数

int val_bits;// 存储寄存器的位数

unsigned int max_register; // 最大寄存器地址,防止访问越界

int (*reg_read)(void *context, unsigned int reg, unsigned int *val);//读寄存器

int (*reg_write)(void *context, unsigned int reg, unsigned int val);//写寄存器

u8 read_flag_mask;// 读寄存器掩码

u8 write_flag_mask;// 写寄存器掩码

二、regmap初始化

Regmap支持多种硬件接口的初始化API,最常用的为I2C和SPI,初始化函数原型如下:

regmap_init_i2c(struct i2c_client *i2c, struct regmap_config *config);   

regmap_init_spi(struct spi_device *spi, strcut regmap_config *config);

regmap_init_spi()"函数接受一个指向SPI设备的指针(spi)和Regmap配置参数(config)。它首先分配内存以存储Regmap对象,然后设置Regmap的相关字段和操作函数,以便与SPI总线进行通信。最后,函数返回指向初始化的Regmap对象的指针

三、使用regmap

配置和注册regmap实例后,就可以调用regmap提供的read/write/update等操作了。常用的操作函数原型如下:

//向单个reg写入val

int regmap_write(struct regmap *map, int reg, int val);   

//向单个reg写入指定长度的数据,数据存放在val中

int regmap_raw_write(struct regmap *map, int reg, void *val, size_t val_len);

// 写多个reg

int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,size_t val_count);

// 直接写入reg,不经过regmap cache

int regmap_multi_reg_write_bypassed(struct regmap *map, const struct reg_sequence *regs,int num_regs);

//写多个reg,并立即刷新cache写入

int regmap_raw_write_async(struct regmap *map, unsigned int reg,const void *val, size_t val_len);

// 读取单个reg的数据到val中/

int regmap_read(struct regmap *map, int reg, int *val);

// 读取单个reg中指定长度的数据

int regmap_raw_read(struct regmap *map, int reg, void *val, size_t val_len);

// 读取从reg开始之后val_count个寄存器的数据到val中

int regmap_bulk_read(struct regmap *map, int reg, void *val, size_t val_count);

// 更新reg寄存器中mask指定的位

int regmap_update_bits(struct regmap *map, int reg, int mask, int val);

//写入寄存器值指定bit *

int regmap_write_bits(struct regmap *map, unsigned int reg, unsigned int mask, unsigned int val);

// 设置读写寄存器不通过cache模式而是bypass模式,读写立即生效,一般在audio等确保时序性驱动中用到

void regcache_cache_bypass(arizona->regmap, true);

四、释放regmap

在驱动注销时释放已注册的regmap。

void regmap_exit(struct regmap *map);

<think>我们正在讨论regmap框架。根据引用内容,regmapLinux内核中的一个子系统,它提供了一种统一的接口来访问硬件设备的寄存器,无论底层是通过I2C、SPI还是其他总线。这样可以简化驱动开发,因为开发者不需要为不同的总线编写重复的寄存器访问代码。 从引用[1]中可以看到,使用regmap的步骤: 1. 定义一个regmap配置结构体(struct regmap_config),指定寄存器的位数、值的位数、最大寄存器地址、缓存类型等。 2. 初始化regmap,例如通过I2C客户端和配置结构体来初始化regmap_init_i2c(i2c_client, &xxx_regmap_config); 3. 使用regmap提供的读写操作函数:regmap_read()和regmap_write()等。 引用[2]和[3]提到了regulator_config结构体,其中包含一个regmap指针。这表明在调节器(regulator)驱动中,可以使用regmap来访问寄存器。 引用[4]提到在描述调节器的静态信息(struct regulator_desc)时,会包含操作函数集(struct regulator_ops)以及使用regmap时相应的寄存器和位图信息。 因此,regmap框架的核心是提供一种抽象,使得驱动程序可以以总线无关的方式访问寄存器,同时提供缓存机制来优化访问效率。 下面我将详细介绍regmap框架。</think>### Regmap框架详解 RegmapLinux内核中用于**统一寄存器访问**的抽象层框架,主要解决不同总线(I2C/SPI/MMIO等)寄存器操作差异性问题。其核心设计是通过标准化接口封装底层硬件访问细节,提供统一的寄存器读写API。 #### 核心组件 1. **`struct regmap_config`** [^1][^4] ```c struct regmap_config { int reg_bits; // 寄存器地址位数(如I2C常用8位) int val_bits; // 寄存器值位数(如16位数据) unsigned int max_register; // 最大寄存器地址 enum regcache_type cache_type; // 缓存类型(如REGCACHE_RBTREE) bool volatile_reg; // 易失性寄存器标识 bool readable_reg; // 可读寄存器标识 }; ``` 作用:描述寄存器映射的**静态特征**,包括地址/数据位宽、缓存策略等关键参数。 2. **`struct regmap`** [^1][^2] - 核心操作句柄,通过`regmap_init_i2c()`/`regmap_init_spi()`等总线特定接口初始化 - 封装了底层物理总线的访问方法 3. **操作接口** - 寄存器读:`regmap_read(regmap, reg_addr, &value)` - 寄存器写:`regmap_write(regmap, reg_addr, value)` - 批量操作:`regmap_bulk_read()`/`regmap_bulk_write()` #### 工作流程 1. **初始化配置** [^1] ```c // 定义寄存器映射配置 static const struct regmap_config xxx_regmap_config = { .reg_bits = 8, .val_bits = 16, .max_register = 0xFF, .cache_type = REGCACHE_FLAT, }; // 关联I2C设备 regmap = regmap_init_i2c(i2c_client, &xxx_regmap_config); ``` 2. **寄存器操作** [^1] ```c // 读取寄存器0x20的值 u32 reg_val; regmap_read(regmap, 0x20, &reg_val); // 向寄存器0x30写入0xABCD regmap_write(regmap, 0x30, 0xABCD); ``` 3. **集成到驱动框架** [^2][^3] ```c struct regulator_config { struct regmap *regmap; // 关键集成点 struct device *dev; const struct regulator_init_data *init_data; }; ``` 在regulator等子系统中,通过`regulator_config.regmap`字段传递regmap实例。 #### 核心优势 1. **总线抽象** - 同一套代码支持I2C/SPI/MMIO等多种总线 - 驱动程序无需关注底层物理传输细节 2. **缓存机制** [^1][^4] - 支持REGCACHE_RBTREE/REGCACHE_FLAT等缓存策略 - 减少实际硬件访问次数 - 对易失性寄存器(`volatile_reg`)自动绕过缓存 3. **安全防护** - 自动校验寄存器地址范围(`max_register`) - 验证读写权限(`readable_reg`等) 4. **调试支持** - 通过sysfs实时监控寄存器访问 - 支持寄存器内容快照分析 #### 典型应用场景 1. **电源管理(regulator)** [^2][^3] ```c // 在regulator驱动中通过regmap设置使能位 regmap_write(act8865->regmap, ACT8865_ENABLE_REG, 0x01); ``` 2. **传感器驱动** - 统一访问温度/湿度传感器的校准寄存器 3. **编解码器驱动** - 配置音频芯片的音量/均衡器寄存器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值