devm_regmap_init_i2c

内核在3.1版本加入了regmap模块,主要是给I2C,SPI总线的读写提供一个统一的接口,后来陆续添加了以下接口的支持:
1. 支持SPMI,MMIO
2.Spinlock和客制化lock机制
3.Cache支持
4.字节序转换
5.寄存器范围检查
6.IRQ支持
7.只读和只写寄存器
8.Precious寄存器和volatile寄存器
9.寄存器页
devm_regmap_init_i2c_第1张图片

devm_regmap_init_i2c_第2张图片
devm_regmap_init_i2c_第3张图片


两个最重要的结构体struct regmap_config和struct regmap:
struct regmap_config: 与设备相关的寄存器信息,其成员如下:

reg_bits: 设备寄存器的位数,若是1字节寄存器,则设置为8
val_bits: 设备寄存器设置的值的位数
writeable_reg: 当寄存器写入时,会调用该函数,一般是用户自定义id。若寄存器不可写,该函数返回false,这是单个寄存器的写操作,且是可选的。
wr_table: 若驱动代码未提供writeable_reg回调(如本实例所示),则regmap会在进行写操作前检查该wr_table。若是寄存器地址处于wr_table所提供的地址范围之内,则进行写操作。这个也是可选的,也就是说驱动可忽略它的定义并将它设置为NULL。
--- yes_rangs: 处于该地址范围内表示可用地址
--- n_yes_rangs: 上面范围内地址的数量
--- no_rangs: 处于该地址范围内表示不可用地址
--- n_no_rangs: 上面范围内地址的数量

readable_reg: 这个和writeable_reg类似,只不过针对的是读操作。
rd_table: 这个与wr_table类似,针对的是读操作。
volatile_reg: 这个与writeable_reg类似,只不过针对的是cache的写和读操作。
volatile_table: 若是驱动没有提供volatile_reg回调,则regmap会检查寄存器是否为volatile,若寄存器地址位于volatile_table范围内,则不做cache操作。这也是可选的,驱动可忽略它的定义并设置它为NULL。
lock: 用户自定义回调,在启动读或写操作前调用,函数会获取一个锁并返回。这也是可选的,若没有提供该函数,则regmap将使用自己的锁机制。
unlock:用户自定义回调函数,用于解锁,解的锁是前面lock申请的。这也是可选的,若未提供,则会使用regmap内部锁机制。
lock_arg: 传递给lock和unlock回调函数的参数
fast_io: 若没有自定义lock和unlock锁机制,则regmap内部使用互斥来做锁或解锁。若想要regmap使用自旋锁spinlock,则fast_io应该设置为true,否则,regmap会使用基于mutex的锁。
max_register: 在做读写之前,regmap检查寄存器地址数是否小于max_register,且只有当寄存器地址数小于该值时,才会进行读写操作。
read_flag_mask: 一般在spi或i2c中,在首个字节中的首位表示读写位,该mask在寄存器值的高字节中设置。
write_flag_mask:该mask也是设置寄存器值的最高字节。

如上实例所示,regmap_config配置传到regmap_init中,regmap_init创建一个regmap结构体并返回,它将在以后的读写操作中使用。

devm_regmap_field_alloc:  申请并初始化寄存器字段
struct regmap_field *devm_regmap_field_alloc(struct device *dev, struct regmap *regmap, struct reg_field reg_field)
dev --> 需要交互的设备
regmap --> 寄存器字段所在的regmap bank
reg_field --> 初始化的寄存器字段值
返回成功,则返回一个指向regmap_filed结构的指针。失败在返回ERR_PTR(),同时会自动回收regmap_filed。

devm_regmap_init_i2c_第4张图片
读寄存器:

从单个寄存器中读取值:
devm_regmap_init_i2c_第5张图片

参考文档

你可能感兴趣的:(LINUX)