diff --git a/Software/Development/OperatingSystem/Linux/Kernel/Modules/RegMap/RegMap_机制.md b/Software/Development/OperatingSystem/Linux/Kernel/Modules/RegMap/RegMap_机制.md new file mode 100644 index 0000000..56e1149 --- /dev/null +++ b/Software/Development/OperatingSystem/Linux/Kernel/Modules/RegMap/RegMap_机制.md @@ -0,0 +1,99 @@ +# RegMap 机制 + +## 1.概要 + +regmap 机制是在 Linux 3.1 加入进来的特性。主要目的是减少慢速 I/O 驱动上的重复逻辑,提供一种通用的接口来操作底层硬件上的寄存器。其实这就是内核做的一次重构。regmap 除了能做到统一的 I/O 接口,还可以在驱动和硬件 IC 之间做一层缓存,从而能减少底层 I/O 的操作次数。 + +为了让慢速 I/O 能够专注于自身的逻辑,内核把 SPI, I2C 等总线操作方式全部封装在 regmap 里,这样驱动若要做 I/O 操作,直接调用 regmap 的函数就可以了。 + +使用 regmap 机制进行总线访问的基本流程如下: + +1. 配置 regmap_config 结构体; +2. 调用 regmap_init 类方法进行初始化; +3. 调用 regmap_write/regmap_read 方法进行读写; +4. 退出时调用 regmap_exit 释放资源。 + +regmap 机制的主要 API 声明在 文件中。 + +## 2.struct regmap_config + +```cpp +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; + + unsigned long read_flag_mask; + unsigned long 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; +}; +``` + +## 2.I2C + +主要调用 devm_regmap_init_i2c() 方法来对 remap 进行初始化。 + +**函数原型:** + +函数原型如下: + +```cpp +#include +struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config *config); +``` + +**返回值:** + +成功返回有效的 struct regmap 指针,失败返回 NULL。可以用 IS_ERR() 来判断结果。 + +## 3.SPI + +主要调用 devm_regmap_init_spi() 方法来对 remap 进行初始化。 + +**函数原型:** + +函数原型如下: + +```cpp +#include +struct regmap *devm_regmap_init_spi(struct spi_device *spi, const struct regmap_config *config); +``` + +**返回值:** + +成功返回有效的 struct regmap 指针,失败返回 NULL。可以用 IS_ERR() 来判断结果。