kernel version:4.9.186
software platform:Qualcomm android 10
regmap机制引入屏蔽了I2C、SPI读写的细节,提高了驱动代码复用性。
一、regmap初始化
以I2C和SPI两个常用接口为例。
devm_regmap_init_i2c(i2c, config)
devm_regmap_init_spi(dev, config)
i2c为i2c_client对象指针;dev为spi_device对象指针;
config为regmap_config结构体对象,是regmap注册时的重要结构体。
函数返回值为struct regmap指针
二、regmap读写接口
regmap读写接口屏蔽了i2c和spi读写的具体细节,提供统一接口。
int regmap_write(struct regmap *map, unsigned int reg, unsigned int val);
int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val);
三、regmap释放
void regmap_exit(struct regmap *map);
四、wm8988驱动中regmap的使用
struct wm8988_priv {
struct regmap *regmap;
};
struct reg_default {
unsigned int reg;
unsigned int def;
};
static const struct reg_default wm8988_reg_defaults[] = {
{ 0, 0x0097 },
......
};
static bool wm8988_writeable(struct device *dev, unsigned int reg)
{
switch (reg) {
case WM8988_LINVOL:
......
return true;
default:
return false;
}
}
static const struct regmap_config wm8988_regmap = {
.reg_bits = 7, //寄存器地址位数
.val_bits = 9, //寄存器value位数
.max_register = WM8988_LPPB, //寄存器最大地址
.writeable_reg = wm8988_writeable,
.cache_type = REGCACHE_RBTREE, //cache方式,下面展开
.reg_defaults = wm8988_reg_defaults, //上电时寄存器默认值,使用cache会使用
//如果不设置,会尝试从硬件读取
.num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults), //reg_defaults的元素个数
};
static int wm8988_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8988_priv *wm8988;
......
wm8988->regmap = devm_regmap_init_i2c(i2c, &wm8988_regmap);
......
}
五、ragmap中的cache使用
enum regcache_type {
REGCACHE_NONE, //不使用缓存
REGCACHE_RBTREE, //使用红黑树,
REGCACHE_COMPRESSED, //使用LZO 压缩,
REGCACHE_FLAT, //本质上是数组,
};
经过regmap cache,提高访问效率,对于写操作,待cache存在一定数据量或者超出时间后写入物理寄存器,但降低实时性。
不经过regmap cache,对于写操作,立即写入物理寄存器,实时性好。
cache同步
/* Sync the register cache with the hardware. */
int regcache_sync(struct regmap *map);
/* regcache_sync_region: Sync part of the register cache with the hardware. */
int regcache_sync_region(struct regmap *map, unsigned int min, unsigned int max);