1 /*
2  * Copyright 2018-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_common.h"
9 #include "fsl_pca9420.h"
10 #include "fsl_power.h"
11 
12 /*******************************************************************************
13  * Definitions
14  ******************************************************************************/
15 
16 /*******************************************************************************
17  * Prototypes
18  ******************************************************************************/
19 
20 /*******************************************************************************
21  * Variables
22  ******************************************************************************/
23 
24 /*******************************************************************************
25  * Code
26  ******************************************************************************/
PCA9420_GetDefaultConfig(pca9420_config_t * config)27 void PCA9420_GetDefaultConfig(pca9420_config_t *config)
28 {
29     assert(config);
30 
31     /* Set callback function to NULL Pointer. */
32     config->I2C_SendFunc    = NULL;
33     config->I2C_ReceiveFunc = NULL;
34 
35     /* Enable power up sequence when VIN on */
36     config->powerUpCfg = kPCA9420_ShipWkup_PowerUp;
37     /* Disable power down sequence. */
38     config->startPowerDown = kPCA9420_PwrDnDisabled;
39     /* Continue charging when wdog timeout. */
40     config->wdogChargeCtrl = kPCA9420_ChgInWatchdogChargerContinue;
41     /* Enable power good detection. */
42     config->powerGoodEnable = kPCA9420_PGoodEnabled;
43     /* VIN current limit. */
44     config->vinCurrentLimit = kPCA9420_VinIlim_370_425_489;
45     /* VIN over voltage protection set to 5.5V. */
46     config->vinOvpThreshold = kPCA9420_VinOvpSel5V5;
47     /* VIN under voltage lockout set to 3.1V. */
48     config->vinUvloThreshold = kPCA9420_VinUvloSel3V1;
49     /* VSYS pre-warning voltage set to 3.5V. */
50     config->asysPreWarnThreshold = kPCA9420_AsysPreWarn3V5;
51     /* VSYS input source set to either VBAT or VIN. */
52     config->asysInputSource = kPCA9420_AsysInputSelVbatVin;
53     /* VSYS under voltage lockout set to 2.7V. */
54     config->asysUvloThreshold = kPCA9420_AsysUvloSel2V7;
55     /* Fast charge timer enabled. */
56     config->chargeTermDisable = kPCA9420_ChargeTermEnabled;
57     /* Thermal shutdown temperature set to 110 degree Celsius. */
58     config->thermalShutdownThreshold = kPCA9420_ThemShdn110C;
59     /* Die warning temperature set to 85 degree Celsius. */
60     config->tempWarnThreshold = kPCA9420_DieTempWarn85C;
61     /* ON pin long glitch timer set to 8 seconds. */
62     config->onPinTimer = kPCA9420_OnGltLong8s;
63     /* Enable active discharge control for all regulators. */
64     config->disableSw1Bleed  = false;
65     config->disableSw2Bleed  = false;
66     config->disableLdo1Bleed = false;
67     config->disableLdo2Bleed = false;
68     /* I2C slave address. */
69     config->slaveAddress = PCA9420_DEFAULT_I2C_ADDR;
70 }
71 
PCA9420_Init(pca9420_handle_t * handle,const pca9420_config_t * config)72 void PCA9420_Init(pca9420_handle_t *handle, const pca9420_config_t *config)
73 {
74     uint8_t topCtl[4], regCtl;
75     bool result;
76 
77     assert(handle);
78     assert(config);
79 
80     /* Initialize Callback functions. */
81     handle->I2C_SendFunc    = config->I2C_SendFunc;
82     handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc;
83     /* Set Slave Address. */
84     handle->slaveAddress = config->slaveAddress;
85 
86     topCtl[0] = (uint8_t)(((uint32_t)config->vinCurrentLimit) | ((uint32_t)config->powerUpCfg) |
87                           ((uint32_t)config->startPowerDown) | ((uint32_t)config->wdogChargeCtrl) |
88                           ((uint32_t)config->powerGoodEnable));
89     topCtl[1] = (uint8_t)(((uint32_t)config->asysPreWarnThreshold) | ((uint32_t)config->asysInputSource) |
90                           ((uint32_t)config->vinOvpThreshold) | ((uint32_t)config->vinUvloThreshold));
91     topCtl[2] = (uint8_t)(((uint32_t)config->asysUvloThreshold) | ((uint32_t)config->chargeTermDisable) |
92                           ((uint32_t)config->thermalShutdownThreshold) | ((uint32_t)config->tempWarnThreshold));
93     topCtl[3] = ((uint8_t)config->onPinTimer);
94     regCtl    = (config->disableSw1Bleed ? (uint8_t)kPCA9420_RegCtlSw1Bleed : 0U) |
95              (config->disableSw2Bleed ? (uint8_t)kPCA9420_RegCtlSw2Bleed : 0U) |
96              (config->disableLdo1Bleed ? (uint8_t)kPCA9420_RegCtlLdo1Bleed : 0U) |
97              (config->disableLdo2Bleed ? (uint8_t)kPCA9420_RegCtlLdo2Bleed : 0U);
98 
99     result = PCA9420_WriteRegs(handle, PCA9420_TOP_CNTL0, topCtl, sizeof(topCtl));
100     result = result ? PCA9420_WriteRegs(handle, PCA9420_ACT_DISCHARGE_CNTL_1, &regCtl, 1U) : result;
101     if (!result)
102     {
103         assert(false);
104     }
105 }
106 
PCA9420_GetDefaultModeConfig(pca9420_modecfg_t * config)107 void PCA9420_GetDefaultModeConfig(pca9420_modecfg_t *config)
108 {
109     /* Don't enter ship mode in this PMIC mode. */
110     config->shipModeEnable = kPCA9420_ShipModeDisabled;
111     /* Use Pin to select mode. */
112     config->modeSel = kPCA9420_ModeSelPin;
113     /* No mode switch on ON pin falling edge. */
114     config->onCfg = kPCA9420_OnCfgDisableModeSwitch;
115     /* Watch dog disabled. */
116     config->wdogTimerCfg = kPCA9420_WdTimerDisabled;
117     /* SW1 output set to 1.0V. */
118     config->sw1OutVolt = kPCA9420_Sw1OutVolt1V000;
119     /* SW2 output set to 1.8V. */
120     config->sw2OutVolt = kPCA9420_Sw2OutVolt1V800;
121     /* LDO1 output set to 1.8V. */
122     config->ldo1OutVolt = kPCA9420_Ldo1OutVolt1V800;
123     /* LDO2 output set to 3.3V. */
124     config->ldo2OutVolt = kPCA9420_Ldo2OutVolt3V300;
125     /* All regulators output enabled. */
126     config->enableSw1Out  = true;
127     config->enableSw2Out  = true;
128     config->enableLdo1Out = true;
129     config->enableLdo2Out = true;
130 }
131 
PCA9420_GetRegulatorVolt(pca9420_modecfg_t * config,pca9420_regulator_mv_t * volt)132 void PCA9420_GetRegulatorVolt(pca9420_modecfg_t *config, pca9420_regulator_mv_t *volt)
133 {
134     assert(config);
135     assert(volt);
136 
137     /* SW1 voltage */
138     if (config->sw1OutVolt <= kPCA9420_Sw1OutVolt1V500)
139     {
140         volt->mVoltSw1 = 500U + (uint32_t)config->sw1OutVolt * 25U;
141     }
142     else if (config->sw1OutVolt < kPCA9420_Sw1OutVolt1V800)
143     {
144         volt->mVoltSw1 = 1500U;
145     }
146     else
147     {
148         volt->mVoltSw1 = 1800U;
149     }
150     /* SW2 voltage */
151     if (config->sw2OutVolt <= kPCA9420_Sw2OutVolt2V100)
152     {
153         volt->mVoltSw2 = 1500U + (uint32_t)config->sw2OutVolt * 25U;
154     }
155     else if (config->sw2OutVolt < kPCA9420_Sw2OutVolt2V700)
156     {
157         volt->mVoltSw2 = 2100U;
158     }
159     else if (config->sw2OutVolt <= kPCA9420_Sw2OutVolt3V300)
160     {
161         volt->mVoltSw2 = 2700U + ((uint32_t)config->sw2OutVolt - (uint32_t)kPCA9420_Sw2OutVolt2V700) * 25U;
162     }
163     else
164     {
165         volt->mVoltSw2 = 3300U;
166     }
167     /* LDO1 voltage */
168     if (config->ldo1OutVolt <= kPCA9420_Ldo1OutVolt1V900)
169     {
170         volt->mVoltLdo1 = 1700U + (((uint32_t)config->ldo1OutVolt) >> PCA9420_MODECFG_2_LDO1_OUT_SHIFT) * 25U;
171     }
172     else
173     {
174         volt->mVoltLdo1 = 1900U;
175     }
176     /* LDO2 voltage */
177     if (config->ldo2OutVolt <= kPCA9420_Ldo2OutVolt2V100)
178     {
179         volt->mVoltLdo2 = 1500U + (uint32_t)config->ldo2OutVolt * 25U;
180     }
181     else if (config->ldo2OutVolt < kPCA9420_Ldo2OutVolt2V700)
182     {
183         volt->mVoltLdo2 = 2100U;
184     }
185     else if (config->ldo2OutVolt <= kPCA9420_Ldo2OutVolt3V300)
186     {
187         volt->mVoltLdo2 = 2700U + ((uint32_t)config->ldo2OutVolt - (uint32_t)kPCA9420_Ldo2OutVolt2V700) * 25U;
188     }
189     else
190     {
191         volt->mVoltLdo2 = 3300U;
192     }
193 }
194 
PCA9420_WriteModeConfigs(pca9420_handle_t * handle,pca9420_mode_t modeBase,const pca9420_modecfg_t * configs,uint32_t num)195 void PCA9420_WriteModeConfigs(pca9420_handle_t *handle,
196                               pca9420_mode_t modeBase,
197                               const pca9420_modecfg_t *configs,
198                               uint32_t num)
199 {
200     uint8_t modeCfgRegBase = PCA9420_MODECFG_0_0;
201     uint8_t modeCfg[16];
202     uint32_t i;
203     bool result;
204 
205     assert((num >= 1U) && (num <= 4U));
206 
207     switch (modeBase)
208     {
209         case kPCA9420_Mode0:
210             modeCfgRegBase = PCA9420_MODECFG_0_0;
211             break;
212         case kPCA9420_Mode1:
213             modeCfgRegBase = PCA9420_MODECFG_1_0;
214             break;
215         case kPCA9420_Mode2:
216             modeCfgRegBase = PCA9420_MODECFG_2_0;
217             break;
218         case kPCA9420_Mode3:
219             modeCfgRegBase = PCA9420_MODECFG_3_0;
220             break;
221         default:
222             assert(false);
223             break;
224     }
225 
226     for (i = 0; i < num; i++)
227     {
228         modeCfg[i * 4U]      = (uint8_t)(((uint32_t)(configs[i].shipModeEnable)) | ((uint32_t)(configs[i].modeSel)) |
229                                     ((uint32_t)(configs[i].sw1OutVolt)));
230         modeCfg[i * 4U + 1U] = (uint8_t)(((uint32_t)(configs[i].onCfg)) | ((uint32_t)(configs[i].sw2OutVolt)));
231         modeCfg[i * 4U + 2U] = (uint8_t)(((uint32_t)(configs[i].ldo1OutVolt)) |
232                                          (configs[i].enableSw1Out ? (uint32_t)kPCA9420_RegulatorSwitch1 : 0U) |
233                                          (configs[i].enableSw2Out ? (uint32_t)kPCA9420_RegulatorSwitch2 : 0U) |
234                                          (configs[i].enableLdo1Out ? (uint32_t)kPCA9420_RegulatorLdo1 : 0U) |
235                                          (configs[i].enableLdo2Out ? (uint32_t)kPCA9420_RegulatorLdo2 : 0U));
236         modeCfg[i * 4U + 3U] = (uint8_t)(((uint32_t)(configs[i].wdogTimerCfg)) | ((uint32_t)(configs[i].ldo2OutVolt)));
237     }
238 
239     result = PCA9420_WriteRegs(handle, modeCfgRegBase, modeCfg, 4U * num);
240     if (!result)
241     {
242         assert(false);
243     }
244 }
245 
PCA9420_ReadModeConfigs(pca9420_handle_t * handle,pca9420_mode_t modeBase,pca9420_modecfg_t * configs,uint32_t num)246 void PCA9420_ReadModeConfigs(pca9420_handle_t *handle,
247                              pca9420_mode_t modeBase,
248                              pca9420_modecfg_t *configs,
249                              uint32_t num)
250 {
251     uint8_t modeCfgRegBase = PCA9420_MODECFG_0_0;
252     uint8_t modeCfg[16]    = {0U};
253     uint32_t i;
254     bool result;
255 
256     assert((num >= 1U) && (num <= 4U));
257 
258     switch (modeBase)
259     {
260         case kPCA9420_Mode0:
261             modeCfgRegBase = PCA9420_MODECFG_0_0;
262             break;
263         case kPCA9420_Mode1:
264             modeCfgRegBase = PCA9420_MODECFG_1_0;
265             break;
266         case kPCA9420_Mode2:
267             modeCfgRegBase = PCA9420_MODECFG_2_0;
268             break;
269         case kPCA9420_Mode3:
270             modeCfgRegBase = PCA9420_MODECFG_3_0;
271             break;
272         default:
273             assert(false);
274             break;
275     }
276 
277     result = PCA9420_ReadRegs(handle, modeCfgRegBase, modeCfg, 4U * num);
278     if (!result)
279     {
280         assert(false);
281     }
282 
283     for (i = 0; i < num; i++)
284     {
285         configs[i].shipModeEnable = (pca9420_ship_en_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_SHIP_EN_MASK);
286         configs[i].modeSel    = (pca9420_mode_sel_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK);
287         configs[i].sw1OutVolt = (pca9420_sw1_out_t)(uint8_t)(modeCfg[i * 4U] & PCA9420_MODECFG_0_SW1_OUT_MASK);
288 
289         configs[i].onCfg      = (pca9420_on_cfg_t)(uint8_t)(modeCfg[i * 4U + 1U] & PCA9420_MODECFG_1_ON_CFG_MASK);
290         configs[i].sw2OutVolt = (pca9420_sw2_out_t)(uint8_t)(modeCfg[i * 4U + 1U] & PCA9420_MODECFG_1_SW2_OUT_MASK);
291 
292         configs[i].ldo1OutVolt  = (pca9420_ldo1_out_t)(uint8_t)(modeCfg[i * 4U + 2U] & PCA9420_MODECFG_2_LDO1_OUT_MASK);
293         configs[i].enableSw1Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorSwitch1)) != 0U) ? true : false;
294         configs[i].enableSw2Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorSwitch2)) != 0U) ? true : false;
295         configs[i].enableLdo1Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorLdo1)) != 0U) ? true : false;
296         configs[i].enableLdo2Out = ((modeCfg[i * 4U + 2U] & ((uint8_t)kPCA9420_RegulatorLdo2)) != 0U) ? true : false;
297 
298         configs[i].wdogTimerCfg = (pca9420_wd_timer_t)(uint8_t)(modeCfg[i * 4U + 3U] & PCA9420_MODECFG_3_WD_TIMER_MASK);
299         configs[i].ldo2OutVolt  = (pca9420_ldo2_out_t)(uint8_t)(modeCfg[i * 4U + 3U] & PCA9420_MODECFG_3_LDO2_OUT_MASK);
300     }
301 }
302 
PCA9420_ModeControlledByI2C(pca9420_handle_t * handle,pca9420_mode_t mode)303 static bool PCA9420_ModeControlledByI2C(pca9420_handle_t *handle, pca9420_mode_t mode)
304 {
305     uint8_t modeCfgReg = PCA9420_MODECFG_0_0;
306     uint8_t modeCfg0   = 0U;
307     bool result;
308 
309     switch (mode)
310     {
311         case kPCA9420_Mode0:
312             modeCfgReg = PCA9420_MODECFG_0_0;
313             break;
314         case kPCA9420_Mode1:
315             modeCfgReg = PCA9420_MODECFG_1_0;
316             break;
317         case kPCA9420_Mode2:
318             modeCfgReg = PCA9420_MODECFG_2_0;
319             break;
320         case kPCA9420_Mode3:
321             modeCfgReg = PCA9420_MODECFG_3_0;
322             break;
323         default:
324             assert(false);
325             break;
326     }
327     result = PCA9420_ReadRegs(handle, modeCfgReg, &modeCfg0, 1);
328     assert(result);
329     if ((modeCfg0 & PCA9420_MODECFG_0_MODE_CTRL_SEL_MASK) == (uint8_t)kPCA9420_ModeSelI2C)
330     {
331         result = true;
332     }
333     else
334     {
335         result = false;
336     }
337 
338     return result;
339 }
340 
PCA9420_SwitchMode(pca9420_handle_t * handle,pca9420_mode_t mode)341 bool PCA9420_SwitchMode(pca9420_handle_t *handle, pca9420_mode_t mode)
342 {
343     bool result;
344 
345     /* Switch by Pins first */
346     POWER_SetPmicMode((uint32_t)mode, kCfg_Run);
347 
348     /* Switch by I2C next to make sure switch succeeds no matter modes are controlled by Pins or I2C. */
349     result = PCA9420_ModifyReg(handle, PCA9420_TOP_CNTL3, PCA9420_TOP_CNTL3_MODE_I2C_MASK,
350                                ((uint8_t)mode) << PCA9420_TOP_CNTL3_MODE_I2C_SHIFT);
351 
352     return result;
353 }
354 
PCA9420_GetCurrentMode(pca9420_handle_t * handle,pca9420_mode_t * mode)355 bool PCA9420_GetCurrentMode(pca9420_handle_t *handle, pca9420_mode_t *mode)
356 {
357     bool result      = true;
358     uint8_t regValue = 0U;
359     pca9420_mode_t pinMode, i2cMode;
360 
361     assert(mode);
362 
363     pinMode = (pca9420_mode_t)(POWER_GetPmicMode(kCfg_Run));
364 
365     if (!PCA9420_ModeControlledByI2C(handle, pinMode))
366     {
367         *mode = pinMode;
368     }
369     else
370     {
371         result = PCA9420_ReadRegs(handle, PCA9420_TOP_CNTL3, &regValue, 1);
372         if (result)
373         {
374             i2cMode = (pca9420_mode_t)(uint8_t)((regValue & PCA9420_TOP_CNTL3_MODE_I2C_MASK) >>
375                                                 PCA9420_TOP_CNTL3_MODE_I2C_SHIFT);
376             *mode   = i2cMode;
377         }
378     }
379 
380     return result;
381 }
382 
PCA9420_GetRegulatorStatus(pca9420_handle_t * handle)383 uint8_t PCA9420_GetRegulatorStatus(pca9420_handle_t *handle)
384 {
385     bool result;
386     uint8_t status = 0;
387 
388     /* powerGoodEnable must be configured to true, otherwise the status is always 0. */
389     result = PCA9420_ReadRegs(handle, PCA9420_REG_STATUS, &status, 1);
390     if (!result)
391     {
392         assert(false);
393     }
394 
395     return status;
396 }
397 
PCA9420_FeedWatchDog(pca9420_handle_t * handle)398 void PCA9420_FeedWatchDog(pca9420_handle_t *handle)
399 {
400     uint8_t regValue = 1;
401 
402     (void)PCA9420_WriteRegs(handle, PCA9420_TOP_CNTL4, &regValue, 1);
403 }
404 
PCA9420_WriteRegs(pca9420_handle_t * handle,uint8_t regBase,uint8_t * val,uint32_t size)405 bool PCA9420_WriteRegs(pca9420_handle_t *handle, uint8_t regBase, uint8_t *val, uint32_t size)
406 {
407     assert(handle);
408     assert(handle->I2C_SendFunc);
409     assert(val);
410 
411     return (kStatus_Success == handle->I2C_SendFunc(handle->slaveAddress, regBase, 1U, val, size)) ? true : false;
412 }
413 
PCA9420_ReadRegs(pca9420_handle_t * handle,uint8_t regBase,uint8_t * val,uint32_t size)414 bool PCA9420_ReadRegs(pca9420_handle_t *handle, uint8_t regBase, uint8_t *val, uint32_t size)
415 {
416     assert(handle);
417     assert(handle->I2C_ReceiveFunc);
418     assert(val);
419 
420     return (kStatus_Success == handle->I2C_ReceiveFunc(handle->slaveAddress, regBase, 1U, val, size)) ? true : false;
421 }
422 
PCA9420_ModifyReg(pca9420_handle_t * handle,uint8_t reg,uint8_t mask,uint8_t val)423 bool PCA9420_ModifyReg(pca9420_handle_t *handle, uint8_t reg, uint8_t mask, uint8_t val)
424 {
425     bool result;
426     uint8_t regValue = 0U;
427 
428     assert(handle);
429 
430     /* Read back the register content. */
431     result = PCA9420_ReadRegs(handle, reg, &regValue, 1);
432     if (result)
433     {
434         /* Modify the bit-fields you want to change. */
435         regValue &= (uint8_t)~mask;
436         regValue |= val;
437 
438         /* Write back the content to the registers. */
439         result = PCA9420_WriteRegs(handle, reg, &regValue, 1);
440     }
441 
442     return result;
443 }
444 
PCA9420_EnableInterrupts(pca9420_handle_t * handle,uint32_t source)445 void PCA9420_EnableInterrupts(pca9420_handle_t *handle, uint32_t source)
446 {
447     bool result;
448     uint8_t regValues[6];
449 
450     assert(handle);
451 
452     /* Read back the register content. */
453     result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
454     if (!result)
455     {
456         assert(false);
457     }
458 
459     regValues[0] = regValues[2] = regValues[4] = 0U; /* Don't clear int status */
460 
461     regValues[1] &= (uint8_t)(~(source & 0xFFU));         /* SUB_INT0_MASK */
462     regValues[3] &= (uint8_t)(~((source >> 8) & 0xFFU));  /* SUB_INT1_MASK */
463     regValues[5] &= (uint8_t)(~((source >> 16) & 0xFFU)); /* SUB_INT2_MASK */
464 
465     result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
466     if (!result)
467     {
468         assert(false);
469     }
470 }
471 
PCA9420_DisableInterrupts(pca9420_handle_t * handle,uint32_t source)472 void PCA9420_DisableInterrupts(pca9420_handle_t *handle, uint32_t source)
473 {
474     bool result;
475     uint8_t regValues[6];
476 
477     assert(handle);
478 
479     /* Read back the register content. */
480     result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
481     if (!result)
482     {
483         assert(false);
484     }
485 
486     regValues[0] = regValues[2] = regValues[4] = 0U; /* Don't clear int status */
487 
488     regValues[1] |= (uint8_t)(source & 0xFFU);         /* SUB_INT0_MASK */
489     regValues[3] |= (uint8_t)((source >> 8) & 0xFFU);  /* SUB_INT1_MASK */
490     regValues[5] |= (uint8_t)((source >> 16) & 0xFFU); /* SUB_INT2_MASK */
491 
492     result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
493     if (!result)
494     {
495         assert(false);
496     }
497 }
498 
PCA9420_GetInterruptStatus(pca9420_handle_t * handle)499 uint32_t PCA9420_GetInterruptStatus(pca9420_handle_t *handle)
500 {
501     bool result;
502     uint8_t regValues[6] = {0U};
503 
504     assert(handle);
505 
506     /* Read back the register content. */
507     result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
508     if (!result)
509     {
510         assert(false);
511     }
512 
513     return (((uint32_t)regValues[4]) << 16) | (((uint32_t)regValues[2]) << 8) | (uint32_t)regValues[0];
514 }
515 
PCA9420_ClearInterruptStatus(pca9420_handle_t * handle,uint32_t source)516 void PCA9420_ClearInterruptStatus(pca9420_handle_t *handle, uint32_t source)
517 {
518     bool result;
519     uint8_t regValues[6];
520 
521     assert(handle);
522 
523     /* Read back the register content. */
524     result = PCA9420_ReadRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
525     if (!result)
526     {
527         assert(false);
528     }
529 
530     regValues[0] = (uint8_t)(source & 0xFFU);         /* SUB_INT1 */
531     regValues[2] = (uint8_t)((source >> 8) & 0xFFU);  /* SUB_INT2 */
532     regValues[4] = (uint8_t)((source >> 16) & 0xFFU); /* SUB_INT3 */
533 
534     result = PCA9420_WriteRegs(handle, PCA9420_SUB_INT0, regValues, sizeof(regValues));
535     if (!result)
536     {
537         assert(false);
538     }
539 }
540 /*******************************************************************************
541  * EOF
542  ******************************************************************************/
543