regmap子系统-之-readmap_read读7bit寄存器问题定位

regmap子系统是Linux内核中用于简化i2c、spi等设备寄存器访问的抽象层,提供统一的regmap_write和regmap_read接口。本文详细介绍了regmap子系统的框架、数据结构和工作原理,包括regmap、regmap_bus以及它们之间的关系。特别讨论了regmap_read在处理7bit寄存器读取时涉及的缓存和字节序问题,并通过实例展示了如何解决读取7bit寄存器值时遇到的挑战。
摘要由CSDN通过智能技术生成

regmap子系统框架介绍

regmap子系统的作用

随着linux内核的设备驱动越来越多,内核中有很多设备使用iic和spi等总线进行控制,尤其在hwmon子系统、regulator子系统中,大部分的设备基本上就是i2c、spi设备。在之前,如针对i2c设备我们通过接口i2c_transfer、i2c_master_send等接口进行读写操作,而针对spi 设备我们则通过接口spi_write、spi_sync、spi_async等接口实现读写操作。虽然直接调用i2c或spi设备的操作接口也很方便,但这些子系统中的读写接口中充斥着大量的i2c、spi操作,以及重复代码。
基于这些方面的考虑吧,linux内核提供了regmap子系统,而这些子系统针对spi、i2c设备的操作提供了一次抽象,对外提供对spi、i2c等设备相关寄存器的统一访问接口(regmap_write、regmap_read)等,而在regmap子系统内部再通过调用i2c、spi等设备的寄存器读写接口,实现对具体设备寄存器的读写操作。通过使用regmap子系统提供的接口,使hwmon、regulator子系统中基本上很少出现直接通过i2c、spi接口读写i2c/spi设备寄存器操作,取而代之的则是regmap_write/read等接口,同时regmap子系统提供缓存机制,也可以减小对设备的访问次数。

regmap子系统框架

regmap子系统主要包含regmap、regmap_bus两大部分,其中regmap表示一个慢速i/o设备的reg操作的映射、regmap_bus则表示一类慢速i/o设备的reg操作(如i2c设备可定义对应的regmap_bus,提供寄存器的读写操作接口、spi设备也定义对应的remap_bus,提供寄存器的读写接口)。

1、具体的regmap_bus,可提供对应的regmap创建接口,可由内核其他设备驱动模块调用(如我们上一专栏中使用regmap_init_i2c接口,创建i2c_client对应的regmap);
在这里插入图片描述

2、regmap子系统对外提供了regmap的寄存器读写接口,包含regmap_write、regmap_read、regmap_bulk_write、regmap_bulk_read等接口;
在这里插入图片描述

3、对于regmap而言,若该regmap是依附于具体regmap_bus,则借助regmap_bus的读写接口,实现对i/o设备的寄存器访问操作。
在这里插入图片描述

4、regmap内部提供了一些操作接口,实现对regmap_bus接口的封装调用(如包含对缓存的访问操作、在对寄存器进行写操作前,先对寄存器、值进行format操作,然后再调用remap_bus的读写接口进行寄存器的读写接口);
在这里插入图片描述
先使用regcache_read去读缓存的值,如果读失败,继续会调用map->reg_read去读实际寄存器的值,这个其实调用的还是regmap_bus得接口

	ret = map->bus->read(map->bus_context, map->work_buf,
			     map->format.reg_bytes + map->format.pad_bytes,
			     val, val_len);

5、借助于regmap_bus的读写接口,最终再调用具体外设的访问接口(如针对i2c设备,则调用i2c_transfer、i2c_master_send等接口实现对具体i2c设备的进行读写操作)。
在这里插入图片描述
在这里插入图片描述
针对regmap子系统而言,regmap_bus的实现由内核层完成、属于regmap子系统的一部分(目前实现了regmap_i2c、regmap_spi、regmap_mmio等regmap_bus),内核层通过实现remap_i2c、regmap_spi,只需要使用i2c、spi的regmap创建接口,然后就可使用regmap提供的操作接口regmap_write、regmap_read等,实现对这两类设备的访问操作。

regmap子系统数据结构与源代码

我们知道大多的传感器芯片(io扩展芯片、温度传感器、电源管理芯片、input设备、hwmon类型设备等等),基本上都是spi设备或者iic设备,而在这些设备的业务处理接口中充斥着大量的iic设备读写、spi设备读写的调用。因此linux内核子系统提供了regmap子系统,该子系统对外提供统一的读写接口,我们只需要在驱动的probe、remove(xxx_i2c_dev_probe、xxx_spi_dev_probe接口)接口中,完成regmap的创建,接着在具体的业务处理接口中直接调用regmap子系统提供的读写接口即可。

而regmap子系统主要的好处有两个:
1.提供统一的读写接口
2.提供缓存机制。
为了实现统一的读写接口,regmap子系统提供了regamp数据结构、regmap_bus数据结构、regcache_ops数据结构等,下面我们来简要说明下。

针对regmap子系统而言,其提供的主要数据结构抽象可理解如下(数据结构间的关联图如下所示):

1、regmap_bus数据结构,该数据结构即对具体总线控制器map的抽象(i2c、spi模块均完成了regmap_bus的定义,其中定义了对i2c设备、spi设备的统一读写接口);
drivers/base/regmap/regmap-i2c.c
在这里插入图片描述
在这里插入图片描述
2、regmap数据结构即为对具体设备的map(如一个i2c设备、spi设备均需要一个regmap),而regmap里则包含regcache相关的支持、该regmap关联的regmap、寄存器是否可读写等接口;
在regmap_init函数里来填充regmap结构体
在这里插入图片描述

3、为了在进行regmap初始化时,对regmap进行初始化,regmap也提供了数据结构regmap_config,实现对regmap的初始化操作。
在这里插入图片描述
regmap子系统的数据结构间的定义相对来说并不复杂,并且regmap子系统的设计相对来说也不算复杂(比如并没有提供remap_bus的注册接口,也不需要关注系统中已经定义了多少个regmap_bus以及系统中已经创建了多少个regmap等等),相比于设备驱动模型、pinctrl子系统、input子系统而言,算是较简单的子系统设计。针对regmap子系统,只要我们理解了regmap、regmap_bus的定义,基本上也可以大概了解regmap子系统的实现了。下面我们详细说明下。

在这里插入图片描述
regmap_bus的定义,其主要提供如下几个方面的内容:

Regmap bus的同步写接口;
Regmap bus的异步写接口;
Regmap bus的读接口;
Regmap bus的读写flag;
Regmap bus的寄存器、寄存器值的格式(大端、小端);
Regmap bus异步写相关的缓存申请接口等

regmap_bus的定义也是比较简单,只需提供regmap_bus对应总线控制器的访问方法即可。
在这里插入图片描述
regmp的定义,针对regmap的定义包含如下几个方面:

  • 该regmap对应的设备(即struct device *dev);
  • 该regmap对应的缓存;
  • 该regmap所绑定的regmap_bus(若该regmap不依附于regmap_bus,则需要单独提供读写接口);
  • 该regmap相关的异步写链表以及异步写相关的等待队列;
  • 该regmap相关的cache操作接口、是否支持cache操作等ÿ
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值