1 /*
2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 /* #include <adc.h> */
8 #include <dm.h>
9 #include <errno.h>
10 #include <common.h>
11 #include <malloc.h>
12 #include <fdtdec.h>
13 #include <asm/gpio.h>
14 #include <common.h>
15 #include <power/pmic.h>
16 #include <dm/uclass-internal.h>
17 #include <power/charge_display.h>
18 #include <power/charge_animation.h>
19 #include <power/fuel_gauge.h>
20 #include <power/rk8xx_pmic.h>
21 #include <linux/usb/phy-rockchip-usb2.h>
22 #include "fg_regs.h"
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static int dbg_enable = 0;
27 #define DBG(args...) \
28 do { \
29 if (dbg_enable) { \
30 printf(args); \
31 } \
32 } while (0)
33
34 #define BAT_INFO(fmt, args...) printf("rk816-bat: "fmt, ##args)
35
36 #define DRIVER_VERSION "2.0"
37
38 /* THERMAL_REG */
39 #define TEMP_115C (0x03 << 2)
40 #define FB_TEMP_MSK 0x0c
41
42 /* CHRG_CTRL_REG2*/
43 #define FINISH_100MA (0x00 << 6)
44 #define FINISH_150MA (0x01 << 6)
45 #define FINISH_200MA (0x02 << 6)
46 #define FINISH_250MA (0x03 << 6)
47 #define FINISH_CUR_MSK 0xc7
48
49 /* CHRG_CTRL_REG3*/
50 #define CHRG_TERM_DIG_SIGNAL (1 << 5)
51 #define CHRG_TIMER_CCCV_EN (1 << 2)
52
53 /* CHRG_CTRL_REG */
54 #define ILIM_450MA (0x00)
55 #define ILIM_2000MA (0x07)
56 #define CHRG_CT_EN (1 << 7)
57
58 /* USB_CTRL_REG */
59 #define INPUT_CUR_MSK 0x0f
60
61 /* VB_MON_REG */
62 #define PLUG_IN_STS (1 << 6)
63
64 /* GGSTS */
65 #define BAT_CON (1 << 4)
66 #define VOL_INSTANT (1 << 0)
67 #define VOL_AVG (0 << 0)
68 #define VOL_AVG_MASK (1 << 0)
69
70 /* TS_CTRL_REG */
71 #define GG_EN (1 << 7)
72
73 /* CHRG_USB_CTRL*/
74 #define CHRG_EN (1 << 7)
75
76 /* BAT_CTRL_REG */
77 #define USB_SYS_EN (1 << 6)
78
79 /*SUP_STS_REG*/
80 #define BAT_EXS (1 << 7)
81 #define USB_EXIST (1 << 1)
82 #define USB_EFF (1 << 0)
83 #define CHARGE_OFF (0x00 << 4)
84 #define DEAD_CHARGE (0x01 << 4)
85 #define TRICKLE_CHARGE (0x02 << 4)
86 #define CC_OR_CV (0x03 << 4)
87 #define CHARGE_FINISH (0x04 << 4)
88 #define USB_OVER_VOL (0x05 << 4)
89 #define BAT_TMP_ERR (0x06 << 4)
90 #define TIMER_ERR (0x07 << 4)
91 #define USB_VLIMIT_EN (1 << 3)
92 #define USB_CLIMIT_EN (1 << 2)
93 #define BAT_STATUS_MSK 0x70
94
95 /* GGCON */
96 #define ADC_CUR_MODE (1 << 1)
97
98 /* CALI PARAM */
99 #define FINISH_CALI_CURR 1500
100 #define TERM_CALI_CURR 600
101 #define VIRTUAL_POWER_VOL 4200
102 #define VIRTUAL_POWER_CUR 1000
103 #define VIRTUAL_POWER_SOC 66
104 #define SECONDS(n) ((n) * 1000)
105
106 /* CALC PARAM */
107 #define MAX_PERCENTAGE 100
108 #define MAX_INTERPOLATE 1000
109 #define MAX_INT 0x7fff
110 #define MIN_FCC 500
111
112 /* DC ADC */
113 #define FG_INIT (1 << 3)
114 #define FG_RESET_LATE (1 << 1)
115 #define FG_RESET_NOW (1 << 0)
116 #define CHRG_TERM_DSOC 90
117 #define CHRG_TERM_K 650
118 #define CHRG_FULL_K 400
119 #define ADC_CALIB_THRESHOLD 4
120 #define DC_ADC_TRIGGER 150
121 #define DIV(x) ((x) ? (x) : 1)
122
123 #define SAMPLE_RES_20MR 20
124
125 /***********************************************************/
126 struct battery_priv {
127 struct udevice *dev;
128 int chrg_type;
129 int poffset;
130 int bat_res;
131 int current_avg;
132 int voltage_avg;
133 int voltage_ocv;
134 int voltage_k;
135 int voltage_b;
136 int dsoc;
137 int rsoc;
138 int fcc;
139 u32 qmax;
140 int remain_cap;
141 u32 design_cap;
142 int nac;
143 u32 *ocv_table;
144 u32 ocv_size;
145 int virtual_power;
146 int sample_res;
147 int pwroff_min;
148 int sm_old_cap;
149 int sm_linek;
150 int sm_chrg_dsoc;
151 int adc_allow_update;
152 int chrg_vol_sel;
153 int chrg_cur_input;
154 int chrg_cur_sel;
155 int dts_vol_sel;
156 int dts_cur_input;
157 int dts_cur_sel;
158 int max_soc_offset;
159 struct gpio_desc dc_det;
160 int dc_type;
161 int dc_det_adc;
162 ulong vol_mode_base;
163 ulong finish_chrg_base;
164 u8 calc_dsoc;
165 u8 calc_rsoc;
166 int sm_meet_soc;
167 u8 halt_cnt;
168 bool is_halt;
169 bool is_ocv_calib;
170 bool is_max_soc_offset;
171 bool is_first_power_on;
172 bool is_sw_reset;
173 int pwr_dsoc;
174 int pwr_rsoc;
175 int pwr_vol;
176 int res_fac;
177 int over_20mR;
178 };
179
180 enum charger_type {
181 NO_CHARGER = 0,
182 USB_CHARGER,
183 AC_CHARGER,
184 DC_CHARGER,
185 UNDEF_CHARGER,
186 };
187
188 enum dc_type {
189 DC_TYPE_OF_NONE = 0,
190 DC_TYPE_OF_GPIO,
191 DC_TYPE_OF_ADC,
192 };
193
194 static const char *charger_type_to_name[] = {
195 "NONE",
196 "USB",
197 "AC",
198 "DC",
199 "UNKN",
200 };
201
202 /*
203 * If sample resistor changes, we need caculate a new CHRG_CUR_SEL[] table.
204 *
205 * Calculation method:
206 * 1. find 20mR(default) current charge table, that is:
207 * 20mR: [1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400]
208 *
209 * 2. caculate Rfac(not care much, just using it) by sample resistor(ie. Rsam);
210 * Rsam = 20mR: Rfac = 10;
211 * Rsam > 20mR: Rfac = Rsam * 10 / 20;
212 * Rsam < 20mR: Rfac = 20 * 10 / Rsam;
213 *
214 * 3. from step2, we get Rfac, then we can get new charge current table by 20mR
215 * charge table:
216 * Iorg: member from 20mR charge table; Inew: new member for charge table.
217 *
218 * Rsam > 20mR: Inew = Iorg * 10 / Rfac;
219 * Rsam < 20mR: Inew = Iorg * Rfac / 10;
220 *
221 * Notice: Inew should round up if it is not a integer!!!
222 *
223 * Example:
224 * 10mR: [2000, 2400, 2800, 3200, 3600, 4000, 4500, 4800]
225 * 20mR: [1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400]
226 * 40mR: [500, 600, 700, 800, 900, 1000, 1125, 1200]
227 * 50mR: [400, 480, 560, 640, 720, 800, 900, 960]
228 * 60mR: [334, 400, 467, 534, 600, 667, 750, 800]
229 *
230 * You should add property 'sample_res = <Rsam>' at battery node.
231 */
232 static const u32 CHRG_VOL_SEL[] = {
233 4050, 4100, 4150, 4200, 4250, 4300, 4350
234 };
235
236 static const u32 CHRG_CUR_SEL[] = {
237 1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400
238 };
239
240 static const u32 CHRG_CUR_INPUT[] = {
241 450, 800, 850, 1000, 1250, 1500, 1750, 2000
242 };
243
244 /* 'res_fac' has been *10, so we need divide 10 */
245 #define RES_FAC_MUX(value, res_fac) ((value) * res_fac / 10)
246
247 /* 'res_fac' has been *10, so we need 'value * 10' before divide 'res_fac' */
248 #define RES_FAC_DIV(value, res_fac) ((value) * 10 / res_fac)
249
rk816_bat_read(struct battery_priv * di,u8 reg)250 static int rk816_bat_read(struct battery_priv *di, u8 reg)
251 {
252 return pmic_reg_read(di->dev->parent, reg);
253 }
254
rk816_bat_write(struct battery_priv * di,u8 reg,u8 buf)255 static void rk816_bat_write(struct battery_priv *di, u8 reg, u8 buf)
256 {
257 pmic_reg_write(di->dev->parent, reg, buf);
258 }
259
rk816_bat_dwc_otg_check_dpdm(void)260 static int rk816_bat_dwc_otg_check_dpdm(void)
261 {
262 #if defined(CONFIG_PHY_ROCKCHIP_INNO_USB2) && !defined(CONFIG_SPL_BUILD)
263 return rockchip_chg_get_type();
264 #else
265 BAT_INFO("rockchip_chg_get_type() is not implement\n");
266 return NO_CHARGER;
267 #endif
268 }
269
rk816_bat_get_rsoc(struct battery_priv * di)270 static int rk816_bat_get_rsoc(struct battery_priv *di)
271 {
272 return (di->remain_cap + di->fcc / 200) * 100 / DIV(di->fcc);
273 }
274
rk816_bat_get_dsoc(struct battery_priv * di)275 static int rk816_bat_get_dsoc(struct battery_priv *di)
276 {
277 return rk816_bat_read(di, SOC_REG);
278 }
279
rk816_bat_enable_input_current(struct battery_priv * di)280 static void rk816_bat_enable_input_current(struct battery_priv *di)
281 {
282 u8 val;
283
284 val = rk816_bat_read(di, BAT_CTRL_REG);
285 val |= USB_SYS_EN;
286 rk816_bat_write(di, BAT_CTRL_REG, val);
287 }
288
rk816_bat_enable_gauge(struct battery_priv * di)289 static void rk816_bat_enable_gauge(struct battery_priv *di)
290 {
291 u8 val;
292
293 val = rk816_bat_read(di, TS_CTRL_REG);
294 val |= GG_EN;
295 rk816_bat_write(di, TS_CTRL_REG, val);
296 }
297
rk816_bat_set_vol_instant_mode(struct battery_priv * di)298 static void rk816_bat_set_vol_instant_mode(struct battery_priv *di)
299 {
300 u8 val;
301
302 val = rk816_bat_read(di, GGSTS_REG);
303 val |= VOL_INSTANT;
304 rk816_bat_write(di, GGSTS_REG, val);
305 }
306
rk816_bat_set_vol_avg_mode(struct battery_priv * di)307 static void rk816_bat_set_vol_avg_mode(struct battery_priv *di)
308 {
309 u8 val;
310
311 val = rk816_bat_read(di, GGSTS_REG);
312 val &= ~VOL_AVG_MASK;
313 val |= VOL_AVG;
314 rk816_bat_write(di, GGSTS_REG, val);
315 }
316
rk816_bat_get_vcalib0(struct battery_priv * di)317 static int rk816_bat_get_vcalib0(struct battery_priv *di)
318 {
319 int val = 0;
320
321 val |= rk816_bat_read(di, VCALIB0_REGL) << 0;
322 val |= rk816_bat_read(di, VCALIB0_REGH) << 8;
323
324 return val;
325 }
326
rk816_bat_get_vcalib1(struct battery_priv * di)327 static int rk816_bat_get_vcalib1(struct battery_priv *di)
328 {
329 int val = 0;
330
331 val |= rk816_bat_read(di, VCALIB1_REGL) << 0;
332 val |= rk816_bat_read(di, VCALIB1_REGH) << 8;
333
334 return val;
335 }
336
rk816_bat_set_coffset(struct battery_priv * di,int val)337 static void rk816_bat_set_coffset(struct battery_priv *di, int val)
338 {
339 u8 buf;
340
341 buf = (val >> 0) & 0xff;
342 rk816_bat_write(di, CAL_OFFSET_REGL, buf);
343 buf = (val >> 8) & 0xff;
344 rk816_bat_write(di, CAL_OFFSET_REGH, buf);
345 }
346
rk816_bat_get_ioffset(struct battery_priv * di)347 static int rk816_bat_get_ioffset(struct battery_priv *di)
348 {
349 int val = 0;
350
351 val |= rk816_bat_read(di, IOFFSET_REGL) << 0;
352 val |= rk816_bat_read(di, IOFFSET_REGH) << 8;
353
354 return val;
355 }
356
rk816_bat_save_dsoc(struct battery_priv * di,u8 save_soc)357 static void rk816_bat_save_dsoc(struct battery_priv *di, u8 save_soc)
358 {
359 static int old_soc = -1;
360
361 if (old_soc != save_soc) {
362 old_soc = save_soc;
363 rk816_bat_write(di, SOC_REG, save_soc);
364 }
365 }
366
rk816_bat_save_cap(struct battery_priv * di,int cap)367 static void rk816_bat_save_cap(struct battery_priv *di, int cap)
368 {
369 u8 buf;
370 static int old_cap;
371
372 if (old_cap == cap)
373 return;
374
375 if (cap >= di->qmax)
376 cap = di->qmax;
377
378 old_cap = cap;
379 buf = (cap >> 24) & 0xff;
380 rk816_bat_write(di, REMAIN_CAP_REG3, buf);
381 buf = (cap >> 16) & 0xff;
382 rk816_bat_write(di, REMAIN_CAP_REG2, buf);
383 buf = (cap >> 8) & 0xff;
384 rk816_bat_write(di, REMAIN_CAP_REG1, buf);
385 buf = (cap >> 0) & 0xff;
386 rk816_bat_write(di, REMAIN_CAP_REG0, buf);
387 }
388
rk816_bat_init_voltage_kb(struct battery_priv * di)389 static void rk816_bat_init_voltage_kb(struct battery_priv *di)
390 {
391 int vcalib0, vcalib1;
392
393 vcalib0 = rk816_bat_get_vcalib0(di);
394 vcalib1 = rk816_bat_get_vcalib1(di);
395 di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0);
396 di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000;
397 DBG("%s. vk=%d, vb=%d\n", __func__, di->voltage_k, di->voltage_b);
398 }
399
rk816_bat_get_ocv_voltage(struct battery_priv * di)400 static int rk816_bat_get_ocv_voltage(struct battery_priv *di)
401 {
402 int vol, val = 0;
403
404 val |= rk816_bat_read(di, BAT_OCV_REGL) << 0;
405 val |= rk816_bat_read(di, BAT_OCV_REGH) << 8;
406 vol = di->voltage_k * val / 1000 + di->voltage_b;
407 vol = vol * 1100 / 1000;
408
409 return vol;
410 }
411
rk816_bat_get_avg_current(struct battery_priv * di)412 static int rk816_bat_get_avg_current(struct battery_priv *di)
413 {
414 int cur, val = 0;
415
416 val |= rk816_bat_read(di, BAT_CUR_AVG_REGL) << 0;
417 val |= rk816_bat_read(di, BAT_CUR_AVG_REGH) << 8;
418
419 if (val & 0x800)
420 val -= 4096;
421 if (!di->over_20mR)
422 cur = RES_FAC_MUX(val * 1506, di->res_fac) / 1000;
423 else
424 cur = RES_FAC_DIV(val * 1506, di->res_fac) / 1000;
425
426 return cur;
427 }
428
rk816_bat_get_avg_voltage(struct battery_priv * di)429 static int rk816_bat_get_avg_voltage(struct battery_priv *di)
430 {
431 int vol, val = 0;
432
433 val |= rk816_bat_read(di, BAT_VOL_REGL) << 0;
434 val |= rk816_bat_read(di, BAT_VOL_REGH) << 8;
435 vol = di->voltage_k * val / 1000 + di->voltage_b;
436 vol = vol * 1100 / 1000;
437
438 return vol;
439 }
440
rk816_bat_get_est_voltage(struct battery_priv * di)441 static int rk816_bat_get_est_voltage(struct battery_priv *di)
442 {
443 int est_vol, vol, curr;
444
445 vol = rk816_bat_get_avg_voltage(di);
446 curr = rk816_bat_get_avg_current(di);
447 est_vol = vol - (di->bat_res * curr / 1000);
448
449 return (est_vol > 2800) ? est_vol : vol;
450 }
451
rk816_bat_finish_ma(struct battery_priv * di,int fcc)452 static u8 rk816_bat_finish_ma(struct battery_priv *di, int fcc)
453 {
454 u8 ma;
455
456 if (fcc > 5000)
457 ma = FINISH_250MA;
458 else if (fcc >= 4000)
459 ma = FINISH_200MA;
460 else if (fcc >= 3000)
461 ma = FINISH_150MA;
462 else
463 ma = FINISH_100MA;
464
465 /* adjust ma according to sample resistor */
466 if (di->sample_res < 20) {
467 /* ma should div 2 */
468 if (ma == FINISH_200MA)
469 ma = FINISH_100MA;
470 else if (ma == FINISH_250MA)
471 ma = FINISH_150MA;
472 } else if (di->sample_res > 20) {
473 /* ma should mux 2 */
474 if (ma == FINISH_100MA)
475 ma = FINISH_200MA;
476 else if (ma == FINISH_150MA)
477 ma = FINISH_250MA;
478 }
479
480 return ma;
481 }
482
rk816_bat_select_chrg_cv(struct battery_priv * di)483 static void rk816_bat_select_chrg_cv(struct battery_priv *di)
484 {
485 int index, chrg_vol_sel, chrg_cur_sel, chrg_cur_input;
486
487 chrg_vol_sel = di->dts_vol_sel;
488 chrg_cur_sel = di->dts_cur_sel;
489 chrg_cur_input = di->dts_cur_input;
490
491 if (di->sample_res < 20) {
492 if (chrg_cur_sel > 2000)
493 chrg_cur_sel = RES_FAC_DIV(chrg_cur_sel, di->res_fac);
494 else
495 chrg_cur_sel = 1000;
496 } else if (di->sample_res > 20) {
497 chrg_cur_sel = RES_FAC_MUX(chrg_cur_sel, di->res_fac);
498 if (chrg_cur_sel > 2400)
499 chrg_cur_sel = 2400;
500 if (chrg_cur_sel < 1000)
501 chrg_cur_sel = 1000;
502 }
503
504 for (index = 0; index < ARRAY_SIZE(CHRG_VOL_SEL); index++) {
505 if (chrg_vol_sel < CHRG_VOL_SEL[index])
506 break;
507 di->chrg_vol_sel = (index << 4);
508 }
509
510 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_INPUT); index++) {
511 if (chrg_cur_input < CHRG_CUR_INPUT[index])
512 break;
513 di->chrg_cur_input = (index << 0);
514 }
515
516 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_SEL); index++) {
517 if (chrg_cur_sel < CHRG_CUR_SEL[index])
518 break;
519 di->chrg_cur_sel = (index << 0);
520 }
521
522 DBG("<%s>. vol=0x%x, input=0x%x, sel=0x%x\n",
523 __func__, di->chrg_vol_sel, di->chrg_cur_input, di->chrg_cur_sel);
524 }
525
rk816_bat_init_chrg_config(struct battery_priv * di)526 static void rk816_bat_init_chrg_config(struct battery_priv *di)
527 {
528 u8 chrg_ctrl1, usb_ctrl, chrg_ctrl2, chrg_ctrl3;
529 u8 sup_sts, ggcon, thermal, finish_ma;
530
531 rk816_bat_select_chrg_cv(di);
532 finish_ma = rk816_bat_finish_ma(di, di->fcc);
533
534 ggcon = rk816_bat_read(di, GGCON_REG);
535 sup_sts = rk816_bat_read(di, SUP_STS_REG);
536 usb_ctrl = rk816_bat_read(di, USB_CTRL_REG);
537 thermal = rk816_bat_read(di, THERMAL_REG);
538 chrg_ctrl2 = rk816_bat_read(di, CHRG_CTRL_REG2);
539 chrg_ctrl3 = rk816_bat_read(di, CHRG_CTRL_REG3);
540
541 /* set charge current and voltage */
542 usb_ctrl &= ~INPUT_CUR_MSK;
543 usb_ctrl |= di->chrg_cur_input;
544 chrg_ctrl1 = (CHRG_EN | di->chrg_vol_sel | di->chrg_cur_sel);
545
546 /* digital signal and finish current*/
547 chrg_ctrl3 |= CHRG_TERM_DIG_SIGNAL;
548 chrg_ctrl2 &= ~FINISH_CUR_MSK;
549 chrg_ctrl2 |= finish_ma;
550
551 /* cccv mode */
552 chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN;
553
554 /* enable voltage limit and enable input current limit */
555 sup_sts |= USB_VLIMIT_EN;
556 sup_sts |= USB_CLIMIT_EN;
557
558 /* set feedback temperature */
559 usb_ctrl |= CHRG_CT_EN;
560 thermal &= ~FB_TEMP_MSK;
561 thermal |= TEMP_115C;
562
563 /* adc current mode */
564 ggcon |= ADC_CUR_MODE;
565
566 rk816_bat_write(di, GGCON_REG, ggcon);
567 rk816_bat_write(di, SUP_STS_REG, sup_sts);
568 rk816_bat_write(di, USB_CTRL_REG, usb_ctrl);
569 rk816_bat_write(di, THERMAL_REG, thermal);
570 rk816_bat_write(di, CHRG_CTRL_REG1, chrg_ctrl1);
571 rk816_bat_write(di, CHRG_CTRL_REG2, chrg_ctrl2);
572 rk816_bat_write(di, CHRG_CTRL_REG3, chrg_ctrl3);
573 }
574
interpolate(int value,u32 * table,int size)575 static u32 interpolate(int value, u32 *table, int size)
576 {
577 uint8_t i;
578 uint16_t d;
579
580 for (i = 0; i < size; i++) {
581 if (value < table[i])
582 break;
583 }
584
585 if ((i > 0) && (i < size)) {
586 d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1));
587 d /= table[i] - table[i - 1];
588 d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1));
589 } else {
590 d = i * ((MAX_INTERPOLATE + size / 2) / size);
591 }
592
593 if (d > 1000)
594 d = 1000;
595
596 return d;
597 }
598
599 /* returns (a * b) / c */
ab_div_c(u32 a,u32 b,u32 c)600 static int32_t ab_div_c(u32 a, u32 b, u32 c)
601 {
602 bool sign;
603 u32 ans = MAX_INT;
604 int32_t tmp;
605
606 sign = ((((a ^ b) ^ c) & 0x80000000) != 0);
607
608 if (c != 0) {
609 if (sign)
610 c = -c;
611 tmp = ((int32_t)a * b + (c >> 1)) / c;
612 if (tmp < MAX_INT)
613 ans = tmp;
614 }
615
616 if (sign)
617 ans = -ans;
618
619 return ans;
620 }
621
rk816_bat_vol_to_cap(struct battery_priv * di,int voltage)622 static int rk816_bat_vol_to_cap(struct battery_priv *di, int voltage)
623 {
624 u32 *ocv_table, tmp;
625 int ocv_size, ocv_cap;
626
627 ocv_table = di->ocv_table;
628 ocv_size = di->ocv_size;
629 tmp = interpolate(voltage, ocv_table, ocv_size);
630 ocv_cap = ab_div_c(tmp, di->fcc, MAX_INTERPOLATE);
631
632 return ocv_cap;
633 }
634
rk816_bat_vol_to_soc(struct battery_priv * di,int voltage)635 static int rk816_bat_vol_to_soc(struct battery_priv *di, int voltage)
636 {
637 u32 *ocv_table, tmp;
638 int ocv_size, ocv_soc;
639
640 ocv_table = di->ocv_table;
641 ocv_size = di->ocv_size;
642 tmp = interpolate(voltage, ocv_table, ocv_size);
643 ocv_soc = ab_div_c(tmp, MAX_PERCENTAGE, MAX_INTERPOLATE);
644
645 return ocv_soc;
646 }
647
rk816_bat_get_prev_cap(struct battery_priv * di)648 static int rk816_bat_get_prev_cap(struct battery_priv *di)
649 {
650 int val = 0;
651
652 val |= rk816_bat_read(di, REMAIN_CAP_REG3) << 24;
653 val |= rk816_bat_read(di, REMAIN_CAP_REG2) << 16;
654 val |= rk816_bat_read(di, REMAIN_CAP_REG1) << 8;
655 val |= rk816_bat_read(di, REMAIN_CAP_REG0) << 0;
656
657 return val;
658 }
659
rk816_bat_save_fcc(struct battery_priv * di,u32 cap)660 static void rk816_bat_save_fcc(struct battery_priv *di, u32 cap)
661 {
662 u8 buf;
663
664 buf = (cap >> 24) & 0xff;
665 rk816_bat_write(di, NEW_FCC_REG3, buf);
666 buf = (cap >> 16) & 0xff;
667 rk816_bat_write(di, NEW_FCC_REG2, buf);
668 buf = (cap >> 8) & 0xff;
669 rk816_bat_write(di, NEW_FCC_REG1, buf);
670 buf = (cap >> 0) & 0xff;
671 rk816_bat_write(di, NEW_FCC_REG0, buf);
672 }
673
rk816_bat_get_fcc(struct battery_priv * di)674 static int rk816_bat_get_fcc(struct battery_priv *di)
675 {
676 int val = 0;
677
678 val |= rk816_bat_read(di, NEW_FCC_REG3) << 24;
679 val |= rk816_bat_read(di, NEW_FCC_REG2) << 16;
680 val |= rk816_bat_read(di, NEW_FCC_REG1) << 8;
681 val |= rk816_bat_read(di, NEW_FCC_REG0) << 0;
682
683 if (val < MIN_FCC)
684 val = di->design_cap;
685 else if (val > di->qmax)
686 val = di->qmax;
687
688 return val;
689 }
690
rk816_bat_get_pwroff_min(struct battery_priv * di)691 static u8 rk816_bat_get_pwroff_min(struct battery_priv *di)
692 {
693 u8 cur, last;
694
695 cur = rk816_bat_read(di, NON_ACT_TIMER_CNT_REG);
696 last = rk816_bat_read(di, NON_ACT_TIMER_CNT_SAVE_REG);
697 rk816_bat_write(di, NON_ACT_TIMER_CNT_SAVE_REG, cur);
698
699 return (cur != last) ? cur : 0;
700 }
701
rk816_bat_get_coulomb_cap(struct battery_priv * di)702 static int rk816_bat_get_coulomb_cap(struct battery_priv *di)
703 {
704 int cap, val = 0;
705
706 val |= rk816_bat_read(di, GASCNT_REG3) << 24;
707 val |= rk816_bat_read(di, GASCNT_REG2) << 16;
708 val |= rk816_bat_read(di, GASCNT_REG1) << 8;
709 val |= rk816_bat_read(di, GASCNT_REG0) << 0;
710
711 if (!di->over_20mR)
712 cap = RES_FAC_MUX(val / 2390, di->res_fac);
713 else
714 cap = RES_FAC_DIV(val / 2390, di->res_fac);
715
716 return cap;
717 }
718
rk816_bat_init_capacity(struct battery_priv * di,u32 capacity)719 static void rk816_bat_init_capacity(struct battery_priv *di, u32 capacity)
720 {
721 u8 buf;
722 u32 cap;
723 int delta;
724
725 delta = capacity - di->remain_cap;
726 if (!delta)
727 return;
728
729 if (!di->over_20mR)
730 cap = RES_FAC_DIV(capacity * 2390, di->res_fac);
731 else
732 cap = RES_FAC_MUX(capacity * 2390, di->res_fac);
733
734 buf = (cap >> 24) & 0xff;
735 rk816_bat_write(di, GASCNT_CAL_REG3, buf);
736 buf = (cap >> 16) & 0xff;
737 rk816_bat_write(di, GASCNT_CAL_REG2, buf);
738 buf = (cap >> 8) & 0xff;
739 rk816_bat_write(di, GASCNT_CAL_REG1, buf);
740 buf = (cap >> 0) & 0xff;
741 rk816_bat_write(di, GASCNT_CAL_REG0, buf);
742 udelay(75);
743 di->remain_cap = rk816_bat_get_coulomb_cap(di);
744 di->rsoc = rk816_bat_get_rsoc(di);
745 }
746
is_rk816_bat_ocv_valid(struct battery_priv * di)747 static bool is_rk816_bat_ocv_valid(struct battery_priv *di)
748 {
749 return di->pwroff_min >= 30 ? true : false;
750 }
751
rk816_bat_get_usb_state(struct battery_priv * di)752 static int rk816_bat_get_usb_state(struct battery_priv *di)
753 {
754 int charger_type;
755
756 switch (rk816_bat_dwc_otg_check_dpdm()) {
757 case 0:
758 if ((rk816_bat_read(di, VB_MON_REG) & PLUG_IN_STS) != 0)
759 charger_type = DC_CHARGER;
760 else
761 charger_type = NO_CHARGER;
762 break;
763 case 1:
764 case 3:
765 charger_type = USB_CHARGER;
766 break;
767 case 2:
768 case 4:
769 charger_type = AC_CHARGER;
770 break;
771 default:
772 charger_type = NO_CHARGER;
773 }
774
775 return charger_type;
776 }
777
rk816_bat_clr_initialized_state(struct battery_priv * di)778 static void rk816_bat_clr_initialized_state(struct battery_priv *di)
779 {
780 u8 val;
781
782 val = rk816_bat_read(di, MISC_MARK_REG);
783 val &= ~FG_INIT;
784 rk816_bat_write(di, MISC_MARK_REG, val);
785 }
786
rk816_bat_is_initialized(struct battery_priv * di)787 static bool rk816_bat_is_initialized(struct battery_priv *di)
788 {
789 return (rk816_bat_read(di, MISC_MARK_REG) & FG_INIT) ? true : false;
790 }
791
rk816_bat_set_initialized_state(struct battery_priv * di)792 static void rk816_bat_set_initialized_state(struct battery_priv *di)
793 {
794 u8 val;
795
796 val = rk816_bat_read(di, MISC_MARK_REG);
797 if (rk816_bat_get_usb_state(di) != NO_CHARGER) {
798 val |= FG_INIT;
799 rk816_bat_write(di, MISC_MARK_REG, val);
800 BAT_INFO("fuel gauge initialized... estv=%d, ch=%d\n",
801 rk816_bat_get_est_voltage(di),
802 rk816_bat_get_usb_state(di));
803 }
804 }
805
rk816_bat_first_pwron(struct battery_priv * di)806 static void rk816_bat_first_pwron(struct battery_priv *di)
807 {
808 int ocv_vol;
809
810 rk816_bat_save_fcc(di, di->design_cap);
811 ocv_vol = rk816_bat_get_ocv_voltage(di);
812 di->fcc = rk816_bat_get_fcc(di);
813 di->nac = rk816_bat_vol_to_cap(di, ocv_vol);
814 di->rsoc = rk816_bat_vol_to_soc(di, ocv_vol);
815 di->dsoc = di->rsoc;
816 rk816_bat_init_capacity(di, di->nac);
817 rk816_bat_set_initialized_state(di);
818
819 BAT_INFO("first power on: soc=%d\n", di->dsoc);
820 }
821
rk816_bat_get_halt_cnt(struct battery_priv * di)822 static u8 rk816_bat_get_halt_cnt(struct battery_priv *di)
823 {
824 return rk816_bat_read(di, HALT_CNT_REG);
825 }
826
rk816_bat_inc_halt_cnt(struct battery_priv * di)827 static void rk816_bat_inc_halt_cnt(struct battery_priv *di)
828 {
829 u8 cnt;
830
831 cnt = rk816_bat_read(di, HALT_CNT_REG);
832 rk816_bat_write(di, HALT_CNT_REG, ++cnt);
833 }
834
is_rk816_bat_last_halt(struct battery_priv * di)835 static bool is_rk816_bat_last_halt(struct battery_priv *di)
836 {
837 int pre_cap = rk816_bat_get_prev_cap(di);
838 int now_cap = rk816_bat_get_coulomb_cap(di);
839
840 /* over 5%: system halt last time */
841 if (abs(now_cap - pre_cap) > (di->fcc / 20)) {
842 rk816_bat_inc_halt_cnt(di);
843 return true;
844 } else {
845 return false;
846 }
847 }
848
rk816_bat_not_first_pwron(struct battery_priv * di)849 static void rk816_bat_not_first_pwron(struct battery_priv *di)
850 {
851 int pre_soc, pre_cap, ocv_cap, ocv_soc, ocv_vol, now_cap;
852
853 di->fcc = rk816_bat_get_fcc(di);
854 pre_soc = rk816_bat_get_dsoc(di);
855 pre_cap = rk816_bat_get_prev_cap(di);
856 now_cap = rk816_bat_get_coulomb_cap(di);
857 di->pwr_dsoc = pre_soc;
858 di->pwr_rsoc = (now_cap + di->fcc / 200) * 100 / DIV(di->fcc);
859 di->is_halt = is_rk816_bat_last_halt(di);
860 di->halt_cnt = rk816_bat_get_halt_cnt(di);
861 di->is_ocv_calib = is_rk816_bat_ocv_valid(di);
862
863 if (di->is_halt) {
864 BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
865 pre_cap, now_cap);
866 if (now_cap < 0)
867 now_cap = 0;
868 rk816_bat_init_capacity(di, now_cap);
869 pre_cap = di->remain_cap;
870 pre_soc = di->rsoc;
871 goto finish;
872 } else if (di->is_ocv_calib) {
873 ocv_vol = rk816_bat_get_ocv_voltage(di);
874 ocv_soc = rk816_bat_vol_to_soc(di, ocv_vol);
875 ocv_cap = rk816_bat_vol_to_cap(di, ocv_vol);
876 pre_cap = ocv_cap;
877 BAT_INFO("do ocv calib.. rsoc=%d\n", ocv_soc);
878
879 if (abs(ocv_soc - pre_soc) >= di->max_soc_offset) {
880 BAT_INFO("trigger max soc offset, soc: %d -> %d\n",
881 pre_soc, ocv_soc);
882 pre_soc = ocv_soc;
883 di->is_max_soc_offset = true;
884 }
885 BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
886 }
887 finish:
888 di->dsoc = pre_soc;
889 di->nac = pre_cap;
890 rk816_bat_init_capacity(di, di->nac);
891 rk816_bat_set_initialized_state(di);
892 BAT_INFO("dl=%d rl=%d cap=%d m=%d v=%d ov=%d c=%d pl=%d ch=%d Ver=%s\n",
893 di->dsoc, di->rsoc, di->remain_cap, di->pwroff_min,
894 rk816_bat_get_avg_voltage(di), rk816_bat_get_ocv_voltage(di),
895 rk816_bat_get_avg_current(di), rk816_bat_get_dsoc(di),
896 rk816_bat_get_usb_state(di), DRIVER_VERSION
897 );
898 }
899
is_rk816_bat_first_poweron(struct battery_priv * di)900 static bool is_rk816_bat_first_poweron(struct battery_priv *di)
901 {
902 u8 buf;
903
904 buf = rk816_bat_read(di, GGSTS_REG);
905 if (buf & BAT_CON) {
906 buf &= ~BAT_CON;
907 rk816_bat_write(di, GGSTS_REG, buf);
908 return true;
909 }
910
911 return false;
912 }
913
rk816_bat_ocv_sw_reset(struct battery_priv * di)914 static bool rk816_bat_ocv_sw_reset(struct battery_priv *di)
915 {
916 u8 buf;
917
918 buf = rk816_bat_read(di, MISC_MARK_REG);
919 if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) ||
920 (buf & FG_RESET_NOW)) {
921 buf &= ~FG_RESET_LATE;
922 buf &= ~FG_RESET_NOW;
923 rk816_bat_write(di, MISC_MARK_REG, buf);
924 BAT_INFO("manual reset fuel gauge\n");
925 return true;
926 } else {
927 return false;
928 }
929 }
930
rk816_bat_calc_linek(struct battery_priv * di)931 static int rk816_bat_calc_linek(struct battery_priv *di)
932 {
933 int linek, diff, delta;
934
935 di->calc_dsoc = di->dsoc;
936 di->calc_rsoc = di->rsoc;
937 di->sm_old_cap = di->remain_cap;
938
939 delta = abs(di->dsoc - di->rsoc);
940 diff = delta * 3;
941 di->sm_meet_soc = (di->dsoc >= di->rsoc) ?
942 (di->dsoc + diff) : (di->rsoc + diff);
943
944 if (di->dsoc < di->rsoc)
945 linek = 1000 * (delta + diff) / DIV(diff);
946 else if (di->dsoc > di->rsoc)
947 linek = 1000 * diff / DIV(delta + diff);
948 else
949 linek = 1000;
950
951 di->sm_chrg_dsoc = di->dsoc * 1000;
952
953 DBG("<%s>. meet=%d, diff=%d, link=%d, calc: dsoc=%d, rsoc=%d\n",
954 __func__, di->sm_meet_soc, diff, linek,
955 di->calc_dsoc, di->calc_rsoc);
956
957 return linek;
958 }
959
rk816_bat_get_coffset(struct battery_priv * di)960 static int rk816_bat_get_coffset(struct battery_priv *di)
961 {
962 int val = 0;
963
964 val |= rk816_bat_read(di, CAL_OFFSET_REGL) << 0;
965 val |= rk816_bat_read(di, CAL_OFFSET_REGH) << 8;
966
967 return val;
968 }
969
rk816_bat_init_poffset(struct battery_priv * di)970 static void rk816_bat_init_poffset(struct battery_priv *di)
971 {
972 int coffset, ioffset;
973
974 coffset = rk816_bat_get_coffset(di);
975 ioffset = rk816_bat_get_ioffset(di);
976 di->poffset = coffset - ioffset;
977 }
978
rk816_bat_select_sample_res(struct battery_priv * di)979 static void rk816_bat_select_sample_res(struct battery_priv *di)
980 {
981 /* Here, res_fac is 10 times of real value for good calcuation */
982 if (di->sample_res == SAMPLE_RES_20MR) {
983 di->over_20mR = 0;
984 di->res_fac = 10;
985 } else if (di->sample_res > SAMPLE_RES_20MR) {
986 di->over_20mR = 1;
987 di->res_fac = di->sample_res * 10 / SAMPLE_RES_20MR;
988 } else {
989 di->over_20mR = 0;
990 di->res_fac = SAMPLE_RES_20MR * 10 / di->sample_res;
991 }
992 }
is_rk816_bat_exist(struct battery_priv * di)993 static bool is_rk816_bat_exist(struct battery_priv *di)
994 {
995 return (rk816_bat_read(di, SUP_STS_REG) & BAT_EXS) ? true : false;
996 }
997
rk816_bat_set_current(struct battery_priv * di,int input_current)998 static void rk816_bat_set_current(struct battery_priv *di, int input_current)
999 {
1000 u8 usb_ctrl;
1001
1002 usb_ctrl = rk816_bat_read(di, USB_CTRL_REG);
1003 usb_ctrl &= ~INPUT_CUR_MSK;
1004 usb_ctrl |= (input_current);
1005 rk816_bat_write(di, USB_CTRL_REG, usb_ctrl);
1006 }
1007
rk816_bat_charger_setting(struct battery_priv * di,int charger)1008 static void rk816_bat_charger_setting(struct battery_priv *di, int charger)
1009 {
1010 static u8 old_charger = UNDEF_CHARGER;
1011
1012 /*charger changed*/
1013 if (old_charger != charger) {
1014 if (charger == NO_CHARGER)
1015 rk816_bat_set_current(di, ILIM_450MA);
1016 else if (charger == USB_CHARGER)
1017 rk816_bat_set_current(di, ILIM_450MA);
1018 else if (charger == DC_CHARGER || charger == AC_CHARGER)
1019 rk816_bat_set_current(di, di->chrg_cur_input);
1020 else
1021 BAT_INFO("charger setting error %d\n", charger);
1022
1023 old_charger = charger;
1024 }
1025 }
1026
rk816_bat_get_dc_state(struct battery_priv * di)1027 static int rk816_bat_get_dc_state(struct battery_priv *di)
1028 {
1029 /* struct adc_channel val; */
1030
1031 if (di->dc_type == DC_TYPE_OF_NONE) {
1032 return NO_CHARGER;
1033 } else if (di->dc_type == DC_TYPE_OF_ADC) {
1034 /*
1035 if (adc_channels_single_shot("saradc", 0, &val)) {
1036 printf("read saradc value failed\n");
1037 return NO_CHARGER;
1038 }
1039
1040 return (val.data >= DC_ADC_TRIGGER) ? DC_CHARGER : NO_CHARGER;
1041 */
1042 return NO_CHARGER;
1043 } else {
1044 return (dm_gpio_get_value(&di->dc_det)) ?
1045 DC_CHARGER : NO_CHARGER;
1046 }
1047 }
1048
rk816_bat_get_charger_type(struct battery_priv * di)1049 static int rk816_bat_get_charger_type(struct battery_priv *di)
1050 {
1051 int charger_type = NO_CHARGER;
1052
1053 /* check by ic hardware: this check make check work safer */
1054 if ((rk816_bat_read(di, VB_MON_REG) & PLUG_IN_STS) == 0)
1055 return NO_CHARGER;
1056
1057 /* virtual or bat not exist */
1058 if (di->virtual_power)
1059 return DC_CHARGER;
1060
1061 /* check DC first */
1062 charger_type = rk816_bat_get_dc_state(di);
1063 if (charger_type == DC_CHARGER)
1064 return charger_type;
1065
1066 /* check USB second */
1067 return rk816_bat_get_usb_state(di);
1068 }
1069
rk816_bat_need_initialize(struct battery_priv * di)1070 static bool rk816_bat_need_initialize(struct battery_priv *di)
1071 {
1072 bool initialize = false;
1073 #ifdef CONFIG_DM_CHARGE_DISPLAY
1074 struct charge_animation_pdata *pdata;
1075 struct udevice *dev;
1076 int est_voltage;
1077
1078 if (!uclass_find_first_device(UCLASS_CHARGE_DISPLAY, &dev)) {
1079 pdata = dev_get_platdata(dev);
1080 est_voltage = rk816_bat_get_avg_voltage(di);
1081 if ((pdata->uboot_charge) ||
1082 (pdata->low_power_voltage >= est_voltage))
1083 initialize = true;
1084 }
1085 #endif
1086
1087 return initialize;
1088 }
1089
rk816_bat_init_rsoc(struct battery_priv * di)1090 void rk816_bat_init_rsoc(struct battery_priv *di)
1091 {
1092 bool initialize = false;
1093
1094 di->is_first_power_on = is_rk816_bat_first_poweron(di);
1095 /* If first power on, we must do initialization */
1096 if (di->is_first_power_on)
1097 initialize = true;
1098 /* Only charger online and under threshold, we do initialization */
1099 else if (rk816_bat_get_charger_type(di) != NO_CHARGER)
1100 initialize = rk816_bat_need_initialize(di);
1101
1102 printf("Fuel gauge initialize = %d\n", initialize);
1103
1104 if (!initialize)
1105 return;
1106
1107 di->pwroff_min = rk816_bat_get_pwroff_min(di);
1108 di->is_sw_reset = rk816_bat_ocv_sw_reset(di);
1109
1110 if (di->is_first_power_on || di->is_sw_reset)
1111 rk816_bat_first_pwron(di);
1112 else
1113 rk816_bat_not_first_pwron(di);
1114
1115 rk816_bat_save_dsoc(di, di->dsoc);
1116 rk816_bat_save_cap(di, di->remain_cap);
1117 }
1118
rk816_fg_init(struct battery_priv * di)1119 static int rk816_fg_init(struct battery_priv *di)
1120 {
1121 rk816_bat_enable_input_current(di);
1122 rk816_bat_enable_gauge(di);
1123 rk816_bat_set_vol_instant_mode(di);
1124 rk816_bat_init_voltage_kb(di);
1125 rk816_bat_init_poffset(di);
1126 rk816_bat_select_sample_res(di);
1127 rk816_bat_clr_initialized_state(di);
1128 di->dsoc = rk816_bat_get_dsoc(di);
1129 di->remain_cap = rk816_bat_get_prev_cap(di);
1130
1131 /*
1132 * It's better to init fg in kernel,
1133 * so avoid init in uboot as far as possible.
1134 */
1135 rk816_bat_init_rsoc(di);
1136 rk816_bat_init_chrg_config(di);
1137 di->chrg_type = rk816_bat_get_charger_type(di);
1138 di->voltage_avg = rk816_bat_get_avg_voltage(di);
1139 di->voltage_ocv = rk816_bat_get_ocv_voltage(di);
1140 di->current_avg = rk816_bat_get_avg_current(di);
1141 di->sm_linek = rk816_bat_calc_linek(di);
1142 di->finish_chrg_base = get_timer(0);
1143 di->pwr_vol = di->voltage_avg;
1144 rk816_bat_charger_setting(di, di->chrg_type);
1145
1146 printf("Battery: soc=%d%%, cap=%dmAh, voltage=%dmv, Charger: %s%s\n",
1147 di->dsoc, di->remain_cap, di->voltage_avg,
1148 charger_type_to_name[di->chrg_type],
1149 di->virtual_power ? "(virtual)" : "");
1150
1151 return 0;
1152 }
1153
rk816_bat_get_chrg_status(struct battery_priv * di)1154 static u8 rk816_bat_get_chrg_status(struct battery_priv *di)
1155 {
1156 u8 status;
1157
1158 status = rk816_bat_read(di, SUP_STS_REG) & BAT_STATUS_MSK;
1159 switch (status) {
1160 case CHARGE_OFF:
1161 DBG("CHARGE-OFF...\n");
1162 break;
1163 case DEAD_CHARGE:
1164 DBG("DEAD CHARGE...\n");
1165 break;
1166 case TRICKLE_CHARGE:
1167 DBG("TRICKLE CHARGE...\n ");
1168 break;
1169 case CC_OR_CV:
1170 DBG("CC or CV...\n");
1171 break;
1172 case CHARGE_FINISH:
1173 DBG("CHARGE FINISH...\n");
1174 break;
1175 case USB_OVER_VOL:
1176 DBG("USB OVER VOL...\n");
1177 break;
1178 case BAT_TMP_ERR:
1179 DBG("BAT TMP ERROR...\n");
1180 break;
1181 case TIMER_ERR:
1182 DBG("TIMER ERROR...\n");
1183 break;
1184 case USB_EXIST:
1185 DBG("USB EXIST...\n");
1186 break;
1187 case USB_EFF:
1188 DBG(" USB EFF...\n");
1189 break;
1190 default:
1191 return -EINVAL;
1192 }
1193
1194 return status;
1195 }
1196
rk816_bat_finish_chrg(struct battery_priv * di)1197 static void rk816_bat_finish_chrg(struct battery_priv *di)
1198 {
1199 u32 tgt_sec = 0;
1200
1201 if (di->dsoc < 100) {
1202 tgt_sec = di->fcc * 3600 / 100 / FINISH_CALI_CURR;
1203 if (get_timer(di->finish_chrg_base) > SECONDS(tgt_sec)) {
1204 di->finish_chrg_base = get_timer(0);
1205 di->dsoc++;
1206 }
1207 }
1208 DBG("<%s>. sec=%d, finish_sec=%lu\n", __func__, SECONDS(tgt_sec),
1209 get_timer(di->finish_chrg_base));
1210 }
1211
rk816_bat_debug_info(struct battery_priv * di)1212 static void rk816_bat_debug_info(struct battery_priv *di)
1213 {
1214 u8 sup_sts, ggcon, ggsts, vb_mod, rtc, thermal, misc;
1215 u8 usb_ctrl, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3;
1216 uint32_t chrg_cur;
1217 static const char *name[] = {"NONE", "USB", "AC", "DC", "UNDEF"};
1218
1219 if (!dbg_enable)
1220 return;
1221 ggcon = rk816_bat_read(di, GGCON_REG);
1222 ggsts = rk816_bat_read(di, GGSTS_REG);
1223 sup_sts = rk816_bat_read(di, SUP_STS_REG);
1224 usb_ctrl = rk816_bat_read(di, USB_CTRL_REG);
1225 thermal = rk816_bat_read(di, THERMAL_REG);
1226 vb_mod = rk816_bat_read(di, VB_MON_REG);
1227 misc = rk816_bat_read(di, MISC_MARK_REG);
1228 rtc = rk816_bat_read(di, SECONDS_REG);
1229 chrg_ctrl1 = rk816_bat_read(di, CHRG_CTRL_REG1);
1230 chrg_ctrl2 = rk816_bat_read(di, CHRG_CTRL_REG2);
1231 chrg_ctrl3 = rk816_bat_read(di, CHRG_CTRL_REG3);
1232 if (!di->over_20mR)
1233 chrg_cur = RES_FAC_MUX(CHRG_CUR_SEL[chrg_ctrl1 & 0x0f],
1234 di->res_fac);
1235 else
1236 chrg_cur = RES_FAC_DIV(CHRG_CUR_SEL[chrg_ctrl1 & 0x0f],
1237 di->res_fac);
1238
1239 DBG("\n---------------------- DEBUG REGS ------------------------\n"
1240 "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, SUP_STS= 0x%2x\n"
1241 "VB_MOD=0x%2x, USB_CTRL=0x%2x, THERMAL=0x%2x, MISC=0x%2x\n"
1242 "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n",
1243 ggcon, ggsts, rtc, sup_sts, vb_mod, usb_ctrl,
1244 thermal, misc, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3
1245 );
1246 DBG("----------------------------------------------------------\n"
1247 "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
1248 "K=%d, old_cap=%d, charger=%s, Is=%d, Ip=%d, Vs=%d, Rfac=%d\n"
1249 "min=%d, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d, Rsam=%d\n"
1250 "off: i=0x%x, c=0x%x, max=%d, ocv_c=%d, halt: st=%d, cnt=%d\n"
1251 "pwr: dsoc=%d, rsoc=%d, vol=%d, exist=%d\n",
1252 di->dsoc, rk816_bat_get_rsoc(di), rk816_bat_get_avg_voltage(di),
1253 rk816_bat_get_avg_current(di), di->remain_cap, di->fcc,
1254 di->rsoc - di->dsoc,
1255 di->sm_linek, di->sm_old_cap, name[di->chrg_type],
1256 chrg_cur,
1257 CHRG_CUR_INPUT[usb_ctrl & 0x0f],
1258 CHRG_VOL_SEL[(chrg_ctrl1 & 0x70) >> 4], di->res_fac,
1259 di->pwroff_min,
1260 di->sm_meet_soc, di->calc_dsoc, di->calc_rsoc,
1261 rk816_bat_get_ocv_voltage(di), di->sample_res,
1262 rk816_bat_get_ioffset(di),
1263 rk816_bat_get_coffset(di), di->is_max_soc_offset,
1264 di->is_ocv_calib, di->is_halt, di->halt_cnt, di->pwr_dsoc,
1265 di->pwr_rsoc, di->pwr_vol, is_rk816_bat_exist(di)
1266 );
1267 rk816_bat_get_chrg_status(di);
1268 DBG("###########################################################\n");
1269 }
1270
rk816_bat_linek_algorithm(struct battery_priv * di)1271 static void rk816_bat_linek_algorithm(struct battery_priv *di)
1272 {
1273 int delta_cap, ydsoc, tmp;
1274 u8 chg_st = rk816_bat_get_chrg_status(di);
1275
1276 /* slow down */
1277 if (di->dsoc == 99)
1278 di->sm_linek = CHRG_FULL_K;
1279 else if (di->dsoc >= CHRG_TERM_DSOC && di->current_avg > TERM_CALI_CURR)
1280 di->sm_linek = CHRG_TERM_K;
1281
1282 delta_cap = di->remain_cap - di->sm_old_cap;
1283 ydsoc = di->sm_linek * delta_cap * 100 / DIV(di->fcc);
1284 if (ydsoc > 0) {
1285 tmp = (di->sm_chrg_dsoc + 1) / 1000;
1286 if (tmp != di->dsoc)
1287 di->sm_chrg_dsoc = di->dsoc * 1000;
1288 di->sm_chrg_dsoc += ydsoc;
1289 di->dsoc = (di->sm_chrg_dsoc + 1) / 1000;
1290 di->sm_old_cap = di->remain_cap;
1291 if (di->dsoc == di->rsoc && di->sm_linek != CHRG_FULL_K &&
1292 di->sm_linek != CHRG_TERM_K)
1293 di->sm_linek = 1000;
1294 }
1295
1296 if ((di->sm_linek == 1000 || di->dsoc >= 100) &&
1297 (chg_st != CHARGE_FINISH)) {
1298 if (di->sm_linek == 1000)
1299 di->dsoc = di->rsoc;
1300 di->sm_chrg_dsoc = di->dsoc * 1000;
1301 }
1302
1303 DBG("linek=%d, sm_dsoc=%d, delta_cap=%d, ydsoc=%d, old_cap=%d\n"
1304 "calc: dsoc=%d, rsoc=%d, meet=%d\n",
1305 di->sm_linek, di->sm_chrg_dsoc, delta_cap, ydsoc, di->sm_old_cap,
1306 di->calc_dsoc, di->calc_rsoc, di->sm_meet_soc);
1307 }
1308
rk816_bat_get_iadc(struct battery_priv * di)1309 static int rk816_bat_get_iadc(struct battery_priv *di)
1310 {
1311 int val = 0;
1312
1313 val |= rk816_bat_read(di, BAT_CUR_AVG_REGL) << 0;
1314 val |= rk816_bat_read(di, BAT_CUR_AVG_REGH) << 8;
1315 if (val > 2047)
1316 val -= 4096;
1317
1318 return val;
1319 }
1320
rk816_bat_adc_calib(struct battery_priv * di)1321 static bool rk816_bat_adc_calib(struct battery_priv *di)
1322 {
1323 int i, ioffset, coffset, adc;
1324
1325 if (abs(di->current_avg) < ADC_CALIB_THRESHOLD)
1326 return false;
1327
1328 for (i = 0; i < 5; i++) {
1329 adc = rk816_bat_get_iadc(di);
1330 coffset = rk816_bat_get_coffset(di);
1331 rk816_bat_set_coffset(di, coffset + adc);
1332 mdelay(200);
1333 adc = rk816_bat_get_iadc(di);
1334 if (abs(adc) < ADC_CALIB_THRESHOLD) {
1335 coffset = rk816_bat_get_coffset(di);
1336 ioffset = rk816_bat_get_ioffset(di);
1337 di->poffset = coffset - ioffset;
1338 rk816_bat_write(di, POFFSET_REG, di->poffset);
1339 BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n",
1340 coffset, ioffset, di->poffset);
1341 return true;
1342 } else {
1343 BAT_INFO("coffset calib again %d..\n", i);
1344 rk816_bat_set_coffset(di, coffset);
1345 mdelay(200);
1346 }
1347 }
1348
1349 return false;
1350 }
1351
rk816_bat_smooth_charge(struct battery_priv * di)1352 static void rk816_bat_smooth_charge(struct battery_priv *di)
1353 {
1354 u8 chg_st = rk816_bat_get_chrg_status(di);
1355
1356 if (di->vol_mode_base && get_timer(di->vol_mode_base) > SECONDS(10)) {
1357 rk816_bat_set_vol_avg_mode(di);
1358 di->vol_mode_base = 0;
1359 }
1360
1361 /* not charge mode and not keep in uboot charge: exit */
1362 if ((di->chrg_type == NO_CHARGER) ||
1363 !rk816_bat_is_initialized(di)) {
1364 DBG("chrg=%d, initialized=%d\n", di->chrg_type,
1365 rk816_bat_is_initialized(di));
1366 goto out;
1367 }
1368
1369 /* update rsoc and remain cap */
1370 di->remain_cap = rk816_bat_get_coulomb_cap(di);
1371 di->rsoc = rk816_bat_get_rsoc(di);
1372 if (di->remain_cap > di->fcc) {
1373 di->sm_old_cap -= (di->remain_cap - di->fcc);
1374 rk816_bat_init_capacity(di, di->fcc);
1375 }
1376
1377 /* finish charge step */
1378 if (chg_st == CHARGE_FINISH) {
1379 DBG("finish charge step...\n");
1380 if (di->adc_allow_update)
1381 di->adc_allow_update = !rk816_bat_adc_calib(di);
1382 rk816_bat_finish_chrg(di);
1383 rk816_bat_init_capacity(di, di->fcc);
1384 } else {
1385 DBG("smooth charge step...\n");
1386 di->adc_allow_update = true;
1387 di->finish_chrg_base = get_timer(0);
1388 rk816_bat_linek_algorithm(di);
1389 }
1390
1391 /* dsoc limit */
1392 if (di->dsoc > 100)
1393 di->dsoc = 100;
1394 else if (di->dsoc < 0)
1395 di->dsoc = 0;
1396
1397 rk816_bat_save_dsoc(di, di->dsoc);
1398 rk816_bat_save_cap(di, di->remain_cap);
1399 out:
1400 rk816_bat_debug_info(di);
1401 }
1402
rk816_bat_bat_is_exit(struct udevice * dev)1403 static int rk816_bat_bat_is_exit(struct udevice *dev)
1404 {
1405 struct battery_priv *di = dev_get_priv(dev);
1406
1407 return is_rk816_bat_exist(di);
1408 }
1409
rk816_bat_update_get_soc(struct udevice * dev)1410 static int rk816_bat_update_get_soc(struct udevice *dev)
1411 {
1412 struct battery_priv *di = dev_get_priv(dev);
1413 static ulong seconds;
1414
1415 /* set charge current */
1416 di->chrg_type =
1417 rk816_bat_get_charger_type(di);
1418 rk816_bat_charger_setting(di, di->chrg_type);
1419
1420 /* fg calc every 5 seconds */
1421 if (!seconds)
1422 seconds = get_timer(0);
1423 if (get_timer(seconds) >= SECONDS(5)) {
1424 seconds = get_timer(0);
1425 rk816_bat_smooth_charge(di);
1426 }
1427
1428 /* bat exist, fg init success(dts pass) and uboot charge: report data */
1429 if (!di->virtual_power && di->voltage_k)
1430 return di->dsoc;
1431 else
1432 return VIRTUAL_POWER_SOC;
1433 }
1434
rk816_bat_update_get_voltage(struct udevice * dev)1435 static int rk816_bat_update_get_voltage(struct udevice *dev)
1436 {
1437 struct battery_priv *di = dev_get_priv(dev);
1438
1439 if (!di->virtual_power && di->voltage_k)
1440 return rk816_bat_get_est_voltage(di);
1441 else
1442 return VIRTUAL_POWER_VOL;
1443 }
1444
rk816_bat_update_get_current(struct udevice * dev)1445 static int rk816_bat_update_get_current(struct udevice *dev)
1446 {
1447 struct battery_priv *di = dev_get_priv(dev);
1448
1449 if (!di->virtual_power && di->voltage_k)
1450 return rk816_bat_get_avg_current(di);
1451 else
1452 return VIRTUAL_POWER_CUR;
1453 }
1454
rk816_bat_update_get_chrg_online(struct udevice * dev)1455 static bool rk816_bat_update_get_chrg_online(struct udevice *dev)
1456 {
1457 struct battery_priv *di = dev_get_priv(dev);
1458
1459 return rk816_bat_get_charger_type(di);
1460 }
1461
1462 static struct dm_fuel_gauge_ops fg_ops = {
1463 .bat_is_exist = rk816_bat_bat_is_exit,
1464 .get_soc = rk816_bat_update_get_soc,
1465 .get_voltage = rk816_bat_update_get_voltage,
1466 .get_current = rk816_bat_update_get_current,
1467 .get_chrg_online = rk816_bat_update_get_chrg_online,
1468 };
1469
rk816_fg_ofdata_to_platdata(struct udevice * dev)1470 static int rk816_fg_ofdata_to_platdata(struct udevice *dev)
1471 {
1472 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
1473 struct battery_priv *di = dev_get_priv(dev);
1474 const char *prop;
1475 int len;
1476
1477 if (rk8xx->variant != 0x8160) {
1478 debug("%s: Not support pmic variant: rk%x\n",
1479 __func__, rk8xx->variant);
1480 return -EINVAL;
1481 } else {
1482 di->dev = dev;
1483 }
1484
1485 /* Parse ocv table */
1486 prop = dev_read_prop(dev, "ocv_table", &len);
1487 if (!prop) {
1488 printf("can't find ocv_table prop\n");
1489 return -EINVAL;
1490 }
1491
1492 di->ocv_table = calloc(len, 1);
1493 if (!di->ocv_table) {
1494 printf("can't calloc ocv_table\n");
1495 return -ENOMEM;
1496 }
1497
1498 di->ocv_size = len / 4;
1499 if (dev_read_u32_array(dev, "ocv_table",
1500 di->ocv_table, di->ocv_size)) {
1501 printf("can't read ocv_table\n");
1502 free(di->ocv_table);
1503 return -EINVAL;
1504 }
1505
1506 /* Parse neccessay */
1507 di->design_cap = dev_read_u32_default(dev, "design_capacity", -1);
1508 if (di->design_cap < 0) {
1509 printf("can't read design_capacity\n");
1510 return -EINVAL;
1511 }
1512
1513 di->qmax = dev_read_u32_default(dev, "design_qmax", -1);
1514 if (di->qmax < 0) {
1515 printf("can't read design_qmax\n");
1516 return -EINVAL;
1517 }
1518
1519 /* Parse un-neccessay */
1520 di->dts_vol_sel = dev_read_u32_default(dev, "max_chrg_voltage", 4200);
1521 di->dts_cur_input = dev_read_u32_default(dev, "max_input_current", 2000);
1522 di->dts_cur_sel = dev_read_u32_default(dev, "max_chrg_current", 1200);
1523 di->max_soc_offset = dev_read_u32_default(dev, "max_soc_offset", 70);
1524 di->virtual_power = dev_read_u32_default(dev, "virtual_power", 0);
1525 di->sample_res = dev_read_u32_default(dev, "sample_res", 20);
1526 di->bat_res = dev_read_u32_default(dev, "bat_res", 135);
1527
1528 /* Parse dc type */
1529 di->dc_det_adc = dev_read_u32_default(dev, "dc_det_adc", 0);
1530 if (di->dc_det_adc <= 0) {
1531 if (!gpio_request_by_name_nodev(dev_ofnode(dev), "dc_det_gpio",
1532 0, &di->dc_det, GPIOD_IS_IN)) {
1533 di->dc_type = DC_TYPE_OF_GPIO;
1534 } else {
1535 di->dc_type = DC_TYPE_OF_NONE;
1536 }
1537 } else {
1538 di->dc_type = DC_TYPE_OF_ADC;
1539 }
1540
1541 /* Is battery attached */
1542 if (!is_rk816_bat_exist(di))
1543 di->virtual_power = 1;
1544
1545 DBG("-------------------------------:\n");
1546 DBG("max_input_current:%d\n", di->dts_cur_input);
1547 DBG("max_chrg_current:%d\n", di->dts_cur_sel);
1548 DBG("max_chrg_voltage:%d\n", di->dts_vol_sel);
1549 DBG("design_capacity :%d\n", di->design_cap);
1550 DBG("design_qmax:%d\n", di->qmax);
1551 DBG("max_soc_offset:%d\n", di->max_soc_offset);
1552 DBG("dc_det_adc:%d\n", di->dc_det_adc);
1553 DBG("res_sample:%d\n", di->sample_res);
1554
1555 return 0;
1556 }
1557
rk816_fg_probe(struct udevice * dev)1558 static int rk816_fg_probe(struct udevice *dev)
1559 {
1560 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
1561 struct battery_priv *di = dev_get_priv(dev);
1562
1563 if (rk8xx->variant != 0x8160) {
1564 printf("Not support pmic variant: rk%x\n", rk8xx->variant);
1565 return -EINVAL;
1566 }
1567
1568 return rk816_fg_init(di);
1569 }
1570
1571 U_BOOT_DRIVER(rk816_fg) = {
1572 .name = "rk816_fg",
1573 .id = UCLASS_FG,
1574 .probe = rk816_fg_probe,
1575 .ops = &fg_ops,
1576 .ofdata_to_platdata = rk816_fg_ofdata_to_platdata,
1577 .priv_auto_alloc_size = sizeof(struct battery_priv),
1578 };
1579