1 /*
2  * Copyright 2021 ~ 2022, 2024 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_pf5020.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 #define PF5020_REGULATOR_PG_EN_MASK  (0x1U)
14 #define PF5020_REGULATOR_PG_EN_SHIFT (0U)
15 #define PF5020_REGULATOR_PG_EN(x) \
16     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_PG_EN_SHIFT)) & PF5020_REGULATOR_PG_EN_MASK)
17 
18 #define PF5020_REGULATOR_WDBYPASS_MASK  (0x2U)
19 #define PF5020_REGULATOR_WDBYPASS_SHIFT (1U)
20 #define PF5020_REGULATOR_WDBYPASS(x) \
21     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_WDBYPASS_SHIFT)) & PF5020_REGULATOR_WDBYPASS_MASK)
22 
23 #define PF5020_REGULATOR_ILIM_BYPASS_MASK  (0x20U)
24 #define PF5020_REGULATOR_ILIM_BYPASS_SHIFT (5U)
25 #define PF5020_REGULATOR_ILIM_BYPASS(x) \
26     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_ILIM_BYPASS_SHIFT)) & PF5020_REGULATOR_ILIM_BYPASS_MASK)
27 
28 #define PF5020_REGULATOR_OV_BYPASS_MASK  (0x40U)
29 #define PF5020_REGULATOR_OV_BYPASS_SHIFT (6U)
30 #define PF5020_REGULATOR_OV_BYPASS(x) \
31     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_OV_BYPASS_SHIFT)) & PF5020_REGULATOR_OV_BYPASS_MASK)
32 
33 #define PF5020_REGULATOR_UV_BYPASS_MASK  (0x80U)
34 #define PF5020_REGULATOR_UV_BYPASS_SHIFT (7U)
35 #define PF5020_REGULATOR_UV_BYPASS(x) \
36     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_UV_BYPASS_SHIFT)) & PF5020_REGULATOR_UV_BYPASS_MASK)
37 
38 #define PF5020_REGULATOR_FLT_REN_MASK  (0x80U)
39 #define PF5020_REGULATOR_FLT_REN_SHIFT (7U)
40 #define PF5020_REGULATOR_FLT_REN(x) \
41     (((uint8_t)(((uint8_t)(x)) << PF5020_REGULATOR_FLT_REN_SHIFT)) & PF5020_REGULATOR_FLT_REN_MASK)
42 
43 #define PF5020_BUCK_REGULATOR_RUN_MODE_MASK  (0x3U)
44 #define PF5020_BUCK_REGULATOR_RUN_MODE_SHIFT (0U)
45 #define PF5020_BUCK_REGULATOR_RUN_MODE(x) \
46     (((uint8_t)(((uint8_t)(x)) << PF5020_BUCK_REGULATOR_RUN_MODE_SHIFT)) & PF5020_BUCK_REGULATOR_RUN_MODE_MASK)
47 
48 #define PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK  (0xCU)
49 #define PF5020_BUCK_REGULATOR_STANDBY_MODE_SHIFT (2U)
50 #define PF5020_BUCK_REGULATOR_STANDBY_MODE(x) \
51     (((uint8_t)(((uint8_t)(x)) << PF5020_BUCK_REGULATOR_STANDBY_MODE_SHIFT)) & PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK)
52 
53 #define PF5020_BUCK_REGULATOR_ILIM_MASK  (0x18U)
54 #define PF5020_BUCK_REGULATOR_ILIM_SHIFT (3U)
55 #define PF5020_BUCK_REGULATOR_ILIM(x) \
56     (((uint8_t)(((uint8_t)(x)) << PF5020_BUCK_REGULATOR_ILIM_SHIFT)) & PF5020_BUCK_REGULATOR_ILIM_MASK)
57 
58 #define PF5020_BUCK_REGULATOR_PDGPR_MASK  (0x30U)
59 #define PF5020_BUCK_REGULATOR_PDGPR_SHIFT (4U)
60 #define PF5020_BUCK_REGULATOR_PDGPR(x) \
61     (((uint8_t)(((uint8_t)(x)) << PF5020_BUCK_REGULATOR_PDGPR_SHIFT)) & PF5020_BUCK_REGULATOR_PDGPR_MASK)
62 
63 #define PF5020_BUCK_REGULATOR_PHASE_MASK  (0x7U)
64 #define PF5020_BUCK_REGULATOR_PHASE_SHIFT (0U)
65 #define PF5020_BUCK_REGULATOR_PHASE(x) \
66     (((uint8_t)(((uint8_t)(x)) << PF5020_BUCK_REGULATOR_PHASE_SHIFT)) & PF5020_BUCK_REGULATOR_PHASE_MASK)
67 
68 #define PF5020_SW2_CONFIG2_VTTEN_MASK  (0x40U)
69 #define PF5020_SW2_CONFIG2_VTTEN_SHIFT (6U)
70 #define PF5020_SW2_CONFIG2_VTTEN(x) \
71     (((uint8_t)(((uint8_t)(x)) << PF5020_SW2_CONFIG2_VTTEN_SHIFT)) & PF5020_SW2_CONFIG2_VTTEN_MASK)
72 
73 #define PF5020_LDO1_CONFIG2_STBY_EN_MASK  (0x1U)
74 #define PF5020_LDO1_CONFIG2_STBY_EN_SHIFT (0U)
75 #define PF5020_LDO1_CONFIG2_STBY_EN(x) \
76     (((uint8_t)(((uint8_t)(x)) << PF5020_LDO1_CONFIG2_STBY_EN_SHIFT)) & PF5020_LDO1_CONFIG2_STBY_EN_MASK)
77 
78 #define PF5020_LDO1_CONFIG2_RUN_EN_MASK  (0x2U)
79 #define PF5020_LDO1_CONFIG2_RUN_EN_SHIFT (1U)
80 #define PF5020_LDO1_CONFIG2_RUN_EN(x) \
81     (((uint8_t)(((uint8_t)(x)) << PF5020_LDO1_CONFIG2_RUN_EN_SHIFT)) & PF5020_LDO1_CONFIG2_RUN_EN_MASK)
82 
83 #define PF5020_LDO1_CONFIG2_LDO1_PDGRP_MASK  (0x60U)
84 #define PF5020_LDO1_CONFIG2_LDO1_PDGRP_SHIFT (5U)
85 #define PF5020_LDO1_CONFIG2_LDO1_PDGRP(x) \
86     (((uint8_t)(((uint8_t)(x)) << PF5020_LDO1_CONFIG2_LDO1_PDGRP_SHIFT)) & PF5020_LDO1_CONFIG2_LDO1_PDGRP_MASK)
87 
88 #define PF5020_CTRL1_WD_STBY_EN_MASK  (0x4U)
89 #define PF5020_CTRL1_WD_STBY_EN_SHIFT (2U)
90 #define PF5020_CTRL1_WD_STBY_EN(x) \
91     (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL1_WD_STBY_EN_SHIFT)) & PF5020_CTRL1_WD_STBY_EN_MASK)
92 
93 #define PF5020_CTRL1_WD_EN_MASK  (0x8U)
94 #define PF5020_CTRL1_WD_EN_SHIFT (3U)
95 #define PF5020_CTRL1_WD_EN(x)    (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL1_WD_EN_SHIFT)) & PF5020_CTRL1_WD_EN_MASK)
96 
97 #define PF5020_CTRL1_TMP_MON_EN_MASK  (0x10U)
98 #define PF5020_CTRL1_TMP_MON_EN_SHIFT (4U)
99 #define PF5020_CTRL1_TMP_MON_EN(x) \
100     (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL1_TMP_MON_EN_SHIFT)) & PF5020_CTRL1_TMP_MON_EN_MASK)
101 
102 #define PF5020_CTRL2_TMP_MON_AON_MASK  (0x10U)
103 #define PF5020_CTRL2_TMP_MON_AON_SHIFT (4U)
104 #define PF5020_CTRL2_TMP_MON_AON(x) \
105     (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL2_TMP_MON_AON_SHIFT)) & PF5020_CTRL2_TMP_MON_AON_MASK)
106 
107 #define PF5020_CTRL3_PMIC_OFF_MASK  (0x2U)
108 #define PF5020_CTRL3_PMIC_OFF_SHIFT (1U)
109 #define PF5020_CTRL3_PMIC_OFF(x) \
110     (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL3_PMIC_OFF_SHIFT)) & PF5020_CTRL3_PMIC_OFF_MASK)
111 
112 #define PF5020_CTRL3_UV_DB_MASK  (0x30U)
113 #define PF5020_CTRL3_UV_DB_SHIFT (4U)
114 #define PF5020_CTRL3_UV_DB(x)    (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL3_UV_DB_SHIFT)) & PF5020_CTRL3_UV_DB_MASK)
115 
116 #define PF5020_CTRL3_OV_DB_MASK  (0xC0U)
117 #define PF5020_CTRL3_OV_DB_SHIFT (6U)
118 #define PF5020_CTRL3_OV_DB(x)    (((uint8_t)(((uint8_t)(x)) << PF5020_CTRL3_OV_DB_SHIFT)) & PF5020_CTRL3_OV_DB_MASK)
119 
120 #define PF5020_AMUX_AMUX_SEL_MASK  (0x1FU)
121 #define PF5020_AMUX_MAUX_SEL_SHIFT (0U)
122 #define PF5020_AMUX_MAUX_SEL(x)    (((uint8_t)(((uint8_t)(x)) << PF5020_AMUX_MAUX_SEL_SHIFT)) & PF5020_AMUX_AMUX_SEL_MASK)
123 
124 #define PF5020_AMUX_AMUX_EN_MASK  (0x20U)
125 #define PF5020_AMUX_AMUX_EN_SHIFT (5U)
126 #define PF5020_AMUX_AMUX_EN(x)    (((uint8_t)(((uint8_t)(x)) << PF5020_AMUX_AMUX_EN_SHIFT)) & PF5020_AMUX_AMUX_EN_MASK)
127 
128 #define PF5020_VMONEN1_SW1VMON_EN_MASK  (0x1U)
129 #define PF5020_VMONEN1_SW1VMON_EN_SHIFT (0U)
130 #define PF5020_VMONEN1_SW1VMON_EN(x) \
131     (((uint8_t)(((uint8_t)(x)) << PF5020_VMONEN1_SW1VMON_EN_SHIFT)) & PF5020_VMONEN1_SW1VMON_EN_MASK)
132 
133 #define PF5020_VMONEN1_SW2VMON_EN_MASK  (0x2U)
134 #define PF5020_VMONEN1_SW2VMON_EN_SHIFT (1U)
135 #define PF5020_VMONEN1_SW2VMON_EN(x) \
136     (((uint8_t)(((uint8_t)(x)) << PF5020_VMONEN1_SW2VMON_EN_SHIFT)) & PF5020_VMONEN1_SW2VMON_EN_MASK)
137 
138 #define PF5020_VMONEN1_SWND1VMON_EN_MASK  (0x40U)
139 #define PF5020_VMONEN1_SWND1VMON_EN_SHIFT (6U)
140 #define PF5020_VMONEN1_SWND1VMON_EN(x) \
141     (((uint8_t)(((uint8_t)(x)) << PF5020_VMONEN1_SWND1VMON_EN_SHIFT)) & PF5020_VMONEN1_SWND1VMON_EN_MASK)
142 
143 #define PF5020_VMONEN2_LDO1VMON_EN_MASK  (0x1U)
144 #define PF5020_VMONEN2_LDO1VMON_EN_SHIFT (0U)
145 #define PF5020_VMONEN2_LDO1VMON_EN(x) \
146     (((uint8_t)(((uint8_t)(x)) << PF5020_VMONEN2_LDO1VMON_EN_SHIFT)) & PF5020_VMONEN2_LDO1VMON_EN_MASK)
147 
148 #define PF5020_PWRUP_CTRL_RESETBMCU_PDGRP_MASK  (0xCU)
149 #define PF5020_PWRUP_CTRL_RESETBMCU_PDGRP_SHIFT (2U)
150 #define PF5020_PWRUP_CTRL_RESETBMCU_PDGRP(x) \
151     (((uint8_t)(((uint8_t)(x)) << PF5020_PWRUP_CTRL_RESETBMCU_PDGRP_SHIFT)) & PF5020_PWRUP_CTRL_RESETBMCU_PDGRP_MASK)
152 
153 #define PF5020_PWRUP_CTRL_PGOOD_PDGRP_MASK  (0x30U)
154 #define PF5020_PWRUP_CTRL_PGOOD_PDGRP_SHIFT (4U)
155 #define PF5020_PWRUP_CTRL_PGOOD_PDGRP(x) \
156     (((uint8_t)(((uint8_t)(x)) << PF5020_PWRUP_CTRL_PGOOD_PDGRP_SHIFT)) & PF5020_PWRUP_CTRL_PGOOD_PDGRP_MASK)
157 
158 #define PF5020_PWRUP_CTRL_PWRDWN_MODE_MASK  (0x40U)
159 #define PF5020_PWRUP_CTRL_PWRDWN_MODE_SHIFT (6U)
160 #define PF5020_PWRUP_CTRL_PWRDWN_MODE(x) \
161     (((uint8_t)(((uint8_t)(x)) << PF5020_PWRUP_CTRL_PWRDWN_MODE_SHIFT)) & PF5020_PWRUP_CTRL_PWRDWN_MODE_MASK)
162 
163 /*******************************************************************************
164  * Prototypes
165  ******************************************************************************/
166 static status_t PF5020_SetRegulatorCommonConfig(pf5020_handle_t *handle,
167                                                 pf5020_regulator_name_t regulatorName,
168                                                 bool enableUVBypass,
169                                                 bool enableOVBypass,
170                                                 bool enableWatchdogBypass,
171                                                 bool enablePGMonitor,
172                                                 bool faultReEnabled,
173                                                 bool enableILIMBypass);
174 
175 static status_t PF5020_MaskInterrupts(pf5020_handle_t *handle, uint64_t interruptMask, bool enableMask);
176 
177 /*******************************************************************************
178  * Variables
179  ******************************************************************************/
180 
181 /*******************************************************************************
182  * Code
183  ******************************************************************************/
PF5020_SetRegulatorCommonConfig(pf5020_handle_t * handle,pf5020_regulator_name_t regulatorName,bool enableUVBypass,bool enableOVBypass,bool enableWatchdogBypass,bool enablePGMonitor,bool faultReEnabled,bool enableILIMBypass)184 static status_t PF5020_SetRegulatorCommonConfig(pf5020_handle_t *handle,
185                                                 pf5020_regulator_name_t regulatorName,
186                                                 bool enableUVBypass,
187                                                 bool enableOVBypass,
188                                                 bool enableWatchdogBypass,
189                                                 bool enablePGMonitor,
190                                                 bool faultReEnabled,
191                                                 bool enableILIMBypass)
192 {
193     assert(handle);
194 
195     uint8_t regAddrShift;
196     uint8_t tmp8;
197     status_t status = kStatus_Success;
198 
199     /* Calculate register address shift based on regulator name. */
200     if (regulatorName == kPF5020_RegulatorLdo1)
201     {
202         regAddrShift = ((uint8_t)regulatorName - 1U) * 8U + 7U;
203     }
204     else
205     {
206         regAddrShift = (uint8_t)regulatorName * 8U;
207     }
208 
209     tmp8 = PF5020_REGULATOR_PG_EN(enablePGMonitor) | PF5020_REGULATOR_WDBYPASS(enableWatchdogBypass) |
210            PF5020_REGULATOR_ILIM_BYPASS(enableILIMBypass) | PF5020_REGULATOR_OV_BYPASS(enableOVBypass) |
211            PF5020_REGULATOR_UV_BYPASS(enableUVBypass);
212 
213     status = PF5020_ModifyReg(handle, PF5020_SW2_CONFIG1 + regAddrShift, 0xE3U, tmp8);
214 
215     if (status == kStatus_Success)
216     {
217         status = PF5020_ModifyReg(handle, PF5020_SW1_CONFIG2 + regAddrShift, 0x80U,
218                                   PF5020_REGULATOR_FLT_REN(faultReEnabled));
219     }
220 
221     return status;
222 }
223 
PF5020_MaskInterrupts(pf5020_handle_t * handle,uint64_t interruptMask,bool enableMask)224 static status_t PF5020_MaskInterrupts(pf5020_handle_t *handle, uint64_t interruptMask, bool enableMask)
225 {
226     static const uint8_t maskRegArray[] = PF5020_INT_MASK_ARRAY;
227     uint8_t maskReg;
228     uint8_t regIndex;
229     uint64_t tmp64;
230     uint8_t maskRegValue;
231     status_t status = kStatus_Success;
232 
233     for (regIndex = 0U; regIndex < 7U; regIndex++)
234     {
235         /* Get each interrupt mask register's value. */
236         tmp64 = interruptMask & (0xFFULL << (regIndex * 8U));
237 
238         if (tmp64 != 0ULL)
239         {
240             if ((tmp64 & (uint64_t)kPF5020_ILIM_Ldo1IlimInterrupt) != 0ULL)
241             {
242                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_ILIM_Ldo1IlimInterrupt);
243                 status = PF5020_WriteReg(handle, PF5020_LDO_ILIM_MASK, enableMask ? 0U : 1U);
244             }
245             if ((tmp64 & (uint64_t)kPF5020_UV_Ldo1UvInterrupt) != 0ULL)
246             {
247                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_UV_Ldo1UvInterrupt);
248                 status = PF5020_WriteReg(handle, PF5020_LDO_UV_MASK, enableMask ? 0U : 1U);
249             }
250 
251             if ((tmp64 & (uint64_t)kPF5020_OV_Ldo1OvInterrupt) != 0UL)
252             {
253                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_OV_Ldo1OvInterrupt);
254                 status = PF5020_WriteReg(handle, PF5020_LDO_OV_MASK, enableMask ? 0U : 1U);
255             }
256             if (status == kStatus_Success)
257             {
258                 maskRegValue = (uint8_t)((tmp64 >> (regIndex * 8U)) & 0xFFU);
259                 maskReg      = maskRegArray[regIndex];
260                 status = PF5020_ModifyReg(handle, maskReg, maskRegValue, enableMask ? (~maskRegValue) : maskRegValue);
261             }
262         }
263     }
264 
265     return status;
266 }
267 
268 /*!
269  * brief Write to PF5020 register via I2C.
270  *
271  * param handle The pointer to pf5020_handle_t.
272  * param regAddr The address of register to write.
273  * param val The value to be write.
274  *
275  * retval #kStatus_Success The transaction was started successfully.
276  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
277  *      transaction is already in progress.
278  */
PF5020_WriteReg(pf5020_handle_t * handle,uint8_t regAddr,uint8_t val)279 status_t PF5020_WriteReg(pf5020_handle_t *handle, uint8_t regAddr, uint8_t val)
280 {
281     assert(handle);
282     assert(handle->I2C_SendFunc);
283 
284     return handle->I2C_SendFunc(handle->slaveAddress, regAddr, 1U, &val, 1U);
285 }
286 
287 /*!
288  * brief Read value from PF5020 register via I2C.
289  *
290  * param handle The pointer to pf5020_handle_t.
291  * param regAddr The address of register to write.
292  * param val Pointer store return value.
293  *
294  * retval #kStatus_Success The transaction was started successfully.
295  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
296  *      transaction is already in progress.
297  */
PF5020_ReadReg(pf5020_handle_t * handle,uint8_t regAddr,uint8_t * val)298 status_t PF5020_ReadReg(pf5020_handle_t *handle, uint8_t regAddr, uint8_t *val)
299 {
300     assert(handle);
301     assert(handle->I2C_ReceiveFunc);
302 
303     return handle->I2C_ReceiveFunc(handle->slaveAddress, regAddr, 1U, val, 1U);
304 }
305 
306 /*!
307  * brief Read and modify the register value
308  *
309  * param handle The pointer to pf5020_handle_t structure.
310  * param regAddr The address of register.
311  * param mask The mask of register bit to be modified.
312  * param val The value to be set.
313  *
314  * retval #kStatus_Success The transaction was started successfully.
315  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
316  *      transaction is already in progress.
317  */
PF5020_ModifyReg(pf5020_handle_t * handle,uint8_t regAddr,uint8_t mask,uint8_t val)318 status_t PF5020_ModifyReg(pf5020_handle_t *handle, uint8_t regAddr, uint8_t mask, uint8_t val)
319 {
320     assert(handle);
321 
322     status_t status = kStatus_Success;
323     uint8_t tmp8;
324 
325     status = PF5020_ReadReg(handle, regAddr, &tmp8);
326 
327     if (status == kStatus_Success)
328     {
329         tmp8 &= (uint8_t)~mask;
330         tmp8 |= (val & mask);
331         status = PF5020_WriteReg(handle, regAddr, tmp8);
332     }
333 
334     return status;
335 }
336 
337 /*!
338  * brief Dump the value of continuous registers.
339  *
340  * param handle The pointer to pf5020_handle_t structure.
341  * param regAddr The address of start register.
342  * param buffer The buffer to store the dumped registers' value.
343  * param length The length of the continuous registers to be dumped.
344  *
345  * retval #kStatus_Success The transaction was started successfully.
346  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
347  *      transaction is already in progress.
348  */
PF5020_DumpReg(pf5020_handle_t * handle,uint8_t regAddr,uint8_t * buffer,uint8_t length)349 status_t PF5020_DumpReg(pf5020_handle_t *handle, uint8_t regAddr, uint8_t *buffer, uint8_t length)
350 {
351     assert(handle);
352     assert(handle->I2C_ReceiveFunc);
353 
354     uint8_t i       = 0U;
355     status_t status = kStatus_Success;
356 
357     for (i = 0U; i < length; i++)
358     {
359         status = PF5020_ReadReg(handle, regAddr++, buffer++);
360         if (status != kStatus_Success)
361         {
362             /* In case of fail to read register. */
363             break;
364         }
365     }
366 
367     return status;
368 }
369 
370 /*!
371  * brief Get default initialize configuration.
372  *
373  * code
374  *   config->I2C_SendFunc = NULL;
375  *   config->I2C_ReceiveFunc = NULL;
376  *   config->slaveAddress = 0x08U;
377  * endcode
378  * param config The pointer to pf5020_config_t structure.
379  */
PF5020_GetDefaultConfig(pf5020_config_t * config)380 void PF5020_GetDefaultConfig(pf5020_config_t *config)
381 {
382     assert(config);
383 
384     config->I2C_SendFunc    = NULL;
385     config->I2C_ReceiveFunc = NULL;
386     /* In default, the slave address of PF5020 is 0x08. */
387     config->slaveAddress = 0x08U;
388 }
389 
390 /*!
391  * brief Initialize runtime handle.
392  *
393  * param handle The pointer to pf5020_handle_t structure.
394  * param config The pointer to pf5020_config_t structure.
395  */
PF5020_CreateHandle(pf5020_handle_t * handle,const pf5020_config_t * config)396 void PF5020_CreateHandle(pf5020_handle_t *handle, const pf5020_config_t *config)
397 {
398     assert(handle);
399     assert(config);
400 
401     handle->I2C_SendFunc    = config->I2C_SendFunc;
402     handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc;
403     handle->slaveAddress    = config->slaveAddress;
404 }
405 
406 /*!
407  * brief Set power up sequencer time base.
408  *
409  * param handle The pointer to pf5020_handle_t structure.
410  * param timeBase The time base value to set, please refer pf5020_sequencer_time_base_t for details.
411  *
412  * retval #kStatus_Success The transaction was started successfully.
413  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
414  *      transaction is already in progress.
415  */
PF5020_SetSequencerTimeBase(pf5020_handle_t * handle,pf5020_sequencer_time_base_t timeBase)416 status_t PF5020_SetSequencerTimeBase(pf5020_handle_t *handle, pf5020_sequencer_time_base_t timeBase)
417 {
418     assert(handle);
419 
420     return PF5020_ModifyReg(handle, PF5020_PWRUP_CTRL, 0x3U, (uint8_t)timeBase & 0x3U);
421 }
422 
423 /*!
424  * brief Set power up sequence, when transitioning from standby state to run state, the power up sequencer is activated
425  * only if any of the regulators is re-enabled during this transition.
426  *
427  * param handle The pointer to pf5020_handle_t structure.
428  * param powerUpSeq The pointer to pf5020_power_up_sequence_t structure.
429  * retval #kStatus_Success The transaction was started successfully.
430  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
431  *      transaction is already in progress.
432  */
PF5020_SetPowerUpSequence(pf5020_handle_t * handle,pf5020_power_up_sequence_t * powerUpSeq)433 status_t PF5020_SetPowerUpSequence(pf5020_handle_t *handle, pf5020_power_up_sequence_t *powerUpSeq)
434 {
435     assert(handle);
436     assert(powerUpSeq);
437 
438     static const uint8_t seqReqArray[] = PF5020_SEQ_REG_ARRAY;
439     uint8_t tmp8;
440     uint8_t i;
441     status_t status;
442 
443     for (i = 0U; i < 6U; i++)
444     {
445         status = PF5020_ReadReg(handle, seqReqArray[i], &tmp8);
446         /* if the sequence order to set is same as register value, it is no need to set register again. */
447         if ((tmp8 != *((uint8_t *)powerUpSeq + i)) && (status == kStatus_Success))
448         {
449             status = PF5020_WriteReg(handle, seqReqArray[i], *((uint8_t *)powerUpSeq + i));
450         }
451 
452         if (status != kStatus_Success)
453         {
454             break;
455         }
456     }
457 
458     return status;
459 }
460 
461 /*!
462  * brief Set power down mode, sequential mode or group mode.
463  *
464  * param handle The pointer to pf5020_handle_t structure.
465  * param powerDownMode The power down mode to set, please refer to pf5020_power_down_mode_t.
466  * retval #kStatus_Success The transaction was started successfully.
467  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
468  *      transaction is already in progress.
469  */
PF5020_SetPowerDownMode(pf5020_handle_t * handle,pf5020_power_down_mode_t powerDownMode)470 status_t PF5020_SetPowerDownMode(pf5020_handle_t *handle, pf5020_power_down_mode_t powerDownMode)
471 {
472     assert(handle);
473 
474     return PF5020_ModifyReg(handle, PF5020_PWRUP_CTRL, PF5020_PWRUP_CTRL_PWRDWN_MODE_MASK,
475                             PF5020_PWRUP_CTRL_PWRDWN_MODE(powerDownMode));
476 }
477 
478 /*!
479  * brief Set power down groups that each internal module placed to.
480  *
481  * param handle The pointer to pf5020_handle_t structure.
482  * param groupConfig Pointer to the pf5020_power_down_group_config_t structure.
483  * retval #kStatus_Success The transaction was started successfully.
484  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
485  *      transaction is already in progress.
486  */
PF5020_SetPowerDownGroups(pf5020_handle_t * handle,const pf5020_power_down_group_config_t * groupConfig)487 status_t PF5020_SetPowerDownGroups(pf5020_handle_t *handle, const pf5020_power_down_group_config_t *groupConfig)
488 {
489     assert(handle);
490     assert(groupConfig);
491 
492     status_t status;
493 
494     status = PF5020_ModifyReg(handle, PF5020_PWRUP_CTRL,
495                               PF5020_PWRUP_CTRL_PGOOD_PDGRP_MASK | PF5020_PWRUP_CTRL_RESETBMCU_PDGRP_MASK,
496                               PF5020_PWRUP_CTRL_RESETBMCU_PDGRP(groupConfig->resetBMCUGroup) |
497                                   PF5020_PWRUP_CTRL_PGOOD_PDGRP(groupConfig->pGoodGroup));
498 
499     if (status == kStatus_Success)
500     {
501         status = PF5020_ModifyReg(handle, PF5020_SW1_MODE, PF5020_BUCK_REGULATOR_PDGPR_MASK,
502                                   PF5020_BUCK_REGULATOR_PDGPR(groupConfig->sw1Group));
503     }
504     if (status == kStatus_Success)
505     {
506         status = PF5020_ModifyReg(handle, PF5020_SW2_MODE1, PF5020_BUCK_REGULATOR_PDGPR_MASK,
507                                   PF5020_BUCK_REGULATOR_PDGPR(groupConfig->sw2Group));
508     }
509     if (status == kStatus_Success)
510     {
511         status = PF5020_ModifyReg(handle, PF5020_SWND1_MODE1, PF5020_BUCK_REGULATOR_PDGPR_MASK,
512                                   PF5020_BUCK_REGULATOR_PDGPR(groupConfig->swnd1Group));
513     }
514     if (status == kStatus_Success)
515     {
516         status = PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG2, PF5020_LDO1_CONFIG2_LDO1_PDGRP_MASK,
517                                   PF5020_LDO1_CONFIG2_LDO1_PDGRP(groupConfig->ldo1Group));
518     }
519 
520     return status;
521 }
522 
523 /*!
524  * brief Set selected power down group's delay.
525  *
526  * param handle The pointer to pf5020_handle_t structure.
527  * param group The selected power down group, please refer to pf5020_power_down_group_t for details.
528  * param delay The delay value to be set, please refer to pf5020_power_down_delay_t for details.
529  * retval #kStatus_Success The transaction was started successfully.
530  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
531  *      transaction is already in progress.
532  */
PF5020_SetPowerDownGroupDelay(pf5020_handle_t * handle,pf5020_power_down_group_t group,pf5020_power_down_delay_t delay)533 status_t PF5020_SetPowerDownGroupDelay(pf5020_handle_t *handle,
534                                        pf5020_power_down_group_t group,
535                                        pf5020_power_down_delay_t delay)
536 {
537     assert(handle);
538 
539     return PF5020_ModifyReg(handle, PF5020_PWRDN_DLY1, (0x3U << (2U * (3U - (uint8_t)group))),
540                             (uint8_t)delay << (2U * (3U - (uint8_t)group)));
541 }
542 
543 /*!
544  * brief Set delay to disable the regulators after RESETBMCU is asserted.
545  *
546  * param handle The pointer to pf5020_handle_t structure.
547  * param delay The delay value, please refer to pf5020_resetBMCU_delay_t.
548  * retval #kStatus_Success The transaction was started successfully.
549  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
550  *      transaction is already in progress.
551  */
PF5020_SetResetBMcuPinDelay(pf5020_handle_t * handle,pf5020_resetBMCU_delay_t delay)552 status_t PF5020_SetResetBMcuPinDelay(pf5020_handle_t *handle, pf5020_resetBMCU_delay_t delay)
553 {
554     assert(handle);
555 
556     return PF5020_WriteReg(handle, PF5020_PWRDN_DLY2, (uint8_t)delay);
557 }
558 
559 /*!
560  * brief Turn off PF5020 PMIC.
561  *
562  * param handle The pointer to pf5020_handle_t structure.
563  * retval #kStatus_Success The transaction was started successfully.
564  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
565  *      transaction is already in progress.
566  */
PF5020_TurnOffPMIC(pf5020_handle_t * handle)567 status_t PF5020_TurnOffPMIC(pf5020_handle_t *handle)
568 {
569     assert(handle);
570 
571     return PF5020_ModifyReg(handle, PF5020_CTRL3, PF5020_CTRL3_PMIC_OFF_MASK, PF5020_CTRL3_PMIC_OFF_MASK);
572 }
573 
574 /*!
575  * brief Configure internal high speed clock.
576  *
577  * param handle The pointer to pf5020_handle_t structure.
578  * param config The pointer to pf5020_high_speed_clk_config_t structure.
579  * retval #kStatus_Success The transaction was started successfully.
580  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
581  *      transaction is already in progress.
582  */
PF5020_CLK_ConfigHighSpeedClock(pf5020_handle_t * handle,const pf5020_high_speed_clk_config_t * config)583 status_t PF5020_CLK_ConfigHighSpeedClock(pf5020_handle_t *handle, const pf5020_high_speed_clk_config_t *config)
584 {
585     assert(handle);
586     assert(config);
587 
588     uint8_t tmp8;
589 
590     tmp8 = ((uint8_t)(config->clkFreq) | ((uint8_t)(config->enableSS) << 5U) | ((uint8_t)(config->ssRange) << 4U));
591     return PF5020_ModifyReg(handle, PF5020_FREQ_CTRL, 0x3FU, tmp8);
592 }
593 
594 /*!
595  * brief Enable/disable clock sync out.
596  *
597  * param handle The pointer to pf5020_handle_t structure.
598  * param enable Used to enable/disable sync output.
599  * retval #kStatus_Success The transaction was started successfully.
600  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
601  *      transaction is already in progress.
602  */
PF5020_CLK_EnableSyncOut(pf5020_handle_t * handle,bool enable)603 status_t PF5020_CLK_EnableSyncOut(pf5020_handle_t *handle, bool enable)
604 {
605     return PF5020_ModifyReg(handle, PF5020_FREQ_CTRL, 0x80U, enable ? 0x80U : 0U);
606 }
607 
608 /*!
609  * brief Set VSNS LDO output voltage.
610  *
611  * param handle The pointer to pf5020_handle_t structure.
612  * param voltage The output voltage of VSNVS, please refer to pf5020_vsnvs_ldo_output_voltage_t.
613  * retval #kStatus_Success The transaction was started successfully.
614  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
615  *      transaction is already in progress.
616  */
PF5020_SetVsnvsLdoOutputVoltage(pf5020_handle_t * handle,pf5020_vsnvs_ldo_output_voltage_t voltage)617 status_t PF5020_SetVsnvsLdoOutputVoltage(pf5020_handle_t *handle, pf5020_vsnvs_ldo_output_voltage_t voltage)
618 {
619     assert(handle);
620 
621     return PF5020_WriteReg(handle, PF5020_VSNVS_CONFIG1, (uint8_t)voltage);
622 }
623 
624 /* SW1 Buck Regulator Control APIs. */
625 /*!
626  * brief Set SW1 Buck regulator global configuration.
627  *
628  * param handle The pointer to pf5020_handle_t structure.
629  * param config The pointer to pf5020_sw1_regulator_config_t structure.
630  * retval #kStatus_Success The transaction was started successfully.
631  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
632  *      transaction is already in progress.
633  */
PF5020_SW1_SetGlobalConfig(pf5020_handle_t * handle,const pf5020_sw1_regulator_config_t * config)634 status_t PF5020_SW1_SetGlobalConfig(pf5020_handle_t *handle, const pf5020_sw1_regulator_config_t *config)
635 {
636     assert(handle);
637     assert(config);
638 
639     status_t status;
640     uint8_t value         = 0U;
641     uint8_t mask          = 0U;
642     bool enableILIMBypass = true;
643 
644     /* Set SW1 DVS Ramp. */
645     status = PF5020_ModifyReg(handle, PF5020_SW_RAMP, 0x7U, (uint8_t)(config->sw1DvsRamp));
646 
647     if (status == kStatus_Success)
648     {
649         /* Set SW1 output voltage in run state. */
650         status = PF5020_WriteReg(handle, PF5020_SW1_RUN_VOLT, config->sw1RunOutputVolt);
651     }
652     if (status == kStatus_Success)
653     {
654         /* Set SW1 output voltage in standby state. */
655         status = PF5020_WriteReg(handle, PF5020_SW1_STBY_VOLT, config->sw1StandbyOutputVolt);
656     }
657 
658     if (status == kStatus_Success)
659     {
660         /* Update operate mode in run/standby state. */
661         status = PF5020_ModifyReg(handle, PF5020_SW1_MODE,
662                                   PF5020_BUCK_REGULATOR_RUN_MODE_MASK | PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK,
663                                   PF5020_BUCK_REGULATOR_RUN_MODE(config->sw1RunOperateMode) |
664                                       PF5020_BUCK_REGULATOR_STANDBY_MODE(config->sw1StandbyOperateMode));
665     }
666     if (status == kStatus_Success)
667     {
668         if (config->sw1CurrentLimit != kPF5020_BuckRegulatorCurrentLimitBypass)
669         {
670             enableILIMBypass = false;
671             value |= PF5020_BUCK_REGULATOR_ILIM(config->sw1CurrentLimit);
672             mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
673         }
674 
675         status = PF5020_SetRegulatorCommonConfig(
676             handle, kPF5020_BuckRegulatorSw1, config->sw1EnableUVBypass, config->sw1EnableOVBypass,
677             config->sw1EnableWatchdogBypass, config->sw1EnablePGMonitor, config->sw1FaultReEnabled, enableILIMBypass);
678 
679         if (status == kStatus_Success)
680         {
681             value |= PF5020_BUCK_REGULATOR_PHASE(config->sw1PhaseShift);
682             mask |= PF5020_BUCK_REGULATOR_PHASE_MASK;
683             /* Set SW1 Config2 register, this register can be used to set current limitation value and phase shift.  */
684             status = PF5020_ModifyReg(handle, PF5020_SW1_CONFIG2, mask, value);
685         }
686     }
687 
688     return status;
689 }
690 
691 /*!
692  * brief Set DVS Ramp for SW1 buck regulator.
693  *
694  * param handle The pointer to pf5020_handle_t structure.
695  * param dvsRamp The DVS ramp value to set, please refer to pf5020_type1_buck_regulator_dvs_ramp_t for details.
696  * retval #kStatus_Success The transaction was started successfully.
697  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
698  *      transaction is already in progress.
699  */
PF5020_SW1_SetDvsRamp(pf5020_handle_t * handle,pf5020_type1_buck_regulator_dvs_ramp_t dvsRamp)700 status_t PF5020_SW1_SetDvsRamp(pf5020_handle_t *handle, pf5020_type1_buck_regulator_dvs_ramp_t dvsRamp)
701 {
702     assert(handle);
703 
704     return PF5020_ModifyReg(handle, PF5020_SW_RAMP, 0x3U, (uint8_t)dvsRamp);
705 }
706 
707 /*!
708  * brief Set SW1 regulator's output voltage and operate mode in run state.
709  *
710  * param handle The pointer to pf5020_handle_t structure.
711  * param runOutputVolt The output voltage of SW1 in run state.
712  * param runOperateMode The operate mode of SW1 in run state.
713  * retval #kStatus_Success The transaction was started successfully.
714  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
715  *      transaction is already in progress.
716  */
PF5020_SW1_SetRunStateOption(pf5020_handle_t * handle,uint8_t runOutputVolt,pf5020_buck_regulator_operate_mode_t runOperateMode)717 status_t PF5020_SW1_SetRunStateOption(pf5020_handle_t *handle,
718                                       uint8_t runOutputVolt,
719                                       pf5020_buck_regulator_operate_mode_t runOperateMode)
720 {
721     assert(handle);
722 
723     uint8_t sw1RunMode;
724     uint8_t sw1RunVolt;
725     status_t status = kStatus_Success;
726 
727     (void)PF5020_ReadReg(handle, PF5020_SW1_MODE, &sw1RunMode);
728     sw1RunMode &= PF5020_BUCK_REGULATOR_RUN_MODE_MASK;
729     sw1RunMode = sw1RunMode >> PF5020_BUCK_REGULATOR_RUN_MODE_SHIFT;
730     (void)PF5020_ReadReg(handle, PF5020_SW1_RUN_VOLT, &sw1RunVolt);
731 
732     if (sw1RunVolt != runOutputVolt)
733     {
734         status = PF5020_WriteReg(handle, PF5020_SW1_RUN_VOLT, runOutputVolt);
735     }
736     if ((sw1RunMode != (uint8_t)runOperateMode) && (status == kStatus_Success))
737     {
738         status = PF5020_ModifyReg(handle, PF5020_SW1_MODE, PF5020_BUCK_REGULATOR_RUN_MODE_MASK,
739                                   PF5020_BUCK_REGULATOR_RUN_MODE(runOperateMode));
740     }
741 
742     return status;
743 }
744 
745 /*!
746  * brief Set SW1 regulator's output voltage and operate mode in standby state.
747  *
748  * param handle The pointer to pf5020_handle_t structure.
749  * param standbyOutputVolt The output voltage of SW1 in standby state.
750  * param standbyOperateMode The operate mode of SW1 in standby state.
751  * retval #kStatus_Success The transaction was started successfully.
752  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
753  *      transaction is already in progress.
754  */
PF5020_SW1_SetStandbyStateOption(pf5020_handle_t * handle,uint8_t standbyOutputVolt,pf5020_buck_regulator_operate_mode_t standbyOperateMode)755 status_t PF5020_SW1_SetStandbyStateOption(pf5020_handle_t *handle,
756                                           uint8_t standbyOutputVolt,
757                                           pf5020_buck_regulator_operate_mode_t standbyOperateMode)
758 {
759     assert(handle);
760 
761     uint8_t sw1StandbyMode;
762     uint8_t sw1StandbyVolt;
763     status_t status = kStatus_Success;
764 
765     (void)PF5020_ReadReg(handle, PF5020_SW1_MODE, &sw1StandbyMode);
766     sw1StandbyMode &= PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK;
767     sw1StandbyMode = sw1StandbyMode >> PF5020_BUCK_REGULATOR_STANDBY_MODE_SHIFT;
768 
769     (void)PF5020_ReadReg(handle, PF5020_SW1_STBY_VOLT, &sw1StandbyVolt);
770 
771     if (sw1StandbyVolt != standbyOutputVolt)
772     {
773         status = PF5020_WriteReg(handle, PF5020_SW1_STBY_VOLT, standbyOutputVolt);
774     }
775 
776     if ((sw1StandbyMode != (uint8_t)standbyOperateMode) && (status == kStatus_Success))
777     {
778         status = PF5020_ModifyReg(handle, PF5020_SW1_MODE, PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK,
779                                   PF5020_BUCK_REGULATOR_STANDBY_MODE(standbyOperateMode));
780     }
781 
782     return status;
783 }
784 
785 /*!
786  * brief Set SW1 regulator fault detection related options.
787  *
788  * param handle The pointer to pf5020_handle_t structure.
789  * param currentLimit SW1 buck regulator current limitation value, please refer to
790  *                      pf5020_buck_regulator_current_limit_t for details.
791  * param enableUVBypass Enable/disable UV bypass.
792  * param enableOVBypass Enable/disable OV bypass.
793  * param faultReEnabled Used to control whether return to sw1 regulator previous state if fault condition is cleared.
794  * retval #kStatus_Success The transaction was started successfully.
795  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
796  *      transaction is already in progress.
797  */
PF5020_SW1_SetFaultDetection(pf5020_handle_t * handle,pf5020_buck_regulator_current_limit_t currentLimit,bool enableUVBypass,bool enableOVBypass,bool faultReEnabled)798 status_t PF5020_SW1_SetFaultDetection(pf5020_handle_t *handle,
799                                       pf5020_buck_regulator_current_limit_t currentLimit,
800                                       bool enableUVBypass,
801                                       bool enableOVBypass,
802                                       bool faultReEnabled)
803 {
804     assert(handle);
805 
806     status_t status;
807     bool enableILIMBypass   = false;
808     uint8_t sw1Config2Mask  = 0U;
809     uint8_t sw1Config2Value = 0U;
810 
811     if (currentLimit == kPF5020_BuckRegulatorCurrentLimitBypass)
812     {
813         enableILIMBypass = true;
814     }
815     else
816     {
817         sw1Config2Mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
818         sw1Config2Value |= PF5020_BUCK_REGULATOR_ILIM(currentLimit);
819     }
820 
821     sw1Config2Mask |= PF5020_REGULATOR_FLT_REN_MASK;
822     sw1Config2Value |= PF5020_REGULATOR_FLT_REN(faultReEnabled);
823     status = PF5020_ModifyReg(handle, PF5020_SW1_CONFIG2, sw1Config2Mask, sw1Config2Value);
824 
825     if (status == kStatus_Success)
826     {
827         status = PF5020_ModifyReg(
828             handle, PF5020_SW1_CONFIG1,
829             PF5020_REGULATOR_ILIM_BYPASS_MASK | PF5020_REGULATOR_OV_BYPASS_MASK | PF5020_REGULATOR_UV_BYPASS_MASK,
830             PF5020_REGULATOR_ILIM_BYPASS(enableILIMBypass) | PF5020_REGULATOR_OV_BYPASS(enableOVBypass) |
831                 PF5020_REGULATOR_UV_BYPASS(enableUVBypass));
832     }
833 
834     return status;
835 }
836 
837 /*!
838  * brief Set SW1 regulator phase shift value.
839  *
840  * param handle The pointer to pf5020_handle_t structure.
841  * param phaseShift SW1 buck regulator phase shift value, please refer to pf5020_buck_regulator_phase_shift_t
842  *                   for details.
843  * retval #kStatus_Success The transaction was started successfully.
844  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
845  *      transaction is already in progress.
846  */
PF5020_SW1_SetPhaseShift(pf5020_handle_t * handle,pf5020_buck_regulator_phase_shift_t phaseShift)847 status_t PF5020_SW1_SetPhaseShift(pf5020_handle_t *handle, pf5020_buck_regulator_phase_shift_t phaseShift)
848 {
849     assert(handle);
850 
851     status_t status = kStatus_Success;
852     uint8_t sw1Phase;
853 
854     (void)PF5020_ReadReg(handle, PF5020_SW1_CONFIG2, &sw1Phase);
855     sw1Phase &= PF5020_BUCK_REGULATOR_PHASE_MASK;
856     sw1Phase = sw1Phase >> PF5020_BUCK_REGULATOR_PHASE_SHIFT;
857 
858     if (sw1Phase != (uint8_t)phaseShift)
859     {
860         status = PF5020_ModifyReg(handle, PF5020_SW1_CONFIG2, PF5020_BUCK_REGULATOR_PHASE_MASK,
861                                   PF5020_BUCK_REGULATOR_PHASE(phaseShift));
862     }
863 
864     return status;
865 }
866 
867 /*!
868  * brief Enable/disable PG monitor for SW1 regulator.
869  *
870  * param handle The pointer to pf5020_handle_t structure.
871  * param enable Enable/disable PG monitor.
872  * retval #kStatus_Success The transaction was started successfully.
873  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
874  *      transaction is already in progress.
875  */
PF5020_SW1_EnablePGMonitor(pf5020_handle_t * handle,bool enable)876 status_t PF5020_SW1_EnablePGMonitor(pf5020_handle_t *handle, bool enable)
877 {
878     assert(handle);
879 
880     return PF5020_ModifyReg(handle, PF5020_SW1_CONFIG1, PF5020_REGULATOR_PG_EN_MASK, PF5020_REGULATOR_PG_EN(enable));
881 }
882 
883 /*!
884  * brief Enable/disable watchdog bypass for SW1 regulator.
885  *
886  * param handle The pointer to pf5020_handle_t structure.
887  * param enable Enable/disable watchdog bypass.
888  * retval #kStatus_Success The transaction was started successfully.
889  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
890  *      transaction is already in progress.
891  */
PF5020_SW1_EnableWatchDogBypass(pf5020_handle_t * handle,bool enable)892 status_t PF5020_SW1_EnableWatchDogBypass(pf5020_handle_t *handle, bool enable)
893 {
894     assert(handle);
895 
896     return PF5020_ModifyReg(handle, PF5020_SW1_CONFIG1, PF5020_REGULATOR_WDBYPASS_MASK,
897                             PF5020_REGULATOR_WDBYPASS(enable));
898 }
899 
900 /*!
901  * brief Set SW2 Buck regulator global configuration.
902  *
903  * param handle The pointer to pf5020_handle_t structure.
904  * param config The pointer to pf5020_sw2_regulator_config_t structure.
905  * retval #kStatus_Success The transaction was started successfully.
906  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
907  *      transaction is already in progress.
908  */
PF5020_SW2_SetGlobalConfig(pf5020_handle_t * handle,const pf5020_sw2_regulator_config_t * config)909 status_t PF5020_SW2_SetGlobalConfig(pf5020_handle_t *handle, const pf5020_sw2_regulator_config_t *config)
910 {
911     assert(handle);
912     assert(config);
913 
914     status_t status;
915     uint8_t value         = 0U;
916     uint8_t mask          = 0U;
917     bool enableILIMBypass = true;
918 
919     /* Set SW2 DVS Ramp. */
920     status = PF5020_ModifyReg(handle, PF5020_SW_RAMP, 0xCU, ((uint8_t)config->sw2DvsRamp) << 2U);
921 
922     if (status == kStatus_Success)
923     {
924         /* Set SW2 output voltage in run state. */
925         status = PF5020_WriteReg(handle, PF5020_SW2_RUN_VOLT, config->sw2RunOutputVolt);
926     }
927     if (status == kStatus_Success)
928     {
929         /* Set SW2 output voltage in standby state. */
930         status = PF5020_WriteReg(handle, PF5020_SW2_STBY_VOLT, config->sw2StandbyOutputVolt);
931     }
932 
933     if (status == kStatus_Success)
934     {
935         /* Update SW2 operate mode in run/standby state. */
936         status = PF5020_ModifyReg(handle, PF5020_SW2_MODE1,
937                                   PF5020_BUCK_REGULATOR_RUN_MODE_MASK | PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK,
938                                   PF5020_BUCK_REGULATOR_RUN_MODE(config->sw2RunOperateMode) |
939                                       PF5020_BUCK_REGULATOR_STANDBY_MODE(config->sw2StandbyOperateMode));
940     }
941     if (status == kStatus_Success)
942     {
943         if (config->sw2CurrentLimit != kPF5020_BuckRegulatorCurrentLimitBypass)
944         {
945             enableILIMBypass = false;
946             value |= PF5020_BUCK_REGULATOR_ILIM(config->sw2CurrentLimit);
947             mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
948         }
949         status = PF5020_SetRegulatorCommonConfig(
950             handle, kPF5020_BuckRegulatorSw2, config->sw2EnableUVBypass, config->sw2EnableOVBypass,
951             config->sw2EnableWatchdogBypass, config->sw2EnablePGMonitor, config->sw2FaultReEnabled, enableILIMBypass);
952 
953         if (status == kStatus_Success)
954         {
955             value |= PF5020_BUCK_REGULATOR_PHASE(config->sw2PhaseShift) |
956                      PF5020_SW2_CONFIG2_VTTEN(config->sw2EnableVTTOperation);
957             mask |= PF5020_BUCK_REGULATOR_PHASE_MASK | PF5020_SW2_CONFIG2_VTTEN_MASK;
958             /* Update SW2 CONFIG2 register, this register can be used to set current limitation and phase shift. */
959             status = PF5020_ModifyReg(handle, PF5020_SW2_CONFIG2, mask, value);
960         }
961     }
962 
963     return status;
964 }
965 
966 /*!
967  * brief Set DVS Ramp for SW2 buck regulator.
968  *
969  * param handle The pointer to pf5020_handle_t structure.
970  * param dvsRamp The DVS ramp value to set, please refer to pf5020_type1_buck_regulator_dvs_ramp_t for details.
971  * retval #kStatus_Success The transaction was started successfully.
972  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
973  *      transaction is already in progress.
974  */
PF5020_SW2_SetDvsRamp(pf5020_handle_t * handle,pf5020_type1_buck_regulator_dvs_ramp_t dvsRamp)975 status_t PF5020_SW2_SetDvsRamp(pf5020_handle_t *handle, pf5020_type1_buck_regulator_dvs_ramp_t dvsRamp)
976 {
977     assert(handle);
978 
979     return PF5020_ModifyReg(handle, PF5020_SW_RAMP, 0xCU, ((uint8_t)dvsRamp << 2U));
980 }
981 
982 /*!
983  * brief Set SW2 regulator's output voltage and operate mode in run state.
984  *
985  * param handle The pointer to pf5020_handle_t structure.
986  * param runOutputVolt The output voltage of SW2 in run state.
987  * param runOperateMode The operate mode of SW2 in run state.
988  * retval #kStatus_Success The transaction was started successfully.
989  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
990  *      transaction is already in progress.
991  */
PF5020_SW2_SetRunStateOption(pf5020_handle_t * handle,uint8_t runOutputVolt,pf5020_buck_regulator_operate_mode_t runOperateMode)992 status_t PF5020_SW2_SetRunStateOption(pf5020_handle_t *handle,
993                                       uint8_t runOutputVolt,
994                                       pf5020_buck_regulator_operate_mode_t runOperateMode)
995 {
996     assert(handle);
997 
998     uint8_t sw2RunMode;
999     uint8_t sw2RunVolt;
1000     status_t status = kStatus_Success;
1001 
1002     (void)PF5020_ReadReg(handle, PF5020_SW2_MODE1, &sw2RunMode);
1003     sw2RunMode &= PF5020_BUCK_REGULATOR_RUN_MODE_MASK;
1004     sw2RunMode = sw2RunMode >> PF5020_BUCK_REGULATOR_RUN_MODE_SHIFT;
1005     (void)PF5020_ReadReg(handle, PF5020_SW2_RUN_VOLT, &sw2RunVolt);
1006 
1007     if (sw2RunVolt != runOutputVolt)
1008     {
1009         status = PF5020_WriteReg(handle, PF5020_SW2_RUN_VOLT, runOutputVolt);
1010     }
1011     if ((sw2RunMode != (uint8_t)runOperateMode) && (status == kStatus_Success))
1012     {
1013         status = PF5020_ModifyReg(handle, PF5020_SW2_MODE1, PF5020_BUCK_REGULATOR_RUN_MODE_MASK,
1014                                   PF5020_BUCK_REGULATOR_RUN_MODE(runOperateMode));
1015     }
1016 
1017     return status;
1018 }
1019 
1020 /*!
1021  * brief Set SW2 regulator's output voltage and operate mode in standby state.
1022  *
1023  * param handle The pointer to pf5020_handle_t structure.
1024  * param standbyOutputVolt The output voltage of SW2 in standby state.
1025  * param standbyOperateMode The operate mode of SW2 in standby state.
1026  * retval #kStatus_Success The transaction was started successfully.
1027  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1028  *      transaction is already in progress.
1029  */
PF5020_SW2_SetStandbyStateOption(pf5020_handle_t * handle,uint8_t standbyOutputVolt,pf5020_buck_regulator_operate_mode_t standbyOperateMode)1030 status_t PF5020_SW2_SetStandbyStateOption(pf5020_handle_t *handle,
1031                                           uint8_t standbyOutputVolt,
1032                                           pf5020_buck_regulator_operate_mode_t standbyOperateMode)
1033 {
1034     assert(handle);
1035 
1036     uint8_t sw2StandbyMode;
1037     uint8_t sw2StandbyVolt;
1038     status_t status = kStatus_Success;
1039 
1040     (void)PF5020_ReadReg(handle, PF5020_SW2_MODE1, &sw2StandbyMode);
1041     sw2StandbyMode &= PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK;
1042     sw2StandbyVolt = sw2StandbyMode >> PF5020_BUCK_REGULATOR_STANDBY_MODE_SHIFT;
1043 
1044     (void)PF5020_ReadReg(handle, PF5020_SW2_STBY_VOLT, &sw2StandbyVolt);
1045 
1046     if (sw2StandbyVolt != standbyOutputVolt)
1047     {
1048         status = PF5020_WriteReg(handle, PF5020_SW2_STBY_VOLT, standbyOutputVolt);
1049     }
1050 
1051     if ((sw2StandbyMode != (uint8_t)standbyOperateMode) && (status == kStatus_Success))
1052     {
1053         status = PF5020_ModifyReg(handle, PF5020_SW2_MODE1, PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK,
1054                                   PF5020_BUCK_REGULATOR_STANDBY_MODE(standbyOperateMode));
1055     }
1056 
1057     return status;
1058 }
1059 
1060 /*!
1061  * brief Set SW2 regulator phase shift value.
1062  *
1063  * param handle The pointer to pf5020_handle_t structure.
1064  * param phaseShift SW2 buck regulator phase shift value, please refer to pf5020_buck_regulator_phase_shift_t
1065  *                   for details.
1066  * retval #kStatus_Success The transaction was started successfully.
1067  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1068  *      transaction is already in progress.
1069  */
PF5020_SW2_SetPhaseShift(pf5020_handle_t * handle,pf5020_buck_regulator_phase_shift_t phaseShift)1070 status_t PF5020_SW2_SetPhaseShift(pf5020_handle_t *handle, pf5020_buck_regulator_phase_shift_t phaseShift)
1071 {
1072     assert(handle);
1073 
1074     status_t status = kStatus_Success;
1075     uint8_t sw2Phase;
1076 
1077     (void)PF5020_ReadReg(handle, PF5020_SW2_CONFIG2, &sw2Phase);
1078     sw2Phase &= PF5020_BUCK_REGULATOR_PHASE_MASK;
1079     sw2Phase = sw2Phase >> PF5020_BUCK_REGULATOR_PHASE_SHIFT;
1080 
1081     if (sw2Phase != (uint8_t)phaseShift)
1082     {
1083         status = PF5020_ModifyReg(handle, PF5020_SW2_CONFIG2, PF5020_BUCK_REGULATOR_PHASE_MASK,
1084                                   PF5020_BUCK_REGULATOR_PHASE(phaseShift));
1085     }
1086 
1087     return status;
1088 }
1089 
1090 /*!
1091  * brief Enable/disable SW2 VTT operateion.
1092  *
1093  * param handle The pointer to pf5020_handle_t structure.
1094  * param enable Used to enable/disable VTT operation.
1095  * retval #kStatus_Success The transaction was started successfully.
1096  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1097  *      transaction is already in progress.
1098  */
PF5020_SW2_EnableVTTOperation(pf5020_handle_t * handle,bool enable)1099 status_t PF5020_SW2_EnableVTTOperation(pf5020_handle_t *handle, bool enable)
1100 {
1101     return PF5020_ModifyReg(handle, PF5020_SW2_CONFIG2, PF5020_SW2_CONFIG2_VTTEN_MASK,
1102                             PF5020_SW2_CONFIG2_VTTEN(enable));
1103 }
1104 
1105 /*!
1106  * brief Set SW2 regulator fault detection related options.
1107  *
1108  * param handle The pointer to pf5020_handle_t structure.
1109  * param currentLimit SW2 buck regulator current limitation value, please refer to
1110  *                      pf5020_buck_regulator_current_limit_t for details.
1111  * param enableUVBypass Enable/disable UV bypass.
1112  * param enableOVBypass Enable/disable OV bypass.
1113  * param faultReEnabled Used to control whether return to sw1 regulator previous state if fault condition is cleared.
1114  * retval #kStatus_Success The transaction was started successfully.
1115  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1116  *      transaction is already in progress.
1117  */
PF5020_SW2_SetFaultDetection(pf5020_handle_t * handle,pf5020_buck_regulator_current_limit_t currentLimit,bool enableUVBypass,bool enableOVBypass,bool faultReEnabled)1118 status_t PF5020_SW2_SetFaultDetection(pf5020_handle_t *handle,
1119                                       pf5020_buck_regulator_current_limit_t currentLimit,
1120                                       bool enableUVBypass,
1121                                       bool enableOVBypass,
1122                                       bool faultReEnabled)
1123 {
1124     assert(handle);
1125 
1126     status_t status;
1127     bool enableILIMBypass   = false;
1128     uint8_t sw2Config2Mask  = 0U;
1129     uint8_t sw2Config2Value = 0U;
1130 
1131     if (currentLimit == kPF5020_BuckRegulatorCurrentLimitBypass)
1132     {
1133         enableILIMBypass = true;
1134     }
1135     else
1136     {
1137         sw2Config2Mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
1138         sw2Config2Value |= PF5020_BUCK_REGULATOR_ILIM(currentLimit);
1139     }
1140 
1141     sw2Config2Mask |= PF5020_REGULATOR_FLT_REN_MASK;
1142     sw2Config2Value |= PF5020_REGULATOR_FLT_REN(faultReEnabled);
1143     status = PF5020_ModifyReg(handle, PF5020_SW1_CONFIG2, sw2Config2Mask, sw2Config2Value);
1144 
1145     if (status == kStatus_Success)
1146     {
1147         status = PF5020_ModifyReg(
1148             handle, PF5020_SW1_CONFIG1,
1149             PF5020_REGULATOR_ILIM_BYPASS_MASK | PF5020_REGULATOR_OV_BYPASS_MASK | PF5020_REGULATOR_UV_BYPASS_MASK,
1150             PF5020_REGULATOR_ILIM_BYPASS(enableILIMBypass) | PF5020_REGULATOR_OV_BYPASS(enableOVBypass) |
1151                 PF5020_REGULATOR_UV_BYPASS(enableUVBypass));
1152     }
1153 
1154     return status;
1155 }
1156 
1157 /*!
1158  * brief Enable/disable PG monitor for SW2 regulator.
1159  *
1160  * param handle The pointer to pf5020_handle_t structure.
1161  * param enable Enable/disable PG monitor.
1162  * retval #kStatus_Success The transaction was started successfully.
1163  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1164  *      transaction is already in progress.
1165  */
PF5020_SW2_EnablePGMonitor(pf5020_handle_t * handle,bool enable)1166 status_t PF5020_SW2_EnablePGMonitor(pf5020_handle_t *handle, bool enable)
1167 {
1168     return PF5020_ModifyReg(handle, PF5020_SW2_CONFIG1, PF5020_REGULATOR_PG_EN_MASK, PF5020_REGULATOR_PG_EN(enable));
1169 }
1170 
1171 /*!
1172  * brief Enable/disable watchdog bypass for SW2 regulator.
1173  *
1174  * param handle The pointer to pf5020_handle_t structure.
1175  * param enable Enable/disable watchdog bypass.
1176  * retval #kStatus_Success The transaction was started successfully.
1177  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1178  *      transaction is already in progress.
1179  */
PF5020_SW2_EnableWatchDogBypass(pf5020_handle_t * handle,bool enable)1180 status_t PF5020_SW2_EnableWatchDogBypass(pf5020_handle_t *handle, bool enable)
1181 {
1182     return PF5020_ModifyReg(handle, PF5020_SW2_CONFIG1, PF5020_REGULATOR_WDBYPASS_MASK,
1183                             PF5020_REGULATOR_WDBYPASS(enable));
1184 }
1185 
1186 /*!
1187  * brief Set SWND1 Buck regulator global configuration.
1188  *
1189  * param handle The pointer to pf5020_handle_t structure.
1190  * param config The pointer to pf5020_swnd1_regulator_config_t structure.
1191  * retval #kStatus_Success The transaction was started successfully.
1192  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1193  *      transaction is already in progress.
1194  */
PF5020_SWND1_SetGlobalConfig(pf5020_handle_t * handle,const pf5020_swnd1_regulator_config_t * config)1195 status_t PF5020_SWND1_SetGlobalConfig(pf5020_handle_t *handle, const pf5020_swnd1_regulator_config_t *config)
1196 {
1197     assert(handle);
1198     assert(config);
1199 
1200     status_t status       = kStatus_Success;
1201     uint8_t value         = 0U;
1202     uint8_t mask          = 0U;
1203     bool enableILIMBypass = true;
1204 
1205     /* Set output voltage in run/standby state. */
1206     status = PF5020_WriteReg(handle, PF5020_SWND1_RUN_VOLT, (uint8_t)(config->swnd1OutputVolt));
1207 
1208     if (status == kStatus_Success)
1209     {
1210         /* Set SWND1 operate mode in run/standby state. */
1211         status = PF5020_ModifyReg(handle, PF5020_SWND1_MODE1,
1212                                   PF5020_BUCK_REGULATOR_RUN_MODE_MASK | PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK,
1213                                   PF5020_BUCK_REGULATOR_RUN_MODE(config->swnd1RunOperateMode) |
1214                                       PF5020_BUCK_REGULATOR_STANDBY_MODE(config->swnd1StandbyOperateMode));
1215     }
1216 
1217     if (status == kStatus_Success)
1218     {
1219         if (config->swnd1CurrentLimit != kPF5020_BuckRegulatorCurrentLimitBypass)
1220         {
1221             enableILIMBypass = false;
1222             value |= PF5020_BUCK_REGULATOR_ILIM(config->swnd1CurrentLimit);
1223             mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
1224         }
1225         status = PF5020_SetRegulatorCommonConfig(handle, kPF5020_BuckRegulatorSwnd1, config->swnd1EnableUVBypass,
1226                                                  config->swnd1EnableOVBypass, config->swnd1EnableWatchdogBypass,
1227                                                  config->swnd1EnablePGMonitor, config->swnd1FaultReEnabled,
1228                                                  enableILIMBypass);
1229 
1230         if (status == kStatus_Success)
1231         {
1232             value |= PF5020_BUCK_REGULATOR_PHASE(config->swnd1PhaseShift);
1233             mask |= PF5020_BUCK_REGULATOR_PHASE_MASK;
1234             /* Update SWND1 CONFIG2 register, this register can be used to set current limitation and phase shift. */
1235             status = PF5020_ModifyReg(handle, PF5020_SWND1_CONFIG2, mask, value);
1236         }
1237     }
1238 
1239     return status;
1240 }
1241 
1242 /*!
1243  * brief Set run/standby output voltage for SWND1 regulator.
1244  *
1245  * param handle The pointer to pf5020_handle_t structure.
1246  * param outputVolt The output voltage of SWND1 regulator in run/standby state,
1247  *                  please refer to pf5020_swnd1_output_voltage_t for details.
1248  * retval #kStatus_Success The transaction was started successfully.
1249  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1250  *      transaction is already in progress.
1251  */
PF5020_SWND1_SetOutputVoltage(pf5020_handle_t * handle,pf5020_swnd1_output_voltage_t outputVolt)1252 status_t PF5020_SWND1_SetOutputVoltage(pf5020_handle_t *handle, pf5020_swnd1_output_voltage_t outputVolt)
1253 {
1254     assert(handle);
1255 
1256     uint8_t swnd1Volt;
1257     status_t status = kStatus_Success;
1258 
1259     (void)PF5020_ReadReg(handle, PF5020_SWND1_RUN_VOLT, &swnd1Volt);
1260 
1261     if (swnd1Volt != (uint8_t)outputVolt)
1262     {
1263         status = PF5020_WriteReg(handle, PF5020_SWND1_RUN_VOLT, (uint8_t)outputVolt);
1264     }
1265 
1266     return status;
1267 }
1268 
1269 /*!
1270  * brief Set SWND1 regulator's operate mode in run and standby state.
1271  *
1272  * param handle The pointer to pf5020_handle_t structure.
1273  * param runOperateMode The operate mode of SWND1 in run state, please refer to pf5020_buck_regulator_operate_mode_t.
1274  * param standbyOperateMode The operate mode of SWND1 in standby state, please refer to
1275  * pf5020_buck_regulator_operate_mode_t. retval #kStatus_Success The transaction was started successfully. retval
1276  * #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking transaction is already in
1277  * progress.
1278  */
PF5020_SWND1_SetOperateMode(pf5020_handle_t * handle,pf5020_buck_regulator_operate_mode_t runOperateMode,pf5020_buck_regulator_operate_mode_t standbyOperateMode)1279 status_t PF5020_SWND1_SetOperateMode(pf5020_handle_t *handle,
1280                                      pf5020_buck_regulator_operate_mode_t runOperateMode,
1281                                      pf5020_buck_regulator_operate_mode_t standbyOperateMode)
1282 {
1283     assert(handle);
1284 
1285     uint8_t tmp8;
1286     uint8_t swnd1RunMode;
1287     uint8_t swnd1StandbyMode;
1288     status_t status;
1289 
1290     (void)PF5020_ReadReg(handle, PF5020_SWND1_MODE1, &tmp8);
1291 
1292     swnd1RunMode     = (tmp8 & PF5020_BUCK_REGULATOR_RUN_MODE_MASK);
1293     swnd1StandbyMode = ((tmp8 & PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK) >> PF5020_BUCK_REGULATOR_STANDBY_MODE_SHIFT);
1294 
1295     if (swnd1RunMode != (uint8_t)runOperateMode)
1296     {
1297         tmp8 =
1298             ((tmp8 & (uint8_t)(~PF5020_BUCK_REGULATOR_RUN_MODE_MASK)) | PF5020_BUCK_REGULATOR_RUN_MODE(runOperateMode));
1299     }
1300 
1301     if (swnd1StandbyMode != (uint8_t)standbyOperateMode)
1302     {
1303         tmp8 = ((tmp8 & (uint8_t)(~PF5020_BUCK_REGULATOR_STANDBY_MODE_MASK)) |
1304                 PF5020_BUCK_REGULATOR_STANDBY_MODE(standbyOperateMode));
1305     }
1306 
1307     status = PF5020_WriteReg(handle, PF5020_SWND1_MODE1, tmp8);
1308 
1309     return status;
1310 }
1311 
1312 /*!
1313  * brief Set SWND1 regulator phase shift value.
1314  *
1315  * param handle The pointer to pf5020_handle_t structure.
1316  * param phaseShift SWND1 buck regulator phase shift value, please refer to pf5020_buck_regulator_phase_shift_t
1317  *                   for details.
1318  * retval #kStatus_Success The transaction was started successfully.
1319  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1320  *      transaction is already in progress.
1321  */
PF5020_SWND1_SetPhaseShift(pf5020_handle_t * handle,pf5020_buck_regulator_phase_shift_t phaseShift)1322 status_t PF5020_SWND1_SetPhaseShift(pf5020_handle_t *handle, pf5020_buck_regulator_phase_shift_t phaseShift)
1323 {
1324     assert(handle);
1325 
1326     status_t status = kStatus_Success;
1327     uint8_t swnd1Phase;
1328 
1329     (void)PF5020_ReadReg(handle, PF5020_SWND1_CONFIG2, &swnd1Phase);
1330     swnd1Phase &= PF5020_BUCK_REGULATOR_PHASE_MASK;
1331     swnd1Phase = swnd1Phase >> PF5020_BUCK_REGULATOR_PHASE_SHIFT;
1332 
1333     if (swnd1Phase != (uint8_t)phaseShift)
1334     {
1335         status = PF5020_ModifyReg(handle, PF5020_SWND1_CONFIG2, PF5020_BUCK_REGULATOR_PHASE_MASK,
1336                                   PF5020_BUCK_REGULATOR_PHASE(phaseShift));
1337     }
1338 
1339     return status;
1340 }
1341 
1342 /*!
1343  * brief Set SWND1 regulator fault detection related options.
1344  *
1345  * param handle The pointer to pf5020_handle_t structure.
1346  * param currentLimit SWND1 buck regulator current limitation value, please refer to
1347  *                      pf5020_buck_regulator_current_limit_t for details.
1348  * param enableUVBypass Enable/disable UV bypass.
1349  * param enableOVBypass Enable/disable OV bypass.
1350  * param faultReEnabled Used to control whether return to sw1 regulator previous state if fault condition is cleared.
1351  * retval #kStatus_Success The transaction was started successfully.
1352  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1353  *      transaction is already in progress.
1354  */
PF5020_SWND1_SetFaultDetection(pf5020_handle_t * handle,pf5020_buck_regulator_current_limit_t currentLimit,bool enableUVBypass,bool enableOVBypass,bool faultReEnabled)1355 status_t PF5020_SWND1_SetFaultDetection(pf5020_handle_t *handle,
1356                                         pf5020_buck_regulator_current_limit_t currentLimit,
1357                                         bool enableUVBypass,
1358                                         bool enableOVBypass,
1359                                         bool faultReEnabled)
1360 {
1361     assert(handle);
1362 
1363     status_t status;
1364     bool enableILIMBypass     = false;
1365     uint8_t swnd1Config2Mask  = 0U;
1366     uint8_t swnd1Config2Value = 0U;
1367 
1368     if (currentLimit == kPF5020_BuckRegulatorCurrentLimitBypass)
1369     {
1370         enableILIMBypass = true;
1371     }
1372     else
1373     {
1374         swnd1Config2Mask |= PF5020_BUCK_REGULATOR_ILIM_MASK;
1375         swnd1Config2Value |= PF5020_BUCK_REGULATOR_ILIM(currentLimit);
1376     }
1377 
1378     swnd1Config2Mask |= PF5020_REGULATOR_FLT_REN_MASK;
1379     swnd1Config2Value |= PF5020_REGULATOR_FLT_REN(faultReEnabled);
1380     status = PF5020_ModifyReg(handle, PF5020_SWND1_CONFIG2, swnd1Config2Mask, swnd1Config2Value);
1381 
1382     if (status == kStatus_Success)
1383     {
1384         status = PF5020_ModifyReg(
1385             handle, PF5020_SWND1_CONFIG1,
1386             PF5020_REGULATOR_ILIM_BYPASS_MASK | PF5020_REGULATOR_OV_BYPASS_MASK | PF5020_REGULATOR_UV_BYPASS_MASK,
1387             PF5020_REGULATOR_ILIM_BYPASS(enableILIMBypass) | PF5020_REGULATOR_OV_BYPASS(enableOVBypass) |
1388                 PF5020_REGULATOR_UV_BYPASS(enableUVBypass));
1389     }
1390 
1391     return status;
1392 }
1393 
1394 /*!
1395  * brief Enable/disable PG monitor for SWND1 regulator.
1396  *
1397  * param handle The pointer to pf5020_handle_t structure.
1398  * param enable Enable/disable PG monitor.
1399  * retval #kStatus_Success The transaction was started successfully.
1400  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1401  *      transaction is already in progress.
1402  */
PF5020_SWND1_EnablePGMonitor(pf5020_handle_t * handle,bool enable)1403 status_t PF5020_SWND1_EnablePGMonitor(pf5020_handle_t *handle, bool enable)
1404 {
1405     assert(handle);
1406 
1407     return PF5020_ModifyReg(handle, PF5020_SWND1_CONFIG1, PF5020_REGULATOR_PG_EN_MASK, PF5020_REGULATOR_PG_EN(enable));
1408 }
1409 
1410 /*!
1411  * brief Enable/disable watchdog bypass for SW1 regulator.
1412  *
1413  * param handle The pointer to pf5020_handle_t structure.
1414  * param enable Enable/disable watchdog bypass.
1415  * retval #kStatus_Success The transaction was started successfully.
1416  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1417  *      transaction is already in progress.
1418  */
PF5020_SWND1_EnableWatchDogBypass(pf5020_handle_t * handle,bool enable)1419 status_t PF5020_SWND1_EnableWatchDogBypass(pf5020_handle_t *handle, bool enable)
1420 {
1421     assert(handle);
1422 
1423     return PF5020_ModifyReg(handle, PF5020_SWND1_CONFIG1, PF5020_REGULATOR_WDBYPASS_MASK,
1424                             PF5020_REGULATOR_WDBYPASS(enable));
1425 }
1426 
1427 /*!
1428  * brief Set LDO1 global configuration.
1429  *
1430  * param handle The pointer to pf5020_handle_t structure.
1431  * param config The pointer to pf5020_ldo1_regulator_config structure.
1432  * retval #kStatus_Success The transaction was started successfully.
1433  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1434  *      transaction is already in progress.
1435  */
PF5020_LDO1_SetGlobalConfig(pf5020_handle_t * handle,const pf5020_ldo1_regulator_config * config)1436 status_t PF5020_LDO1_SetGlobalConfig(pf5020_handle_t *handle, const pf5020_ldo1_regulator_config *config)
1437 {
1438     assert(handle);
1439     assert(config);
1440 
1441     status_t status = kStatus_Success;
1442 
1443     /* Set LDO1 output voltage in run state. */
1444     status = PF5020_WriteReg(handle, PF5020_LDO1_RUN_VOLT, (uint8_t)(config->ldo1RunOutputVolt));
1445 
1446     if (status == kStatus_Success)
1447     {
1448         /* Set LDO1 output voltage in standby state. */
1449         status = PF5020_WriteReg(handle, PF5020_LDO1_STBY_VOLT, (uint8_t)(config->ldo1StandbyOutputVolt));
1450     }
1451 
1452     if (status == kStatus_Success)
1453     {
1454         status = PF5020_ModifyReg(
1455             handle, PF5020_LDO1_CONFIG2, PF5020_LDO1_CONFIG2_RUN_EN_MASK | PF5020_LDO1_CONFIG2_STBY_EN_MASK,
1456             PF5020_LDO1_CONFIG2_STBY_EN(config->ldo1StandbyEnable) | PF5020_LDO1_CONFIG2_RUN_EN(config->ldo1RunEnable));
1457     }
1458 
1459     if (status == kStatus_Success)
1460     {
1461         status = PF5020_SetRegulatorCommonConfig(handle, kPF5020_RegulatorLdo1, config->ldo1EnableUVBypass,
1462                                                  config->ldo1EnableOVBypass, config->ldo1EnableWatchdogBypass,
1463                                                  config->ldo1EnablePGMonitor, config->ldo1FaultReEnabled,
1464                                                  config->ldo1EnableILIMBypass);
1465     }
1466 
1467     return status;
1468 }
1469 
1470 /*!
1471  * brief Set LDO1 regulator's output voltage and operate mode in run state.
1472  *
1473  * param handle The pointer to pf5020_handle_t structure.
1474  * param runEnable Enable/disable LDO1 in run state.
1475  * param runOuputVolt The output voltage of LDO1 in run state, please refer to pf5020_ldo1_output_voltage_t.
1476  * retval #kStatus_Success The transaction was started successfully.
1477  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1478  *      transaction is already in progress.
1479  */
PF5020_LDO1_SetRunStateOption(pf5020_handle_t * handle,bool runEnable,pf5020_ldo1_output_voltage_t runOuputVolt)1480 status_t PF5020_LDO1_SetRunStateOption(pf5020_handle_t *handle,
1481                                        bool runEnable,
1482                                        pf5020_ldo1_output_voltage_t runOuputVolt)
1483 {
1484     assert(handle);
1485 
1486     status_t status;
1487 
1488     if (runEnable)
1489     {
1490         status = PF5020_WriteReg(handle, PF5020_LDO1_RUN_VOLT, (uint8_t)runOuputVolt);
1491     }
1492     else
1493     {
1494         status = PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG2, PF5020_LDO1_CONFIG2_RUN_EN_MASK,
1495                                   PF5020_LDO1_CONFIG2_RUN_EN(runEnable));
1496     }
1497 
1498     return status;
1499 }
1500 
1501 /*!
1502  * brief Set LDO1 regulator's output voltage and operate mode in standby state.
1503  *
1504  * param handle The pointer to pf5020_handle_t structure.
1505  * param standbyEnable Enable/disable LDO1 in standby state.
1506  * param standbyOuputVolt The output voltage of LDO1 in standby state, please refer to pf5020_ldo1_output_voltage_t.
1507  * retval #kStatus_Success The transaction was started successfully.
1508  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1509  *      transaction is already in progress.
1510  */
PF5020_LDO1_SetStandbyStateOption(pf5020_handle_t * handle,bool standbyEnable,pf5020_ldo1_output_voltage_t standbyOuputVolt)1511 status_t PF5020_LDO1_SetStandbyStateOption(pf5020_handle_t *handle,
1512                                            bool standbyEnable,
1513                                            pf5020_ldo1_output_voltage_t standbyOuputVolt)
1514 {
1515     assert(handle);
1516 
1517     status_t status;
1518 
1519     if (standbyEnable)
1520     {
1521         status = PF5020_WriteReg(handle, PF5020_LDO1_STBY_VOLT, (uint8_t)standbyOuputVolt);
1522     }
1523     else
1524     {
1525         status = PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG2, PF5020_LDO1_CONFIG2_STBY_EN_MASK,
1526                                   PF5020_LDO1_CONFIG2_STBY_EN(standbyEnable));
1527     }
1528 
1529     return status;
1530 }
1531 
1532 /*!
1533  * brief Set SWND1 regulator fault detection related options.
1534  *
1535  * param handle The pointer to pf5020_handle_t structure.
1536  * param enableILIMBypass Enable/disable ILIM bypass.
1537  * param enableUVBypass Enable/disable UV bypass.
1538  * param enableOVBypass Enable/disable OV bypass.
1539  * param faultReEnabled Used to control whether return to ldos1 regulator previous state if fault condition is cleared.
1540  * retval #kStatus_Success The transaction was started successfully.
1541  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1542  *      transaction is already in progress.
1543  */
PF5020_LDO1_SetFaultDetection(pf5020_handle_t * handle,bool enableILIMBypass,bool enableUVBypass,bool enableOVBypass,bool faultReEnabled)1544 status_t PF5020_LDO1_SetFaultDetection(
1545     pf5020_handle_t *handle, bool enableILIMBypass, bool enableUVBypass, bool enableOVBypass, bool faultReEnabled)
1546 {
1547     assert(handle);
1548 
1549     status_t status;
1550 
1551     status = PF5020_ModifyReg(
1552         handle, PF5020_LDO1_CONFIG1,
1553         PF5020_REGULATOR_ILIM_BYPASS_MASK | PF5020_REGULATOR_OV_BYPASS_MASK | PF5020_REGULATOR_UV_BYPASS_MASK,
1554         PF5020_REGULATOR_ILIM_BYPASS(enableILIMBypass) | PF5020_REGULATOR_OV_BYPASS(enableOVBypass) |
1555             PF5020_REGULATOR_UV_BYPASS(enableUVBypass));
1556 
1557     if (status == kStatus_Success)
1558     {
1559         status = PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG2, PF5020_REGULATOR_FLT_REN_MASK,
1560                                   PF5020_REGULATOR_FLT_REN(faultReEnabled));
1561     }
1562 
1563     return status;
1564 }
1565 
1566 /*!
1567  * brief Enable/disable PG monitor for LDO1 regulator.
1568  *
1569  * param handle The pointer to pf5020_handle_t structure.
1570  * param enable Enable/disable PG monitor.
1571  * retval #kStatus_Success The transaction was started successfully.
1572  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1573  *      transaction is already in progress.
1574  */
PF5020_LDO1_EnablePGMonitor(pf5020_handle_t * handle,bool enable)1575 status_t PF5020_LDO1_EnablePGMonitor(pf5020_handle_t *handle, bool enable)
1576 {
1577     assert(handle);
1578 
1579     return PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG1, PF5020_REGULATOR_PG_EN_MASK, PF5020_REGULATOR_PG_EN(enable));
1580 }
1581 
1582 /*!
1583  * brief Enable/disable watchdog bypass for LDO1 regulator.
1584  *
1585  * param handle The pointer to pf5020_handle_t structure.
1586  * param enable Enable/disable watchdog bypass.
1587  * retval #kStatus_Success The transaction was started successfully.
1588  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1589  *      transaction is already in progress.
1590  */
PF5020_LDO1_EnableWatchDogBypass(pf5020_handle_t * handle,bool enable)1591 status_t PF5020_LDO1_EnableWatchDogBypass(pf5020_handle_t *handle, bool enable)
1592 {
1593     assert(handle);
1594 
1595     return PF5020_ModifyReg(handle, PF5020_LDO1_CONFIG1, PF5020_REGULATOR_WDBYPASS_MASK,
1596                             PF5020_REGULATOR_WDBYPASS(enable));
1597 }
1598 
1599 /*!
1600  * brief Set voltage monitor debounce time.
1601  *
1602  * param handle The pointer to pf5020_handle_t structure.
1603  * param uvDebounceTime UV monitor debounce time, please refer to pf5020_uv_debounce_time_t.
1604  * param ovDebounceTime OV monitor debounce time, please refer to pf5020_ov_debounce_time_t.
1605  * retval #kStatus_Success The transaction was started successfully.
1606  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1607  *      transaction is already in progress.
1608  */
PF5020_SetVoltageMonitorDebounceTime(pf5020_handle_t * handle,pf5020_uv_debounce_time_t uvDebounceTime,pf5020_ov_debounce_time_t ovDebounceTime)1609 status_t PF5020_SetVoltageMonitorDebounceTime(pf5020_handle_t *handle,
1610                                               pf5020_uv_debounce_time_t uvDebounceTime,
1611                                               pf5020_ov_debounce_time_t ovDebounceTime)
1612 {
1613     assert(handle);
1614 
1615     return PF5020_ModifyReg(handle, PF5020_CTRL3, PF5020_CTRL3_UV_DB_MASK | PF5020_CTRL3_OV_DB_MASK,
1616                             PF5020_CTRL3_UV_DB(uvDebounceTime) | PF5020_CTRL3_OV_DB(ovDebounceTime));
1617 }
1618 
1619 /*!
1620  * brief Enable/disable selected regulator's voltage monitor.
1621  *
1622  * param handle The pointer to pf5020_handle_t structure.
1623  * param name The regulator to be set.
1624  * param enable Enable/disable voltage monitor.
1625  * retval #kStatus_Success The transaction was started successfully.
1626  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1627  *      transaction is already in progress.
1628  */
PF5020_EnableVoltageMonitor(pf5020_handle_t * handle,pf5020_regulator_name_t name,bool enable)1629 status_t PF5020_EnableVoltageMonitor(pf5020_handle_t *handle, pf5020_regulator_name_t name, bool enable)
1630 {
1631     assert(handle);
1632 
1633     status_t status = kStatus_Success;
1634 
1635     switch (name)
1636     {
1637         case kPF5020_BuckRegulatorSw1:
1638         {
1639             status = PF5020_ModifyReg(handle, PF5020_VMONEN1, PF5020_VMONEN1_SW1VMON_EN_MASK,
1640                                       PF5020_VMONEN1_SW1VMON_EN(enable));
1641             break;
1642         }
1643         case kPF5020_BuckRegulatorSw2:
1644         {
1645             status = PF5020_ModifyReg(handle, PF5020_VMONEN1, PF5020_VMONEN1_SW2VMON_EN_MASK,
1646                                       PF5020_VMONEN1_SW2VMON_EN(enable));
1647             break;
1648         }
1649         case kPF5020_BuckRegulatorSwnd1:
1650         {
1651             status = PF5020_ModifyReg(handle, PF5020_VMONEN1, PF5020_VMONEN1_SWND1VMON_EN_MASK,
1652                                       PF5020_VMONEN1_SWND1VMON_EN(enable));
1653             break;
1654         }
1655         case kPF5020_RegulatorLdo1:
1656         {
1657             status = PF5020_ModifyReg(handle, PF5020_VMONEN2, PF5020_VMONEN2_LDO1VMON_EN_MASK,
1658                                       PF5020_VMONEN2_LDO1VMON_EN(enable));
1659             break;
1660         }
1661         default:
1662         {
1663             assert(false);
1664             break;
1665         }
1666     }
1667 
1668     return status;
1669 }
1670 
1671 /*!
1672  * brief Set fault counter maximum value.
1673  *
1674  * param handle Pointer to the pf5020_handle_t structure.
1675  * param maxValue Ranges from 0 to 15.
1676  * retval #kStatus_Success The transaction was started successfully.
1677  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1678  *      transaction is already in progress.
1679  */
PF5020_SetFaultCounterMaxValue(pf5020_handle_t * handle,uint8_t maxValue)1680 status_t PF5020_SetFaultCounterMaxValue(pf5020_handle_t *handle, uint8_t maxValue)
1681 {
1682     assert(handle);
1683 
1684     return PF5020_ModifyReg(handle, PF5020_FAULT_COUNTER, 0xF0U, ((maxValue << 4U) & 0xF0U));
1685 }
1686 
1687 /*!
1688  * brief Get fault counter current value.
1689  *
1690  * param handle The pointer to pf5020_handle_t structure.
1691  * retval #kStatus_Success The transaction was started successfully.
1692  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1693  *      transaction is already in progress.
1694  */
PF5020_GetFaultCounterCurrentValue(pf5020_handle_t * handle)1695 uint8_t PF5020_GetFaultCounterCurrentValue(pf5020_handle_t *handle)
1696 {
1697     assert(handle);
1698 
1699     uint8_t tmp8;
1700 
1701     (void)PF5020_ReadReg(handle, PF5020_FAULT_COUNTER, &tmp8);
1702     tmp8 = tmp8 & 0x0FU;
1703 
1704     return tmp8;
1705 }
1706 
1707 /*!
1708  * brief Set the expire value of the fault timer, when a regulator experiences a fault event, a fault timer will start.
1709  *
1710  * param handle Pointer to the pf5020_handle_t structure.
1711  * param expireValue The expire value of fault timer, ranges from 0 to 11, the actual expire time = 2 ^ expireValue.
1712  *
1713  * retval #kStatus_Success The transaction was started successfully.
1714  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1715  *      transaction is already in progress.
1716  */
PF5020_SetFaultTimerExpireValue(pf5020_handle_t * handle,uint8_t expireValue)1717 status_t PF5020_SetFaultTimerExpireValue(pf5020_handle_t *handle, uint8_t expireValue)
1718 {
1719     assert(handle);
1720 
1721     return PF5020_ModifyReg(handle, PF5020_FAULT_TIMERS, 0x0FU, (expireValue & 0x0FU));
1722 }
1723 
1724 /*!
1725  * brief Set reset behaviour asserted by WDI.
1726  *
1727  * param handle The pointer to pf5020_handle_t structure.
1728  * param wdiMode Used to control the WDI asserted performs a hard WD reset or soft WD reset.
1729  * retval #kStatus_Success The transaction was started successfully.
1730  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1731  *      transaction is already in progress.
1732  */
PF5020_WDOG_SetWDIMode(pf5020_handle_t * handle,pf5020_wdi_mode_t wdiMode)1733 status_t PF5020_WDOG_SetWDIMode(pf5020_handle_t *handle, pf5020_wdi_mode_t wdiMode)
1734 {
1735     assert(handle);
1736 
1737     return PF5020_ModifyReg(handle, PF5020_CTRL1, 0x20U, (((uint8_t)wdiMode << 5U) & 0x20U));
1738 }
1739 
1740 /*!
1741  * brief Enable/disable WDI watchdog event in standby state.
1742  *
1743  * param handle The pointer to pf5020_handle_t structure.
1744  * param enable Used to control whether generate a watchdog event in standby mode if the WDI is asserted.
1745  * retval #kStatus_Success The transaction was started successfully.
1746  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1747  *      transaction is already in progress.
1748  */
PF5020_WDOG_EnableWDIStanby(pf5020_handle_t * handle,bool enable)1749 status_t PF5020_WDOG_EnableWDIStanby(pf5020_handle_t *handle, bool enable)
1750 {
1751     assert(handle);
1752 
1753     return PF5020_ModifyReg(handle, PF5020_CTRL1, 0x2U, (((uint8_t)enable << 1U) & 0x2U));
1754 }
1755 
1756 /*!
1757  * brief Configure internal watchdog timer.
1758  *
1759  * param handle The pointer to pf5020_handle_t structure.
1760  * param config Pointer to pf5020_wdog_internal_timer_config_t structure.
1761  * retval #kStatus_Success The transaction was started successfully.
1762  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1763  *      transaction is already in progress.
1764  */
PF5020_WDOG_ConfigInternalTimer(pf5020_handle_t * handle,const pf5020_wdog_internal_timer_config_t * config)1765 status_t PF5020_WDOG_ConfigInternalTimer(pf5020_handle_t *handle, const pf5020_wdog_internal_timer_config_t *config)
1766 {
1767     assert(handle);
1768     assert(config);
1769 
1770     status_t status;
1771 
1772     status = PF5020_WriteReg(handle, PF5020_WD_CONFIG, config->timerDuration);
1773 
1774     if (status == kStatus_Success)
1775     {
1776         status = PF5020_ModifyReg(handle, PF5020_WD_EXPIRE, 0x70U, ((config->cyclicCounterMaxVale << 4U) & 0x70U));
1777     }
1778 
1779     if (status == kStatus_Success)
1780     {
1781         status = PF5020_ModifyReg(handle, PF5020_CTRL1, PF5020_CTRL1_WD_EN_MASK | PF5020_CTRL1_WD_STBY_EN_MASK,
1782                                   PF5020_CTRL1_WD_STBY_EN(config->enableStandby) | PF5020_CTRL1_WD_EN(config->enable));
1783     }
1784 
1785     return status;
1786 }
1787 
1788 /*!
1789  * brief Get cyclic counter current value.
1790  *
1791  * param handle The pointer to pf5020_handle_t structure.
1792  * return Current cyclic counter value.
1793  */
PF5020_WDOG_GetCyclicCounterValue(pf5020_handle_t * handle)1794 uint8_t PF5020_WDOG_GetCyclicCounterValue(pf5020_handle_t *handle)
1795 {
1796     assert(handle);
1797 
1798     uint8_t tmp8;
1799 
1800     (void)PF5020_ReadReg(handle, PF5020_WD_EXPIRE, &tmp8);
1801     tmp8 &= 0x7U;
1802 
1803     return tmp8;
1804 }
1805 
1806 /*!
1807  * brief Refresh internal watchdog timer.
1808  *
1809  * param handle The pointer to pf5020_handle_t structure.
1810  * retval #kStatus_Success The transaction was started successfully.
1811  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1812  *      transaction is already in progress.
1813  */
PF5020_WDOG_RefreshInternalTimer(pf5020_handle_t * handle)1814 status_t PF5020_WDOG_RefreshInternalTimer(pf5020_handle_t *handle)
1815 {
1816     assert(handle);
1817 
1818     return PF5020_WriteReg(handle, PF5020_WD_CLEAR, 0x1U);
1819 }
1820 
1821 /*!
1822  * brief Set watchdog event counter maximum value.
1823  *
1824  * param handle The pointer to pf5020_handle_t structure.
1825  * param maxValue The maximum value of watchdog event counter.
1826  * retval #kStatus_Success The transaction was started successfully.
1827  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1828  *      transaction is already in progress.
1829  */
PF5020_WDOG_SetWDEventCounterMaxValue(pf5020_handle_t * handle,uint8_t maxValue)1830 status_t PF5020_WDOG_SetWDEventCounterMaxValue(pf5020_handle_t *handle, uint8_t maxValue)
1831 {
1832     assert(handle);
1833 
1834     return PF5020_ModifyReg(handle, PF5020_WD_COUNTER, 0xF0U, ((maxValue << 4U) & 0xF0U));
1835 }
1836 
1837 /*!
1838  * brief Get watchdog event counter current value.
1839  *
1840  * param handle The pointer to pf5020_handle_t structure.
1841  * return Watch dog event counter current value.
1842  */
PF5020_WDOG_GetWDEventCounterCurrentValue(pf5020_handle_t * handle)1843 uint8_t PF5020_WDOG_GetWDEventCounterCurrentValue(pf5020_handle_t *handle)
1844 {
1845     assert(handle);
1846 
1847     uint8_t tmp8;
1848 
1849     (void)PF5020_ReadReg(handle, PF5020_WD_COUNTER, &tmp8);
1850     tmp8 &= 0xFU;
1851 
1852     return tmp8;
1853 }
1854 
1855 /*!
1856  * brief Configure internal thermal monitor.
1857  *
1858  * param handle The pointer to pf5020_handle_t structure.
1859  * param enable Enable/disable temperature sensor circuit.
1860  * param mode Used to set temperature sensor operate mode, please refer to pf5020_temp_sensor_operate_mode_t.
1861  * retval #kStatus_Success The transaction was started successfully.
1862  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1863  *      transaction is already in progress.
1864  */
PF5020_TMP_SetThermalMonitorConfig(pf5020_handle_t * handle,bool enable,pf5020_temp_sensor_operate_mode_t mode)1865 status_t PF5020_TMP_SetThermalMonitorConfig(pf5020_handle_t *handle,
1866                                             bool enable,
1867                                             pf5020_temp_sensor_operate_mode_t mode)
1868 {
1869     assert(handle);
1870 
1871     status_t status;
1872 
1873     status = PF5020_ModifyReg(handle, PF5020_CTRL1, PF5020_CTRL1_TMP_MON_EN_MASK, PF5020_CTRL1_TMP_MON_EN(enable));
1874 
1875     if (status == kStatus_Success)
1876     {
1877         status = PF5020_ModifyReg(handle, PF5020_CTRL2, PF5020_CTRL2_TMP_MON_AON_MASK, PF5020_CTRL2_TMP_MON_AON(mode));
1878     }
1879 
1880     return status;
1881 }
1882 
1883 /*!
1884  * brief Configure analog multiplexer.
1885  *
1886  * param handle The pointer to pf5020_handle_t structure.
1887  * param enable Enable/disable analog multiplexer.
1888  * param amuxSel Used to select amux output, please refer to pf5020_amux_selection_t
1889  * retval #kStatus_Success The transaction was started successfully.
1890  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1891  *      transaction is already in progress.
1892  */
PF5020_AMUX_SetAnalogMuxConfig(pf5020_handle_t * handle,bool enable,pf5020_amux_selection_t amuxSel)1893 status_t PF5020_AMUX_SetAnalogMuxConfig(pf5020_handle_t *handle, bool enable, pf5020_amux_selection_t amuxSel)
1894 {
1895     assert(handle);
1896 
1897     return PF5020_ModifyReg(handle, PF5020_AMUX, PF5020_AMUX_AMUX_SEL_MASK | PF5020_AMUX_AMUX_EN_MASK,
1898                             PF5020_AMUX_MAUX_SEL(amuxSel) | PF5020_AMUX_AMUX_EN(enable));
1899 }
1900 
1901 /*!
1902  * brief Enable interrupts.
1903  *
1904  * param handle The pointer to pf5020_handle_t structure.
1905  * param interruptMask The mask of interrupts to clear, should be the OR'ed value of pf5020_interrupt_t.
1906  * retval #kStatus_Success The transaction was started successfully.
1907  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1908  *      transaction is already in progress.
1909  */
PF5020_EnableInterrupts(pf5020_handle_t * handle,uint64_t interruptMask)1910 status_t PF5020_EnableInterrupts(pf5020_handle_t *handle, uint64_t interruptMask)
1911 {
1912     assert(handle);
1913 
1914     return PF5020_MaskInterrupts(handle, interruptMask, true);
1915 }
1916 
1917 /*!
1918  * brief Disable Interrupts.
1919  *
1920  * param handle The pointer to pf5020_handle_t structure.
1921  * param interruptMask The mask of interrupts to clear, should be the OR'ed value of pf5020_interrupt_t.
1922  * retval #kStatus_Success The transaction was started successfully.
1923  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1924  *      transaction is already in progress.
1925  */
PF5020_DisableInterrupts(pf5020_handle_t * handle,uint64_t interruptMask)1926 status_t PF5020_DisableInterrupts(pf5020_handle_t *handle, uint64_t interruptMask)
1927 {
1928     assert(handle);
1929 
1930     return PF5020_MaskInterrupts(handle, interruptMask, false);
1931 }
1932 
1933 /*!
1934  * brief Get latched interrupts.
1935  *
1936  * param handle The pointer to pf5020_handle_t structure.
1937  * param interrptLatched Pointer to store the latched interrupt value.
1938  * retval #kStatus_Success The transaction was started successfully.
1939  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
1940  *      transaction is already in progress.
1941  */
PF5020_GetInterruptLatchStatus(pf5020_handle_t * handle,uint64_t * interrptLatched)1942 status_t PF5020_GetInterruptLatchStatus(pf5020_handle_t *handle, uint64_t *interrptLatched)
1943 {
1944     assert(handle);
1945 
1946     static const uint8_t latchRegArray[] = PF5020_INT_LATCH_ARRAY;
1947     uint8_t sysIntStatus;
1948     status_t status;
1949     uint8_t i;
1950     uint8_t tmp8;
1951 
1952     /* Get first level interrupt latch value, if the bit in SYS_INT register is set, it means related second level
1953      * interrupts are latched in second level interrupt register.
1954      */
1955     status = PF5020_ReadReg(handle, PF5020_SYS_INT, &sysIntStatus);
1956 
1957     if (status == kStatus_Success)
1958     {
1959         for (i = 0U; i < 7U; i++)
1960         {
1961             /* If first level interrupt is set, then read related second level interrupt latch register. */
1962             if ((sysIntStatus & (1U << i)) != 0U)
1963             {
1964                 status = PF5020_ReadReg(handle, latchRegArray[i], &tmp8);
1965                 *interrptLatched |= ((uint64_t)tmp8 << (i * 8U));
1966 
1967                 if ((i == 3U) && (status == kStatus_Success))
1968                 {
1969                     status = PF5020_ReadReg(handle, PF5020_LDO_ILIM_INT, &tmp8);
1970                     if ((status == kStatus_Success) && (tmp8 != 0U))
1971                     {
1972                         *interrptLatched |= (uint64_t)kPF5020_ILIM_Ldo1IlimInterrupt;
1973                     }
1974                 }
1975 
1976                 if ((i == 4U) && (status == kStatus_Success))
1977                 {
1978                     status = PF5020_ReadReg(handle, PF5020_LDO_UV_INT, &tmp8);
1979                     if ((tmp8 != 0U) && (status == kStatus_Success))
1980                     {
1981                         *interrptLatched |= (uint64_t)kPF5020_UV_Ldo1UvInterrupt;
1982                     }
1983                 }
1984 
1985                 if ((i == 5U) && (status == kStatus_Success))
1986                 {
1987                     status = PF5020_ReadReg(handle, PF5020_LDO_OV_INT, &tmp8);
1988                     if ((tmp8 != 0U) && (status == kStatus_Success))
1989                     {
1990                         *interrptLatched |= (uint64_t)kPF5020_OV_Ldo1OvInterrupt;
1991                     }
1992                 }
1993             }
1994         }
1995     }
1996 
1997     return status;
1998 }
1999 
2000 /*!
2001  * brief Clear latched interrupts.
2002  *
2003  * param handle The pointer to pf5020_handle_t structure.
2004  * param interruptMask The mask of interrupts to clear, should be the OR'ed value of pf5020_interrupt_t.
2005  * retval #kStatus_Success The transaction was started successfully.
2006  * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking
2007  *      transaction is already in progress.
2008  */
PF5020_ClearInterruptStatus(pf5020_handle_t * handle,uint64_t interruptMask)2009 status_t PF5020_ClearInterruptStatus(pf5020_handle_t *handle, uint64_t interruptMask)
2010 {
2011     assert(handle);
2012 
2013     static const uint8_t latchRegArray[] = PF5020_INT_LATCH_ARRAY;
2014     status_t status;
2015     uint8_t sysIntStatus;
2016     uint8_t i;
2017     uint8_t tmp8;
2018     uint64_t tmp64;
2019 
2020     /* Read SYS_INT register, it provides information about the interrupt register that originated the interrupt event.
2021      */
2022     status = PF5020_ReadReg(handle, PF5020_SYS_INT, &sysIntStatus);
2023 
2024     for (i = 0U; i < 7U; i++)
2025     {
2026         if ((sysIntStatus & (1U << i)) != 0U)
2027         {
2028             tmp64 = interruptMask & (0xFFULL << (8ULL * i));
2029             if ((tmp64 & (uint64_t)kPF5020_ILIM_Ldo1IlimInterrupt) != 0ULL)
2030             {
2031                 status = PF5020_WriteReg(handle, PF5020_LDO_ILIM_INT, 1U);
2032                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_ILIM_Ldo1IlimInterrupt);
2033             }
2034 
2035             if ((tmp64 & (uint64_t)kPF5020_UV_Ldo1UvInterrupt) != 0ULL)
2036             {
2037                 status = PF5020_WriteReg(handle, PF5020_LDO_UV_INT, 1U);
2038                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_UV_Ldo1UvInterrupt);
2039             }
2040 
2041             if ((tmp64 & (uint64_t)kPF5020_OV_Ldo1OvInterrupt) != 0ULL)
2042             {
2043                 status = PF5020_WriteReg(handle, PF5020_LDO_OV_INT, 1U);
2044                 tmp64 &= (uint64_t)(~(uint64_t)kPF5020_OV_Ldo1OvInterrupt);
2045             }
2046 
2047             tmp8 = (uint8_t)(tmp64 >> (8ULL * i)) & (0xFFU);
2048 
2049             if (status == kStatus_Success)
2050             {
2051                 status = PF5020_WriteReg(handle, latchRegArray[i], tmp8);
2052             }
2053         }
2054     }
2055 
2056     return status;
2057 }
2058