Regmsp
Linux下的很多开发都是针对寄存器, 为了方便进行管理
比如有一些产品更改寄存器的方法有多种, I2C, SPI等, 当进行更改的时候需要的工作量比较大
使用regmap模型可以进一步简化使用
重点是和寄存器打交道, 提供统一的接口
最主要的就是i2c, spi, mmio
实现
Linux内 核 将regmap框 架 抽 象 为regmap结 构 体 , 这 个 结 构 体 定 义 在 文 件drivers/base/regmap/internal.h中
有很多的函数以及table,这些需要驱动编写人员根据实际情况选择性的初始化
regmap的初始化通过结构体regmap_config来完成
regmap_config结构体就是用来初始化regmap的,这个结构体也定义在include/linux/regmap.h
struct regmap_config {
const char *name;
int reg_bits;
int reg_stride;
int pad_bits;
int val_bits;
bool (*writeable_reg)(struct device *dev, unsigned int reg);
bool (*readable_reg)(struct device *dev, unsigned int reg);
bool (*volatile_reg)(struct device *dev, unsigned int reg);
bool (*precious_reg)(struct device *dev, unsigned int reg);
regmap_lock lock;
regmap_unlock unlock;
void *lock_arg;
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
bool fast_io;
unsigned int max_register;
const struct regmap_access_table *wr_table;
const struct regmap_access_table *rd_table;
const struct regmap_access_table *volatile_table;
const struct regmap_access_table *precious_table;
const struct reg_default *reg_defaults;
unsigned int num_reg_defaults;
enum regcache_type cache_type;
const void *reg_defaults_raw;
unsigned int num_reg_defaults_raw;
u8 read_flag_mask;
u8 write_flag_mask;
bool use_single_rw;
bool can_multi_write;
enum regmap_endian reg_format_endian;
enum regmap_endian val_format_endian;
const struct regmap_range_cfg *ranges;
unsigned int num_ranges;
};
reg_bits:寄存器地址位数,必填字段。reg_stride:寄存器地址步长。val_bits:寄存器值位数,必填字段。read_flag_mask:读标志掩码。write_flag_mask:写标志掩码。
regmap支持多种物理总线,比如I2C和SPI,我们需要根据所使用的接口来选择合适的regmap初始化函数
struct regmap * regmap_init_spi(struct spi_device *spi,const struct regmap_config *config)
spi:需要使用regmap的spi_device。config:regmap_config结构体,需要程序编写人员初始化一个regmap_config实例,然后将其地址赋值给此参数。返回值:申请到的并进过初始化的regmap。实际就是把结构体和标准的驱动进行绑定
struct regmap*regmap_init_i2c(struct i2c_client *i2c,const struct regmap_config *config)
i2c:需要使用regmap的i2c_client。config:regmap_config结构体,需要程序编写人员初始化一个regmap_config实例,然后将其地址赋值给此参数。
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val)
map:要操作的regmap。reg:要读的寄存器。val:读到的寄存器值。返回值:0,读取成功;其他值,读取失败。
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val)
map:要操作的regmap。reg:要写的寄存器。val:要写的寄存器值。
int regmap_update_bits (struct regmap *map, unsigned int reg,unsigned int mask,unsigned int val)
map:要操作的regmap。reg:要操作的寄存器。mask:掩码,需要更新的位必须在掩码中设置为1。val:需要更新的位值。返回值:0,写成功;其他值,写失败。
int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,size_t val_count)
读取多个寄存器的值, map:要操作的regmap。reg:要读取的第一个寄存器。val:读取到的数据缓冲区。val_count:要读取的寄存器数量。
int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,size_t val_count)
map:要操作的regmap。reg:要写的第一个寄存器。val:要写的寄存器数据缓冲区。val_count:要写的寄存器数量。返回值:0,写成功;其他值,读失败。
标准的SPI驱动,其中第21行将寄存器的地址bit7置1,表示这是一个读操作。当我们使用regmap的时候就不需要手动将寄存器地址的bit7置1,在初始化regmap_config的时候直接将read_flag_mask设置为0X80即可