blob: df673dcd9b8fde06ab61663147b16cf668a87c49 [file] [log] [blame]
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -07001/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are
5met:
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above
9 copyright notice, this list of conditions and the following
10 disclaimer in the documentation and/or other materials provided
11 with the distribution.
12 * Neither the name of The Linux Foundation nor the names of its
13 contributors may be used to endorse or promote products derived
14 from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#include "pm_fg_adc_usr.h"
30#include "pm_fg_driver.h"
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070031#include "pm_smbchg_driver.h"
32#include "pm_err_flags.h"
33#include "pm_comm.h"
lijuang33f9eea2015-08-29 15:40:05 +080034#include "pm_fg_adc_usr.h"
35#include "pm_fg_driver.h"
36#include <platform/timer.h>
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070037#include <sys/types.h>
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070038
39/*===========================================================================
40 TYPE DEFINITIONS
41===========================================================================*/
42#define RAW_IBAT_LSB 39
43#define RAW_VBAT_LSB 39
44#define OFFSET_LSB_NUM 12 //Offset LSB Numerator
45#define OFFSET_LSB_DENOM 10 //Offset LSB Denominator
46#define GAIN_LSB_DENOM 400 // Gain LSB is 0.32/128 = 1/400
lijuang33f9eea2015-08-29 15:40:05 +080047#define PM_MAX_ADC_READY_DELAY 2000
48#define PM_MIN_ADC_READY_DELAY 1 * 1000 //1ms
Channagoud Kadabi4ab0b172015-07-13 20:12:26 -070049
Channagoud Kadabi9dc19c82015-04-23 14:20:55 -070050/*===========================================================================
51 FUNCTION DEFINITIONS
52===========================================================================*/
53/**
54* @brief This function grant access to FG ADC User access *
55* @details
56* This function grant access to FG ADC User access
57*
58* @param[in] pm_fg_data_type Self
59*
60* @return pm_err_flag_type
61* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
62* version of the PMIC.
63* PM_ERR_FLAG__SUCCESS = SUCCESS.
64*
65*/
66pm_err_flag_type pm_fg_adc_usr_grant_sec_access(pm_fg_data_type *fg_adc_usr_ptr)
67{
68
69 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
70
71 if(NULL == fg_adc_usr_ptr)
72 {
73 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
74 }
75 else
76 {
77 pm_register_address_type sec_access = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_sec_access;
78 err_flag = pm_comm_write_byte(fg_adc_usr_ptr->comm_ptr->slave_id, sec_access, 0xA5, 0);
79 }
80
81 return err_flag;
82}
83
84/* Interrupt */
85pm_err_flag_type pm_fg_adc_usr_irq_enable(uint32 pmic_device, pm_fg_adc_usr_irq_type irq, boolean enable)
86{
87 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
88 pm_register_address_type irq_reg;
89 pm_register_data_type data = 1 << irq;
90
91 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
92
93 if (NULL == fg_adc_usr_ptr)
94 {
95 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
96 }
97 else if (irq >= PM_FG_ADC_USR_IRQ_INVALID)
98 {
99 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
100 }
101 else
102 {
103 if (enable)
104 {
105 irq_reg = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_en_set;
106 }
107 else
108 {
109 irq_reg = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_en_clr;
110 }
111
112 err_flag = pm_comm_write_byte(fg_adc_usr_ptr->comm_ptr->slave_id, irq_reg, data, 0);
113 }
114 return err_flag;
115}
116
117pm_err_flag_type pm_fg_adc_usr_irq_clear(uint32 pmic_device, pm_fg_adc_usr_irq_type irq)
118{
119 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
120 pm_register_data_type data = 1 << irq;
121 pm_register_address_type int_latched_clr;
122 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
123
124 if (NULL == fg_adc_usr_ptr)
125 {
126 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
127 }
128 else if (irq >= PM_FG_ADC_USR_IRQ_INVALID)
129 {
130 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
131 }
132 else
133 {
134 int_latched_clr = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_latched_clr;
135 err_flag = pm_comm_write_byte(fg_adc_usr_ptr->comm_ptr->slave_id, int_latched_clr, data, 0);
136 }
137
138 return err_flag;
139}
140
141
142pm_err_flag_type pm_fg_adc_usr_irq_set_trigger(uint32 pmic_device, pm_fg_adc_usr_irq_type irq, pm_irq_trigger_type trigger)
143{
144 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
145 uint8 mask = 1 << irq;
146 pm_register_data_type set_type, polarity_high, polarity_low;
147 pm_register_address_type int_set_type, int_polarity_high, int_polarity_low;
148
149 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
150
151 if (NULL == fg_adc_usr_ptr)
152 {
153 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
154 }
155 else if (irq >= PM_FG_ADC_USR_IRQ_INVALID)
156 {
157 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
158 }
159 else
160 {
161 int_set_type = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_set_type;
162 int_polarity_high = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_polarity_high;
163 int_polarity_low = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_polarity_low;
164
165 switch (trigger)
166 {
167 case PM_IRQ_TRIGGER_ACTIVE_LOW:
168 set_type = 0x00;
169 polarity_high = 0x00;
170 polarity_low = 0xFF;
171 break;
172 case PM_IRQ_TRIGGER_ACTIVE_HIGH:
173 set_type = 0x00;
174 polarity_high = 0xFF;
175 polarity_low = 0x00;
176 break;
177 case PM_IRQ_TRIGGER_RISING_EDGE:
178 set_type = 0xFF;
179 polarity_high = 0xFF;
180 polarity_low = 0x00;
181 break;
182 case PM_IRQ_TRIGGER_FALLING_EDGE:
183 set_type = 0xFF;
184 polarity_high = 0x00;
185 polarity_low = 0xFF;
186 break;
187 case PM_IRQ_TRIGGER_DUAL_EDGE:
188 set_type = 0xFF;
189 polarity_high = 0xFF;
190 polarity_low = 0xFF;
191 break;
192 default:
193 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
194 }
195 err_flag = pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, int_set_type, mask, set_type, 0);
196 err_flag |= pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, int_polarity_high, mask, polarity_high, 0);
197 err_flag |= pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, int_polarity_low, mask, polarity_low, 0);
198 }
199
200 return err_flag;
201}
202
203
204pm_err_flag_type pm_fg_adc_usr_irq_status(uint32 pmic_device, pm_fg_adc_usr_irq_type irq, pm_irq_status_type type, boolean *status)
205{
206 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
207 pm_register_data_type data;
208 uint8 mask = 1 << irq;
209 pm_register_address_type int_sts;
210 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
211
212 if (NULL == fg_adc_usr_ptr)
213 {
214 err_flag = PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
215 }
216 else if (irq >= PM_FG_ADC_USR_IRQ_INVALID)
217 {
218 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
219 }
220 else
221 {
222 switch (type)
223 {
224 case PM_IRQ_STATUS_RT:
225 int_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_rt_sts;
226 break;
227 case PM_IRQ_STATUS_LATCHED:
228 int_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_latched_sts;
229 break;
230 case PM_IRQ_STATUS_PENDING:
231 int_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->int_pending_sts;
232 break;
233 default:
234 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
235 }
236
237 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, int_sts, mask, &data, 0);
238 *status = data ? TRUE : FALSE;
239 }
240
241 return err_flag;
242}
243
244
245
246/**
247* @brief This function enable/disables BMS Fule Gauge Algorithm BCL (battery current limiting s/w use) *
248* @details
249* This function enable/disables BMS Fule Gauge Algorithm BCL (battery current limiting s/w use)
250*
251* @param[in] pmic_device_index. Primary: 0 Secondary: 1
252* @param[in]enable enable/disable BCL monitoring
253*
254* @return pm_err_flag_type
255* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
256* version of the PMIC.
257* PM_ERR_FLAG__SUCCESS = SUCCESS.
258*
259*/
260pm_err_flag_type pm_fg_adc_usr_enable_bcl_monitoring(uint32 pmic_device, boolean enable)
261{
262 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
263 pm_register_address_type fg_adc_usr_bcl_monitoring = 0x00;
264 uint8 mask = 0x80;
265
266 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
267
268 if (NULL == fg_adc_usr_ptr)
269 {
270 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
271 }
272 else
273 {
274 fg_adc_usr_bcl_monitoring = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_en_ctl;
275 err_flag = pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bcl_monitoring, mask, (pm_register_data_type)(enable << 7), 0);
276 }
277
278 return err_flag;
279
280}
281
282
283/**
284* @brief This function returns BMS Fule Gauge BCL (battery current limiting s/w use) *
285* @details
286* This function returns BMS Fule Gauge BCL (battery current limiting s/w use)
287*
288* @param[in] pmic_device_index. Primary: 0 Secondary: 1
289* @param[out]enable BCL monitoring sts
290*
291* @return pm_err_flag_type
292* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
293* version of the PMIC.
294* PM_ERR_FLAG__SUCCESS = SUCCESS.
295*
296*/
297pm_err_flag_type pm_fg_adc_usr_get_bcl_monitoring_sts(uint32 pmic_device, boolean *enable)
298{
299 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
300 pm_register_address_type fg_adc_usr_bcl_monitoring = 0x00;
301 pm_register_data_type data = 0x00;
302 uint8 mask = 0x80;
303
304 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
305
306 if (NULL == fg_adc_usr_ptr)
307 {
308 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
309 }
310 else
311 {
312 fg_adc_usr_bcl_monitoring = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_en_ctl;
313 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bcl_monitoring, mask, &data, 0);
314 *enable = (boolean )data;
315 }
316
317 return err_flag;
318
319}
320
321
322/**
323* @brief This function returns of status of adc_usrery parameter update request *
324* @details
325* This function returns of status of battery parameter update request (VBAT, IBAT, VBAT_CP, IBAT_CP, IBAT_MAX, IBAT_MAX_CP, VBAT_MIN, VBAT_MIN_CP)
326*
327* @param[in] pmic_device_index. Primary: 0 Secondary: 1
328* @param[in]enable enable/disable BCL monitoring
329*
330* @return pm_err_flag_type
331* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
332* version of the PMIC.
333* PM_ERR_FLAG__SUCCESS = SUCCESS.
334*
335*/
336pm_err_flag_type pm_fg_adc_usr_get_access_bat_req_sts(uint32 pmic_device, boolean *enable)
337{
338
339 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
340 pm_register_address_type fg_adc_usr_bat_req_sts = 0x00;
341 pm_register_data_type data = 0x00;
342 uint8 mask = 0x80;
343
344 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
345
346 if (NULL == fg_adc_usr_ptr)
347 {
348 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
349 }
350 else
351 {
352 fg_adc_usr_bat_req_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_access_bat_req;
353 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bat_req_sts, mask, &data, 0);
354 *enable = (boolean )data;
355 }
356
357 return err_flag;
358
359}
360
361
362
363/**
364* @brief This function enable/disables the updates of VBAT, IBAT, VBAT_CP, IBAT_CP, IBAT_MAX, IBAT_MAX_CP, VBAT_MIN, VBAT_MIN_CP *
365* @details
366* This function enable/disables the updates of VBAT, IBAT, VBAT_CP, IBAT_CP, IBAT_MAX, IBAT_MAX_CP, VBAT_MIN, VBAT_MIN_CP
367*
368* @param[in] pmic_device_index. Primary: 0 Secondary: 1
369* @param[in]enable enable/disable BCL monitoring
370*
371* @return pm_err_flag_type
372* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
373* version of the PMIC.
374* PM_ERR_FLAG__SUCCESS = SUCCESS.
375*
376*/
377pm_err_flag_type pm_fg_adc_usr_set_access_bat_req(uint32 pmic_device, boolean enable)
378{
379 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
380 pm_register_address_type fg_adc_usr_bat_req_sts = 0x00;
381 uint8 mask = 0x80;
382
383 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
384
385 if (NULL == fg_adc_usr_ptr)
386 {
387 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
388 }
389 else
390 {
391 fg_adc_usr_bat_req_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_access_bat_req;
392 err_flag = pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bat_req_sts, mask, (pm_register_data_type)enable, 0);
393 }
394
395 return err_flag;
396}
397
398
399/**
400* @brief This function returns the grant status of battery parameter update request *
401* @details
402* This function returns of status of battery parameter update request (VBAT, IBAT, VBAT_CP, IBAT_CP, IBAT_MAX, IBAT_MAX_CP, VBAT_MIN, VBAT_MIN_CP)
403*
404* @param[in] pmic_device_index. Primary: 0 Secondary: 1
405* @param[in]enable enable/disable BCL monitoring
406*
407* @return pm_err_flag_type
408* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
409* version of the PMIC.
410* PM_ERR_FLAG__SUCCESS = SUCCESS.
411*
412*/
413pm_err_flag_type pm_fg_adc_usr_get_access_bat_grnt_sts(uint32 pmic_device, boolean *enable)
414{
415 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
416 pm_register_address_type fg_adc_usr_bat_grnt_sts = 0x00;
417 pm_register_data_type data = 0x00;
418 uint8 mask = 0x80;
419
420 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
421
422 if (NULL == fg_adc_usr_ptr)
423 {
424 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
425 }
426 else
427 {
428 fg_adc_usr_bat_grnt_sts = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_access_bat_grnt;
429 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bat_grnt_sts, mask, &data, 0);
430 *enable = (boolean )data;
431 }
432
433 return err_flag;
434
435}
436
437
438
439/**
440* @brief This function returns status RDY bit after battery parameter update request is serviced *
441* @details
442* After the first readings from ADC are obtained, this bit is set to 1; At reset and shutdown, this bit gets automatically cleared
443*
444* @param[in] pmic_device_index. Primary: 0 Secondary: 1
445* @param[in]enable enable/disable BCL monitoring
446*
447* @return pm_err_flag_type
448* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
449* version of the PMIC.
450* PM_ERR_FLAG__SUCCESS = SUCCESS.
451*
452*/
453pm_err_flag_type pm_fg_adc_usr_get_bcl_values(uint32 pmic_device, boolean *enable)
454{
455 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
456 pm_register_address_type fg_adc_usr_bcl_values = 0x00;
457 pm_register_data_type data = 0x00;
458 uint8 mask = 0x80;
459
460 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
461
462 if (NULL == fg_adc_usr_ptr)
463 {
464 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
465 }
466 else
467 {
468 fg_adc_usr_bcl_values = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_values;
469 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bcl_values, mask, &data, 0);
470 *enable = (boolean )data;
471 }
472
473 return err_flag;
474
475}
476
477
478/**
479* @brief This function returns battery ADC Voltage *
480* @details
481* 8 bit signed partial ADC value, MSB = 0 is positive voltage (positive number), only positive voltages are captured, 1 LSB = 39 mV
482*
483* @param[in] pmic_device_index. Primary: 0 Secondary: 1
484* @param[out]vbat_adc Battery Voltage
485*
486* @return pm_err_flag_type
487* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
488* version of the PMIC.
489* PM_ERR_FLAG__SUCCESS = SUCCESS.
490*
491*/
492pm_err_flag_type pm_fg_adc_usr_get_vbat(uint32 pmic_device, uint32 *vbat_adc)
493{
494 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
495 pm_register_address_type fg_adc_usr_vbat = 0x00;
496 pm_register_address_type fg_adc_usr_vbat_cp = 0x00;
497 pm_register_data_type data = 0x00;
498 pm_register_data_type data1 = 0x00;
499
500 int8 temp_data = 0;
501 int32 temp_data1 = 0;
502
503 //Compare data thrice in copy register and original register to make sure we have right data
504 uint32 total_count = 3;
505 uint32 count = 0;
506
507 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
508
509 *vbat_adc = 0;
510
511 if (NULL == fg_adc_usr_ptr)
512 {
513 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
514 }
515 else
516 {
517 fg_adc_usr_vbat = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_vbat;
518 fg_adc_usr_vbat_cp = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_vbat_cp;
519
520 do {
521 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_vbat, &data1, 0);
522 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_vbat_cp, &data, 0);
523
524 if(data == data1)
525 {
526 break;
527 }
528
529 if((total_count - 1) == count)
530 {
531 data = 0;
532 err_flag = PM_ERR_FLAG__INVALID;
533 }
534
535 count++;
536
537 }while ( count < total_count);
538
539 //Convert uint8 to int8
540 temp_data = data;
541
542 //Convert int8 to int32
543 temp_data1 = temp_data;
544
545 *vbat_adc = temp_data1 * RAW_VBAT_LSB;
546 }
547
548 return err_flag;
549}
550
551
552/**
553* @brief This function returns battery ADC Current *
554* @details
555* 8 bit signed partial ADC value, MSB = 0 is discharging current (positive number), only discharging currents are captured, 1 LSB = 39 mA
556*
557* @param[in] pmic_device_index. Primary: 0 Secondary: 1
558* @param[out]ibat_adc Battery Current
559*
560* @return pm_err_flag_type
561* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
562* version of the PMIC.
563* PM_ERR_FLAG__SUCCESS = SUCCESS.
564*
565*/
566pm_err_flag_type pm_fg_adc_usr_get_ibat(uint32 pmic_device, int32 *ibat_adc)
567{
568 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
569 pm_register_address_type fg_adc_usr_ibat = 0x00;
570 pm_register_address_type fg_adc_usr_ibat_cp = 0x00;
571 pm_register_data_type data = 0x00;
572 pm_register_data_type data1 = 0x00;
573
574 int8 temp_data = 0;
575 int32 temp_data1 = 0;
576
577 uint32 count = 0;
578 //Compare data thrice in copy register and original register to make sure we have right data
579 uint32 total_count = 3;
580
581 pm_fg_data_type *fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
582
583 if (NULL == fg_adc_usr_ptr)
584 {
585 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
586 }
587 else if (NULL == ibat_adc)
588 {
589 err_flag = PM_ERR_FLAG__PAR2_OUT_OF_RANGE;
590 }
591 else
592 {
593 fg_adc_usr_ibat = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_ibat;
594 fg_adc_usr_ibat_cp = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_ibat_cp;
595
596 do
597 {
598 /*Read original register and copy register to make sure available data is reliable*/
599 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_ibat, &data1, 0);
600 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_ibat_cp, &data, 0);
601
602 if (data1 == data)
603 {
604 break;
605 }
606 if ((total_count - 1) == count)
607 {
608 err_flag = PM_ERR_FLAG__INVALID;
609 }
610 count++;
611
612 }
613 while (count < total_count);
614
615 //Convert uint8 to int8
616 temp_data = data;
617
618 //Convert int8 to int32
619 temp_data1 = temp_data;
620
621 *ibat_adc = temp_data1 * RAW_IBAT_LSB;
622 }
623
624 return err_flag;
625}
626
627
628/**
629* @brief This function returns minimum battery Voltage *
630* @details
631* Running Vbat Min stored and then cleared by SW
632*
633* @param[in] pmic_device_index. Primary: 0 Secondary: 1
634* @param[out]vbat_min Battery Minimum Voltage
635*
636* @return pm_err_flag_type
637* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
638* version of the PMIC.
639* PM_ERR_FLAG__SUCCESS = SUCCESS.
640*
641*/
642pm_err_flag_type pm_fg_adc_usr_get_vbat_min(uint32 pmic_device, uint8 *vbat_min)
643{
644 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
645 pm_register_address_type fg_adc_usr_vbat_min = 0x00;
646 pm_register_data_type data = 0x00;
647
648 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
649
650 if (NULL == fg_adc_usr_ptr)
651 {
652 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
653 }
654 else
655 {
656 fg_adc_usr_vbat_min = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_vbat_min;
657 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_vbat_min, &data, 0);
658 *vbat_min = data;
659 }
660
661 return err_flag;
662
663}
664
665/**
666* @brief This function returns max battery current *
667* @details
668* Running Ibat Min stored and then cleared by SW
669*
670* @param[in] pmic_device_index. Primary: 0 Secondary: 1
671* @param[out]ibat_max Battery Maximum Current
672*
673* @return pm_err_flag_type
674* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
675* version of the PMIC.
676* PM_ERR_FLAG__SUCCESS = SUCCESS.
677*
678*/
679pm_err_flag_type pm_fg_adc_usr_get_ibat_max(uint32 pmic_device, uint8 *ibat_max)
680{
681 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
682 pm_register_address_type fg_adc_usr_ibat_max = 0x00;
683 pm_register_data_type data = 0x00;
684
685 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
686
687 if (NULL == fg_adc_usr_ptr)
688 {
689 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
690 }
691 else
692 {
693 fg_adc_usr_ibat_max = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_ibat_max;
694 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_ibat_max, &data, 0);
695 *ibat_max = (uint8)data;
696 }
697
698 return err_flag;
699
700}
701
702
703/**
704* @brief This function returns copy of minimum battery Voltage *
705* @details
706* Running Vbat Min stored and then cleared by SW
707*
708* @param[in] pmic_device_index. Primary: 0 Secondary: 1
709* @param[out]vbat_min Battery Minimum Voltage
710*
711* @return pm_err_flag_type
712* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
713* version of the PMIC.
714* PM_ERR_FLAG__SUCCESS = SUCCESS.
715*
716*/
717pm_err_flag_type pm_fg_adc_usr_get_vbat_min_cp(uint32 pmic_device, uint8 *vbat_min_cp)
718{
719 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
720 pm_register_address_type fg_adc_usr_vbat_min_cp = 0x00;
721 pm_register_data_type data = 0x00;
722
723 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
724
725 if (NULL == fg_adc_usr_ptr)
726 {
727 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
728 }
729 else
730 {
731 fg_adc_usr_vbat_min_cp = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_vbat_min_cp;
732 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_vbat_min_cp, &data, 0);
733 *vbat_min_cp = (uint8)data;
734 }
735
736 return err_flag;
737
738}
739
740/**
741* @brief This function returns copy of max battery current *
742* @details
743* Running Ibat Min stored and then cleared by SW
744*
745* @param[in] pmic_device_index. Primary: 0 Secondary: 1
746* @param[out]ibat_max Battery Maximum Current
747*
748* @return pm_err_flag_type
749* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
750* version of the PMIC.
751* PM_ERR_FLAG__SUCCESS = SUCCESS.
752*
753*/
754pm_err_flag_type pm_fg_adc_usr_get_ibat_max_cp(uint32 pmic_device, uint8 *ibat_max_cp)
755{
756 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
757 pm_register_address_type fg_adc_usr_ibat_max_cp = 0x00;
758 pm_register_data_type data = 0x00;
759
760 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
761
762 if (NULL == fg_adc_usr_ptr)
763 {
764 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
765 }
766 else
767 {
768 fg_adc_usr_ibat_max_cp = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_ibat_max_cp;
769 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_ibat_max_cp, &data, 0);
770 *ibat_max_cp = (uint8)data;
771 }
772
773 return err_flag;
774
775}
776
777
778/**
779* @brief This function returns Battery Resitance in HALF encoding *
780* @details
781* HALF-FLOATING point encoding, 15:11 exp, bit 10 sign, 9:0 mantissa, 1=1 ohm, refer to MDOS for encoding info
782*
783* @param[in] pmic_device_index. Primary: 0 Secondary: 1
784* @param[out]battResistance Battery Resistance
785*
786* @return pm_err_flag_type
787* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
788* version of the PMIC.
789* PM_ERR_FLAG__SUCCESS = SUCCESS.
790*
791*/
792pm_err_flag_type pm_fg_adc_usr_get_half_point_encoding(uint32 pmic_device, uint16 *battResistance)
793{
794
795 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
796 pm_register_address_type addr_msb;
797 pm_register_address_type addr_lsb;
798 pm_register_data_type data_0 = 0x00;
799 pm_register_data_type data_1 = 0x00;
800 uint16 battR = 0x0000;
801
802 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
803
804 if (NULL == fg_adc_usr_ptr)
805 {
806 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
807 }
808 else
809 {
810 addr_lsb = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bat_res_7_0;
811 addr_msb = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bat_res_15_8;
812 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, addr_lsb, &data_0, 0);
813 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, addr_msb, &data_1, 0);
814
815 battR = ((data_1 | battR) << 8) | (data_0 | battR);
816
817 *battResistance = battR;
818 }
819
820 return err_flag;
821
822}
823
824
825/**
826* @brief This function returns BCL mode status *
827* @details
828* This function returns BCL mode status
829*
830* @param[in] pmic_device_index. Primary: 0 Secondary: 1
831* @param[out] bcl_mode BCL mode
832*
833* @return pm_err_flag_type
834* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
835* version of the PMIC.
836* PM_ERR_FLAG__SUCCESS = SUCCESS.
837*
838*/
839pm_err_flag_type pm_fg_adc_usr_get_bcl_mode(uint32 pmic_device, pm_fg_adc_usr_bcl_mode_sts *bcl_mode)
840{
841 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
842 pm_register_address_type fg_adc_usr_bcl_values = 0x00;
843 pm_register_data_type data = 0x00;
844
845 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
846
847 if (NULL == fg_adc_usr_ptr)
848 {
849 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
850 }
851 else
852 {
853 fg_adc_usr_bcl_values = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_values;
854 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bcl_values, &data, 0);
855 data = data >> 0x06;
856 *bcl_mode = (pm_fg_adc_usr_bcl_mode_sts)data;
857 }
858
859 return err_flag;
860
861}
862
863
864/**
865* @brief This function returns votlage gain correction value for battery voltage *
866* @details
867* This function returns gain correction value for battery
868*
869* @param[in] pmic_device_index. Primary: 0 Secondary: 1
870* @param[in] gainCorrection for battery volatge
871*
872* @return pm_err_flag_type
873* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
874* version of the PMIC.
875* PM_ERR_FLAG__SUCCESS = SUCCESS.
876*
877*/
878pm_err_flag_type pm_fg_adc_usr_get_bcl_v_gain_batt(uint32 pmic_device, int32 *v_gain_correction)
879{
880 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
881 pm_register_address_type fg_adc_usr_v_gain_batt = 0x00;
882 pm_register_data_type data = 0x00;
883
884 int8 temp_data = 0;
885 int32 temp_data1 = 0;
886
887 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
888
889 if (NULL == fg_adc_usr_ptr)
890 {
891 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
892 }
893 else
894 {
895 fg_adc_usr_v_gain_batt = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_v_gain_batt;
896 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_v_gain_batt, &data, 0);
897
898 //Convert uint8 to int8
899 temp_data = data;
900
901 //Convert int8 to int32
902 temp_data1 = temp_data;
903
904 *v_gain_correction = temp_data1;
905 }
906
907 return err_flag;
908
909}
910
911/**
912* @brief This function returns current Rsense gain correction value for Battery Current *
913* @details
914* This function returns current Rsense gain correction value for Battery Current
915*
916* @param[in] pmic_device_index. Primary: 0 Secondary: 1
917* @param[in] gainCorrection for battery volatge
918*
919* @return pm_err_flag_type
920* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
921* version of the PMIC.
922* PM_ERR_FLAG__SUCCESS = SUCCESS.
923*
924*/
925pm_err_flag_type pm_fg_adc_usr_get_bcl_i_gain_rsense(uint32 pmic_device, int32 *i_gain_rsense)
926{
927 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
928 pm_register_address_type fg_adc_usr_i_gain_rsense = 0x00;
929 pm_register_data_type data = 0x00;
930
931 int8 temp_data = 0;
932 int32 temp_data1 = 0;
933
934 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);;
935
936 if (NULL == fg_adc_usr_ptr)
937 {
938 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
939 }
940 else
941 {
942 fg_adc_usr_i_gain_rsense = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_i_gain_rsense;
943 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_i_gain_rsense, &data, 0);
944
945 //Convert uint8 to int8
946 temp_data = data;
947
948 //Convert int8 to int32
949 temp_data1 = temp_data;
950
951 *i_gain_rsense = temp_data1;
952 }
953
954 return err_flag;
955}
956
957
958
959/**
960* @brief This function returns current Rsense offset value for Battery Current *
961* @details
962* This function returns current Rsense offset value for Battery Current
963*
964* @param[in] pmic_device_index. Primary: 0 Secondary: 1
965* @param[in] ioffset_rsense Offset Gain Correction battery current
966*
967* @return pm_err_flag_type
968* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
969* version of the PMIC.
970* PM_ERR_FLAG__SUCCESS = SUCCESS.
971*
972*/
973pm_err_flag_type pm_fg_adc_usr_get_bcl_i_offset_rsense(uint32 pmic_device, int32 *i_offset_rsense)
974{
975 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
976 pm_register_address_type fg_adc_usr_i_offset_rsense = 0x00;
977 pm_register_data_type data = 0x00;
978
979 int8 temp_data = 0;
980 int32 temp_data1 = 0;
981
982 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
983
984 if (NULL == fg_adc_usr_ptr)
985 {
986 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
987 }
988 else
989 {
990 fg_adc_usr_i_offset_rsense = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_i_offset_rsense;
991 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_i_offset_rsense, &data, 0);
992
993 //Convert uint8 to int8
994 temp_data = data;
995
996 //Convert int8 to int32
997 temp_data1 = temp_data;
998
999 *i_offset_rsense = (temp_data1 * OFFSET_LSB_NUM) / OFFSET_LSB_DENOM;
1000 }
1001
1002 return err_flag;
1003
1004}
1005
1006
1007/**
1008* @brief This function returns current gain in BATFET for Battery Current *
1009* @details
1010* This function returns current gain in BATFET for Battery Current
1011*
1012* @param[in] pmic_device_index. Primary: 0 Secondary: 1
1013* @param[in] igain_offset_correction Gain Correction for battery current
1014*
1015* @return pm_err_flag_type
1016* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
1017* version of the PMIC.
1018* PM_ERR_FLAG__SUCCESS = SUCCESS.
1019*
1020*/
1021pm_err_flag_type pm_fg_adc_usr_get_bcl_i_gain_batfet(uint32 pmic_device, int32 *i_gain_batfet)
1022{
1023 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1024 pm_register_address_type fg_adc_usr_i_gain_batfet = 0x00;
1025 pm_register_data_type data = 0x00;
1026
1027 int8 temp_data = 0;
1028 int32 temp_data1 = 0;
1029
1030 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
1031
1032 if (NULL == fg_adc_usr_ptr)
1033 {
1034 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
1035 }
1036 else
1037 {
1038 fg_adc_usr_i_gain_batfet = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_i_gain_batfet;
1039 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_i_gain_batfet, &data, 0);
1040
1041 //Convert uint8 to int8
1042 temp_data = data;
1043
1044 //Convert int8 to int32
1045 temp_data1 = temp_data;
1046
1047 *i_gain_batfet = temp_data1;
1048 }
1049
1050 return err_flag;
1051
1052}
1053
1054
1055/**
1056* @brief This function returns current offset in BATFET for Battery Current *
1057* @details
1058* This function returns current gain in BATFET for Battery Current
1059*
1060* @param[in] pmic_device_index. Primary: 0 Secondary: 1
1061* @param[in] ioffset_batfet_correction offset Gain Correction for BATFET
1062*
1063* @return pm_err_flag_type
1064* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
1065* version of the PMIC.
1066* PM_ERR_FLAG__SUCCESS = SUCCESS.
1067*
1068*/
1069pm_err_flag_type pm_fg_adc_usr_get_bcl_i_offset_batfet(uint32 pmic_device, int32 *i_offset_batfet)
1070{
1071 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1072 pm_register_address_type fg_adc_usr_i_offset_batfet = 0x00;
1073 pm_register_data_type data = 0x00;
1074
1075 int8 temp_data = 0;
1076 int32 temp_data1 = 0;
1077
1078 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);;
1079
1080 if (NULL == fg_adc_usr_ptr)
1081 {
1082 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
1083 }
1084 else
1085 {
1086 fg_adc_usr_i_offset_batfet = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_i_offset_batfet;
1087 err_flag = pm_comm_read_byte(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_i_offset_batfet, &data, 0);
1088
1089 //Convert uint8 to int8
1090 temp_data = data;
1091
1092 //Convert int8 to int32
1093 temp_data1 = temp_data;
1094
1095 *i_offset_batfet = ((temp_data1 * OFFSET_LSB_NUM) / OFFSET_LSB_DENOM);
1096 }
1097
1098 return err_flag;
1099}
1100
1101
1102
1103/**
1104* @brief This function returns source used for current sense *
1105* @details
1106* This function returns source used for current sense
1107*
1108* @param[in] pmic_device_index. Primary: 0 Secondary: 1
1109* @param[in] isense_source source used for current sense
1110*
1111* @return pm_err_flag_type
1112* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
1113* version of the PMIC.
1114* PM_ERR_FLAG__SUCCESS = SUCCESS.
1115*
1116*/
1117pm_err_flag_type pm_fg_adc_usr_get_bcl_i_sense_source(uint32 pmic_device, boolean *i_sense_source)
1118{
1119 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1120 pm_register_address_type fg_adc_usr_bcl_isense_source = 0x00;
1121 pm_register_data_type data = 0x00;
1122 uint8 mask = 0x01;
1123
1124 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
1125
1126 if (NULL == fg_adc_usr_ptr)
1127 {
1128 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
1129 }
1130 else
1131 {
1132 fg_adc_usr_bcl_isense_source = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_bcl_i_sense_source;
1133 err_flag = pm_comm_read_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_bcl_isense_source, mask, &data, 0);
1134 *i_sense_source = (boolean )data;
1135 }
1136
1137 return err_flag;
1138}
1139
1140
1141/**
1142* @brief This function cleras stored VBAT minimum *
1143* @details
1144* This function cleras stored VBAT minimum
1145*
1146* @param[in] pmic_device_index. Primary: 0 Secondary: 1
1147* @param[in]enable enable/disable for clearing stored vbat minimum
1148*
1149* @return pm_err_flag_type
1150* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
1151* version of the PMIC.
1152* PM_ERR_FLAG__SUCCESS = SUCCESS.
1153*
1154*/
1155pm_err_flag_type pm_fg_adc_usr_clear_vbat_min(uint32 pmic_device, boolean enable)
1156{
1157 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1158 pm_register_address_type fg_adc_usr_clr_vbat_min = 0x00;
1159
1160 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
1161
1162 if (NULL == fg_adc_usr_ptr)
1163 {
1164 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
1165 }
1166 else
1167 {
1168 fg_adc_usr_clr_vbat_min = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_vbat_min_clr;
1169 err_flag = pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_clr_vbat_min, 0x80, (pm_register_data_type)enable, 0);
1170 }
1171
1172 return err_flag;
1173
1174}
1175
1176/**
1177* @brief This function clears stored IBAT Max *
1178* @details
1179* This function cleras stored IBAT Max
1180*
1181* @param[in] pmic_device_index. Primary: 0 Secondary: 1
1182* @param[in]enable enable/disable for clearing stored vbat minimum
1183*
1184* @return pm_err_flag_type
1185* PM_ERR_FLAG__FEATURE_NOT_SUPPORTED = Feature not available on this
1186* version of the PMIC.
1187* PM_ERR_FLAG__SUCCESS = SUCCESS.
1188*
1189*/
1190pm_err_flag_type pm_fg_adc_usr_clear_ibat_max(uint32 pmic_device, boolean enable)
1191{
1192 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1193 pm_register_address_type fg_adc_usr_clr_ibat_min = 0x00;
1194
1195 pm_fg_data_type* fg_adc_usr_ptr = pm_fg_get_data(pmic_device);
1196
1197 if (NULL == fg_adc_usr_ptr)
1198 {
1199 return PM_ERR_FLAG__FEATURE_NOT_SUPPORTED;
1200 }
1201 else
1202 {
1203 fg_adc_usr_clr_ibat_min = fg_adc_usr_ptr->fg_register->adc_usr_register->base_address + fg_adc_usr_ptr->fg_register->adc_usr_register->fg_adc_usr_ibat_max_clr;
1204 err_flag = pm_comm_write_byte_mask(fg_adc_usr_ptr->comm_ptr->slave_id, fg_adc_usr_clr_ibat_min, 0x80, (pm_register_data_type)enable, 0);
1205 }
1206
1207 return err_flag;
1208
1209}
1210
1211
1212/**
1213PmicFgCalibrateIbat()
1214
1215@brief
1216
1217*/
1218pm_err_flag_type pm_fg_adc_usr_get_calibrated_ibat(uint32 pmic_device, int32 *calibrated_ibat)
1219{
1220 pm_err_flag_type errFlag = PM_ERR_FLAG__SUCCESS;
1221
1222 int32 raw_ibat = 0;
1223 static int32 gain = 0;
1224 static int32 offset = 0;
1225
1226 boolean sense_source = FALSE;
1227
1228 *calibrated_ibat = 0;
1229
1230 errFlag |= pm_fg_adc_usr_get_ibat(pmic_device, &raw_ibat);
1231
1232 if((!gain) || (!offset))
1233 {//gain and offset are constant per part, so we should read them only once
1234 errFlag |= pm_fg_adc_usr_get_bcl_i_sense_source( pmic_device, &sense_source);
1235
1236 if(sense_source)
1237 {// 1 -> pick rsense correction
1238 errFlag |= pm_fg_adc_usr_get_bcl_i_gain_rsense( pmic_device, &gain );
1239 errFlag |= pm_fg_adc_usr_get_bcl_i_offset_rsense( pmic_device, &offset );
1240 }
1241 else
1242 {// 0 -> pick batfet correction
1243 errFlag |= pm_fg_adc_usr_get_bcl_i_gain_batfet( pmic_device, &gain );
1244 errFlag |= pm_fg_adc_usr_get_bcl_i_offset_batfet( pmic_device, &offset );
1245 }
1246 }
1247
1248 *calibrated_ibat = (((raw_ibat + offset) * (GAIN_LSB_DENOM + gain ))/ GAIN_LSB_DENOM);
1249
1250 return errFlag;
1251}
1252
1253pm_err_flag_type pm_fg_adc_usr_get_calibrated_vbat(uint32 pmic_device, uint32 *calibrated_vbat)
1254{
1255 pm_err_flag_type errFlag = PM_ERR_FLAG__SUCCESS;
1256
1257 uint32 raw_vbat = 0;
1258 static int32 gain = 0;
1259
1260 errFlag = pm_fg_adc_usr_get_vbat(pmic_device, &raw_vbat);
1261
1262 if(!gain)
1263 {//Gain is constant w.r.t to every part, so we should read it only once.
1264 errFlag |= pm_fg_adc_usr_get_bcl_v_gain_batt( pmic_device, &gain );
1265 }
1266
1267 /* Applying gain calibration to the raw value*/
1268 // Twos_complement(VBAT_registerval) *39 * (1+ Twos_Complement(V_GAIN_registerval) * (.32/128))
1269 *calibrated_vbat = (uint32)(((raw_vbat * (GAIN_LSB_DENOM + gain)))/GAIN_LSB_DENOM);
1270
1271 return errFlag;
1272}
1273
lijuang33f9eea2015-08-29 15:40:05 +08001274pm_err_flag_type pm_fg_usr_get_vbat(uint32 pmic_device, uint32 *calibrated_vbat)
1275{
1276 uint16 wait_index = 0;
1277 boolean adc_reading_ready = FALSE;
lijuangd521db42015-09-23 14:22:07 +08001278 boolean enable = FALSE;
lijuang33f9eea2015-08-29 15:40:05 +08001279
1280 pm_err_flag_type err_flag = PM_ERR_FLAG__SUCCESS;
1281
1282 pm_fg_driver_init(pmic_device);
1283
lijuangd521db42015-09-23 14:22:07 +08001284 err_flag |= pm_fg_adc_usr_get_bcl_monitoring_sts(pmic_device, &enable);
1285 if (err_flag != PM_ERR_FLAG__SUCCESS) {
1286 return err_flag;
1287 } else {
1288 if (enable == FALSE) {
1289 err_flag |= pm_fg_adc_usr_enable_bcl_monitoring(pmic_device, TRUE);
1290 if (err_flag != PM_ERR_FLAG__SUCCESS)
1291 return err_flag;
1292 }
1293 }
1294
lijuang33f9eea2015-08-29 15:40:05 +08001295 //Check Vbatt ADC level
1296 err_flag |= pm_fg_adc_usr_get_bcl_values(pmic_device, &adc_reading_ready); //Check if Vbatt ADC is ready
1297
1298 //Check if Vbatt ADC is Ready
1299 for (wait_index = 0; wait_index < PM_MAX_ADC_READY_DELAY; wait_index++) {
1300 if(adc_reading_ready == FALSE) {
1301 udelay(PM_MIN_ADC_READY_DELAY);
1302 err_flag |= pm_fg_adc_usr_get_bcl_values(pmic_device, &adc_reading_ready);
1303 } else {
1304 break;
1305 }
1306 }
1307
1308 if ( err_flag != PM_ERR_FLAG__SUCCESS ) {
1309 return err_flag;
1310 }
1311
1312 if (adc_reading_ready) {
1313 err_flag |= pm_fg_adc_usr_get_calibrated_vbat(pmic_device, calibrated_vbat); //Read calibrated vbatt ADC
1314 }
1315
1316 return err_flag;
1317}