1 /*
2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <dm.h>
8 #include <errno.h>
9 #include <common.h>
10 #include <malloc.h>
11 #include <fdtdec.h>
12 #include <asm/gpio.h>
13 #include <common.h>
14 #include <power/pmic.h>
15 #include <dm/uclass-internal.h>
16 #include <power/charge_display.h>
17 #include <power/charge_animation.h>
18 #include <power/fuel_gauge.h>
19 #include <power/rk8xx_pmic.h>
20 #include <linux/usb/phy-rockchip-usb2.h>
21 #include "fg_regs.h"
22
23 DECLARE_GLOBAL_DATA_PTR;
24
25 static int dbg_enable = 0;
26 #define DBG(args...) \
27 do { \
28 if (dbg_enable) { \
29 printf(args); \
30 } \
31 } while (0)
32
33 #define BAT_INFO(fmt, args...) printf("rk818-bat: "fmt, ##args)
34
35 #define DRIVER_VERSION "2.0"
36
37 /* THERMAL_REG */
38 #define TEMP_105C (0x02 << 2)
39 #define FB_TEMP_MSK 0x0c
40
41 /* CHRG_CTRL_REG2 */
42 #define FINISH_100MA (0x00 << 6)
43 #define FINISH_150MA (0x01 << 6)
44 #define FINISH_200MA (0x02 << 6)
45 #define FINISH_250MA (0x03 << 6)
46 #define FINISH_CUR_MSK 0xc7
47
48 /* CHRG_CTRL_REG3 */
49 #define CHRG_TERM_DIG_SIGNAL (1 << 5)
50 #define CHRG_TERM_ANA_SIGNAL (0 << 5)
51 #define CHRG_TIMER_CCCV_EN (1 << 2)
52 #define CHRG_TERM_SIG_MSK (1 << 5)
53
54 /* CHRG_CTRL_REG */
55 #define ILIM_450MA (0x00)
56 #define ILIM_80MA (0x01)
57 #define ILIM_850MA (0x02)
58 #define ILIM_2000MA (0x07)
59 #define CHRG_CT_EN (1 << 7)
60
61 /* USB_CTRL_REG */
62 #define INPUT_CUR_MSK 0x0f
63
64 /* VB_MON_REG */
65 #define PLUG_IN_STS (1 << 6)
66
67 /* GGSTS */
68 #define BAT_CON (1 << 4)
69 #define VOL_INSTANT (1 << 0)
70 #define VOL_AVG (0 << 0)
71
72 /* TS_CTRL_REG */
73 #define GG_EN (1 << 7)
74
75 /* CHRG_USB_CTRL */
76 #define CHRG_EN (1 << 7)
77
78 /* ADC_CTRL_REG */
79 #define ADC_TS2_EN (1 << 4)
80 #define ADC_TS1_EN (1 << 5)
81
82 /* TS_CTRL_REG */
83 #define TS2_ADC_MODE (1 << 5)
84
85 /* SUP_STS_REG */
86 #define BAT_EXS (1 << 7)
87 #define USB_EXIST (1 << 1)
88 #define USB_EFF (1 << 0)
89 #define CHARGE_OFF (0x00 << 4)
90 #define DEAD_CHARGE (0x01 << 4)
91 #define TRICKLE_CHARGE (0x02 << 4)
92 #define CC_OR_CV (0x03 << 4)
93 #define CHARGE_FINISH (0x04 << 4)
94 #define USB_OVER_VOL (0x05 << 4)
95 #define BAT_TMP_ERR (0x06 << 4)
96 #define TIMER_ERR (0x07 << 4)
97 #define USB_VLIMIT_EN (1 << 3)
98 #define USB_CLIMIT_EN (1 << 2)
99 #define BAT_STATUS_MSK 0x70
100
101 /* GGCON */
102 #define ADC_CUR_MODE (1 << 1)
103
104 /* CALI PARAM */
105 #define FINISH_CALI_CURR 1500
106 #define TERM_CALI_CURR 600
107 #define VIRTUAL_POWER_VOL 4200
108 #define VIRTUAL_POWER_CUR 1000
109 #define VIRTUAL_POWER_SOC 66
110 #define SECONDS(n) ((n) * 1000)
111
112 /* CALC PARAM */
113 #define MAX_PERCENTAGE 100
114 #define MAX_INTERPOLATE 1000
115 #define MAX_INT 0x7fff
116 #define MIN_FCC 500
117
118 /* sample resistor and division */
119 #define SAMPLE_RES_10mR 10
120 #define SAMPLE_RES_20mR 20
121 #define SAMPLE_RES_DIV1 1
122 #define SAMPLE_RES_DIV2 2
123
124 #define FG_INIT (1 << 5)
125 #define FG_RESET_LATE (1 << 4)
126 #define FG_RESET_NOW (1 << 3)
127
128 #define DEFAULT_POFFSET 42
129 #define DEFAULT_COFFSET 0x832
130 #define INVALID_COFFSET_MIN 0x780
131 #define INVALID_COFFSET_MAX 0x980
132
133 #define CHRG_TERM_DSOC 90
134 #define CHRG_TERM_K 650
135 #define CHRG_FULL_K 400
136 #define ADC_CALIB_THRESHOLD 4
137
138 #define TS2_THRESHOLD_VOL 4350
139 #define TS2_VALID_VOL 1000
140 #define TS2_VOL_MULTI 0
141 #define TS2_CHECK_CNT 5
142
143 #define ADC_CUR_MSK 0x03
144 #define ADC_CUR_20UA 0x00
145 #define ADC_CUR_40UA 0x01
146 #define ADC_CUR_60UA 0x02
147 #define ADC_CUR_80UA 0x03
148
149 #define NTC_CALC_FACTOR_80UA 7
150 #define NTC_CALC_FACTOR_60UA 9
151 #define NTC_CALC_FACTOR_40UA 13
152 #define NTC_CALC_FACTOR_20UA 27
153 #define NTC_80UA_MAX_MEASURE 27500
154 #define NTC_60UA_MAX_MEASURE 36666
155 #define NTC_40UA_MAX_MEASURE 55000
156 #define NTC_20UA_MAX_MEASURE 110000
157
158 #define ZERO_MIN_VOLTAGE 3800
159
160 #define TS1_NOT_READY 0xabcdabcd
161
162 #define DIV(x) ((x) ? (x) : 1)
163
164 /***********************************************************/
165 struct battery_priv {
166 struct udevice *dev;
167 int chrg_type;
168 int poffset;
169 int bat_res;
170 int current_avg;
171 int voltage_avg;
172 int voltage_ocv;
173 int voltage_k;
174 int voltage_b;
175 int dsoc;
176 int rsoc;
177 int fcc;
178 int qmax;
179 int remain_cap;
180 int design_cap;
181 int nac;
182 u32 *ocv_table;
183 u32 ocv_size;
184 u32 *ntc_table;
185 u32 ntc_size;
186 u32 ntc_factor;
187 u32 ntc_uA;
188 int ntc_degree_from;
189 int temperature;
190 int virtual_power;
191 int ts2_vol_multi;
192 int pwroff_min;
193 int sm_old_cap;
194 int sm_linek;
195 int sm_chrg_dsoc;
196 int adc_allow_update;
197 int chrg_vol_sel;
198 int chrg_cur_input;
199 int chrg_cur_sel;
200 int dts_vol_sel;
201 int dts_cur_input;
202 int dts_cur_sel;
203 int max_soc_offset;
204 int sample_res;
205 int res_div;
206 struct gpio_desc dc_det;
207 int dc_det_adc;
208 ulong finish_chrg_base;
209 ulong term_sig_base;
210 u8 calc_dsoc;
211 u8 calc_rsoc;
212 int sm_meet_soc;
213 u8 halt_cnt;
214 u8 dc_active_level;
215 u8 dc_is_valid;
216 bool is_halt;
217 bool is_ocv_calib;
218 bool is_max_soc_offset;
219 bool is_first_power_on;
220 bool is_sw_reset;
221 int pwr_dsoc;
222 int pwr_rsoc;
223 int pwr_vol;
224 };
225
226 enum charger_type {
227 NO_CHARGER = 0,
228 USB_CHARGER,
229 AC_CHARGER,
230 DC_CHARGER,
231 UNDEF_CHARGER,
232 };
233
234 static const u32 CHRG_VOL_SEL[] = {
235 4050, 4100, 4150, 4200, 4250, 4300, 4350
236 };
237
238 static const u32 CHRG_CUR_SEL[] = {
239 1000, 1200, 1400, 1600, 1800, 2000, 2250, 2400, 2600, 2800, 3000
240 };
241
242 static const u32 CHRG_CUR_INPUT[] = {
243 450, 800, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000
244 };
245
rk818_bat_read(struct battery_priv * di,u8 reg)246 static int rk818_bat_read(struct battery_priv *di, u8 reg)
247 {
248 return pmic_reg_read(di->dev->parent, reg);
249 }
250
rk818_bat_write(struct battery_priv * di,u8 reg,u8 buf)251 static void rk818_bat_write(struct battery_priv *di, u8 reg, u8 buf)
252 {
253 pmic_reg_write(di->dev->parent, reg, buf);
254 }
255
rk818_bat_dwc_otg_check_dpdm(void)256 static int rk818_bat_dwc_otg_check_dpdm(void)
257 {
258 #if defined(CONFIG_PHY_ROCKCHIP_INNO_USB2) && !defined(CONFIG_SPL_BUILD)
259 return rockchip_chg_get_type();
260 #else
261 debug("rockchip_chg_get_type() is not implement\n");
262 return NO_CHARGER;
263 #endif
264 }
265
rk818_bat_get_rsoc(struct battery_priv * di)266 static int rk818_bat_get_rsoc(struct battery_priv *di)
267 {
268 return (di->remain_cap + di->fcc / 200) * 100 / DIV(di->fcc);
269 }
270
rk818_bat_get_dsoc(struct battery_priv * di)271 static int rk818_bat_get_dsoc(struct battery_priv *di)
272 {
273 return rk818_bat_read(di, SOC_REG);
274 }
275
rk818_bat_enable_gauge(struct battery_priv * di)276 static void rk818_bat_enable_gauge(struct battery_priv *di)
277 {
278 u8 val;
279
280 val = rk818_bat_read(di, TS_CTRL_REG);
281 val |= GG_EN;
282 rk818_bat_write(di, TS_CTRL_REG, val);
283 }
284
rk818_bat_get_vcalib0(struct battery_priv * di)285 static int rk818_bat_get_vcalib0(struct battery_priv *di)
286 {
287 int val = 0;
288
289 val |= rk818_bat_read(di, VCALIB0_REGL) << 0;
290 val |= rk818_bat_read(di, VCALIB0_REGH) << 8;
291
292 return val;
293 }
294
rk818_bat_get_vcalib1(struct battery_priv * di)295 static int rk818_bat_get_vcalib1(struct battery_priv *di)
296 {
297 int val = 0;
298
299 val |= rk818_bat_read(di, VCALIB1_REGL) << 0;
300 val |= rk818_bat_read(di, VCALIB1_REGH) << 8;
301
302 return val;
303 }
304
rk818_bat_get_ioffset(struct battery_priv * di)305 static int rk818_bat_get_ioffset(struct battery_priv *di)
306 {
307 int val = 0;
308
309 val |= rk818_bat_read(di, IOFFSET_REGL) << 0;
310 val |= rk818_bat_read(di, IOFFSET_REGH) << 8;
311
312 DBG("<%s>. ioffset: 0x%x\n", __func__, val);
313 return val;
314 }
315
rk818_bat_get_coffset(struct battery_priv * di)316 static int rk818_bat_get_coffset(struct battery_priv *di)
317 {
318 int val = 0;
319
320 val |= rk818_bat_read(di, CAL_OFFSET_REGL) << 0;
321 val |= rk818_bat_read(di, CAL_OFFSET_REGH) << 8;
322
323 DBG("<%s>. coffset: 0x%x\n", __func__, val);
324 return val;
325 }
326
rk818_bat_set_coffset(struct battery_priv * di,int val)327 static void rk818_bat_set_coffset(struct battery_priv *di, int val)
328 {
329 u8 buf;
330
331 buf = (val >> 0) & 0xff;
332 rk818_bat_write(di, CAL_OFFSET_REGL, buf);
333 buf = (val >> 8) & 0xff;
334 rk818_bat_write(di, CAL_OFFSET_REGH, buf);
335
336 DBG("<%s>. set coffset: 0x%x\n", __func__, val);
337 }
338
rk818_bat_init_coffset(struct battery_priv * di)339 static void rk818_bat_init_coffset(struct battery_priv *di)
340 {
341 int ioffset, coffset;
342
343 ioffset = rk818_bat_get_ioffset(di);
344
345 di->poffset = rk818_bat_read(di, POFFSET_REG);
346 if (!di->poffset)
347 di->poffset = DEFAULT_POFFSET;
348
349 coffset = di->poffset + ioffset;
350 if (coffset < INVALID_COFFSET_MIN || coffset > INVALID_COFFSET_MAX)
351 coffset = DEFAULT_COFFSET;
352
353 rk818_bat_set_coffset(di, coffset);
354 }
355
rk818_bat_init_voltage_kb(struct battery_priv * di)356 static void rk818_bat_init_voltage_kb(struct battery_priv *di)
357 {
358 int vcalib0, vcalib1;
359
360 vcalib0 = rk818_bat_get_vcalib0(di);
361 vcalib1 = rk818_bat_get_vcalib1(di);
362 di->voltage_k = (4200 - 3000) * 1000 / DIV(vcalib1 - vcalib0);
363 di->voltage_b = 4200 - (di->voltage_k * vcalib1) / 1000;
364 DBG("%s. vk=%d, vb=%d\n", __func__, di->voltage_k, di->voltage_b);
365 }
366
rk818_bat_get_ocv_voltage(struct battery_priv * di)367 static int rk818_bat_get_ocv_voltage(struct battery_priv *di)
368 {
369 int vol, val = 0;
370
371 val |= rk818_bat_read(di, BAT_OCV_REGL) << 0;
372 val |= rk818_bat_read(di, BAT_OCV_REGH) << 8;
373 vol = di->voltage_k * val / 1000 + di->voltage_b;
374
375 return vol;
376 }
377
rk818_bat_get_avg_current(struct battery_priv * di)378 static int rk818_bat_get_avg_current(struct battery_priv *di)
379 {
380 int val = 0;
381
382 val |= rk818_bat_read(di, BAT_CUR_AVG_REGL) << 0;
383 val |= rk818_bat_read(di, BAT_CUR_AVG_REGH) << 8;
384
385 if (val & 0x800)
386 val -= 4096;
387 val = val * di->res_div * 1506 / 1000;
388
389 return val;
390 }
391
rk818_bat_get_avg_voltage(struct battery_priv * di)392 static int rk818_bat_get_avg_voltage(struct battery_priv *di)
393 {
394 int vol, val = 0;
395
396 val |= rk818_bat_read(di, BAT_VOL_REGL) << 0;
397 val |= rk818_bat_read(di, BAT_VOL_REGH) << 8;
398 vol = di->voltage_k * val / 1000 + di->voltage_b;
399
400 return vol;
401 }
402
rk818_bat_get_est_voltage(struct battery_priv * di)403 static int rk818_bat_get_est_voltage(struct battery_priv *di)
404 {
405 struct charge_animation_pdata *pdata = NULL;
406 struct udevice *dev;
407 int est_vol, vol, curr;
408 int plugin, timeout = 0;
409 int low_power_voltage = 0;
410
411 uclass_find_first_device(UCLASS_CHARGE_DISPLAY, &dev);
412 pdata = dev_get_platdata(dev);
413 low_power_voltage = pdata->low_power_voltage;
414
415 vol = rk818_bat_get_avg_voltage(di);
416 curr = rk818_bat_get_avg_current(di);
417 plugin = rk818_bat_read(di, VB_MON_REG) & PLUG_IN_STS ? 1 : 0;
418 if (di->is_first_power_on || (!plugin && curr >= 0) || (plugin && curr <= 0)) {
419 DBG("%s: curr=%d, plugin=%d, first_on=%d\n",
420 __func__, curr, plugin, di->is_first_power_on);
421 curr = 0;
422 }
423 est_vol = vol - (di->bat_res * curr / 1000);
424
425 while ((est_vol <= low_power_voltage) &&
426 (vol <= low_power_voltage)) {
427 mdelay(100);
428
429 /* Update */
430 vol = rk818_bat_get_avg_voltage(di);
431 curr = rk818_bat_get_avg_current(di);
432 plugin = rk818_bat_read(di, VB_MON_REG) & PLUG_IN_STS;
433 if (di->is_first_power_on || (!plugin && curr >= 0) || (plugin && curr <= 0)) {
434 DBG("%s: while curr=%d, plugin=%d, first_on=%d\n",
435 __func__, curr, plugin, di->is_first_power_on);
436 curr = 0;
437 }
438 est_vol = vol - (di->bat_res * curr / 1000);
439
440 timeout++;
441 if (timeout >= 5)
442 break;
443 }
444
445 return (est_vol >= low_power_voltage) ? est_vol : vol;
446 }
447
rk818_bat_finish_ma(struct battery_priv * di,int fcc)448 static u8 rk818_bat_finish_ma(struct battery_priv *di, int fcc)
449 {
450 u8 ma;
451
452 if (di->res_div == 2)
453 ma = FINISH_100MA;
454 else if (fcc > 5000)
455 ma = FINISH_250MA;
456 else if (fcc >= 4000)
457 ma = FINISH_200MA;
458 else if (fcc >= 3000)
459 ma = FINISH_150MA;
460 else
461 ma = FINISH_100MA;
462
463 return ma;
464 }
465
rk818_bat_select_chrg_cv(struct battery_priv * di)466 static void rk818_bat_select_chrg_cv(struct battery_priv *di)
467 {
468 int index, chrg_vol_sel, chrg_cur_sel, chrg_cur_input;
469
470 chrg_vol_sel = di->dts_vol_sel;
471 chrg_cur_sel = di->dts_cur_sel;
472 chrg_cur_input = di->dts_cur_input;
473 if (di->sample_res == SAMPLE_RES_10mR) {
474 if (chrg_cur_sel > 2000)
475 chrg_cur_sel /= di->res_div;
476 else
477 chrg_cur_sel = 1000;
478 }
479
480 for (index = 0; index < ARRAY_SIZE(CHRG_VOL_SEL); index++) {
481 if (chrg_vol_sel < CHRG_VOL_SEL[index])
482 break;
483 di->chrg_vol_sel = (index << 4);
484 }
485
486 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_INPUT); index++) {
487 if (chrg_cur_input < CHRG_CUR_INPUT[index])
488 break;
489 di->chrg_cur_input = (index << 0);
490 }
491
492 for (index = 0; index < ARRAY_SIZE(CHRG_CUR_SEL); index++) {
493 if (chrg_cur_sel < CHRG_CUR_SEL[index])
494 break;
495 di->chrg_cur_sel = (index << 0);
496 }
497
498 DBG("<%s>. vol=0x%x, input=0x%x, sel=0x%x\n",
499 __func__, di->chrg_vol_sel, di->chrg_cur_input, di->chrg_cur_sel);
500 }
501
rk818_bat_init_chrg_config(struct battery_priv * di)502 static void rk818_bat_init_chrg_config(struct battery_priv *di)
503 {
504 u8 chrg_ctrl1, usb_ctrl, chrg_ctrl2, chrg_ctrl3;
505 u8 sup_sts, ggcon, thermal, finish_ma;
506
507 rk818_bat_select_chrg_cv(di);
508 finish_ma = rk818_bat_finish_ma(di, di->fcc);
509
510 ggcon = rk818_bat_read(di, GGCON_REG);
511 sup_sts = rk818_bat_read(di, SUP_STS_REG);
512 usb_ctrl = rk818_bat_read(di, USB_CTRL_REG);
513 thermal = rk818_bat_read(di, THERMAL_REG);
514 chrg_ctrl2 = rk818_bat_read(di, CHRG_CTRL_REG2);
515 chrg_ctrl3 = rk818_bat_read(di, CHRG_CTRL_REG3);
516
517 /* set charge current and voltage */
518 usb_ctrl &= ~INPUT_CUR_MSK;
519 usb_ctrl |= di->chrg_cur_input;
520 chrg_ctrl1 = (CHRG_EN | di->chrg_vol_sel | di->chrg_cur_sel);
521
522 /* digital signal and finish current*/
523 chrg_ctrl3 &= ~CHRG_TERM_SIG_MSK;
524 chrg_ctrl3 |= CHRG_TERM_ANA_SIGNAL;
525 chrg_ctrl2 &= ~FINISH_CUR_MSK;
526 chrg_ctrl2 |= finish_ma;
527
528 /* cccv mode */
529 chrg_ctrl3 &= ~CHRG_TIMER_CCCV_EN;
530
531 /* enable voltage limit and enable input current limit */
532 sup_sts &= ~USB_VLIMIT_EN;
533 sup_sts |= USB_CLIMIT_EN;
534
535 /* set feedback temperature */
536 usb_ctrl |= CHRG_CT_EN;
537 thermal &= ~FB_TEMP_MSK;
538 thermal |= TEMP_105C;
539
540 /* adc current mode */
541 ggcon |= ADC_CUR_MODE;
542
543 rk818_bat_write(di, GGCON_REG, ggcon);
544 rk818_bat_write(di, SUP_STS_REG, sup_sts);
545 rk818_bat_write(di, USB_CTRL_REG, usb_ctrl);
546 rk818_bat_write(di, THERMAL_REG, thermal);
547 rk818_bat_write(di, CHRG_CTRL_REG1, chrg_ctrl1);
548 rk818_bat_write(di, CHRG_CTRL_REG2, chrg_ctrl2);
549 rk818_bat_write(di, CHRG_CTRL_REG3, chrg_ctrl3);
550 }
551
interpolate(int value,u32 * table,int size)552 static u32 interpolate(int value, u32 *table, int size)
553 {
554 uint8_t i;
555 uint16_t d;
556
557 for (i = 0; i < size; i++) {
558 if (value < table[i])
559 break;
560 }
561
562 if ((i > 0) && (i < size)) {
563 d = (value - table[i - 1]) * (MAX_INTERPOLATE / (size - 1));
564 d /= table[i] - table[i - 1];
565 d = d + (i - 1) * (MAX_INTERPOLATE / (size - 1));
566 } else {
567 d = i * ((MAX_INTERPOLATE + size / 2) / size);
568 }
569
570 if (d > 1000)
571 d = 1000;
572
573 return d;
574 }
575
576 /* returns (a * b) / c */
ab_div_c(u32 a,u32 b,u32 c)577 static int32_t ab_div_c(u32 a, u32 b, u32 c)
578 {
579 bool sign;
580 u32 ans = MAX_INT;
581 int32_t tmp;
582
583 sign = ((((a ^ b) ^ c) & 0x80000000) != 0);
584
585 if (c != 0) {
586 if (sign)
587 c = -c;
588 tmp = ((int32_t)a * b + (c >> 1)) / c;
589 if (tmp < MAX_INT)
590 ans = tmp;
591 }
592
593 if (sign)
594 ans = -ans;
595
596 return ans;
597 }
598
rk818_bat_vol_to_cap(struct battery_priv * di,int voltage)599 static int rk818_bat_vol_to_cap(struct battery_priv *di, int voltage)
600 {
601 u32 *ocv_table, tmp;
602 int ocv_size, ocv_cap;
603
604 ocv_table = di->ocv_table;
605 ocv_size = di->ocv_size;
606 tmp = interpolate(voltage, ocv_table, ocv_size);
607 ocv_cap = ab_div_c(tmp, di->fcc, MAX_INTERPOLATE);
608
609 return ocv_cap;
610 }
611
rk818_bat_vol_to_soc(struct battery_priv * di,int voltage)612 static int rk818_bat_vol_to_soc(struct battery_priv *di, int voltage)
613 {
614 u32 *ocv_table, tmp;
615 int ocv_size, ocv_soc;
616
617 ocv_table = di->ocv_table;
618 ocv_size = di->ocv_size;
619 tmp = interpolate(voltage, ocv_table, ocv_size);
620 ocv_soc = ab_div_c(tmp, MAX_PERCENTAGE, MAX_INTERPOLATE);
621
622 return ocv_soc;
623 }
624
rk818_bat_get_prev_cap(struct battery_priv * di)625 static int rk818_bat_get_prev_cap(struct battery_priv *di)
626 {
627 int val = 0;
628
629 val |= rk818_bat_read(di, REMAIN_CAP_REG3) << 24;
630 val |= rk818_bat_read(di, REMAIN_CAP_REG2) << 16;
631 val |= rk818_bat_read(di, REMAIN_CAP_REG1) << 8;
632 val |= rk818_bat_read(di, REMAIN_CAP_REG0) << 0;
633
634 return val;
635 }
636
rk818_bat_save_fcc(struct battery_priv * di,u32 cap)637 static void rk818_bat_save_fcc(struct battery_priv *di, u32 cap)
638 {
639 u8 buf;
640
641 buf = (cap >> 24) & 0xff;
642 rk818_bat_write(di, NEW_FCC_REG3, buf);
643 buf = (cap >> 16) & 0xff;
644 rk818_bat_write(di, NEW_FCC_REG2, buf);
645 buf = (cap >> 8) & 0xff;
646 rk818_bat_write(di, NEW_FCC_REG1, buf);
647 buf = (cap >> 0) & 0xff;
648 rk818_bat_write(di, NEW_FCC_REG0, buf);
649 }
650
rk818_bat_get_fcc(struct battery_priv * di)651 static int rk818_bat_get_fcc(struct battery_priv *di)
652 {
653 int val = 0;
654
655 val |= rk818_bat_read(di, NEW_FCC_REG3) << 24;
656 val |= rk818_bat_read(di, NEW_FCC_REG2) << 16;
657 val |= rk818_bat_read(di, NEW_FCC_REG1) << 8;
658 val |= rk818_bat_read(di, NEW_FCC_REG0) << 0;
659
660 if (val < MIN_FCC)
661 val = di->design_cap;
662 else if (val > di->qmax)
663 val = di->qmax;
664
665 return val;
666 }
667
rk818_bat_get_pwroff_min(struct battery_priv * di)668 static int rk818_bat_get_pwroff_min(struct battery_priv *di)
669 {
670 u8 cur, last;
671
672 cur = rk818_bat_read(di, NON_ACT_TIMER_CNT_REG);
673 last = rk818_bat_read(di, NON_ACT_TIMER_CNT_SAVE_REG);
674 rk818_bat_write(di, NON_ACT_TIMER_CNT_SAVE_REG, cur);
675
676 return (cur != last) ? cur : 0;
677 }
678
rk818_bat_get_coulomb_cap(struct battery_priv * di)679 static int rk818_bat_get_coulomb_cap(struct battery_priv *di)
680 {
681 int val = 0;
682
683 val |= rk818_bat_read(di, GASCNT_REG3) << 24;
684 val |= rk818_bat_read(di, GASCNT_REG2) << 16;
685 val |= rk818_bat_read(di, GASCNT_REG1) << 8;
686 val |= rk818_bat_read(di, GASCNT_REG0) << 0;
687 val /= 2390;
688
689 return val * di->res_div;
690 }
691
rk818_bat_save_cap(struct battery_priv * di,int cap)692 static void rk818_bat_save_cap(struct battery_priv *di, int cap)
693 {
694 u8 buf;
695 static int old_cap;
696
697 if (old_cap == cap)
698 return;
699
700 if (cap >= di->qmax)
701 cap = di->qmax;
702
703 old_cap = cap;
704 buf = (cap >> 24) & 0xff;
705 rk818_bat_write(di, REMAIN_CAP_REG3, buf);
706 buf = (cap >> 16) & 0xff;
707 rk818_bat_write(di, REMAIN_CAP_REG2, buf);
708 buf = (cap >> 8) & 0xff;
709 rk818_bat_write(di, REMAIN_CAP_REG1, buf);
710 buf = (cap >> 0) & 0xff;
711 rk818_bat_write(di, REMAIN_CAP_REG0, buf);
712 }
713
rk818_bat_init_capacity(struct battery_priv * di,u32 capacity)714 static void rk818_bat_init_capacity(struct battery_priv *di, u32 capacity)
715 {
716 u8 buf;
717 u32 cap;
718 int delta;
719
720 delta = capacity - di->remain_cap;
721 if (!delta)
722 return;
723
724 cap = capacity * 2390 / di->res_div;
725 buf = (cap >> 24) & 0xff;
726 rk818_bat_write(di, GASCNT_CAL_REG3, buf);
727 buf = (cap >> 16) & 0xff;
728 rk818_bat_write(di, GASCNT_CAL_REG2, buf);
729 buf = (cap >> 8) & 0xff;
730 rk818_bat_write(di, GASCNT_CAL_REG1, buf);
731 buf = (cap >> 0) & 0xff;
732 rk818_bat_write(di, GASCNT_CAL_REG0, buf);
733
734 di->remain_cap = rk818_bat_get_coulomb_cap(di);
735 di->rsoc = rk818_bat_get_rsoc(di);
736 rk818_bat_save_cap(di, di->remain_cap);
737 }
738
is_rk818_bat_ocv_valid(struct battery_priv * di)739 static bool is_rk818_bat_ocv_valid(struct battery_priv *di)
740 {
741 return di->pwroff_min >= 30 ? true : false;
742 }
743
rk818_bat_get_usb_state(struct battery_priv * di)744 static int rk818_bat_get_usb_state(struct battery_priv *di)
745 {
746 int charger_type;
747
748 switch (rk818_bat_dwc_otg_check_dpdm()) {
749 case 0:
750 if ((rk818_bat_read(di, VB_MON_REG) & PLUG_IN_STS) != 0)
751 charger_type = DC_CHARGER;
752 else
753 charger_type = NO_CHARGER;
754 break;
755 case 1:
756 case 3:
757 charger_type = USB_CHARGER;
758 break;
759 case 2:
760 case 4:
761 charger_type = AC_CHARGER;
762 break;
763 default:
764 charger_type = NO_CHARGER;
765 }
766
767 return charger_type;
768 }
769
rk818_bat_clr_initialized_state(struct battery_priv * di)770 static void rk818_bat_clr_initialized_state(struct battery_priv *di)
771 {
772 u8 val;
773
774 val = rk818_bat_read(di, MISC_MARK_REG);
775 val &= ~FG_INIT;
776 rk818_bat_write(di, MISC_MARK_REG, val);
777 }
778
rk818_bat_is_initialized(struct battery_priv * di)779 static bool rk818_bat_is_initialized(struct battery_priv *di)
780 {
781 return (rk818_bat_read(di, MISC_MARK_REG) & FG_INIT) ? true : false;
782 }
783
rk818_bat_set_initialized_state(struct battery_priv * di)784 static void rk818_bat_set_initialized_state(struct battery_priv *di)
785 {
786 u8 val;
787
788 val = rk818_bat_read(di, MISC_MARK_REG);
789 if (rk818_bat_get_usb_state(di) != NO_CHARGER) {
790 val |= FG_INIT;
791 rk818_bat_write(di, MISC_MARK_REG, val);
792 BAT_INFO("initialized... estv=%d, ch=%d\n",
793 rk818_bat_get_est_voltage(di),
794 rk818_bat_get_usb_state(di));
795 }
796 }
797
rk818_bat_save_dsoc(struct battery_priv * di,u8 save_soc)798 static void rk818_bat_save_dsoc(struct battery_priv *di, u8 save_soc)
799 {
800 static int old_soc = -1;
801
802 if (old_soc != save_soc) {
803 old_soc = save_soc;
804 rk818_bat_write(di, SOC_REG, save_soc);
805 }
806 }
807
rk818_bat_first_pwron(struct battery_priv * di)808 static void rk818_bat_first_pwron(struct battery_priv *di)
809 {
810 int ocv_vol, vol, curr;
811
812 rk818_bat_save_fcc(di, di->design_cap);
813 ocv_vol = rk818_bat_get_ocv_voltage(di);
814 curr = rk818_bat_get_avg_current(di);
815 di->fcc = rk818_bat_get_fcc(di);
816 di->nac = rk818_bat_vol_to_cap(di, ocv_vol);
817 di->rsoc = rk818_bat_vol_to_soc(di, ocv_vol);
818 di->dsoc = di->rsoc;
819 vol = rk818_bat_get_avg_voltage(di);
820 if (ocv_vol < vol) {
821 BAT_INFO("%s: ocv voltage %d\n", __func__, ocv_vol);
822 ocv_vol = vol;
823 }
824 rk818_bat_save_dsoc(di, di->dsoc);
825 rk818_bat_init_capacity(di, di->nac);
826 rk818_bat_set_initialized_state(di);
827 BAT_INFO("first power on: soc=%d, Vavg=%d, Vocv=%d, c=%d, ch=%d, fcc=%d\n",
828 di->dsoc, vol, ocv_vol, curr, rk818_bat_get_usb_state(di), di->fcc);
829 }
830
rk818_bat_get_halt_cnt(struct battery_priv * di)831 static u8 rk818_bat_get_halt_cnt(struct battery_priv *di)
832 {
833 return rk818_bat_read(di, HALT_CNT_REG);
834 }
835
rk818_bat_inc_halt_cnt(struct battery_priv * di)836 static void rk818_bat_inc_halt_cnt(struct battery_priv *di)
837 {
838 u8 cnt;
839
840 cnt = rk818_bat_read(di, HALT_CNT_REG);
841 rk818_bat_write(di, HALT_CNT_REG, ++cnt);
842 }
843
is_rk818_bat_last_halt(struct battery_priv * di)844 static bool is_rk818_bat_last_halt(struct battery_priv *di)
845 {
846 int pre_cap = rk818_bat_get_prev_cap(di);
847 int now_cap = rk818_bat_get_coulomb_cap(di);
848
849 /* over 5%: system halt last time */
850 if (abs(now_cap - pre_cap) > (di->fcc / 20)) {
851 rk818_bat_inc_halt_cnt(di);
852 return true;
853 } else {
854 return false;
855 }
856 }
857
rk818_bat_not_first_pwron(struct battery_priv * di)858 static void rk818_bat_not_first_pwron(struct battery_priv *di)
859 {
860 int pre_soc, pre_cap, ocv_cap = 0, ocv_soc = 0, ocv_vol, now_cap;
861 int voltage;
862
863 di->fcc = rk818_bat_get_fcc(di);
864 pre_soc = rk818_bat_get_dsoc(di);
865 pre_cap = rk818_bat_get_prev_cap(di);
866 now_cap = rk818_bat_get_coulomb_cap(di);
867 voltage = rk818_bat_get_est_voltage(di);
868 di->pwr_dsoc = pre_soc;
869 di->pwr_rsoc = (now_cap + di->fcc / 200) * 100 / DIV(di->fcc);
870 di->is_halt = is_rk818_bat_last_halt(di);
871 di->halt_cnt = rk818_bat_get_halt_cnt(di);
872 di->is_ocv_calib = is_rk818_bat_ocv_valid(di);
873
874 if (di->is_halt) {
875 BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
876 pre_cap, now_cap);
877 if (now_cap < 0)
878 now_cap = 0;
879 rk818_bat_init_capacity(di, now_cap);
880 pre_cap = di->remain_cap;
881 pre_soc = di->rsoc;
882 goto finish;
883 } else if (di->is_ocv_calib) {
884 ocv_vol = rk818_bat_get_ocv_voltage(di);
885 ocv_soc = rk818_bat_vol_to_soc(di, ocv_vol);
886 ocv_cap = rk818_bat_vol_to_cap(di, ocv_vol);
887 pre_cap = ocv_cap;
888 BAT_INFO("do ocv calib.. rsoc=%d\n", ocv_soc);
889
890 if (abs(ocv_soc - pre_soc) >= di->max_soc_offset) {
891 BAT_INFO("trigger max soc offset, soc: %d -> %d\n",
892 pre_soc, ocv_soc);
893 pre_soc = ocv_soc;
894 di->is_max_soc_offset = true;
895 }
896 BAT_INFO("OCV calib: cap=%d, rsoc=%d\n", ocv_cap, ocv_soc);
897 } else if ((pre_soc == 0) && (voltage >= ZERO_MIN_VOLTAGE)) {
898 if (now_cap < 0)
899 now_cap = 0;
900 rk818_bat_init_capacity(di, now_cap);
901 pre_cap = di->remain_cap;
902 pre_soc = di->rsoc;
903 BAT_INFO("zero calib: voltage=%d\n", voltage);
904 }
905 finish:
906 di->dsoc = pre_soc;
907 di->nac = pre_cap;
908 rk818_bat_init_capacity(di, di->nac);
909 rk818_bat_save_dsoc(di, di->dsoc);
910 rk818_bat_set_initialized_state(di);
911 BAT_INFO("dl=%d rl=%d cap=%d m=%d v=%d ov=%d c=%d pl=%d ch=%d fcc=%d, Ver=%s\n",
912 di->dsoc, di->rsoc, di->remain_cap, di->pwroff_min,
913 rk818_bat_get_avg_voltage(di), rk818_bat_get_ocv_voltage(di),
914 rk818_bat_get_avg_current(di), rk818_bat_get_dsoc(di),
915 rk818_bat_get_usb_state(di), di->fcc, DRIVER_VERSION
916 );
917 }
918
is_rk818_bat_first_poweron(struct battery_priv * di)919 static bool is_rk818_bat_first_poweron(struct battery_priv *di)
920 {
921 u8 buf;
922
923 buf = rk818_bat_read(di, GGSTS_REG);
924 if (buf & BAT_CON) {
925 buf &= ~BAT_CON;
926 rk818_bat_write(di, GGSTS_REG, buf);
927 return true;
928 }
929
930 return false;
931 }
932
rk818_bat_ocv_sw_reset(struct battery_priv * di)933 static bool rk818_bat_ocv_sw_reset(struct battery_priv *di)
934 {
935 u8 buf;
936
937 buf = rk818_bat_read(di, MISC_MARK_REG);
938 if (((buf & FG_RESET_LATE) && di->pwroff_min >= 30) ||
939 (buf & FG_RESET_NOW)) {
940 buf &= ~FG_RESET_LATE;
941 buf &= ~FG_RESET_NOW;
942 rk818_bat_write(di, MISC_MARK_REG, buf);
943 BAT_INFO("manual reset fuel gauge\n");
944 return true;
945 } else {
946 return false;
947 }
948 }
949
rk818_bat_init_rsoc(struct battery_priv * di)950 static void rk818_bat_init_rsoc(struct battery_priv *di)
951 {
952 int charger, voltage, initialize = 0;
953 struct charge_animation_pdata *pdata;
954 struct udevice *dev;
955
956 uclass_find_first_device(UCLASS_CHARGE_DISPLAY, &dev);
957 pdata = dev_get_platdata(dev);
958
959 charger = rk818_bat_get_usb_state(di);
960 voltage = rk818_bat_get_est_voltage(di);
961 di->is_first_power_on = is_rk818_bat_first_poweron(di);
962
963 /*
964 * Do rsoc initialization only when:
965 *
966 * 1. first power on;
967 * 2. charger online + voltage lower than low_power_voltage;
968 * 3. charger online + uboot_charge enabled.
969 * 4. dsoc is 0 but voltage high, obvious wrong.
970 */
971 if (di->is_first_power_on) {
972 initialize = 1;
973 } else if ((di->dsoc == 0) && (voltage >= ZERO_MIN_VOLTAGE)) {
974 initialize = 1;
975 } else if (charger != NO_CHARGER) {
976 if (voltage < pdata->low_power_voltage + 50)
977 initialize = 1;
978 else if (pdata->uboot_charge)
979 initialize = 1;
980 }
981
982 if (!initialize)
983 return;
984
985 di->pwroff_min = rk818_bat_get_pwroff_min(di);
986 di->is_sw_reset = rk818_bat_ocv_sw_reset(di);
987
988 if (di->is_first_power_on || di->is_sw_reset)
989 rk818_bat_first_pwron(di);
990 else
991 rk818_bat_not_first_pwron(di);
992 }
993
rk818_bat_calc_linek(struct battery_priv * di)994 static int rk818_bat_calc_linek(struct battery_priv *di)
995 {
996 int linek, diff, delta;
997
998 di->calc_dsoc = di->dsoc;
999 di->calc_rsoc = di->rsoc;
1000 di->sm_old_cap = di->remain_cap;
1001
1002 delta = abs(di->dsoc - di->rsoc);
1003 diff = delta * 3;
1004 di->sm_meet_soc = (di->dsoc >= di->rsoc) ?
1005 (di->dsoc + diff) : (di->rsoc + diff);
1006
1007 if (di->dsoc < di->rsoc)
1008 linek = 1000 * (delta + diff) / DIV(diff);
1009 else if (di->dsoc > di->rsoc)
1010 linek = 1000 * diff / DIV(delta + diff);
1011 else
1012 linek = 1000;
1013
1014 di->sm_chrg_dsoc = di->dsoc * 1000;
1015
1016 DBG("<%s>. meet=%d, diff=%d, link=%d, calc: dsoc=%d, rsoc=%d\n",
1017 __func__, di->sm_meet_soc, diff, linek,
1018 di->calc_dsoc, di->calc_rsoc);
1019
1020 return linek;
1021 }
1022
rk818_bat_init_ts1(struct battery_priv * di)1023 static void rk818_bat_init_ts1(struct battery_priv *di)
1024 {
1025 u8 buf;
1026 u32 *ntc_table = di->ntc_table;
1027
1028 if (!di->ntc_size)
1029 return;
1030
1031 /* select uA */
1032 buf = rk818_bat_read(di, TS_CTRL_REG);
1033 buf &= ~ADC_CUR_MSK;
1034 /* chose suitable UA for temperature detect */
1035 if (ntc_table[0] < NTC_80UA_MAX_MEASURE) {
1036 di->ntc_factor = NTC_CALC_FACTOR_80UA;
1037 di->ntc_uA = 80;
1038 buf |= ADC_CUR_80UA;
1039 } else if (ntc_table[0] < NTC_60UA_MAX_MEASURE) {
1040 di->ntc_factor = NTC_CALC_FACTOR_60UA;
1041 di->ntc_uA = 60;
1042 buf |= ADC_CUR_60UA;
1043 } else if (ntc_table[0] < NTC_40UA_MAX_MEASURE) {
1044 di->ntc_factor = NTC_CALC_FACTOR_40UA;
1045 di->ntc_uA = 40;
1046 buf |= ADC_CUR_40UA;
1047 } else {
1048 di->ntc_factor = NTC_CALC_FACTOR_20UA;
1049 di->ntc_uA = 20;
1050 buf |= ADC_CUR_20UA;
1051 }
1052 rk818_bat_write(di, TS_CTRL_REG, buf);
1053
1054 /* ADC_TS1_EN */
1055 buf = rk818_bat_read(di, ADC_CTRL_REG);
1056 buf |= ADC_TS1_EN;
1057 rk818_bat_write(di, ADC_CTRL_REG, buf);
1058 }
1059
rk818_bat_init_ts2(struct battery_priv * di)1060 static void rk818_bat_init_ts2(struct battery_priv *di)
1061 {
1062 u8 buf;
1063
1064 if (!di->ts2_vol_multi)
1065 return;
1066
1067 /* TS2 adc mode */
1068 buf = rk818_bat_read(di, TS_CTRL_REG);
1069 buf |= TS2_ADC_MODE;
1070 rk818_bat_write(di, TS_CTRL_REG, buf);
1071
1072 /* TS2 adc enable */
1073 buf = rk818_bat_read(di, ADC_CTRL_REG);
1074 buf |= ADC_TS2_EN;
1075 rk818_bat_write(di, ADC_CTRL_REG, buf);
1076 }
1077
rk818_fg_init(struct battery_priv * di)1078 static int rk818_fg_init(struct battery_priv *di)
1079 {
1080 int cap;
1081
1082 rk818_bat_enable_gauge(di);
1083 rk818_bat_init_voltage_kb(di);
1084 rk818_bat_init_coffset(di);
1085 rk818_bat_init_ts1(di);
1086 rk818_bat_init_ts2(di);
1087 rk818_bat_clr_initialized_state(di);
1088 cap = rk818_bat_get_coulomb_cap(di);
1089 di->dsoc = rk818_bat_get_dsoc(di);
1090 di->rsoc = (cap + di->fcc / 200) * 100 / DIV(di->fcc);
1091
1092 /* dsoc and rsoc maybe initialized here */
1093 rk818_bat_init_rsoc(di);
1094
1095 rk818_bat_init_chrg_config(di);
1096 di->voltage_avg = rk818_bat_get_avg_voltage(di);
1097 di->voltage_ocv = rk818_bat_get_ocv_voltage(di);
1098 di->current_avg = rk818_bat_get_avg_current(di);
1099 di->sm_linek = rk818_bat_calc_linek(di);
1100 di->finish_chrg_base = get_timer(0);
1101 di->term_sig_base = get_timer(0);
1102 di->pwr_vol = di->voltage_avg;
1103
1104 DBG("%s: dsoc=%d, rsoc=%d, v=%d, ov=%d, c=%d, estv=%d\n",
1105 __func__, di->dsoc, di->rsoc, di->voltage_avg, di->voltage_ocv,
1106 di->current_avg, rk818_bat_get_est_voltage(di));
1107
1108 return 0;
1109 }
1110
is_rk818_bat_exist(struct battery_priv * di)1111 static bool is_rk818_bat_exist(struct battery_priv *di)
1112 {
1113 return (rk818_bat_read(di, SUP_STS_REG) & BAT_EXS) ? true : false;
1114 }
1115
rk818_bat_set_current(struct battery_priv * di,int input_current)1116 static void rk818_bat_set_current(struct battery_priv *di, int input_current)
1117 {
1118 u8 usb_ctrl;
1119
1120 usb_ctrl = rk818_bat_read(di, USB_CTRL_REG);
1121 usb_ctrl &= ~INPUT_CUR_MSK;
1122 usb_ctrl |= (input_current);
1123 rk818_bat_write(di, USB_CTRL_REG, usb_ctrl);
1124 }
1125
rk818_bat_get_ts2_voltage(struct battery_priv * di)1126 static int rk818_bat_get_ts2_voltage(struct battery_priv *di)
1127 {
1128 u32 val = 0;
1129
1130 val |= rk818_bat_read(di, RK818_TS2_ADC_REGL) << 0;
1131 val |= rk818_bat_read(di, RK818_TS2_ADC_REGH) << 8;
1132
1133 /* refer voltage 2.2V, 12bit adc accuracy */
1134 val = val * 2200 * di->ts2_vol_multi / 4095;
1135 DBG("<%s>. ts2 voltage=%d\n", __func__, val);
1136
1137 return val;
1138 }
1139
rk818_bat_ts2_update_current(struct battery_priv * di)1140 static void rk818_bat_ts2_update_current(struct battery_priv *di)
1141 {
1142 int ts2_vol, input_current, invalid_cnt = 0, confirm_cnt = 0;
1143
1144 rk818_bat_set_current(di, ILIM_450MA);
1145 input_current = ILIM_850MA;
1146 while (input_current < di->chrg_cur_input) {
1147 mdelay(100);
1148 ts2_vol = rk818_bat_get_ts2_voltage(di);
1149 DBG("******** ts2 vol=%d\n", ts2_vol);
1150 /* filter invalid voltage */
1151 if (ts2_vol <= TS2_VALID_VOL) {
1152 invalid_cnt++;
1153 DBG("%s: invalid ts2 voltage: %d\n, cnt=%d",
1154 __func__, ts2_vol, invalid_cnt);
1155 if (invalid_cnt < TS2_CHECK_CNT)
1156 continue;
1157
1158 /* if fail, set max input current as default */
1159 input_current = di->chrg_cur_input;
1160 rk818_bat_set_current(di, input_current);
1161 break;
1162 }
1163
1164 /* update input current */
1165 if (ts2_vol >= TS2_THRESHOLD_VOL) {
1166 /* update input current */
1167 input_current++;
1168 rk818_bat_set_current(di, input_current);
1169 DBG("********* input=%d\n",
1170 CHRG_CUR_INPUT[input_current & 0x0f]);
1171 } else {
1172 /* confirm lower threshold voltage */
1173 confirm_cnt++;
1174 if (confirm_cnt < TS2_CHECK_CNT) {
1175 DBG("%s: confirm ts2 voltage: %d\n, cnt=%d",
1176 __func__, ts2_vol, confirm_cnt);
1177 continue;
1178 }
1179
1180 /* trigger threshold, so roll back 1 step */
1181 input_current--;
1182 if (input_current == ILIM_80MA ||
1183 input_current < 0)
1184 input_current = ILIM_450MA;
1185 rk818_bat_set_current(di, input_current);
1186 break;
1187 }
1188 }
1189
1190 BAT_INFO("DC_CHARGER charge_cur_input=%d\n",
1191 CHRG_CUR_INPUT[input_current]);
1192 }
1193
rk818_bat_charger_setting(struct battery_priv * di,int charger)1194 static void rk818_bat_charger_setting(struct battery_priv *di, int charger)
1195 {
1196 static u8 old_charger = UNDEF_CHARGER;
1197 struct charge_animation_pdata *pdata;
1198 struct udevice *dev;
1199 int low_power_voltage = 0;
1200
1201 uclass_find_first_device(UCLASS_CHARGE_DISPLAY, &dev);
1202 pdata = dev_get_platdata(dev);
1203 low_power_voltage = pdata->low_power_voltage;
1204
1205 /* charger changed */
1206 if (old_charger != charger) {
1207 if (charger == NO_CHARGER) {
1208 BAT_INFO("NO_CHARGER\n");
1209 rk818_bat_set_current(di, ILIM_450MA);
1210 } else if (charger == USB_CHARGER) {
1211 BAT_INFO("USB_CHARGER\n");
1212 rk818_bat_set_current(di, ILIM_450MA);
1213 } else if (charger == DC_CHARGER || charger == AC_CHARGER) {
1214 if (pdata->uboot_charge && di->ts2_vol_multi) {
1215 rk818_bat_ts2_update_current(di);
1216 } else if ((rk818_bat_get_est_voltage(di) < low_power_voltage) &&
1217 (di->ts2_vol_multi)) {
1218 rk818_bat_ts2_update_current(di);
1219 } else {
1220 rk818_bat_set_current(di, di->chrg_cur_input);
1221 BAT_INFO("DC_CHARGER\n");
1222 }
1223 } else {
1224 BAT_INFO("charger setting error %d\n", charger);
1225 }
1226
1227 old_charger = charger;
1228 }
1229 }
1230
rk818_bat_get_dc_state(struct battery_priv * di)1231 static int rk818_bat_get_dc_state(struct battery_priv *di)
1232 {
1233 if (!di->dc_is_valid)
1234 return NO_CHARGER;
1235
1236 return dm_gpio_get_value(&di->dc_det) ? DC_CHARGER : NO_CHARGER;
1237 }
1238
rk818_bat_get_charger_type(struct battery_priv * di)1239 static int rk818_bat_get_charger_type(struct battery_priv *di)
1240 {
1241 int charger_type = NO_CHARGER;
1242
1243 /* check by ic hardware: this check make check work safer */
1244 if ((rk818_bat_read(di, VB_MON_REG) & PLUG_IN_STS) == 0)
1245 return NO_CHARGER;
1246
1247 /* virtual or bat not exist */
1248 if (di->virtual_power)
1249 return DC_CHARGER;
1250
1251 /* check DC firstly */
1252 charger_type = rk818_bat_get_dc_state(di);
1253 if (charger_type == DC_CHARGER)
1254 return charger_type;
1255
1256 /* check USB secondly */
1257 return rk818_bat_get_usb_state(di);
1258 }
1259
rk818_bat_get_chrg_status(struct battery_priv * di)1260 static u8 rk818_bat_get_chrg_status(struct battery_priv *di)
1261 {
1262 u8 status;
1263
1264 status = rk818_bat_read(di, SUP_STS_REG) & BAT_STATUS_MSK;
1265 switch (status) {
1266 case CHARGE_OFF:
1267 DBG("CHARGE-OFF...\n");
1268 break;
1269 case DEAD_CHARGE:
1270 DBG("DEAD CHARGE...\n");
1271 break;
1272 case TRICKLE_CHARGE:
1273 DBG("TRICKLE CHARGE...\n ");
1274 break;
1275 case CC_OR_CV:
1276 DBG("CC or CV...\n");
1277 break;
1278 case CHARGE_FINISH:
1279 DBG("CHARGE FINISH...\n");
1280 break;
1281 case USB_OVER_VOL:
1282 DBG("USB OVER VOL...\n");
1283 break;
1284 case BAT_TMP_ERR:
1285 DBG("BAT TMP ERROR...\n");
1286 break;
1287 case TIMER_ERR:
1288 DBG("TIMER ERROR...\n");
1289 break;
1290 case USB_EXIST:
1291 DBG("USB EXIST...\n");
1292 break;
1293 case USB_EFF:
1294 DBG("USB EFF...\n");
1295 break;
1296 default:
1297 return -EINVAL;
1298 }
1299
1300 return status;
1301 }
1302
rk818_bat_finish_chrg(struct battery_priv * di)1303 static void rk818_bat_finish_chrg(struct battery_priv *di)
1304 {
1305 u32 tgt_sec = 0;
1306
1307 if (di->dsoc < 100) {
1308 tgt_sec = di->fcc * 3600 / 100 / FINISH_CALI_CURR;
1309 if (get_timer(di->finish_chrg_base) > SECONDS(tgt_sec)) {
1310 di->finish_chrg_base = get_timer(0);
1311 di->dsoc++;
1312 }
1313 }
1314 DBG("<%s>. sec=%d, finish_sec=%lu\n", __func__, SECONDS(tgt_sec),
1315 get_timer(di->finish_chrg_base));
1316 }
1317
rk818_bat_debug_info(struct battery_priv * di)1318 static void rk818_bat_debug_info(struct battery_priv *di)
1319 {
1320 u8 sup_sts, ggcon, ggsts, vb_mod, rtc, thermal, misc;
1321 u8 usb_ctrl, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3;
1322 static const char *name[] = {"NONE", "USB", "AC", "DC", "UNDEF"};
1323
1324 if (!dbg_enable)
1325 return;
1326 ggcon = rk818_bat_read(di, GGCON_REG);
1327 ggsts = rk818_bat_read(di, GGSTS_REG);
1328 sup_sts = rk818_bat_read(di, SUP_STS_REG);
1329 usb_ctrl = rk818_bat_read(di, USB_CTRL_REG);
1330 thermal = rk818_bat_read(di, THERMAL_REG);
1331 vb_mod = rk818_bat_read(di, VB_MON_REG);
1332 misc = rk818_bat_read(di, MISC_MARK_REG);
1333 rtc = rk818_bat_read(di, SECONDS_REG);
1334 chrg_ctrl1 = rk818_bat_read(di, CHRG_CTRL_REG1);
1335 chrg_ctrl2 = rk818_bat_read(di, CHRG_CTRL_REG2);
1336 chrg_ctrl3 = rk818_bat_read(di, CHRG_CTRL_REG3);
1337
1338 DBG("\n---------------------- DEBUG REGS ------------------------\n"
1339 "GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, SUP_STS= 0x%2x\n"
1340 "VB_MOD=0x%2x, USB_CTRL=0x%2x, THERMAL=0x%2x, MISC=0x%2x\n"
1341 "CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n",
1342 ggcon, ggsts, rtc, sup_sts, vb_mod, usb_ctrl,
1343 thermal, misc, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3
1344 );
1345 DBG("----------------------------------------------------------\n"
1346 "Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d, d=%d\n"
1347 "K=%d, old_cap=%d, charger=%s, Is=%d, Ip=%d, Vs=%d\n"
1348 "min=%d, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n"
1349 "off: i=0x%x, c=0x%x, max=%d, ocv_c=%d, halt: st=%d, cnt=%d\n"
1350 "pwr: dsoc=%d, rsoc=%d, vol=%d, Res=%d, mode=%s, T=%d'C\n",
1351 di->dsoc, rk818_bat_get_rsoc(di), rk818_bat_get_avg_voltage(di),
1352 rk818_bat_get_avg_current(di), di->remain_cap, di->fcc,
1353 di->rsoc - di->dsoc,
1354 di->sm_linek, di->sm_old_cap, name[di->chrg_type],
1355 di->res_div * CHRG_CUR_SEL[chrg_ctrl1 & 0x0f],
1356 CHRG_CUR_INPUT[usb_ctrl & 0x0f],
1357 CHRG_VOL_SEL[(chrg_ctrl1 & 0x70) >> 4], di->pwroff_min,
1358 di->sm_meet_soc, di->calc_dsoc, di->calc_rsoc,
1359 rk818_bat_get_ocv_voltage(di), rk818_bat_get_ioffset(di),
1360 rk818_bat_get_coffset(di), di->is_max_soc_offset,
1361 di->is_ocv_calib, di->is_halt, di->halt_cnt, di->pwr_dsoc,
1362 di->pwr_rsoc, di->pwr_vol, di->sample_res,
1363 di->virtual_power ? "VIRTUAL" : "BAT",
1364 di->temperature
1365 );
1366 rk818_bat_get_chrg_status(di);
1367 DBG("###########################################################\n");
1368 }
1369
rk818_bat_linek_algorithm(struct battery_priv * di)1370 static void rk818_bat_linek_algorithm(struct battery_priv *di)
1371 {
1372 int delta_cap, ydsoc, tmp;
1373 u8 chg_st = rk818_bat_get_chrg_status(di);
1374
1375 /* slow down */
1376 if (di->dsoc == 99)
1377 di->sm_linek = CHRG_FULL_K;
1378 else if (di->dsoc >= CHRG_TERM_DSOC && di->current_avg > TERM_CALI_CURR)
1379 di->sm_linek = CHRG_TERM_K;
1380
1381 delta_cap = di->remain_cap - di->sm_old_cap;
1382 ydsoc = di->sm_linek * delta_cap * 100 / DIV(di->fcc);
1383 if (ydsoc > 0) {
1384 tmp = (di->sm_chrg_dsoc + 1) / 1000;
1385 if (tmp != di->dsoc)
1386 di->sm_chrg_dsoc = di->dsoc * 1000;
1387 di->sm_chrg_dsoc += ydsoc;
1388 di->dsoc = (di->sm_chrg_dsoc + 1) / 1000;
1389 di->sm_old_cap = di->remain_cap;
1390 if (di->dsoc == di->rsoc && di->sm_linek != CHRG_FULL_K &&
1391 di->sm_linek != CHRG_TERM_K)
1392 di->sm_linek = 1000;
1393 }
1394
1395 if ((di->sm_linek == 1000 || di->dsoc >= 100) &&
1396 (chg_st != CHARGE_FINISH)) {
1397 if (di->sm_linek == 1000)
1398 di->dsoc = di->rsoc;
1399 di->sm_chrg_dsoc = di->dsoc * 1000;
1400 }
1401
1402 DBG("linek=%d, sm_dsoc=%d, delta_cap=%d, ydsoc=%d, old_cap=%d\n"
1403 "calc: dsoc=%d, rsoc=%d, meet=%d\n",
1404 di->sm_linek, di->sm_chrg_dsoc, delta_cap, ydsoc, di->sm_old_cap,
1405 di->calc_dsoc, di->calc_rsoc, di->sm_meet_soc);
1406 }
1407
rk818_bat_set_term_mode(struct battery_priv * di,int mode)1408 static void rk818_bat_set_term_mode(struct battery_priv *di, int mode)
1409 {
1410 u8 buf;
1411
1412 buf = rk818_bat_read(di, CHRG_CTRL_REG3);
1413 buf &= ~CHRG_TERM_SIG_MSK;
1414 buf |= mode;
1415 rk818_bat_write(di, CHRG_CTRL_REG3, buf);
1416
1417 DBG("set charge to %s term mode\n", mode ? "digital" : "analog");
1418 }
1419
rk818_bat_get_iadc(struct battery_priv * di)1420 static int rk818_bat_get_iadc(struct battery_priv *di)
1421 {
1422 int val = 0;
1423
1424 val |= rk818_bat_read(di, BAT_CUR_AVG_REGL) << 0;
1425 val |= rk818_bat_read(di, BAT_CUR_AVG_REGH) << 8;
1426 if (val > 2047)
1427 val -= 4096;
1428
1429 return val;
1430 }
1431
rk818_bat_adc_calib(struct battery_priv * di)1432 static bool rk818_bat_adc_calib(struct battery_priv *di)
1433 {
1434 int i, ioffset, coffset, adc;
1435
1436 if (abs(di->current_avg) < ADC_CALIB_THRESHOLD)
1437 return false;
1438
1439 for (i = 0; i < 5; i++) {
1440 adc = rk818_bat_get_iadc(di);
1441 coffset = rk818_bat_get_coffset(di);
1442 rk818_bat_set_coffset(di, coffset + adc);
1443 mdelay(200);
1444 adc = rk818_bat_get_iadc(di);
1445 if (abs(adc) < ADC_CALIB_THRESHOLD) {
1446 coffset = rk818_bat_get_coffset(di);
1447 ioffset = rk818_bat_get_ioffset(di);
1448 di->poffset = coffset - ioffset;
1449 rk818_bat_write(di, POFFSET_REG, di->poffset);
1450 BAT_INFO("new offset:c=0x%x, i=0x%x, p=0x%x\n",
1451 coffset, ioffset, di->poffset);
1452 return true;
1453 } else {
1454 BAT_INFO("coffset calib again %d..\n", i);
1455 rk818_bat_set_coffset(di, coffset);
1456 mdelay(200);
1457 }
1458 }
1459
1460 return false;
1461 }
1462
rk818_bat_smooth_charge(struct battery_priv * di)1463 static void rk818_bat_smooth_charge(struct battery_priv *di)
1464 {
1465 u8 chg_st = rk818_bat_get_chrg_status(di);
1466
1467 /* set terminal charge mode */
1468 if (di->term_sig_base && get_timer(di->term_sig_base) > SECONDS(1)) {
1469 DBG("%s: terminal signal finish mode\n", __func__);
1470 rk818_bat_set_term_mode(di, CHRG_TERM_DIG_SIGNAL);
1471 di->term_sig_base = 0;
1472 }
1473
1474 /* not charge mode and not keep in uboot charge: exit */
1475 if ((di->chrg_type == NO_CHARGER) ||
1476 !rk818_bat_is_initialized(di)) {
1477 DBG("chrg=%d, initialized=%d\n", di->chrg_type,
1478 rk818_bat_is_initialized(di));
1479 goto out;
1480 }
1481
1482 /* update rsoc and remain cap */
1483 di->remain_cap = rk818_bat_get_coulomb_cap(di);
1484 di->rsoc = rk818_bat_get_rsoc(di);
1485 if (di->remain_cap > di->fcc) {
1486 di->sm_old_cap -= (di->remain_cap - di->fcc);
1487 rk818_bat_init_capacity(di, di->fcc);
1488 DBG("%s: init capacity: %d\n", __func__, di->fcc);
1489 }
1490
1491 /* finish charge step */
1492 if (chg_st == CHARGE_FINISH) {
1493 DBG("%s: finish charge step...\n", __func__);
1494 if (di->adc_allow_update)
1495 di->adc_allow_update = !rk818_bat_adc_calib(di);
1496 rk818_bat_finish_chrg(di);
1497 rk818_bat_init_capacity(di, di->fcc);
1498 } else {
1499 DBG("%s: smooth charge step...\n", __func__);
1500 di->adc_allow_update = true;
1501 di->finish_chrg_base = get_timer(0);
1502 rk818_bat_linek_algorithm(di);
1503 }
1504
1505 /* dsoc limit */
1506 if (di->dsoc > 100)
1507 di->dsoc = 100;
1508 else if (di->dsoc < 0)
1509 di->dsoc = 0;
1510
1511 DBG("%s: save dsoc=%d and rsoc=%d\n",
1512 __func__, di->dsoc, rk818_bat_get_rsoc(di));
1513
1514 rk818_bat_save_dsoc(di, di->dsoc);
1515 rk818_bat_save_cap(di, di->remain_cap);
1516 out:
1517 rk818_bat_debug_info(di);
1518 }
1519
1520 /*
1521 * Due to hardware design issue, Vdelta = "(R_sample + R_other) * I_avg" will be
1522 * included into TS1 adc value. We must subtract it to get correct adc value.
1523 * The solution:
1524 *
1525 * (1) calculate Vdelta:
1526 *
1527 * adc1 - Vdelta ua1 (adc2 * ua1) - (adc1 * ua2)
1528 * ------------- = ----- ==> equals: Vdelta = -----------------------------
1529 * adc2 - Vdelta ua2 ua1 - ua2
1530 *
1531 *
1532 * (2) calculate correct ADC value:
1533 *
1534 * charging: ADC = adc1 - abs(Vdelta);
1535 * discharging: ADC = adc1 + abs(Vdelta);
1536 */
rk818_bat_get_ntc_res(struct battery_priv * di)1537 static int rk818_bat_get_ntc_res(struct battery_priv *di)
1538 {
1539 static int adc1 = 0, adc2 = 0, ua1 = 0, ua2 = 0;
1540 static int adc1_update = 0, first_in = 1;
1541 static ulong seconds;
1542 int v_delta, val, res;
1543 u8 buf;
1544
1545 /* hold adc1 and wait 1s for adc2 updated */
1546 if (!adc1_update) {
1547 /* update flag and init adc1,adc2 !! */
1548 adc1_update = 1;
1549 seconds = get_timer(0);
1550 adc1 = 0;
1551 adc2 = 0;
1552
1553 /* read sample ua1 */
1554 buf = rk818_bat_read(di, TS_CTRL_REG);
1555 DBG("<%s>. read adc1, sample uA=%d\n",
1556 __func__, ((buf & 0x03) + 1) * 20);
1557
1558 /* read adc adc1 */
1559 ua1 = di->ntc_uA;
1560 adc1 |= rk818_bat_read(di, TS_ADC_REGL) << 0;
1561 adc1 |= rk818_bat_read(di, TS_ADC_REGH) << 8;
1562
1563 /* chose reference UA for adc2 */
1564 ua2 = (ua1 != 20) ? 20 : 40;
1565 buf = rk818_bat_read(di, TS_CTRL_REG);
1566 buf &= ~ADC_CUR_MSK;
1567 buf |= ((ua2 - 20) / 20);
1568 rk818_bat_write(di, TS_CTRL_REG, buf);
1569 }
1570
1571 /* wait 1s for adc2 updated */
1572 if (get_timer(seconds) < SECONDS(1)) {
1573 if (first_in)
1574 first_in = 0;
1575 else
1576 return TS1_NOT_READY;
1577 }
1578
1579 /* update flags ! */
1580 adc1_update = 0;
1581
1582 /* read sample ua2 */
1583 buf = rk818_bat_read(di, TS_CTRL_REG);
1584 DBG("<%s>. read adc2, sample uA=%d\n",
1585 __func__, ((buf & 0x03) + 1) * 20);
1586
1587 /* read adc adc2 */
1588 adc2 |= rk818_bat_read(di, TS_ADC_REGL) << 0;
1589 adc2 |= rk818_bat_read(di, TS_ADC_REGH) << 8;
1590
1591 DBG("<%s>. ua1=%d, ua2=%d, adc1=%d, adc2=%d\n",
1592 __func__, ua1, ua2, adc1, adc2);
1593
1594 /* calculate delta voltage */
1595 if (adc2 != adc1)
1596 v_delta = abs((adc2 * ua1 - adc1 * ua2) / (ua2 - ua1));
1597 else
1598 v_delta = 0;
1599
1600 /* considering current avg direction, calcuate real adc value */
1601 val = (di->current_avg >= 0) ? (adc1 - v_delta) : (adc1 + v_delta);
1602
1603 DBG("<%s>. Iavg=%d, Vdelta=%d, Vadc=%d\n",
1604 __func__, di->current_avg, v_delta, val);
1605
1606 res = val * di->ntc_factor;
1607
1608 DBG("<%s>. val=%d, ntc_res=%d, ntc_factor=%d\n",
1609 __func__, val, res, di->ntc_factor);
1610
1611 DBG("<%s>. t=[%d'C(%d) ~ %dC(%d)]\n", __func__,
1612 di->ntc_degree_from, di->ntc_table[0],
1613 di->ntc_degree_from + di->ntc_size - 1,
1614 di->ntc_table[di->ntc_size - 1]);
1615
1616 rk818_bat_init_ts1(di);
1617
1618 return res;
1619 }
1620
rk818_bat_update_temperature(struct battery_priv * di)1621 static int rk818_bat_update_temperature(struct battery_priv *di)
1622 {
1623 static int first_time = 1, old_temperature = 25;
1624 u32 ntc_size, *ntc_table;
1625 int i, res, temp;
1626
1627 ntc_table = di->ntc_table;
1628 ntc_size = di->ntc_size;
1629
1630 if (ntc_size) {
1631 res = rk818_bat_get_ntc_res(di);
1632 if (res == TS1_NOT_READY) {
1633 di->temperature = old_temperature;
1634 return TS1_NOT_READY;
1635 }
1636
1637 if (res < ntc_table[ntc_size - 1]) {
1638 di->temperature = di->ntc_degree_from;
1639 old_temperature = di->ntc_degree_from;
1640 printf("bat ntc upper max degree: R=%d\n", res);
1641 } else if (res > ntc_table[0]) {
1642 di->temperature = di->ntc_degree_from + di->ntc_size - 1;
1643 old_temperature = di->ntc_degree_from + di->ntc_size - 1;
1644 printf("bat ntc lower min degree: R=%d\n", res);
1645 } else {
1646 for (i = 0; i < ntc_size; i++) {
1647 if (res >= ntc_table[i])
1648 break;
1649 }
1650
1651 /* if first in, init old_temperature */
1652 temp = (i + di->ntc_degree_from);
1653 if (first_time) {
1654 di->temperature = temp;
1655 old_temperature = temp;
1656 first_time = 0;
1657 }
1658
1659 old_temperature = temp;
1660 di->temperature = temp;
1661 }
1662 }
1663
1664 DBG("temperature=%d\n", di->temperature);
1665
1666 return 0;
1667 }
1668
rk818_bat_bat_is_exit(struct udevice * dev)1669 static int rk818_bat_bat_is_exit(struct udevice *dev)
1670 {
1671 struct battery_priv *di = dev_get_priv(dev);
1672
1673 return is_rk818_bat_exist(di);
1674 }
1675
rk818_bat_update_get_soc(struct udevice * dev)1676 static int rk818_bat_update_get_soc(struct udevice *dev)
1677 {
1678 struct battery_priv *di = dev_get_priv(dev);
1679 static ulong seconds, ts1_seconds;
1680 int wait;
1681
1682 /* set charge current */
1683 di->chrg_type =
1684 rk818_bat_get_charger_type(di);
1685 rk818_bat_charger_setting(di, di->chrg_type);
1686
1687 /* fg calc every 5 seconds */
1688 if (!seconds || !ts1_seconds) {
1689 seconds = get_timer(0);
1690 ts1_seconds = get_timer(0);
1691 }
1692
1693 /* temperature calc every 5 seconds */
1694 if (get_timer(ts1_seconds) >= SECONDS(5)) {
1695 DBG("%s: update temperature\n", __func__);
1696 wait = rk818_bat_update_temperature(di);
1697 if (!wait)
1698 ts1_seconds = get_timer(0);
1699 }
1700
1701 if (get_timer(seconds) >= SECONDS(5)) {
1702 DBG("%s: smooth charge\n", __func__);
1703 seconds = get_timer(0);
1704 rk818_bat_smooth_charge(di);
1705 }
1706
1707 /* bat exist, fg init success(dts pass) and uboot charge: report data */
1708 if (!di->virtual_power && di->voltage_k)
1709 return di->dsoc;
1710 else
1711 return VIRTUAL_POWER_SOC;
1712 }
1713
rk818_bat_update_get_current(struct udevice * dev)1714 static int rk818_bat_update_get_current(struct udevice *dev)
1715 {
1716 struct battery_priv *di = dev_get_priv(dev);
1717
1718 if (!di->virtual_power && di->voltage_k)
1719 return rk818_bat_get_avg_current(di);
1720 else
1721 return VIRTUAL_POWER_CUR;
1722 }
1723
rk818_bat_update_get_voltage(struct udevice * dev)1724 static int rk818_bat_update_get_voltage(struct udevice *dev)
1725 {
1726 struct battery_priv *di = dev_get_priv(dev);
1727
1728 if (!di->virtual_power && di->voltage_k)
1729 return rk818_bat_get_est_voltage(di);
1730 else
1731 return VIRTUAL_POWER_VOL;
1732 }
1733
rk818_bat_update_get_chrg_online(struct udevice * dev)1734 static bool rk818_bat_update_get_chrg_online(struct udevice *dev)
1735 {
1736 struct battery_priv *di = dev_get_priv(dev);
1737
1738 return rk818_bat_get_charger_type(di);
1739 }
1740
1741 static struct dm_fuel_gauge_ops fg_ops = {
1742 .bat_is_exist = rk818_bat_bat_is_exit,
1743 .get_soc = rk818_bat_update_get_soc,
1744 .get_voltage = rk818_bat_update_get_voltage,
1745 .get_current = rk818_bat_update_get_current,
1746 .get_chrg_online = rk818_bat_update_get_chrg_online,
1747 };
1748
rk818_fg_ofdata_to_platdata(struct udevice * dev)1749 static int rk818_fg_ofdata_to_platdata(struct udevice *dev)
1750 {
1751 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
1752 struct battery_priv *di = dev_get_priv(dev);
1753 u32 sign, degree_from[2];
1754 const char *prop;
1755 int len, ret;
1756
1757 if (rk8xx->variant != 0x8180) {
1758 debug("%s: Not support pmic variant: rk%x\n",
1759 __func__, rk8xx->variant);
1760 return -EINVAL;
1761 } else {
1762 di->dev = dev;
1763 }
1764
1765 /* Parse ocv table */
1766 prop = dev_read_prop(dev, "ocv_table", &len);
1767 if (!prop) {
1768 printf("can't find ocv_table prop\n");
1769 return -EINVAL;
1770 }
1771
1772 di->ocv_table = calloc(len, 1);
1773 if (!di->ocv_table) {
1774 printf("can't calloc ocv_table\n");
1775 return -ENOMEM;
1776 }
1777
1778 di->ocv_size = len / 4;
1779 if (dev_read_u32_array(dev, "ocv_table",
1780 di->ocv_table, di->ocv_size)) {
1781 printf("can't read ocv_table\n");
1782 free(di->ocv_table);
1783 return -EINVAL;
1784 }
1785
1786 /* Parse neccessay */
1787 di->design_cap = dev_read_u32_default(dev, "design_capacity", -1);
1788 if (di->design_cap < 0) {
1789 printf("can't read design_capacity\n");
1790 return -EINVAL;
1791 }
1792
1793 di->qmax = dev_read_u32_default(dev, "design_qmax", -1);
1794 if (di->qmax < 0) {
1795 printf("can't read design_qmax\n");
1796 return -EINVAL;
1797 }
1798
1799 /* Parse un-neccessay */
1800 di->dts_vol_sel = dev_read_u32_default(dev, "max_chrg_voltage", 4200);
1801 if (di->dts_vol_sel < 0)
1802 di->dts_vol_sel = dev_read_u32_default(dev,
1803 "max_charge_voltagemV", 4200);
1804
1805 di->dts_cur_input = dev_read_u32_default(dev, "max_input_current", 2000);
1806 if (di->dts_cur_input < 0)
1807 di->dts_cur_input = dev_read_u32_default(dev,
1808 "max_input_currentmA", 2000);
1809
1810 di->dts_cur_sel = dev_read_u32_default(dev, "max_chrg_current", 1200);
1811 if (di->dts_cur_sel < 0)
1812 di->dts_cur_sel = dev_read_u32_default(dev,
1813 "max_chrg_currentmA", 1400);
1814
1815 di->max_soc_offset = dev_read_u32_default(dev, "max_soc_offset", 70);
1816 di->virtual_power = dev_read_u32_default(dev, "virtual_power", 0);
1817 di->bat_res = dev_read_u32_default(dev, "bat_res", 135);
1818 di->sample_res = dev_read_u32_default(dev, "sample_res", SAMPLE_RES_20mR);
1819 di->ts2_vol_multi = dev_read_u32_default(dev, "ts2_vol_multi", 0);
1820
1821 di->res_div = (di->sample_res == SAMPLE_RES_20mR) ?
1822 SAMPLE_RES_DIV1 : SAMPLE_RES_DIV2;
1823
1824 ret = gpio_request_by_name_nodev(dev_ofnode(dev), "dc_det_gpio",
1825 0, &di->dc_det, GPIOD_IS_IN);
1826 if (!ret) {
1827 di->dc_is_valid = 1;
1828 debug("DC is valid\n");
1829 } else {
1830 debug("DC is invalid, ret=%d\n", ret);
1831 }
1832
1833 prop = dev_read_prop(dev, "ntc_table", &len);
1834 if (!prop) {
1835 di->ntc_size = 0;
1836 } else {
1837 ret = dev_read_u32_array(dev, "ntc_degree_from",
1838 degree_from, ARRAY_SIZE(degree_from));
1839 if (ret < 0) {
1840 printf("invalid ntc_degree_from\n");
1841 return -EINVAL;
1842 }
1843
1844 sign = degree_from[0];
1845 di->ntc_degree_from = degree_from[1];
1846 if (sign)
1847 di->ntc_degree_from = -di->ntc_degree_from;
1848
1849 di->ntc_size = len / sizeof(u32);
1850 }
1851
1852 if (di->ntc_size) {
1853 di->ntc_table = calloc(len, 1);
1854 if (!di->ntc_table) {
1855 printf("calloc ocv_table fail\n");
1856 return -ENOMEM;
1857 }
1858
1859 ret = dev_read_u32_array(dev, "ntc_table",
1860 di->ntc_table, di->ntc_size);
1861 if (ret < 0) {
1862 printf("read ntc_table array failed\n");
1863 return ret;
1864 }
1865 }
1866
1867 /* Is battery attached */
1868 if (!is_rk818_bat_exist(di))
1869 di->virtual_power = 1;
1870
1871 DBG("-------------------------------:\n");
1872 DBG("max_input_current:%d\n", di->dts_cur_input);
1873 DBG("max_chrg_current:%d\n", di->dts_cur_sel);
1874 DBG("max_chrg_voltage:%d\n", di->dts_vol_sel);
1875 DBG("design_capacity :%d\n", di->design_cap);
1876 DBG("design_qmax:%d\n", di->qmax);
1877 DBG("max_soc_offset:%d\n", di->max_soc_offset);
1878 DBG("sample_res:%d\n", di->sample_res);
1879 DBG("virtual_power:%d\n", di->virtual_power);
1880 DBG("ts2_vol_multi:%d\n", di->ts2_vol_multi);
1881 DBG("dc det: %d\n", di->dc_is_valid);
1882 DBG("ntc_size:%d\n", di->ntc_size);
1883 DBG("ntc_degree_from:%d\n", di->ntc_degree_from);
1884 DBG("ntc_degree_to:%d\n", di->ntc_degree_from + di->ntc_size - 1);
1885
1886 return 0;
1887 }
1888
rk818_fg_probe(struct udevice * dev)1889 static int rk818_fg_probe(struct udevice *dev)
1890 {
1891 struct rk8xx_priv *rk8xx = dev_get_priv(dev->parent);
1892 struct battery_priv *di = dev_get_priv(dev);
1893
1894 if (rk8xx->variant != 0x8180) {
1895 printf("Not support pmic variant: rk%x\n", rk8xx->variant);
1896 return -EINVAL;
1897 }
1898
1899 return rk818_fg_init(di);
1900 }
1901
1902 U_BOOT_DRIVER(rk818_fg) = {
1903 .name = "rk818_fg",
1904 .id = UCLASS_FG,
1905 .probe = rk818_fg_probe,
1906 .ops = &fg_ops,
1907 .ofdata_to_platdata = rk818_fg_ofdata_to_platdata,
1908 .priv_auto_alloc_size = sizeof(struct battery_priv),
1909 };
1910