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