1e41f4b71Sopenharmony_ci# Regulator 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Overview 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci### Regulator 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciThe regulator module controls the voltage and current supplies of some devices in the system. In an embedded system (especially a mobile phone), it is important to control the power consumption, which directly affects the battery endurance. You can use a regulator to shut down the power supply to an idle module in the system or reduce the voltage and current for the module. 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci### Working Principles 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ciIn the Hardware Driver Foundation (HDF), the regulator module uses the unified service mode for API adaptation. In this mode, a device service is used as the regulator manager to handle external access requests in a unified manner, which is reflected in the configuration file. The unified service mode applies when there are many device objects of the same type, for example, when the regulator has more than 10 controllers. If the independent service mode is used, more device nodes need to be configured and more memory resources will be consumed by services. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ciThe regulator module is divided into the following layers: 15e41f4b71Sopenharmony_ci- Interface layer: provides APIs for opening or closing a device and writing data. 16e41f4b71Sopenharmony_ci- Core layer: provides the capabilities of binding, initializing, and releasing devices. 17e41f4b71Sopenharmony_ci- Adaptation layer: implements other functions. 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci **NOTE**<br/>The core layer can call the APIs of the interface layer and uses hooks to call APIs of the adaptation layer. In this way, the adaptation layer can indirectly call the APIs of the interface layer, but the interface layer cannot call the APIs of the adaptation layer. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci**Figure 1** Unified service mode 22e41f4b71Sopenharmony_ci 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci### Constraints 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ciCurrently, the regulator module supports only the kernels (LiteOS) of mini and small systems. 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci## Development Guidelines 32e41f4b71Sopenharmony_ci 33e41f4b71Sopenharmony_ci### When to Use 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ciThe regulator module controls the voltage and current supplies of some devices in the system. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci### Available APIs 38e41f4b71Sopenharmony_ci 39e41f4b71Sopenharmony_ciThe functions in **RegulatorMethod** are used to call the corresponding regulator driver functions: 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci**RegulatorMethod** structure: 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci``` 44e41f4b71Sopenharmony_cistruct RegulatorMethod { 45e41f4b71Sopenharmony_ci int32_t (*open)(struct RegulatorNode *node); 46e41f4b71Sopenharmony_ci int32_t (*close)(struct RegulatorNode *node); 47e41f4b71Sopenharmony_ci int32_t (*release)(struct RegulatorNode *node); 48e41f4b71Sopenharmony_ci int32_t (*enable)(struct RegulatorNode *node); 49e41f4b71Sopenharmony_ci int32_t (*disable)(struct RegulatorNode *node); 50e41f4b71Sopenharmony_ci int32_t (*forceDisable)(struct RegulatorNode *node); 51e41f4b71Sopenharmony_ci int32_t (*setVoltage)(struct RegulatorNode *node, uint32_t minUv, uint32_t maxUv); 52e41f4b71Sopenharmony_ci int32_t (*getVoltage)(struct RegulatorNode *node, uint32_t *voltage); 53e41f4b71Sopenharmony_ci int32_t (*setCurrent)(struct RegulatorNode *node, uint32_t minUa, uint32_t maxUa); 54e41f4b71Sopenharmony_ci int32_t (*getCurrent)(struct RegulatorNode *node, uint32_t *regCurrent); 55e41f4b71Sopenharmony_ci int32_t (*getStatus)(struct RegulatorNode *node, uint32_t *status); 56e41f4b71Sopenharmony_ci}; 57e41f4b71Sopenharmony_ci``` 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci**Table 1** Description of the RegulatorMethod structure 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci| Method | Input Parameter | Return Value | Description | 63e41f4b71Sopenharmony_ci| ------------ | ----------------------------------------------------------- | ----------------- | ---------------- | 64e41f4b71Sopenharmony_ci| open | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Opens a device. | 65e41f4b71Sopenharmony_ci| close | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Closes a device. | 66e41f4b71Sopenharmony_ci| release | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Releases a device handle. | 67e41f4b71Sopenharmony_ci| enable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Enables a regulator. | 68e41f4b71Sopenharmony_ci| disable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Disables a regulator. | 69e41f4b71Sopenharmony_ci| forceDisable | **node**: structure pointer to the regulator node at the core layer. | HDF_STATUS| Forcibly disables a regulator. | 70e41f4b71Sopenharmony_ci| setVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**minUv**: minimum voltage to set. It is a uint32_t variable.<br>**maxUv**: maximum voltage to set. It is a uint32_t variable.| HDF_STATUS| Sets the output voltage range.| 71e41f4b71Sopenharmony_ci| getVoltage | **node**: structure pointer to the regulator node at the core layer.<br>**voltage**: pointer to the output voltage.| HDF_STATUS| Obtains the voltage. | 72e41f4b71Sopenharmony_ci| setCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**minUa**: minimum current to set. It is a uint32_t variable.<br>**maxUa**: maximum current to set. It is a uint32_t variable.| HDF_STATUS| Sets the output current range.| 73e41f4b71Sopenharmony_ci| getCurrent | **node**: structure pointer to the regulator node at the core layer.<br>**regCurrent**: pointer to the output current, which is of the uint32_t type.| HDF_STATUS| Obtains the current. | 74e41f4b71Sopenharmony_ci| getStatus | **node**: structure pointer to the regulator node at the core layer.<br>**status**: pointer to the output status, which is of the uint32_t type.| HDF_STATUS| Obtains the device status. | 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci### How to Develop 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ciThe regulator module adaptation procedure is as follows: 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci1. Instantiate the driver entry. 81e41f4b71Sopenharmony_ci2. Configure attribute files. 82e41f4b71Sopenharmony_ci3. Instantiate the core layer APIs. 83e41f4b71Sopenharmony_ci4. Debug the driver. 84e41f4b71Sopenharmony_ci 85e41f4b71Sopenharmony_ci## Development Example 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci1. Instantiate the driver entry. 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ci The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke. 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci Generally, the HDF calls the **Init** function to load the driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit. 94e41f4b71Sopenharmony_ci 95e41f4b71Sopenharmony_ci ``` 96e41f4b71Sopenharmony_ci struct HdfDriverEntry g_regulatorDriverEntry = { 97e41f4b71Sopenharmony_ci .moduleVersion = 1, 98e41f4b71Sopenharmony_ci .moduleName = "virtual_regulator_driver",// (Mandatory) The value must be the same as that of moduleName in the .hcs file. 99e41f4b71Sopenharmony_ci .Init = VirtualRegulatorInit, 100e41f4b71Sopenharmony_ci .Release = VirtualRegulatorRelease, 101e41f4b71Sopenharmony_ci }; 102e41f4b71Sopenharmony_ci // Call HDF_INIT to register the driver entry with the HDF. 103e41f4b71Sopenharmony_ci HDF_INIT(g_regulatorDriverEntry); 104e41f4b71Sopenharmony_ci ``` 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci2. Configure attribute files. 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci - Add the device node description to the **vendor/hisilicon/hispark_taurus/hdf_config/device_info/device_info.hcs** file. 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci The **deviceNode** information is related to registration of the driver entry. The device attribute values are closely related to the default values or value ranges of the **RegulatorNode** members at the core layer. 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci In the unified service mode, the first device node in the **device_info.hcs** file must be the regulator manager. The parameters must be set as follows: 113e41f4b71Sopenharmony_ci 114e41f4b71Sopenharmony_ci | Member | Value | 115e41f4b71Sopenharmony_ci | --------------- | ------------------------------------------------------------ | 116e41f4b71Sopenharmony_ci | policy | **0**, which indicates that no service is published. | 117e41f4b71Sopenharmony_ci | priority | Driver startup priority, which ranges form 0 to 200. A larger value indicates a lower priority. If the priorities are the same, the device loading sequence is not ensured.| 118e41f4b71Sopenharmony_ci | permission | Driver permission. | 119e41f4b71Sopenharmony_ci | moduleName | **HDF_PLATFORM_REGULATOR_MANAGER** | 120e41f4b71Sopenharmony_ci | serviceName | **HDF_PLATFORM_REGULATOR_MANAGER** | 121e41f4b71Sopenharmony_ci | deviceMatchAttr | Reserved. | 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci Configure regulator controller information from the second node. This node specifies a type of regulator controllers rather than a specific regulator controller. In this example, there is only one regulator device. If there are multiple regulator devices, you need to add the **deviceNode** information to the **device_info** file and add the corresponding device attributes to the **regulator\_config** file. 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci - **device_info.hcs** configuration example 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci ``` 128e41f4b71Sopenharmony_ci root { 129e41f4b71Sopenharmony_ci device_info { 130e41f4b71Sopenharmony_ci platform :: host { 131e41f4b71Sopenharmony_ci hostName = "platform_host"; 132e41f4b71Sopenharmony_ci priority = 50; 133e41f4b71Sopenharmony_ci device_regulator :: device { 134e41f4b71Sopenharmony_ci device0:: deviceNode { // Set an HDF device node for each regulator controller. 135e41f4b71Sopenharmony_ci policy = 1; // Policy for the driver to publish services. 136e41f4b71Sopenharmony_ci priority = 50; // Driver startup priority. 137e41f4b71Sopenharmony_ci permission = 0644; // Permission to create device nodes for the driver. 138e41f4b71Sopenharmony_ci /* (Mandatory) Driver name, which must be the same as the moduleName in the driver entry. */ 139e41f4b71Sopenharmony_ci moduleName = "HDF_PLATFORM_REGULATOR_MANAGER"; 140e41f4b71Sopenharmony_ci serviceName = "HDF_PLATFORM_REGULATOR_MANAGER"; // (Mandatory) Unique name of the service published by the driver. 141e41f4b71Sopenharmony_ci /* (Mandatory) Set the controller private data, which must be same as that in regulator_config.hcs. */ 142e41f4b71Sopenharmony_ci deviceMatchAttr = "hdf_platform_regulator_manager"; 143e41f4b71Sopenharmony_ci } 144e41f4b71Sopenharmony_ci device1 :: deviceNode { 145e41f4b71Sopenharmony_ci policy = 0; 146e41f4b71Sopenharmony_ci priority = 55; 147e41f4b71Sopenharmony_ci permission = 0644; 148e41f4b71Sopenharmony_ci moduleName = "linux_regulator_adapter"; 149e41f4b71Sopenharmony_ci deviceMatchAttr = "linux_regulator_adapter"; 150e41f4b71Sopenharmony_ci } 151e41f4b71Sopenharmony_ci } 152e41f4b71Sopenharmony_ci } 153e41f4b71Sopenharmony_ci } 154e41f4b71Sopenharmony_ci } 155e41f4b71Sopenharmony_ci ``` 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci - **regulator\_config.hcs** configuration example: 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci ``` 160e41f4b71Sopenharmony_ci root { 161e41f4b71Sopenharmony_ci platform { 162e41f4b71Sopenharmony_ci regulator_config { 163e41f4b71Sopenharmony_ci match_attr = "linux_regulator_adapter"; 164e41f4b71Sopenharmony_ci template regulator_controller { // (Mandatory) Template configuration. In the template, you can configure the common parameters shared by device nodes. 165e41f4b71Sopenharmony_ci device_num = 1; 166e41f4b71Sopenharmony_ci name = ""; 167e41f4b71Sopenharmony_ci devName = "regulator_adapter_consumer01"; 168e41f4b71Sopenharmony_ci supplyName = ""; 169e41f4b71Sopenharmony_ci mode = 1; 170e41f4b71Sopenharmony_ci minUv = 0; 171e41f4b71Sopenharmony_ci maxUv = 20000; 172e41f4b71Sopenharmony_ci minUa = 0; 173e41f4b71Sopenharmony_ci maxUa = 0; 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci controller_0x130d0000 :: regulator_controller { 176e41f4b71Sopenharmony_ci device_num = 1; 177e41f4b71Sopenharmony_ci name = "regulator_adapter_1"; 178e41f4b71Sopenharmony_ci devName = "regulator_adapter_consumer01"; 179e41f4b71Sopenharmony_ci supplyName = "virtual-regulator-hdf-adapter"; 180e41f4b71Sopenharmony_ci mode = 1; 181e41f4b71Sopenharmony_ci minUv = 1000; 182e41f4b71Sopenharmony_ci maxUv = 50000; 183e41f4b71Sopenharmony_ci minUa = 0; 184e41f4b71Sopenharmony_ci maxUa = 0; 185e41f4b71Sopenharmony_ci } 186e41f4b71Sopenharmony_ci /* Each regulator controller corresponds to a controller node. If there are multiple regulator controllers, add the corresponding controller nodes one by one. */ 187e41f4b71Sopenharmony_ci controller_0x130d0001 :: regulator_controller { 188e41f4b71Sopenharmony_ci device_num = 1; 189e41f4b71Sopenharmony_ci name = "regulator_adapter_2"; 190e41f4b71Sopenharmony_ci devName = "regulator_adapter_consumer01"; 191e41f4b71Sopenharmony_ci supplyName = "virtual2-regulator-hdf-adapter"; 192e41f4b71Sopenharmony_ci mode = 2; 193e41f4b71Sopenharmony_ci minUv = 0; 194e41f4b71Sopenharmony_ci maxUv = 0; 195e41f4b71Sopenharmony_ci minUa = 1000; 196e41f4b71Sopenharmony_ci maxUa = 50000; 197e41f4b71Sopenharmony_ci } 198e41f4b71Sopenharmony_ci } 199e41f4b71Sopenharmony_ci } 200e41f4b71Sopenharmony_ci } 201e41f4b71Sopenharmony_ci ``` 202e41f4b71Sopenharmony_ci 203e41f4b71Sopenharmony_ci3. Instantiate the core layer APIs. 204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_ci Initialize the **RegulatorNode** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init**, and **Release**) to instantiate **RegulatorMethod** in **RegulatorNode** (so that the underlying driver functions can be called). 206e41f4b71Sopenharmony_ci 207e41f4b71Sopenharmony_ci - Defining a custom structure 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ci The **RegulatorNode** structure holds parameters and data for the driver. The HDF obtains the values in **regulator_config.hcs** using **DeviceResourceIface**. 210e41f4b71Sopenharmony_ci 211e41f4b71Sopenharmony_ci ``` 212e41f4b71Sopenharmony_ci // RegulatorNode is the core layer controller structure. The Init function assigns values to the members of RegulatorNode. 213e41f4b71Sopenharmony_ci struct RegulatorNode { 214e41f4b71Sopenharmony_ci struct RegulatorDesc regulatorInfo; 215e41f4b71Sopenharmony_ci struct DListHead node; 216e41f4b71Sopenharmony_ci struct RegulatorMethod *ops; 217e41f4b71Sopenharmony_ci void *priv; 218e41f4b71Sopenharmony_ci struct OsalMutex lock; 219e41f4b71Sopenharmony_ci }; 220e41f4b71Sopenharmony_ci 221e41f4b71Sopenharmony_ci struct RegulatorDesc { 222e41f4b71Sopenharmony_ci const char *name; /* Regulator name. */ 223e41f4b71Sopenharmony_ci const char *parentName; /* Regulator parent node name. */ 224e41f4b71Sopenharmony_ci struct RegulatorConstraints constraints; /* Regulator constraint information. */ 225e41f4b71Sopenharmony_ci uint32_t minUv; /* Minimum output voltage. */ 226e41f4b71Sopenharmony_ci uint32_t maxUv; /* Maximum output voltage. */ 227e41f4b71Sopenharmony_ci uint32_t minUa; /* Minimum output current. */ 228e41f4b71Sopenharmony_ci uint32_t maxUa; /* Maximum output current. */ 229e41f4b71Sopenharmony_ci uint32_t status; /* Regulator status, which can be on or off. */ 230e41f4b71Sopenharmony_ci int useCount; 231e41f4b71Sopenharmony_ci int consumerRegNums; /* Number of the regulator consumers. */ 232e41f4b71Sopenharmony_ci RegulatorStatusChangecb cb; /* Variable used to notify the regulator status changes. */ 233e41f4b71Sopenharmony_ci }; 234e41f4b71Sopenharmony_ci 235e41f4b71Sopenharmony_ci struct RegulatorConstraints { 236e41f4b71Sopenharmony_ci uint8_t alwaysOn; /* Whether the regulator is always on. */ 237e41f4b71Sopenharmony_ci uint8_t mode; /* Voltage or current. */ 238e41f4b71Sopenharmony_ci uint32_t minUv; /* Minimum output voltage allowed. */ 239e41f4b71Sopenharmony_ci uint32_t maxUv; /* Maximum output voltage allowed. */ 240e41f4b71Sopenharmony_ci uint32_t minUa; /* Minimum output current allowed. */ 241e41f4b71Sopenharmony_ci uint32_t maxUa; /* Maximum output current allowed. */ 242e41f4b71Sopenharmony_ci }; 243e41f4b71Sopenharmony_ci ``` 244e41f4b71Sopenharmony_ci 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci 247e41f4b71Sopenharmony_ci - Instantiating **RegulatorMethod** (other members are initialized by **Init**) 248e41f4b71Sopenharmony_ci 249e41f4b71Sopenharmony_ci ```c 250e41f4b71Sopenharmony_ci // Example of regulator_virtual.c: Instantiate the hooks. 251e41f4b71Sopenharmony_ci static struct RegulatorMethod g_method = { 252e41f4b71Sopenharmony_ci .enable = VirtualRegulatorEnable, 253e41f4b71Sopenharmony_ci .disable = VirtualRegulatorDisable, 254e41f4b71Sopenharmony_ci .setVoltage = VirtualRegulatorSetVoltage, 255e41f4b71Sopenharmony_ci .getVoltage = VirtualRegulatorGetVoltage, 256e41f4b71Sopenharmony_ci .setCurrent = VirtualRegulatorSetCurrent, 257e41f4b71Sopenharmony_ci .getCurrent = VirtualRegulatorGetCurrent, 258e41f4b71Sopenharmony_ci .getStatus = VirtualRegulatorGetStatus, 259e41f4b71Sopenharmony_ci }; 260e41f4b71Sopenharmony_ci ``` 261e41f4b71Sopenharmony_ci 262e41f4b71Sopenharmony_ci 263e41f4b71Sopenharmony_ci 264e41f4b71Sopenharmony_ci - **Init** function 265e41f4b71Sopenharmony_ci 266e41f4b71Sopenharmony_ci **Input parameter**: 267e41f4b71Sopenharmony_ci 268e41f4b71Sopenharmony_ci **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. 269e41f4b71Sopenharmony_ci 270e41f4b71Sopenharmony_ci **Return value**: 271e41f4b71Sopenharmony_ci 272e41f4b71Sopenharmony_ci **HDF\_STATUS** 273e41f4b71Sopenharmony_ci 274e41f4b71Sopenharmony_ci The table below describes some status. For more details, see **HDF\_STATUS** in **/drivers/framework/include/utils/hdf\_base.h**. 275e41f4b71Sopenharmony_ci 276e41f4b71Sopenharmony_ci **Table 2** Description of HDF_STATUS 277e41f4b71Sopenharmony_ci 278e41f4b71Sopenharmony_ci | Status | Description | 279e41f4b71Sopenharmony_ci | ---------------------- | -------------- | 280e41f4b71Sopenharmony_ci | HDF_ERR_INVALID_OBJECT | Invalid controller object.| 281e41f4b71Sopenharmony_ci | HDF_ERR_MALLOC_FAIL | Failed to allocate memory. | 282e41f4b71Sopenharmony_ci | HDF_ERR_INVALID_PARAM | Invalid parameter. | 283e41f4b71Sopenharmony_ci | HDF_ERR_IO | I/O error. | 284e41f4b71Sopenharmony_ci | HDF_SUCCESS | Initialization successful. | 285e41f4b71Sopenharmony_ci | HDF_FAILURE | Initialization failed. | 286e41f4b71Sopenharmony_ci 287e41f4b71Sopenharmony_ci **Function description**: 288e41f4b71Sopenharmony_ci 289e41f4b71Sopenharmony_ci Initializes the custom structure and **RegulatorNode** members, and adds the regulator controller by calling the **RegulatorNodeAdd** function at the core layer. 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci ```c 293e41f4b71Sopenharmony_ci static int32_t VirtualRegulatorInit(struct HdfDeviceObject *device) 294e41f4b71Sopenharmony_ci { 295e41f4b71Sopenharmony_ci int32_t ret; 296e41f4b71Sopenharmony_ci const struct DeviceResourceNode *childNode = NULL; 297e41f4b71Sopenharmony_ci ... 298e41f4b71Sopenharmony_ci DEV_RES_NODE_FOR_EACH_CHILD_NODE(device->property, childNode) { 299e41f4b71Sopenharmony_ci ret = VirtualRegulatorParseAndInit(device, childNode);// (Mandatory) The implementation is as follows: 300e41f4b71Sopenharmony_ci ... 301e41f4b71Sopenharmony_ci } 302e41f4b71Sopenharmony_ci ... 303e41f4b71Sopenharmony_ci } 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci static int32_t VirtualRegulatorParseAndInit(struct HdfDeviceObject *device, const struct DeviceResourceNode *node) 306e41f4b71Sopenharmony_ci { 307e41f4b71Sopenharmony_ci int32_t ret; 308e41f4b71Sopenharmony_ci struct RegulatorNode *regNode = NULL; 309e41f4b71Sopenharmony_ci (void)device; 310e41f4b71Sopenharmony_ci 311e41f4b71Sopenharmony_ci regNode = (struct RegulatorNode *)OsalMemCalloc(sizeof(*regNode));// Load the .hcs file. 312e41f4b71Sopenharmony_ci ... 313e41f4b71Sopenharmony_ci ret = VirtualRegulatorReadHcs(regNode, node); // Read .hcs information. 314e41f4b71Sopenharmony_ci ... 315e41f4b71Sopenharmony_ci regNode->priv = (void *)node; ; // Instantiate the node. 316e41f4b71Sopenharmony_ci regNode->ops = &g_method; // Instantiate OPS. 317e41f4b71Sopenharmony_ci 318e41f4b71Sopenharmony_ci ret = RegulatorNodeAdd(regNode); // Add the node. 319e41f4b71Sopenharmony_ci ... 320e41f4b71Sopenharmony_ci } 321e41f4b71Sopenharmony_ci ``` 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ci - **Release** function 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci **Input parameter**: 326e41f4b71Sopenharmony_ci 327e41f4b71Sopenharmony_ci **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information. 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_ci **Return value**: 330e41f4b71Sopenharmony_ci 331e41f4b71Sopenharmony_ci No value is returned. 332e41f4b71Sopenharmony_ci 333e41f4b71Sopenharmony_ci **Function description**: 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci Releases the memory and deletes the controller. This function assigns values to the **Release** function in the driver entry structure. If the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources. 336e41f4b71Sopenharmony_ci 337e41f4b71Sopenharmony_ci ```c 338e41f4b71Sopenharmony_ci static void VirtualRegulatorRelease(struct HdfDeviceObject *device) 339e41f4b71Sopenharmony_ci { 340e41f4b71Sopenharmony_ci ... 341e41f4b71Sopenharmony_ci RegulatorNodeRemoveAll();// (Mandatory) Call the function at the core layer to release regulator controller devices and services. 342e41f4b71Sopenharmony_ci } 343e41f4b71Sopenharmony_ci ``` 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci4. Debug the driver. 346e41f4b71Sopenharmony_ci 347e41f4b71Sopenharmony_ci (Optional) Verify the basic functions of the new driver, for example, check whether the test cases are successful after the driver is loaded. 348e41f4b71Sopenharmony_ci 349e41f4b71Sopenharmony_ci 350