2 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
3 * Sanghee Kim <sh0130.kim@samsung.com>
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include <asm/arch/power.h>
29 #include "fuelgauge_battery_data.h"
32 #define DEBUG(fmt,args...) printk(fmt, ##args)
34 #define DEBUG(fmt,args...) do {} while(0)
37 #define msleep(a) udelay(a * 1000)
39 /* Register address */
40 #define MAX77693_REG_STATUS 0x00
41 #define MAX77693_REG_CAPREP 0x05
42 #define MAX77693_REG_SOCREP 0x06
43 #define MAX77693_REG_VCELL 0x09
44 #define MAX77693_REG_CURRENT 0x0A
45 #define MAX77693_REG_AVG_CURRENT 0x0B
46 #define MAX77693_REG_CONFIG 0x1D
47 #define MAX77693_REG_VERSION 0x21
48 #define MAX77693_REG_OCV_RO 0xEE
49 #define MAX77693_REG_OCV_WR 0xFB
50 #define MAX77693_REG_VFSOC 0xFF
52 static int fg_bus = -1;
53 static int rst_status;
54 static int charger_status;
56 static u32 vfocv_table;
57 static const char pszfg[] = "max77693-fg:";
59 /* parameter for SDI 1750mA 2012.02.17 */
61 static u16 sdi_1750_cell_character0[16] = {
62 0xACB0, 0xB630, 0xB950, 0xBA20, 0xBBB0, 0xBBE0, 0xBC30, 0xBD00,
63 0xBD60, 0xBDC0, 0xBF30, 0xC0A0, 0xC480, 0xC890, 0xCC40, 0xD010
67 static u16 sdi_1750_cell_character1[16] = {
68 0x0180, 0x0F10, 0x0060, 0x0E40, 0x3DC0, 0x4E10, 0x2D50, 0x3680,
69 0x3680, 0x0D50, 0x0D60, 0x0D80, 0x0C80, 0x0860, 0x0800, 0x0800
73 static u16 sdi_1750_cell_character2[16] = {
74 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080,
75 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080, 0x0080
78 /* parameter for SDI 2100mA 2012.01.25 */
80 static u16 sdi_2100_cell_character0[16] = {
81 0xA890, 0xB780, 0xB9A0, 0xBBF0, 0xBC30, 0xBC80, 0xBCF0, 0xBD50,
82 0xBE60, 0xBFB0, 0xC1B0, 0xC4B0, 0xC560, 0xCCE0, 0xD170, 0xD7A0
86 static u16 sdi_2100_cell_character1[16] = {
87 0x0150, 0x1000, 0x0C10, 0x3850, 0x2E50, 0x32F0, 0x3040, 0x12F0,
88 0x0FE0, 0x1090, 0x09E0, 0x0BD0, 0x0820, 0x0720, 0x0700, 0x0700
92 static u16 sdi_2100_cell_character2[16] = {
93 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
94 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100
97 /* parameter for SDI 2100mA 2012.10.11 */
99 static u16 sdi_3000_cell_character0[16] = {
100 0xAF70, 0xB570, 0xB7A0, 0xB900, 0xBA70, 0xBBF0, 0xBC40, 0xBC90,
101 0xBE20, 0xBF80, 0xC340, 0xC600, 0xCA90, 0xCD90, 0xD3B0, 0xD7C0
105 static u16 sdi_3000_cell_character1[16] = {
106 0x0170, 0x0D20, 0x0BA0, 0x0BF0, 0x0DF0, 0x3F40, 0x3F00, 0x1A00,
107 0x18E0, 0x09F0, 0x0970, 0x0920, 0x0860, 0x0680, 0x0600, 0x0600
111 static u16 sdi_3000_cell_character2[16] = {
112 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
113 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100
116 /* table_soc = (new_vcell - new_v0)*new_slope/100000 (unit : 0.01% ) */
117 static struct fuelgauge_dsg_data_table {
121 } max77693_fg_dsg_soc_table[19] = {
122 { 410100, 280167, 7638 },
123 { 400000, 329011, 12264 },
124 { 380000, 337808, 14022 },
125 { 377600, 346818, 17883 },
126 { 376100, 353171, 22312 },
127 { 375600, 296446, 6367 },
128 { 375000, 360396, 32929 },
129 { 373000, 358802, 29874 },
130 { 371900, 360851, 34015 },
131 { 370900, 362898, 42288 },
132 { 370000, 363902, 47744 },
133 { 369000, 365484, 64460 },
134 { 368300, 364487, 53280 },
135 { 366800, 360937, 25881 },
136 { 364500, 356525, 14484 },
137 { 361000, 353762, 10324 },
138 { 359400, 357230, 20593 },
139 { 355700, 352425, 6500 },
140 { 311600, 311349, 477 }
143 static struct fuelgauge_chg_data_table {
147 } max77693_fg_chg_soc_table[13] = {
148 { 348100, 326900, 634 },
149 { 365300, 331362, 798 },
150 { 368200, 351400, 1939 },
151 { 372200, 366842, 23987 },
152 { 378900, 361312, 11738 },
153 { 381900, 375992, 73529 },
154 { 382400, 374780, 61013 },
155 { 386300, 361965, 22635 },
156 { 388500, 339987, 11946 },
157 { 391200, 361291, 21538 },
158 { 399200, 350354, 15312 },
159 { 418700, 338278, 12277 },
160 { 419700, 365571, 18646 }
163 /* ocv table for finding vfocv */
164 static struct fuelgauge_ocv_data_table {
168 } max77693_fg_ocv_table[17] = {
169 { 10000, -1421176, 543 },
170 { 9983, 325581, 10936 },
171 { 8370, 351593, 16565 },
172 { 6735, 331923, 11164 },
173 { 5939, 364431, 28706 },
174 { 4541, 371623, 52640 },
175 { 3883, 366294, 30560 },
176 { 3501, 371615, 57067 },
177 { 3073, 371628, 57200 },
178 { 2644, 370772, 48267 },
179 { 2282, 371529, 57460 },
180 { 1920, 370165, 40806 },
181 { 1667, 370099, 40159 },
182 { 1414, 335196, 3680 },
183 { 1230, 364884, 32927 },
184 { 285, 325250, 704 },
188 static struct table_soc_data sdi_2100_table_soc_data[] = {
190 { 3306, 1289, 105100, 3170600 },
191 { 3597, 4059, 4100, 3580300 },
192 { 3622, 10148, 8500, 3535900 },
193 { 3672, 16039, 2200, 3637100 },
194 { 3714, 35344, 4100, 3569600 },
195 { 3782, 51984, 7000, 3420600 },
196 { 3902, 69246, 11400, 3112200 },
197 { 4225, 97566, 0, 100000000 },
200 static struct table_soc_data sdi_3000_table_soc_data[] = {
201 { 3301, 1148, 0, 0 },
202 { 3609, 4230, 0, 0 },
203 { 3640, 11828, 0, 0 },
204 { 3657, 13469, 0, 0 },
205 { 3707, 21840, 0, 0 },
206 { 3733, 34992, 0, 0 },
207 { 3758, 43629, 0, 0 },
208 { 3806, 53027, 0, 0 },
209 { 3900, 65387, 0, 0 },
210 { 4265, 100492, 0, 0 },
213 static inline void mdelay(int msec)
218 static inline u16 fuelgauge_reg_read(int reg)
222 i2c_read(MAX77693_FG_ADDR, reg, 1, (uchar *)&data, 2);
227 static inline void fuelgauge_reg_write(int reg, u16 data)
229 i2c_write(MAX77693_FG_ADDR, reg, 1, (uchar *)&data, 2);
232 static inline void fuelgauge_reg_read_16n(int reg, u16 *data)
236 for (i = 0; i < 16; i++)
237 i2c_read(MAX77693_FG_ADDR, reg + i, 1, (uchar *)(data + i), 2);
240 static inline void fuelgauge_reg_write_16n(int reg, u16 *data)
244 for (i = 0; i < 16; i++)
245 i2c_write(MAX77693_FG_ADDR, reg + i, 1, (uchar *)(data + i), 2);
248 static void fuelgauge_reg_write_and_verify(int reg, u16 data)
250 fuelgauge_reg_write(reg, data);
251 fuelgauge_reg_read(reg);
254 void max77693_fg_bus_init(int bus_num)
259 int max77693_fg_probe(void)
261 unsigned char addr = MAX77693_FG_ADDR;
263 i2c_set_bus_num(fg_bus);
265 if (i2c_probe(addr)) {
266 puts("Can't found max77693 fuel gauge\n");
273 u32 max77693_fg_get_cap(void)
277 value = fuelgauge_reg_read(MAX77693_REG_CAPREP);
279 DEBUG("%s\tcaprep = 0x%x\n", pszfg, value);
284 u32 max77693_fg_get_vcell(void)
289 value = fuelgauge_reg_read(MAX77693_REG_VCELL);
291 vcell = (u32)(value >> 3);
293 DEBUG("%s\tvcell = 0x%x (0x%x)\n", pszfg, vcell, value);
299 static u32 max77693_fg_get_ocv(void)
304 value = fuelgauge_reg_read(MAX77693_REG_OCV_RO);
305 ocv = (u32)(value >> 3);
307 DEBUG("%s\tocv = 0x%x (0x%x)\n", pszfg, vcell, value);
309 return ocv * 625 / 1000;
312 u32 max77693_fg_get_soc(void)
317 value = fuelgauge_reg_read(MAX77693_REG_VFSOC);
318 soc = (u32)(value >> 8);
320 DEBUG("%s\tsoc = 0x%x (0x%x)\n", pszfg, soc, value);
325 static u32 max77693_fg_get_vfocv(void)
330 value = fuelgauge_reg_read(MAX77693_REG_OCV_WR);
331 vfocv = (u32)(value >> 3);
333 DEBUG("%s\tvfocv = 0x%x (0x%x)\n", pszfg, vcell, value);
335 return vfocv * 625 / 1000;
338 static u32 max77693_fg_get_average_vcell(void)
346 for (i = 0; i < AVER_SAMPLE_CNT; i++) {
347 vcell_data = max77693_fg_get_vcell() / 1000;
350 if (vcell_data > vcell_max)
351 vcell_max = vcell_data;
352 else if (vcell_data < vcell_min)
353 vcell_min = vcell_data;
355 vcell_max = vcell_data;
356 vcell_min = vcell_data;
358 vcell_total += vcell_data;
361 return (vcell_total - vcell_max - vcell_min) / (AVER_SAMPLE_CNT - 2);
364 static u32 max77693_fg_get_vfocv_table(u32 raw_soc)
370 idx_end = (int)ARRAY_SIZE(max77693_fg_ocv_table) - 1;
371 for (i = 0, idx = 0; i < idx_end; i++) {
372 if (raw_soc == 0 || raw_soc >= 10000) {
374 } else if (raw_soc <= max77693_fg_ocv_table[i].table_soc &&
375 raw_soc > max77693_fg_ocv_table[i + 1].table_soc) {
383 } else if (raw_soc >= 10000) {
386 vfocv = ((raw_soc * 100000) /
387 max77693_fg_ocv_table[idx].table_slope) +
388 max77693_fg_ocv_table[idx].table_v0;
390 DEBUG("[%d] %d = (%d * 100000) / %d + %d\n",
392 max77693_fg_ocv_table[idx].table_slope,
393 max77693_fg_ocv_table[idx].table_v0);
401 static u16 max77693_fg_check_version(void)
403 u16 version = fuelgauge_reg_read(MAX77693_REG_VERSION);
405 DEBUG("%s\tversion: 0x%x\n", pszfg, version);
410 static void max77693_fg_load_init_config(enum battery_type batt_type)
412 u16 data0[16], data1[16], data2[16];
415 u16 *cell_character0, *cell_character1, *cell_character2;
416 u32 vcell, soc, vfocv;
418 u32 rewrite_count = 5;
420 vcell = max77693_fg_get_average_vcell();
421 soc = max77693_fg_get_soc();
422 vfocv = max77693_fg_get_ocv();
424 printf("%s\tPOR start: vcell(%d), vfocv(%d), soc(%d)\n", pszfg, vcell, vfocv, soc);
426 /* update battery parameter */
428 case BATTERY_SDI_1750:
429 printf("%s\tupdate SDI 1750 parameter\n", pszfg);
430 rcomp0 = SDI_1750_RCOMP0;
431 tempco = SDI_1750_TEMPCO;
432 cell_character0 = sdi_1750_cell_character0;
433 cell_character1 = sdi_1750_cell_character1;
434 cell_character2 = sdi_1750_cell_character2;
436 case BATTERY_SDI_2100:
437 printf("%s\tupdate SDI 2100 parameter\n", pszfg);
438 rcomp0 = SDI_2100_RCOMP0;
439 tempco = SDI_2100_TEMPCO;
440 cell_character0 = sdi_2100_cell_character0;
441 cell_character1 = sdi_2100_cell_character1;
442 cell_character2 = sdi_2100_cell_character2;
444 case BATTERY_SDI_3000:
445 printf("%s\tupdate SDI 3000 parameter\n", pszfg);
446 rcomp0 = SDI_3000_RCOMP0;
447 tempco = SDI_3000_TEMPCO;
448 cell_character0 = sdi_3000_cell_character0;
449 cell_character1 = sdi_3000_cell_character1;
450 cell_character2 = sdi_3000_cell_character2;
454 printf("%s\tunknown battery type, keep parameter\n", pszfg);
461 /* 2. Initilize Configuration */
462 fuelgauge_reg_write(MAX77693_REG_CONFIG, 0x2210);
465 /* 4. Unlock Model Access */
466 fuelgauge_reg_write(0x62, 0x0059);
467 fuelgauge_reg_write(0x63, 0x00C4);
469 /* 5. Write/Read/Verify the Custom Model */
470 fuelgauge_reg_write_16n(0x80, cell_character0);
471 fuelgauge_reg_write_16n(0x90, cell_character1);
472 fuelgauge_reg_write_16n(0xA0, cell_character2);
474 fuelgauge_reg_read_16n(0x80, data0);
475 fuelgauge_reg_read_16n(0x90, data1);
476 fuelgauge_reg_read_16n(0xA0, data2);
478 for (i = 0; i < 16; i++) {
479 if (cell_character0[i] != data0[i])
481 if (cell_character1[i] != data1[i])
483 if (cell_character2[i] != data2[i])
487 /* 8. Lock model access */
488 fuelgauge_reg_write(0x62, 0x0000);
489 fuelgauge_reg_write(0x63, 0x0000);
491 /* 9. Verify the model access is locked */
492 fuelgauge_reg_read_16n(0x80, data0);
493 fuelgauge_reg_read_16n(0x90, data1);
494 fuelgauge_reg_read_16n(0xA0, data2);
496 for (i = 0; i < 16; i++) {
497 /* if any model data is non-zero, it's not locked. */
498 if (data0[i] || data1[i] || data2[i]) {
499 if (rewrite_count--) {
500 printf("%s\tLock model access failed, rewrite it\n", pszfg);
503 printf("%s\tLock model access failed, but ignore it\n", pszfg);
508 /* 10. Write Custom Parameters */
509 fuelgauge_reg_write_and_verify(0x38, rcomp0);
510 fuelgauge_reg_write_and_verify(0x39, tempco);
512 /* 11. Delay at least 350mS */
515 /* 12. Initialization Complete */
516 status = fuelgauge_reg_read(MAX77693_REG_STATUS);
517 /* Write and Verify Status with POR bit Cleared */
518 fuelgauge_reg_write_and_verify(MAX77693_REG_STATUS, (status & 0xFFFD));
520 /* 13. Idendify Battery */
522 /* 14. Check for Fuelgauge Reset */
524 /* 16. Save Learned Parameters */
526 /* 17. Restore Learned Parameters */
528 /* 18. Delay at least 350mS */
530 vcell = max77693_fg_get_average_vcell();
531 soc = max77693_fg_get_soc();
532 vfocv = max77693_fg_get_ocv();
534 printf("%s\tPOR finish: vcell(%d), vfocv(%d), soc(%d)\n", pszfg, vcell, vfocv, soc);
537 static int get_table_soc(u32 vcell, enum battery_type batt_type)
539 s32 raw_table_soc = 0;
541 u32 idx_start, idx_end, idx;
542 struct table_soc_data *table_soc_data;
548 case BATTERY_SDI_2100:
549 table_soc_data = sdi_2100_table_soc_data;
550 idx_end = (int)ARRAY_SIZE(sdi_2100_table_soc_data) - 1;
552 case BATTERY_SDI_3000:
553 table_soc_data = sdi_3000_table_soc_data;
554 idx_end = (int)ARRAY_SIZE(sdi_3000_table_soc_data) - 1;
557 printf("%s\tunknown battery type. uses 2100mAh data default.\n", pszfg);
558 table_soc_data = sdi_2100_table_soc_data;
559 idx_end = (int)ARRAY_SIZE(sdi_2100_table_soc_data) - 1;
563 if (vcell < table_soc_data[idx_start].table_vcell) {
564 printf("%s: vcell(%d) out of range, set table soc as 0\n", __func__, vcell);
566 goto calculate_finish;
567 } else if (vcell > table_soc_data[idx_end].table_vcell) {
568 printf("%s: vcell(%d) out of range, set table soc as 100\n", __func__, vcell);
570 goto calculate_finish;
573 while (idx_start <= idx_end) {
574 idx = (idx_start + idx_end) / 2;
575 if (table_soc_data[idx].table_vcell > vcell) {
577 } else if (table_soc_data[idx].table_vcell < vcell) {
582 table_soc = table_soc_data[idx].table_soc;
584 /* high resolution */
585 if (vcell < table_soc_data[idx].table_vcell)
586 table_soc = table_soc_data[idx].table_soc -
587 ((table_soc_data[idx].table_soc - table_soc_data[idx-1].table_soc) *
588 (table_soc_data[idx].table_vcell - vcell) /
589 (table_soc_data[idx].table_vcell - table_soc_data[idx-1].table_vcell));
591 table_soc = table_soc_data[idx].table_soc +
592 ((table_soc_data[idx+1].table_soc - table_soc_data[idx].table_soc) *
593 (vcell - table_soc_data[idx].table_vcell) /
594 (table_soc_data[idx+1].table_vcell - table_soc_data[idx].table_vcell));
596 printf("%s: vcell(%d) is caculated to t-soc(%d.%d)\n", __func__, vcell, table_soc / 1000, table_soc % 1000);
603 static int check_fuelgauge_powered(void)
607 pwr_chk = fuelgauge_reg_read(MAX77693_REG_OCV_RO);
615 void max77693_fg_init(enum battery_type batt_type, int charger_type)
617 u32 soc, vcell, vfocv, power_check, table_soc, soc_diff, soc_chk_cnt, check_cnt;
618 u32 raw_data, t_raw_data;
619 u16 status, reg_data;
620 u8 recalculation_type = 0, soc_valid = 0;
621 u8 raw_vcell[2], t_raw_vcell[2] = {0 , 0};
623 if (max77693_fg_probe()) {
624 printf("%s\tinitialize failed\n", pszfg);
628 power_check = check_fuelgauge_powered();
629 while (power_check == 0) {
631 power_check = check_fuelgauge_powered();
634 printf("%s\t:fuelgauge is not powered(%d).\n", pszfg, check_cnt);
636 if (check_cnt >= FUELGAUGE_POWER_CHECK_COUNT) {
637 printf("%s\t:fuelgauge power failed.\n", pszfg);
642 charger_status = charger_type;
644 rst_status = get_reset_status();
646 status = fuelgauge_reg_read(MAX77693_REG_STATUS);
648 max77693_fg_load_init_config(batt_type);
654 printf("%s\tpor = 0x%04x\n", pszfg, status);
656 vcell = max77693_fg_get_average_vcell();
657 raw_data = (vcell * 1000) / 625;
659 raw_vcell[1] = (raw_data & 0xff00) >> 8;
660 raw_vcell[0] = raw_data & 0xff;
662 /* NOTICE : use soc after initializing, soc can be changed */
663 soc = max77693_fg_get_soc();
664 vfocv = max77693_fg_get_vfocv();
665 max77693_fg_check_version();
667 printf("%s\tvcell = %d mV, soc = %d, vfocv = %d mV\n",
668 pszfg, vcell, soc, vfocv);
670 if ((batt_type == BATTERY_SDI_2100) || (batt_type == BATTERY_SDI_3000)) {
671 table_soc = get_table_soc(vcell, batt_type);
676 check_soc_validation:
677 /* check validation */
679 soc_diff = soc - table_soc;
681 soc_diff = table_soc - soc;
683 if (soc_diff > SOC_DIFF_TH) {
684 printf("%s: [#%d] diff(%d), soc(%d) and table soc(%d)\n", __func__,
685 ++soc_chk_cnt, soc_diff, soc, table_soc);
687 raw_data = (vcell * 1000) / 625;
689 raw_vcell[1] = (raw_data & 0xff00) >> 8;
690 raw_vcell[0] = raw_data & 0xff;
691 fuelgauge_reg_write(MAX77693_REG_OCV_WR, (raw_vcell[1] << 8) | raw_vcell[0]);
695 soc = max77693_fg_get_soc();
696 vfocv = max77693_fg_get_vfocv();
697 vcell = max77693_fg_get_average_vcell();
698 table_soc = get_table_soc(vcell, batt_type);
700 if (soc_chk_cnt < SOC_DIFF_CHECK_COUNT)
701 goto check_soc_validation;
707 recalculation_type = 0;
709 if (rst_status != SWRESET) {
710 if (charger_status) {
711 if (((vcell - CHG_DV) > (vfocv + T_DV)) || /* h/w POR and cable booting case */
712 (vfocv > vcell)) /* h/w POR with cable present case */
713 recalculation_type = 1;
715 if (((vcell + DSG_DV) > (vfocv + T_DV)) || /* fast batt exchange (low -> high) */
716 (vfocv > ((vcell + DSG_DV) + T_DV))) /* fast batt exchange (high -> low) */
717 recalculation_type = 2;
721 if (vfocv_table != 0) {
722 t_raw_data = (vfocv_table * 1000) / 625;
724 t_raw_vcell[1] = (t_raw_data & 0xff00) >> 8;
725 t_raw_vcell[0] = t_raw_data & 0xff;
728 switch (recalculation_type) {
731 /* 0x200 means 40mV */
732 if (vfocv_table != 0)
733 fuelgauge_reg_write(MAX77693_REG_OCV_WR,
734 (t_raw_vcell[1] << 8) | t_raw_vcell[0]);
736 fuelgauge_reg_write(MAX77693_REG_OCV_WR,
738 0x2) << 8) | (raw_vcell[0] - 0x00));
743 /* 0x2C0 means 55mV */
744 /* 0x340 means 65mV */
745 if (vfocv_table != 0)
746 fuelgauge_reg_write(MAX77693_REG_OCV_WR,
747 (t_raw_vcell[1] << 8) | t_raw_vcell[0]);
749 fuelgauge_reg_write(MAX77693_REG_OCV_WR,
751 0x3) << 8) | (raw_vcell[0] + 0x40));
759 /* NOTICE : use soc after initializing, soc can be changed */
760 soc = max77693_fg_get_soc();
761 vfocv = max77693_fg_get_vfocv();
762 max77693_fg_check_version();
764 printf("%s\tvcell = %d mV, soc = %d, vfocv = %d mV\n",
765 pszfg, vcell, soc, vfocv);
769 static int max77693_fg_reg_dump(void)
773 printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F");
774 for (i = 0; i < 0x100; i++) {
776 printf("\n%02X ", i);
778 printf("%04x ", fuelgauge_reg_read(i));
785 void max77693_fg_show_battery(void)
787 unsigned int soc = max77693_fg_get_soc();
788 unsigned int uV = max77693_fg_get_vcell();
790 if (max77693_fg_probe())
793 printf("battery:\t%d%%\n", soc);
794 printf("voltage:\t%d.%6.6d V\n", uV / 1000000, uV % 1000000);
797 static int do_max77693_fg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
801 if (!strncmp(argv[1], "dump", 4)) {
803 max77693_fg_reg_dump();
817 fg, 4, 1, do_max77693_fg,
818 "Fuel gauge utility for MAX77693-FG",
819 "dump - dump the register\n"