驱动开发学习20250513

regmap API——寄存器映射

引入regmap API的原因:为了分解和统一内核开发人员访问SPI/I2C设备的方式

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 (*voltileable_reg)(struct device *dev,unsigned int reg);
	bool (*preciousable_reg)(struct device *dev,unsigned int reg);
	regmap_lock lock;
	regmap_unlock lock;
	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_raw;
	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;
};
  • voltileable_reg:如果寄存器为易失性的,该函数返回true,然后对寄存器执行直接读写;如果寄存器为非易失性的,返回false,缓存用于读取操作,在写入时写入缓存
  • writeable_reg:可选回调函数,如果使用,在写入寄存器之前,自动调用该函数检查寄存器是否可以写入
  • wr_table:不使用writeable_reg函数时,可以使用regmap_access_table,该函数包含yes_range(可写入)和no_range(不可写入)字段,两者都指向struct regmap_range

regmap_config初始化

static const struct regmap_config regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = LM3553_REG_MAX,
	.readable_reg = lm3553_readable_register,
	.volatile_reg = lm3553_volatile_register,
	.precious_reg = lm3553_precious_register,
};

regmap 初始化

  1. SPI初始化
    设置regmap,
    struct regmap * regmap_init_spi(struct spi_device *spi, const struct regmap_config);
  • 输入参数:struct spi_device表示与之交互的设备,
    const strcut regmap_config表示regmap配置
  • 返回值:成功时返回指向分配的struct regmap 指针,出错时返回ERR_PTR()
  1. I2C初始化
    struct regmap * regmap_init_i2c(struct i2c_client *i2c, const struct regmap_config);
  • 输入参数:struct i2c_client表示交互的I2C设备,
    const struct regmap_config表示regmap配置
  • 返回值:成功时返回指向分配的struct regmap 指针,出错时返回ERR_PTR()

设备访问函数

  1. int regmap_write(struct regmap *map, unsigned int reg, unsigned int *val);
    将数据写入设备
  • 若寄存器地址小于等于max_register,则写操作会执行
  • 否则将返回无效I/O错误(-EIO),此时调用writeable_reg,该函数执行前必须返回true,如果返回false,则返回EIO,写操作停止
  • 如果配置了wr_table,结果如下:
    如果在no_range内,返回-EIO;
    如果在yes_range内,执行下一步
    如果不在yes_range和no_range内,返回-EIO,操作中断
    如果cache_type != REGCACHE_NONE,则启动缓存。此时首先更新缓存项,之后执行到硬件的写操作,否则不执行缓存操作
    如果有reg_write,则用它执行写入操作
  1. int regmap_write(struct remap *map, unsigned int reg, unsigned int *val);

  2. int regmap_update_bits(struct regmap *map, unsigned int reg, unsigned int *mask, unsigned int val);
    需要更新的位必须在掩码中设置为1,相应的位应该设置为val中的值
    eg:将第一位和第三位置1,掩码为0b00000101,值为0bxxxxx1x1
    要清除第七位,掩码为0b01000000,值为0bx0xxxxxx

  3. int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, int num_regs);
    向设备写入多个寄存器

  4. regmap_bulk_read()和regmap_bulk_write()用于从设备读取多个寄存器和向设备写入多个寄存器,可被用于处理大块数据。
    int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val, size_t val_count);
    int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, size_t val_count);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值