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![](../public_sys-resources/icon-note.gif) **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![image1](figures/unified-service-mode.png)
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