SPMI 概览

概念

系统电源管理接口 (SPMI) 是一种总线,最多可让 4 个控制器设备与最多 16 个目标设备通信,以完成不同的电源管理任务。每个控制器和目标设备都有一个由 8 位寄存器组成的地址空间,最多 16 位,其功能由硬件供应商定义。

虽然不属于 SPMI 规范,但一些具有多种功能的目标设备可以进一步划分为子目标设备,这些子目标设备对目标地址空间的查看权限有限。对设备功能进行逻辑分离后,其软件驱动程序也可以分离。

编写 SPMI 客户端驱动程序

从客户端驱动程序使用 SPMI 取决于您要使用的设备是目标还是子目标。无论哪种情况,要使用的 FIDL 协议都是 fuchsia.hardware.spmi.Device。

目标设备

首先更新板级驱动程序,以便 SPMI 控制器驱动程序为您的目标添加一个节点。在设备树平台上,这会涉及添加新节点,例如:

#include "sdk/lib/driver/devicetree/visitors/drivers/spmi-controllers/spmi/spmi.h"

spmi@0xffff0000 {
    /* The new node is below */
    $TARGET_DEVICE_TYPE@$TARGET_ID {
        reg = <$TARGET_ID_0 SPMI_USID>, <$TARGET_ID_1 SPMI_USID>;
        reg-names = "$TARGET_NAME_0", "$TARGET_NAME_1";
    };
};

一个目标可以有多个 reg 条目(最多 16 个),从而允许单个设备树节点表示多个 SPMI 目标 (SID)。

您的驱动程序应连接到 fuchsia.hardware.spmi.TargetService,并在其组件清单中为其添加一个条目。SPMI 控制器驱动程序将为每个目标添加一个节点。SPMI 访问器将为您的设备生成一个复合节点规范,其中每个目标都有一个父级,并为每个父级使用以下绑定属性:

属性 可选 用途
fuchsia.hardware.spmi.TargetService 否 SPMI 目标服务。
fuchsia.ID 否 SPMI 目标 ID。
fuchsia.NAME 是 目标的字符串名称。在 devicetree 平台上,这是根据目标节点的 reg-names 属性生成的。如果定义了多个目标,则会使用 reg-names 中的相应名称。

子目标设备

首先更新板级驱动程序,以便 SPMI 控制器驱动程序为您的子目标添加节点。在设备树平台上,这会涉及添加新节点,例如:

#include "sdk/lib/driver/devicetree/visitors/drivers/spmi-controllers/spmi/spmi.h"

spmi@0xffff0000 {
    $TARGET_DEVICE_TYPE@$TARGET_ID {
        reg = <$TARGET_ID SPMI_USID>;
        reg-names = "$TARGET_NAME";

        /* Your driver's node is below */
        $SUB_TARGET_DEVICE_TYPE@$SUB_TARGET_ADDRESS {
            compatible = "$COMPATIBLE"
            reg = <$SUB_TARGET_ADDRESS $SUB_TARGET_SIZE>;
            reg-names = "$SUB_TARGET_NAME";
        };
    };
};

如果您的驱动节点必须是其他一些总线的子级,您还可以通过 spmis 引用属性访问子目标。例如:

#include "sdk/lib/driver/devicetree/visitors/drivers/spmi-controllers/spmi/spmi.h"

$BUS@0xffff1000 {
    /* Your driver's node is below */
    $BUS_CHILD {
        compatible = "$COMPATIBLE"
        spmis = <&$SUB_TARGET_LABEL>;
    };
};

spmi@0xffff0000 {
    $TARGET_DEVICE_TYPE@$TARGET_ID {
        reg = <$TARGET_ID SPMI_USID>;
        reg-names = "$TARGET_NAME";

        /* This is the sub-target your driver can access */
        $SUB_TARGET_LABEL: $SUB_TARGET_DEVICE_TYPE@$SUB_TARGET_ADDRESS {
            reg = <$SUB_TARGET_ADDRESS $SUB_TARGET_SIZE>;
            reg-names = "$SUB_TARGET_NAME";
        };
    };
};

您的驱动程序应连接到 fuchsia.hardware.spmi.SubTargetService,并在其组件清单中为其添加一个条目。SPMI 控制器驱动程序将为您的子目标或引用属性添加一个节点,该节点具有以下绑定属性:

属性 可选 用途
fuchsia.hardware.spmi.SubTargetService 否 SPMI 子目标服务。
fuchsia.ID 否 SPMI 子目标全局 ID。
fuchsia.NAME 是 子目标的字符串名称。在设备树平台上,此名称是根据子目标节点的 reg-names 属性生成的。

通过 fuchsia.hardware.spmi.Device 进行的寄存器访问将映射到子目标的起始地址,并限制在分配给子目标的范围内。

子目标及其父目标都可以有多个 reg 条目,但不能一起使用:具有多个 SID 的父目标不允许有子目标。如果父级定位条件具有子级定位条件,则它必须具有单个 SID,但子级定位条件本身仍可以具有多个 reg 条目(区域)。

子目标设备树绑定

SPMI 设备树访问器禁止以下行为:

  • spmis 属性中引用的目标节点
  • 具有 compatible 属性且在 spmis 属性中被引用的子目标节点
  • 被多个其他节点中的 spmis 属性引用的子目标节点

编写 SPMI 控制器驱动程序

SPMI 控制器驱动程序负责根据从开发板驱动程序收到的 fuchsia.hardware.spmi.ControllerInfo 元数据设置子节点。

目标设备

对于 ControllerInfo 中没有 sub_targets 的每个 TargetInfo,控制器驱动程序应添加一个子节点,该子节点提供 fuchsia.hardware.spmi.TargetService 并具有以下属性:

属性 值
fuchsia.spmi.CONTROLLER_ID ControllerInfo 中的 id(如果指定)
fuchsia.ID TargetInfo 中的 id
fuchsia.NAME TargetInfo 中的 name(如果指定)

子目标设备

对于 ControllerInfo 中每个 TargetInfo 中的每个 SubTargetInfo,控制器驱动程序应添加一个子节点,该子节点提供 fuchsia.hardware.spmi.SubTargetService 并具有以下属性:

属性 值
fuchsia.ID SubTargetInfo 中的 global_id
fuchsia.NAME SubTargetInfo 中的 name(如果指定)

控制器驱动程序应将对子目标的寄存器访问限制在 [0, size) 范围内,并将其偏移 address。

资源